Full Code of alibaba/OpenSandbox for AI

main 4cfdce25f870 cached
1108 files
5.8 MB
1.6M tokens
5263 symbols
1 requests
Download .txt
Showing preview only (6,288K chars total). Download the full file or copy to clipboard to get everything.
Repository: alibaba/OpenSandbox
Branch: main
Commit: 4cfdce25f870
Files: 1108
Total size: 5.8 MB

Directory structure:
gitextract_ee6cl8k3/

├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── FEATURE_REQUEST.md
│   │   └── config.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── deploy-docs-pages.yml
│       ├── egress-test.yaml.yml
│       ├── execd-test.yml
│       ├── ingress-test.yaml
│       ├── publish-components.yml
│       ├── publish-csharp-sdks.yml
│       ├── publish-helm-chart.yml
│       ├── publish-java-sdks.yml
│       ├── publish-js-sdks.yml
│       ├── publish-python-sdks.yml
│       ├── publish-server.yml
│       ├── real-e2e.yml
│       ├── sandbox-k8s-e2e.yml
│       ├── sandbox-k8s-test.yml
│       ├── sdk-tests.yml
│       ├── server-test.yml
│       └── verify-license.yml
├── .gitignore
├── .pre-commit-config.yaml
├── AGENTS.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── cli/
│   ├── README.md
│   ├── pyproject.toml
│   ├── src/
│   │   └── opensandbox_cli/
│   │       ├── __init__.py
│   │       ├── __main__.py
│   │       ├── client.py
│   │       ├── commands/
│   │       │   ├── __init__.py
│   │       │   ├── code.py
│   │       │   ├── command.py
│   │       │   ├── config_cmd.py
│   │       │   ├── file.py
│   │       │   └── sandbox.py
│   │       ├── config.py
│   │       ├── main.py
│   │       ├── output.py
│   │       └── utils.py
│   └── tests/
│       ├── __init__.py
│       ├── conftest.py
│       ├── test_cli_help.py
│       ├── test_commands.py
│       ├── test_config.py
│       ├── test_output.py
│       ├── test_resolve_id.py
│       └── test_utils.py
├── components/
│   ├── egress/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── TODO.md
│   │   ├── build.sh
│   │   ├── docs/
│   │   │   └── benchmark.md
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   ├── nameserver.go
│   │   ├── nameserver_test.go
│   │   ├── nft.go
│   │   ├── pkg/
│   │   │   ├── constants/
│   │   │   │   ├── configuration.go
│   │   │   │   └── constants.go
│   │   │   ├── dnsproxy/
│   │   │   │   ├── exempt.go
│   │   │   │   ├── exempt_test.go
│   │   │   │   ├── proxy.go
│   │   │   │   ├── proxy_linux.go
│   │   │   │   ├── proxy_other.go
│   │   │   │   └── proxy_test.go
│   │   │   ├── events/
│   │   │   │   ├── broadcaster.go
│   │   │   │   ├── events_test.go
│   │   │   │   └── webhook.go
│   │   │   ├── iptables/
│   │   │   │   └── redirect.go
│   │   │   ├── log/
│   │   │   │   └── logger.go
│   │   │   ├── nftables/
│   │   │   │   ├── dynamic.go
│   │   │   │   ├── manager.go
│   │   │   │   └── manager_test.go
│   │   │   └── policy/
│   │   │       ├── policy.go
│   │   │       └── policy_test.go
│   │   ├── policy_server.go
│   │   ├── policy_server_test.go
│   │   └── tests/
│   │       ├── bench-dns-nft.sh
│   │       ├── egress-in-webhook.sh
│   │       ├── hostname.txt
│   │       ├── smoke-dns.sh
│   │       ├── smoke-dynamic-ip.sh
│   │       ├── smoke-nft.sh
│   │       └── webhook-server.py
│   ├── execd/
│   │   ├── .golangci.yml
│   │   ├── DEVELOPMENT.md
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   ├── bootstrap.sh
│   │   ├── build.sh
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   ├── pkg/
│   │   │   ├── flag/
│   │   │   │   ├── flags.go
│   │   │   │   └── parser.go
│   │   │   ├── jupyter/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── auth.go
│   │   │   │   │   ├── auth_test.go
│   │   │   │   │   ├── client.go
│   │   │   │   │   └── types.go
│   │   │   │   ├── client.go
│   │   │   │   ├── debug_integration_test.go
│   │   │   │   ├── execute/
│   │   │   │   │   ├── events.json
│   │   │   │   │   ├── execute.go
│   │   │   │   │   ├── execute_test.go
│   │   │   │   │   ├── executor.go
│   │   │   │   │   ├── types.go
│   │   │   │   │   └── zz_generated.deepcopy.go
│   │   │   │   ├── integration_test.go
│   │   │   │   ├── kernel/
│   │   │   │   │   ├── kernel.go
│   │   │   │   │   ├── kernelspecs.json
│   │   │   │   │   └── types.go
│   │   │   │   ├── live_integration_test.go
│   │   │   │   ├── session/
│   │   │   │   │   ├── session.go
│   │   │   │   │   ├── session_test.go
│   │   │   │   │   ├── sessions.json
│   │   │   │   │   └── types.go
│   │   │   │   └── transport.go
│   │   │   ├── log/
│   │   │   │   └── log.go
│   │   │   ├── runtime/
│   │   │   │   ├── bash_session.go
│   │   │   │   ├── bash_session_test.go
│   │   │   │   ├── bash_session_windows.go
│   │   │   │   ├── command.go
│   │   │   │   ├── command_common.go
│   │   │   │   ├── command_status.go
│   │   │   │   ├── command_status_test.go
│   │   │   │   ├── command_test.go
│   │   │   │   ├── command_windows.go
│   │   │   │   ├── context.go
│   │   │   │   ├── context_test.go
│   │   │   │   ├── ctrl.go
│   │   │   │   ├── env.go
│   │   │   │   ├── env_test.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── helpers_test.go
│   │   │   │   ├── interrupt.go
│   │   │   │   ├── interrupt_windows.go
│   │   │   │   ├── jupyter.go
│   │   │   │   ├── language.go
│   │   │   │   ├── sql.go
│   │   │   │   ├── sql_test.go
│   │   │   │   ├── types.go
│   │   │   │   └── types_test.go
│   │   │   ├── util/
│   │   │   │   ├── glob/
│   │   │   │   │   ├── index.go
│   │   │   │   │   ├── match.go
│   │   │   │   │   ├── match_benchmark_test.go
│   │   │   │   │   ├── match_test.go
│   │   │   │   │   └── pattern.go
│   │   │   │   └── safego/
│   │   │   │       ├── safe.go
│   │   │   │       └── safe_test.go
│   │   │   └── web/
│   │   │       ├── controller/
│   │   │       │   ├── basic.go
│   │   │       │   ├── basic_test.go
│   │   │       │   ├── codeinterpreting.go
│   │   │       │   ├── codeinterpreting_test.go
│   │   │       │   ├── command.go
│   │   │       │   ├── command_test.go
│   │   │       │   ├── filesystem.go
│   │   │       │   ├── filesystem_download.go
│   │   │       │   ├── filesystem_test.go
│   │   │       │   ├── filesystem_upload.go
│   │   │       │   ├── filesystem_windows.go
│   │   │       │   ├── metric.go
│   │   │       │   ├── metric_test.go
│   │   │       │   ├── mock_test.go
│   │   │       │   ├── ping.go
│   │   │       │   ├── sse.go
│   │   │       │   ├── syscall_linux.go
│   │   │       │   ├── syscall_others.go
│   │   │       │   ├── test_helpers.go
│   │   │       │   ├── utils.go
│   │   │       │   ├── utils_test.go
│   │   │       │   └── utils_windows.go
│   │   │       ├── model/
│   │   │       │   ├── codeinterpreting.go
│   │   │       │   ├── codeinterpreting_test.go
│   │   │       │   ├── command.go
│   │   │       │   ├── error.go
│   │   │       │   ├── filesystem.go
│   │   │       │   ├── header.go
│   │   │       │   ├── metric.go
│   │   │       │   └── session.go
│   │   │       ├── proxy.go
│   │   │       └── router.go
│   │   └── tests/
│   │       ├── jupyter.sh
│   │       ├── smoke.sh
│   │       └── smoke_api.py
│   ├── ingress/
│   │   ├── .golangci.yml
│   │   ├── DEVELOPMENT.md
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── build.sh
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   └── pkg/
│   │       ├── flag/
│   │       │   ├── flags.go
│   │       │   └── parser.go
│   │       ├── proxy/
│   │       │   ├── header.go
│   │       │   ├── healthz.go
│   │       │   ├── healthz_test.go
│   │       │   ├── host.go
│   │       │   ├── http.go
│   │       │   ├── http_test.go
│   │       │   ├── logger.go
│   │       │   ├── proxy.go
│   │       │   ├── proxy_test.go
│   │       │   ├── websocket.go
│   │       │   └── websocket_test.go
│   │       ├── renewintent/
│   │       │   ├── intent.go
│   │       │   ├── intent_test.go
│   │       │   ├── publisher.go
│   │       │   ├── redis.go
│   │       │   └── redis_bench_test.go
│   │       └── sandbox/
│   │           ├── agent_sandbox_provider.go
│   │           ├── agent_sandbox_provider_test.go
│   │           ├── batchsandbox_provider.go
│   │           ├── batchsandbox_provider_test.go
│   │           ├── errors_test.go
│   │           ├── factory.go
│   │           └── provider.go
│   └── internal/
│       ├── go.mod
│       ├── go.sum
│       ├── logger/
│       │   ├── logger.go
│       │   └── zap.go
│       └── version/
│           └── version.go
├── docs/
│   ├── .nvmrc
│   ├── .vitepress/
│   │   ├── config.mts
│   │   ├── scripts/
│   │   │   └── docs-manifest.mjs
│   │   └── theme/
│   │       ├── index.ts
│   │       └── styles.css
│   ├── README.md
│   ├── README_zh.md
│   ├── RELEASE_NOTE_TEMPLATE.md
│   ├── architecture.md
│   ├── index.md
│   ├── manual-cleanup-refactor-guide.md
│   ├── package.json
│   ├── secure-container.md
│   ├── single_host_network.md
│   └── zh/
│       └── index.md
├── examples/
│   ├── README.md
│   ├── agent-sandbox/
│   │   ├── README.md
│   │   └── main.py
│   ├── aio-sandbox/
│   │   ├── README.md
│   │   └── main.py
│   ├── chrome/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build.sh
│   │   ├── chrome.sh
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   └── main.py
│   ├── claude-code/
│   │   ├── README.md
│   │   └── main.py
│   ├── code-interpreter/
│   │   ├── README.md
│   │   ├── main.py
│   │   └── main_use_pool.py
│   ├── codex-cli/
│   │   ├── README.md
│   │   └── main.py
│   ├── desktop/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build.sh
│   │   └── main.py
│   ├── docker-ossfs-volume-mount/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── docker-pvc-volume-mount/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── gemini-cli/
│   │   ├── README.md
│   │   └── main.py
│   ├── google-adk/
│   │   ├── README.md
│   │   └── main.py
│   ├── host-volume-mount/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── kimi-cli/
│   │   ├── README.md
│   │   └── main.py
│   ├── kubernetes-pvc-volume-mount/
│   │   ├── README.md
│   │   └── main.py
│   ├── langgraph/
│   │   ├── README.md
│   │   └── main.py
│   ├── nullclaw/
│   │   ├── README.md
│   │   └── main.py
│   ├── openclaw/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── playwright/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build.sh
│   │   └── main.py
│   ├── rl-training/
│   │   ├── README.md
│   │   ├── main.py
│   │   └── requirements.txt
│   └── vscode/
│       ├── Dockerfile
│       ├── README.md
│       ├── build.sh
│       └── main.py
├── kubernetes/
│   ├── .golangci.yml
│   ├── Dockerfile
│   ├── Dockerfile.debug
│   ├── Makefile
│   ├── PROJECT
│   ├── README-ZH.md
│   ├── README.md
│   ├── apis/
│   │   └── sandbox/
│   │       └── v1alpha1/
│   │           ├── batchsandbox_types.go
│   │           ├── doc.go
│   │           ├── groupversion_info.go
│   │           ├── pool_types.go
│   │           └── zz_generated.deepcopy.go
│   ├── build.sh
│   ├── charts/
│   │   ├── opensandbox-controller/
│   │   │   ├── .helmignore
│   │   │   ├── Chart.yaml
│   │   │   ├── README.md
│   │   │   ├── templates/
│   │   │   │   ├── NOTES.txt
│   │   │   │   ├── _helpers.tpl
│   │   │   │   ├── clusterrole.yaml
│   │   │   │   ├── clusterrolebinding.yaml
│   │   │   │   ├── crds/
│   │   │   │   │   ├── batchsandboxes.yaml
│   │   │   │   │   └── pools.yaml
│   │   │   │   ├── deployment.yaml
│   │   │   │   └── serviceaccount.yaml
│   │   │   └── values.yaml
│   │   └── opensandbox-server/
│   │       ├── .helmignore
│   │       ├── Chart.yaml
│   │       ├── README.md
│   │       ├── templates/
│   │       │   ├── NOTES.txt
│   │       │   ├── _helpers.tpl
│   │       │   ├── ingress-gateway.yaml
│   │       │   └── server.yaml
│   │       └── values.yaml
│   ├── cmd/
│   │   ├── controller/
│   │   │   └── main.go
│   │   └── task-executor/
│   │       └── main.go
│   ├── config/
│   │   ├── crd/
│   │   │   ├── bases/
│   │   │   │   ├── sandbox.opensandbox.io_batchsandboxes.yaml
│   │   │   │   └── sandbox.opensandbox.io_pools.yaml
│   │   │   ├── kustomization.yaml
│   │   │   └── kustomizeconfig.yaml
│   │   ├── default/
│   │   │   ├── cert_metrics_manager_patch.yaml
│   │   │   ├── kustomization.yaml
│   │   │   ├── manager_metrics_patch.yaml
│   │   │   └── metrics_service.yaml
│   │   ├── manager/
│   │   │   ├── kustomization.yaml
│   │   │   └── manager.yaml
│   │   ├── manifests/
│   │   │   └── kustomization.yaml
│   │   ├── network-policy/
│   │   │   ├── allow-metrics-traffic.yaml
│   │   │   └── kustomization.yaml
│   │   ├── prometheus/
│   │   │   ├── kustomization.yaml
│   │   │   ├── monitor.yaml
│   │   │   └── monitor_tls_patch.yaml
│   │   ├── rbac/
│   │   │   ├── batchsandbox_admin_role.yaml
│   │   │   ├── batchsandbox_editor_role.yaml
│   │   │   ├── batchsandbox_viewer_role.yaml
│   │   │   ├── kustomization.yaml
│   │   │   ├── leader_election_role.yaml
│   │   │   ├── leader_election_role_binding.yaml
│   │   │   ├── metrics_auth_role.yaml
│   │   │   ├── metrics_auth_role_binding.yaml
│   │   │   ├── metrics_reader_role.yaml
│   │   │   ├── pool_admin_role.yaml
│   │   │   ├── pool_editor_role.yaml
│   │   │   ├── pool_viewer_role.yaml
│   │   │   ├── role.yaml
│   │   │   ├── role_binding.yaml
│   │   │   └── service_account.yaml
│   │   ├── samples/
│   │   │   ├── kustomization.yaml
│   │   │   ├── sandbox_v1alpha1_batchsandbox-with-task.yaml
│   │   │   ├── sandbox_v1alpha1_batchsandbox.yaml
│   │   │   ├── sandbox_v1alpha1_pool.yaml
│   │   │   └── sandbox_v1alpha1_pooled_batchsandbox.yaml
│   │   └── scorecard/
│   │       ├── bases/
│   │       │   └── config.yaml
│   │       ├── kustomization.yaml
│   │       └── patches/
│   │           ├── basic.config.yaml
│   │           └── olm.config.yaml
│   ├── docs/
│   │   ├── BUILD-IMAGES.md
│   │   ├── HELM-DEPLOYMENT.md
│   │   └── logging.md
│   ├── examples/
│   │   ├── controller/
│   │   │   ├── README-ZH.md
│   │   │   ├── README.md
│   │   │   └── main.go
│   │   └── task-executor/
│   │       ├── README.md
│   │       ├── README_zh-CN.md
│   │       └── main.go
│   ├── go.mod
│   ├── go.sum
│   ├── hack/
│   │   ├── boilerplate.go.txt
│   │   ├── debug-task.sh
│   │   ├── pool-perf.py
│   │   └── update-codegen.sh
│   ├── internal/
│   │   ├── controller/
│   │   │   ├── allocator.go
│   │   │   ├── allocator_mock.go
│   │   │   ├── allocator_test.go
│   │   │   ├── apis.go
│   │   │   ├── batchsandbox_controller.go
│   │   │   ├── batchsandbox_controller_test.go
│   │   │   ├── pool_controller.go
│   │   │   ├── pool_controller_test.go
│   │   │   ├── strategy/
│   │   │   │   ├── pool_strategy.go
│   │   │   │   ├── pool_strategy_default.go
│   │   │   │   ├── pool_strategy_factory.go
│   │   │   │   ├── pool_strategy_test.go
│   │   │   │   ├── task_scheduling_strategy.go
│   │   │   │   ├── task_scheduling_strategy_default.go
│   │   │   │   ├── task_scheduling_strategy_default_test.go
│   │   │   │   └── task_scheduling_strategy_factory.go
│   │   │   └── suite_test.go
│   │   ├── scheduler/
│   │   │   ├── default_scheduler.go
│   │   │   ├── default_scheduler_mock.go
│   │   │   ├── default_scheduler_test.go
│   │   │   ├── interface.go
│   │   │   ├── mock/
│   │   │   │   ├── interface.go
│   │   │   │   └── types.go
│   │   │   ├── recovery.go
│   │   │   ├── recovery_test.go
│   │   │   ├── status_collector.go
│   │   │   ├── status_collector_mock.go
│   │   │   └── types.go
│   │   ├── task-executor/
│   │   │   ├── config/
│   │   │   │   └── config.go
│   │   │   ├── manager/
│   │   │   │   ├── interface.go
│   │   │   │   ├── task_manager.go
│   │   │   │   └── task_manager_test.go
│   │   │   ├── runtime/
│   │   │   │   ├── composite.go
│   │   │   │   ├── container.go
│   │   │   │   ├── interface.go
│   │   │   │   ├── process.go
│   │   │   │   └── process_test.go
│   │   │   ├── server/
│   │   │   │   ├── handler.go
│   │   │   │   ├── handler_test.go
│   │   │   │   └── router.go
│   │   │   ├── storage/
│   │   │   │   ├── file_store.go
│   │   │   │   ├── file_store_test.go
│   │   │   │   └── interface.go
│   │   │   ├── types/
│   │   │   │   └── task.go
│   │   │   └── utils/
│   │   │       ├── pathutil.go
│   │   │       └── pathutil_test.go
│   │   └── utils/
│   │       ├── controller/
│   │       │   └── util.go
│   │       ├── expectations/
│   │       │   ├── init.go
│   │       │   ├── resource_version_expectation.go
│   │       │   ├── resource_version_expectation_test.go
│   │       │   ├── scale_expectations.go
│   │       │   └── scale_expectations_test.go
│   │       ├── fieldindex/
│   │       │   └── register.go
│   │       ├── finalizer.go
│   │       ├── helper.go
│   │       ├── json.go
│   │       ├── logging/
│   │       │   └── logger.go
│   │       ├── pod.go
│   │       ├── pod_test.go
│   │       └── requeueduration/
│   │           └── duration.go
│   ├── pkg/
│   │   ├── client/
│   │   │   ├── clientset/
│   │   │   │   └── versioned/
│   │   │   │       ├── clientset.go
│   │   │   │       ├── fake/
│   │   │   │       │   ├── clientset_generated.go
│   │   │   │       │   ├── doc.go
│   │   │   │       │   └── register.go
│   │   │   │       ├── scheme/
│   │   │   │       │   ├── doc.go
│   │   │   │       │   └── register.go
│   │   │   │       └── typed/
│   │   │   │           └── sandbox/
│   │   │   │               └── v1alpha1/
│   │   │   │                   ├── batchsandbox.go
│   │   │   │                   ├── doc.go
│   │   │   │                   ├── fake/
│   │   │   │                   │   ├── doc.go
│   │   │   │                   │   ├── fake_batchsandbox.go
│   │   │   │                   │   ├── fake_pool.go
│   │   │   │                   │   └── fake_sandbox_client.go
│   │   │   │                   ├── generated_expansion.go
│   │   │   │                   ├── pool.go
│   │   │   │                   └── sandbox_client.go
│   │   │   ├── informers/
│   │   │   │   └── externalversions/
│   │   │   │       ├── factory.go
│   │   │   │       ├── generic.go
│   │   │   │       ├── internalinterfaces/
│   │   │   │       │   └── factory_interfaces.go
│   │   │   │       └── sandbox/
│   │   │   │           ├── interface.go
│   │   │   │           └── v1alpha1/
│   │   │   │               ├── batchsandbox.go
│   │   │   │               ├── interface.go
│   │   │   │               └── pool.go
│   │   │   └── listers/
│   │   │       └── sandbox/
│   │   │           └── v1alpha1/
│   │   │               ├── batchsandbox.go
│   │   │               ├── expansion_generated.go
│   │   │               └── pool.go
│   │   ├── task-executor/
│   │   │   ├── client.go
│   │   │   └── types.go
│   │   └── utils/
│   │       ├── endpoints.go
│   │       └── endpoints_test.go
│   └── test/
│       ├── e2e/
│       │   ├── e2e_suite_test.go
│       │   ├── e2e_test.go
│       │   └── testdata/
│       │       ├── batchsandbox-non-pooled-expire.yaml
│       │       ├── batchsandbox-non-pooled.yaml
│       │       ├── batchsandbox-pooled-no-expire.yaml
│       │       ├── batchsandbox-pooled.yaml
│       │       ├── batchsandbox-with-process-task.yaml
│       │       ├── pool-basic.yaml
│       │       ├── pool-with-env.yaml
│       │       ├── pool-with-task-executor.yaml
│       │       └── runtimeclass/
│       │           └── gvisor.yaml
│       ├── e2e_runtime/
│       │   └── gvisor/
│       │       ├── gvisor_test.go
│       │       ├── suite_test.go
│       │       └── testdata/
│       │           ├── gvisor.yaml.tmpl
│       │           └── runtimeclass.yaml
│       ├── e2e_task/
│       │   ├── suite_test.go
│       │   └── task_e2e_test.go
│       └── utils/
│           ├── image.go
│           └── utils.go
├── oseps/
│   ├── 0001-fqdn-based-egress-control.md
│   ├── 0002-kubernetes-sigs-agent-sandbox-support.md
│   ├── 0003-volume-and-volumebinding-support.md
│   ├── 0004-secure-container-runtime.md
│   ├── 0005-client-side-sandbox-pool.md
│   ├── 0006-developer-console.md
│   ├── 0007-fast-sandbox-runtime-support.md
│   ├── 0008-pause-resume-rootfs-snapshot.md
│   ├── 0009-auto-renew-sandbox-on-ingress-access.md
│   ├── 0010-opentelemetry-instrumentation.md
│   ├── CONTRIBUTING.md
│   ├── README.md
│   ├── init-osep.sh
│   └── osep-template.md.template
├── sandboxes/
│   └── code-interpreter/
│       ├── Dockerfile
│       ├── Dockerfile_base
│       ├── README.md
│       ├── README_zh.md
│       ├── build.sh
│       └── scripts/
│           ├── code-interpreter-env.sh
│           ├── code-interpreter.sh
│           └── jupyter_notebook_config.py
├── scripts/
│   ├── add-license.sh
│   ├── bump-component-version.sh
│   ├── csharp-e2e.sh
│   ├── java-e2e.sh
│   ├── javascript-e2e.sh
│   ├── python-e2e.sh
│   ├── spec-doc/
│   │   ├── generate-spec.js
│   │   └── index.html
│   └── verify-license.sh
├── sdks/
│   ├── Directory.Build.props
│   ├── code-interpreter/
│   │   ├── csharp/
│   │   │   ├── OpenSandbox.CodeInterpreter.sln
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── src/
│   │   │   │   └── OpenSandbox.CodeInterpreter/
│   │   │   │       ├── Adapters/
│   │   │   │       │   └── CodesAdapter.cs
│   │   │   │       ├── CodeInterpreter.cs
│   │   │   │       ├── Factory/
│   │   │   │       │   ├── DefaultCodeInterpreterAdapterFactory.cs
│   │   │   │       │   └── ICodeInterpreterAdapterFactory.cs
│   │   │   │       ├── Models/
│   │   │   │       │   └── CodeModels.cs
│   │   │   │       ├── OpenSandbox.CodeInterpreter.csproj
│   │   │   │       └── Services/
│   │   │   │           └── ICodes.cs
│   │   │   └── tests/
│   │   │       └── OpenSandbox.CodeInterpreter.Tests/
│   │   │           ├── CodeInterpreterTests.cs
│   │   │           ├── CodesAdapterTests.cs
│   │   │           ├── FactoryTests.cs
│   │   │           ├── ModelsTests.cs
│   │   │           └── OpenSandbox.CodeInterpreter.Tests.csproj
│   │   ├── javascript/
│   │   │   ├── .nvmrc
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── eslint.config.mjs
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── adapters/
│   │   │   │   │   ├── codesAdapter.ts
│   │   │   │   │   ├── openapiError.ts
│   │   │   │   │   └── sse.ts
│   │   │   │   ├── factory/
│   │   │   │   │   ├── adapterFactory.ts
│   │   │   │   │   └── defaultAdapterFactory.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interpreter.ts
│   │   │   │   ├── models.ts
│   │   │   │   └── services/
│   │   │   │       └── codes.ts
│   │   │   ├── tests/
│   │   │   │   ├── defaultAdapterFactory.headers.test.mjs
│   │   │   │   └── interpreter.headers.test.mjs
│   │   │   ├── tsconfig.json
│   │   │   └── tsup.config.ts
│   │   ├── kotlin/
│   │   │   ├── LICENSE
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── build.gradle.kts
│   │   │   ├── code-interpreter/
│   │   │   │   ├── build.gradle.kts
│   │   │   │   └── src/
│   │   │   │       ├── main/
│   │   │   │       │   └── kotlin/
│   │   │   │       │       └── com/
│   │   │   │       │           └── alibaba/
│   │   │   │       │               └── opensandbox/
│   │   │   │       │                   └── codeinterpreter/
│   │   │   │       │                       ├── CodeInterpreter.kt
│   │   │   │       │                       ├── domain/
│   │   │   │       │                       │   ├── models/
│   │   │   │       │                       │   │   └── execd/
│   │   │   │       │                       │   │       └── executions/
│   │   │   │       │                       │   │           └── CodeModels.kt
│   │   │   │       │                       │   └── services/
│   │   │   │       │                       │       └── Codes.kt
│   │   │   │       │                       └── infrastructure/
│   │   │   │       │                           ├── adapters/
│   │   │   │       │                           │   ├── converter/
│   │   │   │       │                           │   │   └── CodeExecutionConverter.kt
│   │   │   │       │                           │   └── service/
│   │   │   │       │                           │       └── CodesAdapter.kt
│   │   │   │       │                           └── factory/
│   │   │   │       │                               └── AdapterFactory.kt
│   │   │   │       └── test/
│   │   │   │           └── kotlin/
│   │   │   │               └── com/
│   │   │   │                   └── alibaba/
│   │   │   │                       └── opensandbox/
│   │   │   │                           └── codeinterpreter/
│   │   │   │                               ├── CodeInterpreterTest.kt
│   │   │   │                               └── infrastructure/
│   │   │   │                                   └── adapters/
│   │   │   │                                       └── service/
│   │   │   │                                           └── CodesAdapterTest.kt
│   │   │   ├── code-interpreter-bom/
│   │   │   │   └── build.gradle.kts
│   │   │   ├── gradle/
│   │   │   │   ├── libs.versions.toml
│   │   │   │   └── wrapper/
│   │   │   │       ├── gradle-wrapper.jar
│   │   │   │       └── gradle-wrapper.properties
│   │   │   ├── gradle.properties
│   │   │   ├── gradlew
│   │   │   └── settings.gradle.kts
│   │   └── python/
│   │       ├── LICENSE
│   │       ├── Makefile
│   │       ├── README.md
│   │       ├── README_zh.md
│   │       ├── pyproject.toml
│   │       ├── src/
│   │       │   └── code_interpreter/
│   │       │       ├── __init__.py
│   │       │       ├── adapters/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── code_adapter.py
│   │       │       │   ├── converter/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   └── code_execution_converter.py
│   │       │       │   └── factory.py
│   │       │       ├── code_interpreter.py
│   │       │       ├── models/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── code.py
│   │       │       │   └── code_sync.py
│   │       │       ├── py.typed
│   │       │       ├── services/
│   │       │       │   ├── __init__.py
│   │       │       │   └── code.py
│   │       │       └── sync/
│   │       │           ├── __init__.py
│   │       │           ├── adapters/
│   │       │           │   ├── __init__.py
│   │       │           │   ├── code_adapter.py
│   │       │           │   └── factory.py
│   │       │           ├── code_interpreter.py
│   │       │           └── services/
│   │       │               ├── __init__.py
│   │       │               └── code.py
│   │       └── tests/
│   │           ├── test_adapter_eager_init.py
│   │           ├── test_code_interpreter_create_and_delegation.py
│   │           ├── test_code_service_adapter_openapi_calls.py
│   │           └── test_code_service_adapter_streaming.py
│   ├── eslint.base.mjs
│   ├── mcp/
│   │   └── sandbox/
│   │       └── python/
│   │           ├── LICENSE
│   │           ├── README.md
│   │           ├── README_zh.md
│   │           ├── pyproject.toml
│   │           └── src/
│   │               └── opensandbox_mcp/
│   │                   ├── __init__.py
│   │                   ├── __main__.py
│   │                   ├── py.typed
│   │                   └── server.py
│   ├── package.json
│   ├── pnpm-workspace.yaml
│   ├── sandbox/
│   │   ├── csharp/
│   │   │   ├── .editorconfig
│   │   │   ├── Directory.Build.props
│   │   │   ├── OpenSandbox.sln
│   │   │   ├── OpenSandbox.sln.DotSettings.user
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── src/
│   │   │   │   └── OpenSandbox/
│   │   │   │       ├── Adapters/
│   │   │   │       │   ├── CommandsAdapter.cs
│   │   │   │       │   ├── EgressAdapter.cs
│   │   │   │       │   ├── FilesystemAdapter.cs
│   │   │   │       │   ├── HealthAdapter.cs
│   │   │   │       │   ├── MetricsAdapter.cs
│   │   │   │       │   ├── SandboxesAdapter.cs
│   │   │   │       │   └── SseParser.cs
│   │   │   │       ├── Config/
│   │   │   │       │   ├── ConnectionConfig.cs
│   │   │   │       │   └── DiagnosticsOptions.cs
│   │   │   │       ├── Core/
│   │   │   │       │   ├── Constants.cs
│   │   │   │       │   └── Exceptions.cs
│   │   │   │       ├── Factory/
│   │   │   │       │   ├── DefaultAdapterFactory.cs
│   │   │   │       │   └── IAdapterFactory.cs
│   │   │   │       ├── HttpClientProvider.cs
│   │   │   │       ├── Internal/
│   │   │   │       │   ├── ExecutionEventDispatcher.cs
│   │   │   │       │   └── HttpClientWrapper.cs
│   │   │   │       ├── Models/
│   │   │   │       │   ├── Execd.cs
│   │   │   │       │   ├── Execution.cs
│   │   │   │       │   ├── Filesystem.cs
│   │   │   │       │   └── Sandboxes.cs
│   │   │   │       ├── OpenSandbox.csproj
│   │   │   │       ├── Options.cs
│   │   │   │       ├── Sandbox.cs
│   │   │   │       ├── SandboxManager.cs
│   │   │   │       └── Services/
│   │   │   │           ├── IEgress.cs
│   │   │   │           ├── IExecdCommands.cs
│   │   │   │           ├── IExecdHealth.cs
│   │   │   │           ├── IExecdMetrics.cs
│   │   │   │           ├── ISandboxFiles.cs
│   │   │   │           └── ISandboxes.cs
│   │   │   └── tests/
│   │   │       └── OpenSandbox.Tests/
│   │   │           ├── CommandsAdapterTests.cs
│   │   │           ├── ConnectionConfigTests.cs
│   │   │           ├── ConstantsTests.cs
│   │   │           ├── ExceptionTests.cs
│   │   │           ├── ModelsTests.cs
│   │   │           ├── OpenSandbox.Tests.csproj
│   │   │           ├── OptionsTests.cs
│   │   │           ├── SandboxEgressLifecycleTests.cs
│   │   │           ├── SandboxReadinessDiagnosticsTests.cs
│   │   │           ├── SandboxesAdapterTests.cs
│   │   │           └── SseParserTests.cs
│   │   ├── javascript/
│   │   │   ├── .nvmrc
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── eslint.config.mjs
│   │   │   ├── package.json
│   │   │   ├── scripts/
│   │   │   │   └── generate-api.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapters/
│   │   │   │   │   ├── commandsAdapter.ts
│   │   │   │   │   ├── egressAdapter.ts
│   │   │   │   │   ├── filesystemAdapter.ts
│   │   │   │   │   ├── healthAdapter.ts
│   │   │   │   │   ├── metricsAdapter.ts
│   │   │   │   │   ├── openapiError.ts
│   │   │   │   │   ├── sandboxesAdapter.ts
│   │   │   │   │   └── sse.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── egress.ts
│   │   │   │   │   ├── execd.ts
│   │   │   │   │   └── lifecycle.ts
│   │   │   │   ├── config/
│   │   │   │   │   └── connection.ts
│   │   │   │   ├── core/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   └── exceptions.ts
│   │   │   │   ├── factory/
│   │   │   │   │   ├── adapterFactory.ts
│   │   │   │   │   └── defaultAdapterFactory.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── internal.ts
│   │   │   │   ├── manager.ts
│   │   │   │   ├── models/
│   │   │   │   │   ├── execd.ts
│   │   │   │   │   ├── execution.ts
│   │   │   │   │   ├── executionEventDispatcher.ts
│   │   │   │   │   ├── filesystem.ts
│   │   │   │   │   └── sandboxes.ts
│   │   │   │   ├── openapi/
│   │   │   │   │   ├── egressClient.ts
│   │   │   │   │   ├── execdClient.ts
│   │   │   │   │   └── lifecycleClient.ts
│   │   │   │   ├── sandbox.ts
│   │   │   │   └── services/
│   │   │   │       ├── egress.ts
│   │   │   │       ├── execdCommands.ts
│   │   │   │       ├── execdHealth.ts
│   │   │   │       ├── execdMetrics.ts
│   │   │   │       ├── filesystem.ts
│   │   │   │       └── sandboxes.ts
│   │   │   ├── tests/
│   │   │   │   └── sandbox.create.test.mjs
│   │   │   ├── tsconfig.json
│   │   │   └── tsup.config.ts
│   │   ├── kotlin/
│   │   │   ├── LICENSE
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── build.gradle.kts
│   │   │   ├── gradle/
│   │   │   │   ├── libs.versions.toml
│   │   │   │   └── wrapper/
│   │   │   │       ├── gradle-wrapper.jar
│   │   │   │       └── gradle-wrapper.properties
│   │   │   ├── gradle.properties
│   │   │   ├── gradlew
│   │   │   ├── sandbox/
│   │   │   │   ├── Module.md
│   │   │   │   ├── build.gradle.kts
│   │   │   │   └── src/
│   │   │   │       ├── main/
│   │   │   │       │   └── kotlin/
│   │   │   │       │       └── com/
│   │   │   │       │           └── alibaba/
│   │   │   │       │               └── opensandbox/
│   │   │   │       │                   └── sandbox/
│   │   │   │       │                       ├── HttpClientProvider.kt
│   │   │   │       │                       ├── Sandbox.kt
│   │   │   │       │                       ├── SandboxManager.kt
│   │   │   │       │                       ├── config/
│   │   │   │       │                       │   └── ConnectionConfig.kt
│   │   │   │       │                       ├── domain/
│   │   │   │       │                       │   ├── exceptions/
│   │   │   │       │                       │   │   └── SandboxException.kt
│   │   │   │       │                       │   ├── models/
│   │   │   │       │                       │   │   ├── execd/
│   │   │   │       │                       │   │   │   ├── Constants.kt
│   │   │   │       │                       │   │   │   ├── executions/
│   │   │   │       │                       │   │   │   │   ├── CommandModels.kt
│   │   │   │       │                       │   │   │   │   ├── ExecutionModels.kt
│   │   │   │       │                       │   │   │   │   └── RunCommandRequest.kt
│   │   │   │       │                       │   │   │   └── filesystem/
│   │   │   │       │                       │   │   │       └── FilesystemModels.kt
│   │   │   │       │                       │   │   └── sandboxes/
│   │   │   │       │                       │   │       └── SandboxModels.kt
│   │   │   │       │                       │   └── services/
│   │   │   │       │                       │       ├── Commands.kt
│   │   │   │       │                       │       ├── Egress.kt
│   │   │   │       │                       │       ├── Filesystem.kt
│   │   │   │       │                       │       ├── Health.kt
│   │   │   │       │                       │       ├── Metrics.kt
│   │   │   │       │                       │       └── Sandboxes.kt
│   │   │   │       │                       └── infrastructure/
│   │   │   │       │                           ├── adapters/
│   │   │   │       │                           │   ├── converter/
│   │   │   │       │                           │   │   ├── ExceptionConverter.kt
│   │   │   │       │                           │   │   ├── ExecutionConverter.kt
│   │   │   │       │                           │   │   ├── ExecutionEventDispatcher.kt
│   │   │   │       │                           │   │   ├── FilesystemConverter.kt
│   │   │   │       │                           │   │   ├── SandboxModelConverter.kt
│   │   │   │       │                           │   │   └── Serializer.kt
│   │   │   │       │                           │   └── service/
│   │   │   │       │                           │       ├── CommandsAdapter.kt
│   │   │   │       │                           │       ├── EgressAdapter.kt
│   │   │   │       │                           │       ├── FilesystemAdapter.kt
│   │   │   │       │                           │       ├── HealthAdapter.kt
│   │   │   │       │                           │       ├── MetricsAdapter.kt
│   │   │   │       │                           │       └── SandboxesAdapter.kt
│   │   │   │       │                           └── factory/
│   │   │   │       │                               └── AdapterFactory.kt
│   │   │   │       └── test/
│   │   │   │           └── kotlin/
│   │   │   │               └── com/
│   │   │   │                   └── alibaba/
│   │   │   │                       └── opensandbox/
│   │   │   │                           └── sandbox/
│   │   │   │                               ├── SandboxManagerTest.kt
│   │   │   │                               ├── SandboxTest.kt
│   │   │   │                               ├── domain/
│   │   │   │                               │   ├── exceptions/
│   │   │   │                               │   │   └── SandboxExceptionCompatibilityTest.kt
│   │   │   │                               │   └── models/
│   │   │   │                               │       └── VolumeModelsTest.kt
│   │   │   │                               └── infrastructure/
│   │   │   │                                   └── adapters/
│   │   │   │                                       └── service/
│   │   │   │                                           ├── CommandsAdapterTest.kt
│   │   │   │                                           └── SandboxesAdapterTest.kt
│   │   │   ├── sandbox-api/
│   │   │   │   ├── build.gradle.kts
│   │   │   │   └── src/
│   │   │   │       └── main/
│   │   │   │           └── kotlin/
│   │   │   │               └── com/
│   │   │   │                   └── alibaba/
│   │   │   │                       └── opensandbox/
│   │   │   │                           └── sandbox/
│   │   │   │                               └── api/
│   │   │   │                                   ├── models/
│   │   │   │                                   │   └── execd/
│   │   │   │                                   │       └── ExecutionModels.kt
│   │   │   │                                   └── openapitools.json
│   │   │   ├── sandbox-bom/
│   │   │   │   └── build.gradle.kts
│   │   │   └── settings.gradle.kts
│   │   └── python/
│   │       ├── LICENSE
│   │       ├── Makefile
│   │       ├── README.md
│   │       ├── README_zh.md
│   │       ├── pyproject.toml
│   │       ├── scripts/
│   │       │   ├── generate_api.py
│   │       │   ├── openapi_egress_config.yaml
│   │       │   ├── openapi_execd_config.yaml
│   │       │   └── openapi_lifecycle_config.yaml
│   │       ├── src/
│   │       │   └── opensandbox/
│   │       │       ├── __init__.py
│   │       │       ├── adapters/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── command_adapter.py
│   │       │       │   ├── converter/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   ├── command_model_converter.py
│   │       │       │   │   ├── event_node.py
│   │       │       │   │   ├── exception_converter.py
│   │       │       │   │   ├── execution_converter.py
│   │       │       │   │   ├── execution_event_dispatcher.py
│   │       │       │   │   ├── filesystem_model_converter.py
│   │       │       │   │   ├── metrics_model_converter.py
│   │       │       │   │   ├── response_handler.py
│   │       │       │   │   └── sandbox_model_converter.py
│   │       │       │   ├── egress_adapter.py
│   │       │       │   ├── factory.py
│   │       │       │   ├── filesystem_adapter.py
│   │       │       │   ├── health_adapter.py
│   │       │       │   ├── metrics_adapter.py
│   │       │       │   └── sandboxes_adapter.py
│   │       │       ├── api/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── egress/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   ├── api/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   └── policy/
│   │       │       │   │   │       ├── __init__.py
│   │       │       │   │   │       ├── get_policy.py
│   │       │       │   │   │       └── patch_policy.py
│   │       │       │   │   ├── client.py
│   │       │       │   │   ├── errors.py
│   │       │       │   │   ├── models/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   ├── network_policy.py
│   │       │       │   │   │   ├── network_policy_default_action.py
│   │       │       │   │   │   ├── network_rule.py
│   │       │       │   │   │   ├── network_rule_action.py
│   │       │       │   │   │   └── policy_status_response.py
│   │       │       │   │   ├── py.typed
│   │       │       │   │   └── types.py
│   │       │       │   ├── execd/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   ├── api/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   ├── code_interpreting/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   ├── create_code_context.py
│   │       │       │   │   │   │   ├── delete_context.py
│   │       │       │   │   │   │   ├── delete_contexts_by_language.py
│   │       │       │   │   │   │   ├── get_context.py
│   │       │       │   │   │   │   ├── interrupt_code.py
│   │       │       │   │   │   │   ├── list_contexts.py
│   │       │       │   │   │   │   └── run_code.py
│   │       │       │   │   │   ├── command/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   ├── get_background_command_logs.py
│   │       │       │   │   │   │   ├── get_command_status.py
│   │       │       │   │   │   │   ├── interrupt_command.py
│   │       │       │   │   │   │   └── run_command.py
│   │       │       │   │   │   ├── filesystem/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   ├── chmod_files.py
│   │       │       │   │   │   │   ├── download_file.py
│   │       │       │   │   │   │   ├── get_files_info.py
│   │       │       │   │   │   │   ├── make_dirs.py
│   │       │       │   │   │   │   ├── remove_dirs.py
│   │       │       │   │   │   │   ├── remove_files.py
│   │       │       │   │   │   │   ├── rename_files.py
│   │       │       │   │   │   │   ├── replace_content.py
│   │       │       │   │   │   │   ├── search_files.py
│   │       │       │   │   │   │   └── upload_file.py
│   │       │       │   │   │   ├── health/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   └── ping.py
│   │       │       │   │   │   └── metric/
│   │       │       │   │   │       ├── __init__.py
│   │       │       │   │   │       ├── get_metrics.py
│   │       │       │   │   │       └── watch_metrics.py
│   │       │       │   │   ├── client.py
│   │       │       │   │   ├── errors.py
│   │       │       │   │   ├── models/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   ├── chmod_files_body.py
│   │       │       │   │   │   ├── code_context.py
│   │       │       │   │   │   ├── code_context_request.py
│   │       │       │   │   │   ├── command_status_response.py
│   │       │       │   │   │   ├── error_response.py
│   │       │       │   │   │   ├── file_info.py
│   │       │       │   │   │   ├── file_metadata.py
│   │       │       │   │   │   ├── get_files_info_response_200.py
│   │       │       │   │   │   ├── make_dirs_body.py
│   │       │       │   │   │   ├── metrics.py
│   │       │       │   │   │   ├── permission.py
│   │       │       │   │   │   ├── rename_file_item.py
│   │       │       │   │   │   ├── replace_content_body.py
│   │       │       │   │   │   ├── replace_file_content_item.py
│   │       │       │   │   │   ├── run_code_request.py
│   │       │       │   │   │   ├── run_command_request.py
│   │       │       │   │   │   ├── run_command_request_envs.py
│   │       │       │   │   │   ├── server_stream_event.py
│   │       │       │   │   │   ├── server_stream_event_error.py
│   │       │       │   │   │   ├── server_stream_event_results.py
│   │       │       │   │   │   ├── server_stream_event_type.py
│   │       │       │   │   │   └── upload_file_body.py
│   │       │       │   │   ├── py.typed
│   │       │       │   │   └── types.py
│   │       │       │   └── lifecycle/
│   │       │       │       ├── __init__.py
│   │       │       │       ├── api/
│   │       │       │       │   ├── __init__.py
│   │       │       │       │   └── sandboxes/
│   │       │       │       │       ├── __init__.py
│   │       │       │       │       ├── delete_sandboxes_sandbox_id.py
│   │       │       │       │       ├── get_sandboxes.py
│   │       │       │       │       ├── get_sandboxes_sandbox_id.py
│   │       │       │       │       ├── get_sandboxes_sandbox_id_endpoints_port.py
│   │       │       │       │       ├── post_sandboxes.py
│   │       │       │       │       ├── post_sandboxes_sandbox_id_pause.py
│   │       │       │       │       ├── post_sandboxes_sandbox_id_renew_expiration.py
│   │       │       │       │       └── post_sandboxes_sandbox_id_resume.py
│   │       │       │       ├── client.py
│   │       │       │       ├── errors.py
│   │       │       │       ├── models/
│   │       │       │       │   ├── __init__.py
│   │       │       │       │   ├── create_sandbox_request.py
│   │       │       │       │   ├── create_sandbox_request_env.py
│   │       │       │       │   ├── create_sandbox_request_extensions.py
│   │       │       │       │   ├── create_sandbox_request_metadata.py
│   │       │       │       │   ├── create_sandbox_response.py
│   │       │       │       │   ├── create_sandbox_response_metadata.py
│   │       │       │       │   ├── endpoint.py
│   │       │       │       │   ├── endpoint_headers.py
│   │       │       │       │   ├── error_response.py
│   │       │       │       │   ├── host.py
│   │       │       │       │   ├── image_spec.py
│   │       │       │       │   ├── image_spec_auth.py
│   │       │       │       │   ├── list_sandboxes_response.py
│   │       │       │       │   ├── network_policy.py
│   │       │       │       │   ├── network_policy_default_action.py
│   │       │       │       │   ├── network_rule.py
│   │       │       │       │   ├── network_rule_action.py
│   │       │       │       │   ├── ossfs.py
│   │       │       │       │   ├── ossfs_version.py
│   │       │       │       │   ├── pagination_info.py
│   │       │       │       │   ├── pvc.py
│   │       │       │       │   ├── renew_sandbox_expiration_request.py
│   │       │       │       │   ├── renew_sandbox_expiration_response.py
│   │       │       │       │   ├── resource_limits.py
│   │       │       │       │   ├── sandbox.py
│   │       │       │       │   ├── sandbox_metadata.py
│   │       │       │       │   ├── sandbox_status.py
│   │       │       │       │   └── volume.py
│   │       │       │       ├── py.typed
│   │       │       │       └── types.py
│   │       │       ├── config/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── connection.py
│   │       │       │   └── connection_sync.py
│   │       │       ├── constants.py
│   │       │       ├── exceptions/
│   │       │       │   ├── __init__.py
│   │       │       │   └── sandbox.py
│   │       │       ├── manager.py
│   │       │       ├── models/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── execd.py
│   │       │       │   ├── execd_sync.py
│   │       │       │   ├── filesystem.py
│   │       │       │   └── sandboxes.py
│   │       │       ├── py.typed
│   │       │       ├── sandbox.py
│   │       │       ├── services/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── command.py
│   │       │       │   ├── egress.py
│   │       │       │   ├── filesystem.py
│   │       │       │   ├── health.py
│   │       │       │   ├── metrics.py
│   │       │       │   └── sandbox.py
│   │       │       └── sync/
│   │       │           ├── __init__.py
│   │       │           ├── adapters/
│   │       │           │   ├── __init__.py
│   │       │           │   ├── command_adapter.py
│   │       │           │   ├── converter/
│   │       │           │   │   ├── __init__.py
│   │       │           │   │   └── execution_event_dispatcher.py
│   │       │           │   ├── egress_adapter.py
│   │       │           │   ├── factory.py
│   │       │           │   ├── filesystem_adapter.py
│   │       │           │   ├── health_adapter.py
│   │       │           │   ├── metrics_adapter.py
│   │       │           │   └── sandboxes_adapter.py
│   │       │           ├── manager.py
│   │       │           ├── sandbox.py
│   │       │           └── services/
│   │       │               ├── __init__.py
│   │       │               ├── command.py
│   │       │               ├── egress.py
│   │       │               ├── filesystem.py
│   │       │               ├── health.py
│   │       │               ├── metrics.py
│   │       │               └── sandbox.py
│   │       └── tests/
│   │           ├── test_adapters_eager_init.py
│   │           ├── test_command_service_adapter_streaming.py
│   │           ├── test_command_service_sse_client_config.py
│   │           ├── test_connection_config.py
│   │           ├── test_connection_config_env_and_timeout.py
│   │           ├── test_converters_and_error_handling.py
│   │           ├── test_filesystem_search_error_handling.py
│   │           ├── test_models_stability.py
│   │           ├── test_sandbox_business_logic.py
│   │           ├── test_sandbox_close_and_connect_validation.py
│   │           ├── test_sandbox_manager_business_logic.py
│   │           ├── test_sandbox_manager_sync_business_logic.py
│   │           ├── test_sandbox_service_adapter_lifecycle.py
│   │           └── test_sandbox_sync_business_logic.py
│   └── tsconfig.base.json
├── server/
│   ├── .python-version
│   ├── DEVELOPMENT.md
│   ├── Dockerfile
│   ├── LICENSE
│   ├── README.md
│   ├── README_zh.md
│   ├── TROUBLESHOOTING.md
│   ├── TROUBLESHOOTING_zh.md
│   ├── build.sh
│   ├── docker-compose.example.yaml
│   ├── example.batchsandbox-template.yaml
│   ├── example.config.k8s.toml
│   ├── example.config.k8s.zh.toml
│   ├── example.config.toml
│   ├── example.config.zh.toml
│   ├── pyproject.toml
│   ├── src/
│   │   ├── __init__.py
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── lifecycle.py
│   │   │   └── schema.py
│   │   ├── cli.py
│   │   ├── config.py
│   │   ├── main.py
│   │   ├── middleware/
│   │   │   ├── __init__.py
│   │   │   ├── auth.py
│   │   │   └── request_id.py
│   │   ├── py.typed
│   │   └── services/
│   │       ├── __init__.py
│   │       ├── constants.py
│   │       ├── docker.py
│   │       ├── endpoint_auth.py
│   │       ├── factory.py
│   │       ├── helpers.py
│   │       ├── k8s/
│   │       │   ├── __init__.py
│   │       │   ├── agent_sandbox_provider.py
│   │       │   ├── agent_sandbox_template.py
│   │       │   ├── batchsandbox_provider.py
│   │       │   ├── batchsandbox_template.py
│   │       │   ├── client.py
│   │       │   ├── egress_helper.py
│   │       │   ├── image_pull_secret_helper.py
│   │       │   ├── informer.py
│   │       │   ├── kubernetes_service.py
│   │       │   ├── provider_factory.py
│   │       │   ├── rate_limiter.py
│   │       │   ├── security_context.py
│   │       │   ├── template_manager.py
│   │       │   ├── volume_helper.py
│   │       │   └── workload_provider.py
│   │       ├── ossfs_mixin.py
│   │       ├── runtime_resolver.py
│   │       ├── sandbox_service.py
│   │       └── validators.py
│   └── tests/
│       ├── __init__.py
│       ├── conftest.py
│       ├── k8s/
│       │   ├── __init__.py
│       │   ├── conftest.py
│       │   ├── fixtures/
│       │   │   ├── __init__.py
│       │   │   └── k8s_fixtures.py
│       │   ├── test_agent_sandbox_provider.py
│       │   ├── test_agent_sandbox_template.py
│       │   ├── test_batchsandbox_provider.py
│       │   ├── test_batchsandbox_template.py
│       │   ├── test_egress_helper.py
│       │   ├── test_image_pull_secret_helper.py
│       │   ├── test_informer.py
│       │   ├── test_k8s_client.py
│       │   ├── test_kubernetes_service.py
│       │   ├── test_provider_factory.py
│       │   └── test_rate_limiter.py
│       ├── smoke.sh
│       ├── test_agent_sandbox_service.py
│       ├── test_auth_middleware.py
│       ├── test_config.py
│       ├── test_docker_endpoint.py
│       ├── test_docker_path_fix.py
│       ├── test_docker_service.py
│       ├── test_endpoint.py
│       ├── test_endpoint_auth.py
│       ├── test_helpers.py
│       ├── test_ingress.py
│       ├── test_routes.py
│       ├── test_routes_create_delete.py
│       ├── test_routes_endpoint_behavior.py
│       ├── test_routes_get_sandbox.py
│       ├── test_routes_list_sandboxes.py
│       ├── test_routes_pause_resume.py
│       ├── test_routes_proxy.py
│       ├── test_routes_renew_expiration.py
│       ├── test_schema.py
│       ├── test_validators.py
│       └── testdata/
│           ├── config.toml
│           └── k8s_config.toml
├── specs/
│   ├── README.md
│   ├── README_zh.md
│   ├── egress-api.yaml
│   ├── execd-api.yaml
│   └── sandbox-lifecycle.yml
└── tests/
    ├── csharp/
    │   └── OpenSandbox.E2ETests/
    │       ├── CodeInterpreterE2ETests.cs
    │       ├── E2ETestFixture.cs
    │       ├── OpenSandbox.E2ETests.csproj
    │       ├── SandboxE2ETests.cs
    │       └── SandboxManagerE2ETests.cs
    ├── java/
    │   ├── build.gradle.kts
    │   ├── gradle/
    │   │   ├── libs.versions.toml
    │   │   └── wrapper/
    │   │       ├── gradle-wrapper.jar
    │   │       └── gradle-wrapper.properties
    │   ├── gradle.properties
    │   ├── gradlew
    │   ├── settings.gradle.kts
    │   └── src/
    │       └── test/
    │           ├── java/
    │           │   └── com/
    │           │       └── alibaba/
    │           │           └── opensandbox/
    │           │               └── e2e/
    │           │                   ├── BaseE2ETest.java
    │           │                   ├── CodeInterpreterE2ETest.java
    │           │                   ├── SandboxE2ETest.java
    │           │                   └── SandboxManagerE2ETest.java
    │           └── resources/
    │               └── test.properties
    ├── javascript/
    │   ├── README.md
    │   ├── eslint.config.mjs
    │   ├── package.json
    │   ├── tests/
    │   │   ├── base_e2e.ts
    │   │   ├── test_code_interpreter_e2e.test.ts
    │   │   ├── test_sandbox_e2e.test.ts
    │   │   ├── test_sandbox_manager_e2e.test.ts
    │   │   └── test_wait_until_ready_diagnostics.test.ts
    │   ├── tsconfig.json
    │   └── vitest.config.ts
    └── python/
        ├── Makefile
        ├── README.md
        ├── pyproject.toml
        └── tests/
            ├── __init__.py
            ├── base_e2e_test.py
            ├── test_code_interpreter_e2e.py
            ├── test_code_interpreter_e2e_sync.py
            ├── test_sandbox_e2e.py
            ├── test_sandbox_e2e_sync.py
            ├── test_sandbox_manager_e2e.py
            └── test_sandbox_manager_e2e_sync.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/CODEOWNERS
================================================
# CODEOWNERS for OpenSandbox
# Rules are evaluated top-to-bottom; the last matching pattern wins.

# Default owners (fallback for files not matched by specific rules)
* @jwx0925 @hittyt @hellomypastor @Pangjiping @ninan-nn

# Control plane (server)
/server/ @Pangjiping @hittyt @jwx0925 @Generalwin @ninan-nn

# Runtime agent (execd) and sandbox images
/components/execd/ @Pangjiping @hittyt @ninan-nn
/components/ingress/ @Pangjiping @hittyt @Generalwin @Spground
/components/egress/ @Pangjiping @hittyt @jwx0925
/sandboxes/ @Pangjiping @ninan-nn @jwx0925 @hittyt @hellomypastor

# Kubernetes controller
/kubernetes/ @Spground @Generalwin @fengcone @kevinlynx @ninan-nn @hittyt @Pangjiping

# SDKs
/sdks/ @ninan-nn @jwx0925 @hittyt @hellomypastor

# Specs and docs
/specs/ @jwx0925 @hittyt @ninan-nn

# OpenSandbox Enhancement Proposals
/oseps/ @Spground @Generalwin @fengcone @kevinlynx @Pangjiping @ninan-nn @jwx0925 @hittyt


================================================
FILE: .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
================================================
---
name: Feature Request
about: Suggest an idea for OpenSandbox
title: ''
labels: ''
assignees: ''

---

## Why do you need it?
Is your feature request related to a problem? Please describe in details


## How could it be?
A clear and concise description of what you want to happen. You can explain more about input of the feature, and output of it.


## Other related information
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Any Questions or Suggestions?
    url: https://github.com/alibaba/OpenSandbox/issues
    about: Please ask and answer questions here.


================================================
FILE: .github/pull_request_template.md
================================================
# Summary
- What is changing and why?

# Testing
- [ ] Not run (explain why)
- [ ] Unit tests
- [ ] Integration tests
- [ ] e2e / manual verification

# Breaking Changes
- [ ] None
- [ ] Yes (describe impact and migration path)

# Checklist
- [ ] Linked Issue or clearly described motivation
- [ ] Added/updated docs (if needed)
- [ ] Added/updated tests (if needed)
- [ ] Security impact considered
- [ ] Backward compatibility considered


================================================
FILE: .github/workflows/deploy-docs-pages.yml
================================================
name: Deploy Docs Pages

on:
  push:
    branches:
      - main
    paths:
      - "docs/**"
      - "specs/**"
      - "scripts/spec-doc/**"
      - "README.md"
      - "CONTRIBUTING.md"
      - "CODE_OF_CONDUCT.md"
      - "server/**/README*.md"
      - "server/**/DEVELOPMENT.md"
      - "components/**/README*.md"
      - "components/**/DEVELOPMENT.md"
      - "sdks/**/README*.md"
      - "sandboxes/**/README*.md"
      - "kubernetes/**/README*.md"
      - "examples/**/README*.md"
      - "specs/**/README*.md"
      - "oseps/**/*.md"
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    environment:
      name: github-pages
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5

      - name: Setup Node 22
        uses: actions/setup-node@v6
        with:
          node-version: "22"

      - name: Setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9.15.0

      - name: Enable corepack
        run: corepack enable

      - name: Install docs dependencies
        working-directory: docs
        run: pnpm install --frozen-lockfile

      - name: Build docs
        working-directory: docs
        env:
          # Use root base when custom domain is configured via CNAME.
          DOCS_BASE: ${{ hashFiles('docs/public/CNAME') != '' && '/' || steps.pages.outputs.base_path }}
        run: pnpm docs:build

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v4
        with:
          path: docs/.vitepress/dist

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4


================================================
FILE: .github/workflows/egress-test.yaml.yml
================================================
name: Egress Tests

on:
  pull_request:
    branches: [ main ]
    paths:
      - 'components/egress/**'
      - 'components/internal/**'

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version: '1.24.0'

      - name: Run Build
        working-directory: components/egress
        run: |
          go vet ./...
          go build .

      - name: Run tests
        working-directory: components/egress
        run: |
          go test ./...

  smoke:
    runs-on: self-hosted
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Run dns test
        working-directory: components/egress
        run: |
          chmod +x tests/smoke-dns.sh
          ./tests/smoke-dns.sh

      - name: Run nft test
        working-directory: components/egress
        run: |
          chmod +x tests/smoke-nft.sh
          ./tests/smoke-nft.sh

      - name: Run dynamic ip test
        working-directory: components/egress
        run: |
          chmod +x tests/smoke-dynamic-ip.sh
          ./tests/smoke-dynamic-ip.sh

  bench:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Run bench test
        working-directory: components/egress
        run: |
          chmod +x tests/bench-dns-nft.sh
          ./tests/bench-dns-nft.sh
        env:
          BENCH_SAMPLE_SIZE: "20"

      - name: Upload egress logs
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: egress-log-for-bench
          path: /tmp/egress-logs/
          retention-days: 5


================================================
FILE: .github/workflows/execd-test.yml
================================================
name: Execd Tests

on:
  pull_request:
    branches: [ main ]
    paths:
      - 'components/execd/**'
      - 'components/internal/**'

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version: '1.24.0'

      - name: Run golint
        run: |
          cd components/execd
          make golint

      - name: Build (Multi platform compile)
        run: |
          cd components/execd
          #
          make multi-build

      - name: Run tests with coverage
        run: |
          cd components/execd
          go test -v -coverpkg=./... -coverprofile=coverage.out -covermode=atomic ./pkg/...

      - name: Calculate coverage and generate summary
        id: coverage
        run: |
          cd components/execd
          # Extract total coverage percentage
          TOTAL_COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}')
          echo "total_coverage=$TOTAL_COVERAGE" >> $GITHUB_OUTPUT
          
          # Generate GitHub Actions job summary
          echo "## 📊 execd Test Coverage Report" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Total Line Coverage:** $TOTAL_COVERAGE" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Coverage report generated for commit \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "---" >> $GITHUB_STEP_SUMMARY
          echo "*Coverage targets: Core packages >80%, API layer >70%*" >> $GITHUB_STEP_SUMMARY

  smoke:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version: '1.24.0'

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.10'

      - name: Install make (Windows)
        if: matrix.os == 'windows-latest'
        shell: powershell
        run: choco install make -y

      - name: Build
        run: |
          cd components/execd
          make build

      - name: Run smoke test
        run: |
          cd components/execd
          chmod +x tests/smoke.sh
          ./tests/smoke.sh

          sleep 5
          python3 tests/smoke_api.py
      - name: Show logs
        if: always()
        run: |
          set -x
          cat components/execd/startup.log || true
          cat components/execd/execd.log || true


================================================
FILE: .github/workflows/ingress-test.yaml
================================================
name: Ingress Tests

on:
  pull_request:
    branches: [ main ]
    paths:
      - 'components/ingress/**'
      - 'components/internal/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    permissions:
      contents: read
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version: '1.24.0'

      - name: Run golint
        working-directory: components/ingress
        run: |
          make golint

      - name: Run Build
        working-directory: components/ingress
        run: |
          make build

      - name: Run tests
        working-directory: components/ingress
        run: |
          make test


================================================
FILE: .github/workflows/publish-components.yml
================================================
name: Publish Components Image

permissions:
  # required for bump step to push branch and create PR
  contents: write
  pull-requests: write

on:
  workflow_dispatch:
    inputs:
      component:
        description: 'Component to build'
        required: true
        type: choice
        options:
          - execd
          - code-interpreter
          - ingress
          - egress
          - controller
          - task-executor
        default: 'execd'
      image_tag:
        description: 'Docker image tag'
        required: true
        default: 'latest'
  push:
    tags:
      - 'docker/execd/**'
      - 'docker/code-interpreter/**'
      - 'docker/ingress/**'
      - 'docker/egress/**'
      - 'k8s/controller/**'
      - 'k8s/task-executor/**'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}

      - name: Login to ACR
        uses: docker/login-action@v3
        with:
          registry: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com
          username: ${{ secrets.ACR_USERNAME }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Parse tag and set variables
        id: parse_tag
        run: |
          if [[ "${{ github.ref }}" == refs/tags/docker/* ]]; then
            TAG_PATH="${{ github.ref }}"
            TAG_PATH="${TAG_PATH#refs/tags/}"

            COMPONENT=$(echo "$TAG_PATH" | cut -d'/' -f2)
            IMAGE_TAG=$(echo "$TAG_PATH" | cut -d'/' -f3)

            echo "component=$COMPONENT" >> $GITHUB_OUTPUT
            echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
          elif [[ "${{ github.ref }}" == refs/tags/k8s/* ]]; then
            TAG_PATH="${{ github.ref }}"
            TAG_PATH="${TAG_PATH#refs/tags/}"

            COMPONENT=$(echo "$TAG_PATH" | cut -d'/' -f2)
            IMAGE_TAG=$(echo "$TAG_PATH" | cut -d'/' -f3)

            echo "component=$COMPONENT" >> $GITHUB_OUTPUT
            echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
          else
            echo "component=${{ inputs.component }}" >> $GITHUB_OUTPUT
            echo "image_tag=${{ inputs.image_tag }}" >> $GITHUB_OUTPUT
          fi

      - name: Free disk space
        run: |
          sudo rm -rf /usr/share/dotnet /opt/ghc /opt/hostedtoolcache
          sudo apt-get clean
          sudo rm -rf /var/lib/apt/lists/*
          df -h

      - name: Build and push to registries
        run: |
          COMPONENT="${{ steps.parse_tag.outputs.component }}"
          IMAGE_TAG="${{ steps.parse_tag.outputs.image_tag }}"

          if [ "$COMPONENT" == "execd" ]; then
            cd components/execd
          elif [ "$COMPONENT" == "ingress" ]; then
            cd components/ingress
          elif [ "$COMPONENT" == "egress" ]; then
            cd components/egress
          elif [ "$COMPONENT" == "controller" ]; then
            cd kubernetes
          elif [ "$COMPONENT" == "task-executor" ]; then
            cd kubernetes
          else
            cd sandboxes/$COMPONENT
          fi

          export TAG=$IMAGE_TAG
          export COMPONENT=$COMPONENT
          chmod +x build.sh
          ./build.sh

      - name: Bump component version in repo
        if: steps.parse_tag.outputs.image_tag != 'latest' && steps.parse_tag.outputs.image_tag != ''
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          COMPONENT="${{ steps.parse_tag.outputs.component }}"
          IMAGE_TAG="${{ steps.parse_tag.outputs.image_tag }}"
          # Ensure version has 'v' prefix for bump script
          if [[ "$IMAGE_TAG" =~ ^v ]]; then
            VERSION="$IMAGE_TAG"
          else
            VERSION="v${IMAGE_TAG}"
          fi

          ./scripts/bump-component-version.sh "$COMPONENT" "$VERSION"

          BRANCH="bump/${COMPONENT}-${VERSION}"
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git checkout -b "$BRANCH"
          git add -A
          git diff --staged --quiet && echo "No changes to commit" && exit 0
          git commit -m "chore: bump $COMPONENT to $VERSION"
          git push origin "$BRANCH"

          gh pr create \
            --title "chore: bump $COMPONENT to $VERSION" \
            --body "Auto-generated by Publish Components workflow after building \`$COMPONENT:$VERSION\`." \
            --base "$(gh api repos/${{ github.repository }} --jq .default_branch)"


================================================
FILE: .github/workflows/publish-csharp-sdks.yml
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Publish C# SDKs

on:
  push:
    tags:
      - "csharp/sandbox/v*"
      - "csharp/code-interpreter/v*"

permissions:
  contents: read

jobs:
  publish:
    name: Publish (${{ matrix.sdk.name }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        sdk:
          - name: sandbox
            tagPrefix: sandbox
            csprojPath: sdks/sandbox/csharp/src/OpenSandbox/OpenSandbox.csproj
          - name: code-interpreter
            tagPrefix: code-interpreter
            csprojPath: sdks/code-interpreter/csharp/src/OpenSandbox.CodeInterpreter/OpenSandbox.CodeInterpreter.csproj

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up .NET
        uses: actions/setup-dotnet@v5
        with:
          dotnet-version: "10.0.x"

      - name: Parse package version from tag
        if: startsWith(github.ref, format('refs/tags/csharp/{0}/v', matrix.sdk.tagPrefix))
        shell: bash
        run: |
          VERSION="${GITHUB_REF_NAME#csharp/${{ matrix.sdk.tagPrefix }}/v}"
          echo "PACKAGE_VERSION=$VERSION" >> "$GITHUB_ENV"

      - name: Restore
        if: startsWith(github.ref, format('refs/tags/csharp/{0}/v', matrix.sdk.tagPrefix))
        run: |
          EXTRA_RESTORE_ARGS=""
          if [ "${{ matrix.sdk.name }}" = "code-interpreter" ]; then
            EXTRA_RESTORE_ARGS="-p:UseLocalOpenSandboxProjectReference=false"
          fi
          dotnet restore "${{ matrix.sdk.csprojPath }}" ${EXTRA_RESTORE_ARGS}

      - name: Pack
        if: startsWith(github.ref, format('refs/tags/csharp/{0}/v', matrix.sdk.tagPrefix))
        run: |
          EXTRA_PACK_ARGS=""
          if [ "${{ matrix.sdk.name }}" = "code-interpreter" ]; then
            EXTRA_PACK_ARGS="-p:UseLocalOpenSandboxProjectReference=false"
          fi
          dotnet pack "${{ matrix.sdk.csprojPath }}" \
            --configuration Release \
            --no-restore \
            -p:PackageVersion="${PACKAGE_VERSION}" \
            -p:ContinuousIntegrationBuild=true \
            ${EXTRA_PACK_ARGS} \
            --output ./artifacts/${{ matrix.sdk.name }}

      - name: Publish to NuGet
        if: startsWith(github.ref, format('refs/tags/csharp/{0}/v', matrix.sdk.tagPrefix))
        env:
          NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
        run: |
          dotnet nuget push "./artifacts/${{ matrix.sdk.name }}/*.nupkg" \
            --api-key "$NUGET_API_KEY" \
            --source "https://api.nuget.org/v3/index.json" \
            --skip-duplicate


================================================
FILE: .github/workflows/publish-helm-chart.yml
================================================
name: Publish Helm Chart

on:
  workflow_dispatch:
    inputs:
      component:
        description: 'Component to release'
        required: true
        type: choice
        options:
          - opensandbox-controller
          - opensandbox-server
          - opensandbox
        default: 'opensandbox-controller'
      app_version:
        description: 'App version (without v prefix, e.g., 0.1.0)'
        required: true
        default: '0.1.0'
  push:
    tags:
      - 'helm/**'  # Format: helm/<component>/<app_version>, e.g., helm/opensandbox-controller/0.1.0

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure Git
        run: |
          git config user.name "$GITHUB_ACTOR"
          git config user.email "$GITHUB_ACTOR@users.noreply.github.com"

      - name: Install Helm
        uses: azure/setup-helm@v4
        with:
          version: 'latest'

      - name: Parse tag and set variables
        id: parse_tag
        run: |
          if [[ "${{ github.ref }}" == refs/tags/helm/* ]]; then
            TAG_PATH="${{ github.ref }}"
            TAG_PATH="${TAG_PATH#refs/tags/}"
            
            COMPONENT=$(echo "$TAG_PATH" | cut -d'/' -f2)
            VERSION=$(echo "$TAG_PATH" | cut -d'/' -f3)
            
            # Remove 'v' prefix if present
            VERSION=${VERSION#v}
            
            echo "component=$COMPONENT" >> $GITHUB_OUTPUT
            echo "app_version=$VERSION" >> $GITHUB_OUTPUT
          else
            echo "component=${{ inputs.component }}" >> $GITHUB_OUTPUT
            echo "app_version=${{ inputs.app_version }}" >> $GITHUB_OUTPUT
          fi

      - name: Set chart path
        id: chart_path
        run: |
          COMPONENT="${{ steps.parse_tag.outputs.component }}"
          
          if [ "$COMPONENT" == "opensandbox-controller" ]; then
            CHART_PATH="kubernetes/charts/opensandbox-controller"
          elif [ "$COMPONENT" == "opensandbox-server" ]; then
            CHART_PATH="kubernetes/charts/opensandbox-server"
          elif [ "$COMPONENT" == "opensandbox" ]; then
            CHART_PATH="kubernetes/charts/opensandbox"
          else
            echo "Error: Unknown component: $COMPONENT"
            exit 1
          fi
          
          echo "path=$CHART_PATH" >> $GITHUB_OUTPUT

      - name: Get chart version from Chart.yaml
        id: chart_version
        run: |
          CHART_PATH="${{ steps.chart_path.outputs.path }}"
          CHART_VERSION=$(grep '^version:' $CHART_PATH/Chart.yaml | awk '{print $2}')
          echo "version=$CHART_VERSION" >> $GITHUB_OUTPUT
          echo "Chart version: $CHART_VERSION"

      - name: Update Chart.yaml with app version
        run: |
          APP_VERSION="${{ steps.parse_tag.outputs.app_version }}"
          CHART_PATH="${{ steps.chart_path.outputs.path }}"
          
          # Only update appVersion, keep chart version as-is in Chart.yaml
          sed -i "s/^appVersion:.*/appVersion: \"$APP_VERSION\"/" $CHART_PATH/Chart.yaml
          
          echo "Updated Chart.yaml:"
          cat $CHART_PATH/Chart.yaml

      - name: Build dependencies (for opensandbox all-in-one chart)
        if: ${{ steps.parse_tag.outputs.component == 'opensandbox' }}
        run: |
          CHART_PATH="${{ steps.chart_path.outputs.path }}"
          echo "Building dependencies for all-in-one chart..."
          helm dependency build $CHART_PATH

      - name: Lint Helm chart
        run: |
          CHART_PATH="${{ steps.chart_path.outputs.path }}"
          helm lint $CHART_PATH

      - name: Package Helm chart
        run: |
          CHART_PATH="${{ steps.chart_path.outputs.path }}"
          helm package $CHART_PATH

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: helm/${{ steps.parse_tag.outputs.component }}/${{ steps.parse_tag.outputs.app_version }}
          name: Helm Chart ${{ steps.parse_tag.outputs.component }} ${{ steps.chart_version.outputs.version }} (App v${{ steps.parse_tag.outputs.app_version }})
          body: |
            ## ${{ steps.parse_tag.outputs.component }} Helm Chart
            
            **Chart Version:** ${{ steps.chart_version.outputs.version }}
            **App Version:** ${{ steps.parse_tag.outputs.app_version }}
            
            ### Installation
            
            直接从 GitHub Release 安装:
            
            ```bash
            helm install ${{ steps.parse_tag.outputs.component }} \
              https://github.com/${{ github.repository }}/releases/download/helm/${{ steps.parse_tag.outputs.component }}/${{ steps.parse_tag.outputs.app_version }}/${{ steps.parse_tag.outputs.component }}-${{ steps.chart_version.outputs.version }}.tgz \
              --namespace opensandbox-system \
              --create-namespace
            ```
            
            或者先下载后安装:
            
            ```bash
            # 下载
            wget https://github.com/${{ github.repository }}/releases/download/helm/${{ steps.parse_tag.outputs.component }}/${{ steps.parse_tag.outputs.app_version }}/${{ steps.parse_tag.outputs.component }}-${{ steps.chart_version.outputs.version }}.tgz
            
            # 安装
            helm install ${{ steps.parse_tag.outputs.component }} ./${{ steps.parse_tag.outputs.component }}-${{ steps.chart_version.outputs.version }}.tgz \
              --namespace opensandbox-system \
              --create-namespace
            ```
            
            ${{ steps.parse_tag.outputs.component == 'opensandbox' && '**Note**: This is an all-in-one chart that bundles controller and server. The packaged chart already includes all dependencies, no need to run `helm dependency build` when installing from release.' || '' }}
            
            ### What's Changed
            
            - Chart version: ${{ steps.chart_version.outputs.version }}
            - App version: ${{ steps.parse_tag.outputs.app_version }}
          files: |
            ${{ steps.parse_tag.outputs.component }}-*.tgz
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/publish-java-sdks.yml
================================================
name: Publish Java SDKs

on:
  push:
    tags:
      - "java/sandbox/v*"
      - "java/code-interpreter/v*"

permissions:
  contents: read

jobs:
  publish:
    name: Publish (${{ matrix.sdk.name }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        sdk:
          - name: sandbox
            tagPrefix: sandbox
            workingDirectory: sdks/sandbox/kotlin
          - name: code-interpreter
            tagPrefix: code-interpreter
            workingDirectory: sdks/code-interpreter/kotlin

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Java
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: "17"

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v5

      - name: Publish to Maven Central
        working-directory: ${{ matrix.sdk.workingDirectory }}
        if: startsWith(github.ref, format('refs/tags/java/{0}/v', matrix.sdk.tagPrefix))
        env:
          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.ORG_GRADLE_PROJECT_MAVENCENTRALUSERNAME }}
          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_MAVENCENTRALPASSWORD }}
          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGINMEMORYKEY }}
          ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGINMEMORYKEYPASSWORD }}
        run: |
          ./gradlew publishAndReleaseToMavenCentral


================================================
FILE: .github/workflows/publish-js-sdks.yml
================================================
name: Publish JavaScript SDKs

on:
  push:
    tags:
      - "js/sandbox/v*"
      - "js/code-interpreter/v*"

permissions:
  contents: read

jobs:
  publish:
    name: Publish (${{ matrix.sdk.name }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        sdk:
          - name: sandbox
            tagPrefix: sandbox
            workingDirectory: sdks/sandbox/javascript
            packageName: "@alibaba-group/opensandbox"
          - name: code-interpreter
            tagPrefix: code-interpreter
            workingDirectory: sdks/code-interpreter/javascript
            packageName: "@alibaba-group/opensandbox-code-interpreter"

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Node
        uses: actions/setup-node@v6
        with:
          node-version: "20"
          registry-url: "https://registry.npmjs.org"

      - name: Set up pnpm
        uses: pnpm/action-setup@v4
        with:
          version: latest

      - name: Enable corepack
        run: corepack enable

      - name: Get pnpm store path
        id: pnpm-store
        run: echo "STORE_PATH=$(corepack pnpm store path)" >> "$GITHUB_OUTPUT"

      - name: Cache pnpm store
        uses: actions/cache@v5
        with:
          path: ${{ steps.pnpm-store.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-${{ hashFiles('sdks/pnpm-lock.yaml') }}
          restore-keys: ${{ runner.os }}-pnpm-

      - name: Install workspace dependencies
        working-directory: sdks
        run: corepack pnpm install --frozen-lockfile

      - name: Build SDK
        working-directory: sdks
        run: corepack pnpm --filter ${{ matrix.sdk.packageName }}... --sort run build

      - name: Publish to npm
        if: startsWith(github.ref, format('refs/tags/js/{0}/v', matrix.sdk.tagPrefix))
        working-directory: ${{ matrix.sdk.workingDirectory }}
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          corepack pnpm publish --access public --no-git-checks


================================================
FILE: .github/workflows/publish-python-sdks.yml
================================================
# Copyright 2025 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Publish Python SDKs

permissions:
  contents: read

on:
  push:
    tags:
      - "python/sandbox/v*"
      - "python/code-interpreter/v*"
      - "python/mcp/sandbox/v*"

jobs:
  publish-sandbox:
    if: startsWith(github.ref, 'refs/tags/python/sandbox/v')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.10'

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "latest"

      - name: Generate API
        working-directory: sdks/sandbox/python
        run: |
          uv run python scripts/generate_api.py

      - name: Build package
        working-directory: sdks/sandbox/python
        run: |
          uv build

      - name: Publish to PyPI
        working-directory: sdks/sandbox/python
        env:
          UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
        run: |
          uv publish

  publish-code-interpreter:
    if: startsWith(github.ref, 'refs/tags/python/code-interpreter/v')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.10'

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "latest"

      - name: Build package
        working-directory: sdks/code-interpreter/python
        run: |
          uv build

      - name: Publish to PyPI
        working-directory: sdks/code-interpreter/python
        env:
          UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
        run: |
          uv publish

  publish-mcp-sandbox:
    if: startsWith(github.ref, 'refs/tags/python/mcp/sandbox/v')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.10"

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "latest"

      - name: Build package
        working-directory: sdks/mcp/sandbox/python
        run: |
          uv build

      - name: Publish to PyPI
        working-directory: sdks/mcp/sandbox/python
        env:
          UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
        run: |
          uv publish


================================================
FILE: .github/workflows/publish-server.yml
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Publish Server

on:
  push:
    tags:
      - 'server/v*'

permissions:
  contents: read

jobs:
  publish-pypi:
    if: startsWith(github.ref, 'refs/tags/server/v')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.10'

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "latest"

      - name: Build package
        working-directory: server
        run: |
          uv build

      - name: Publish to PyPI
        working-directory: server
        env:
          UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
        run: |
          uv publish

  publish-image:
    if: startsWith(github.ref, 'refs/tags/server/v')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}

      - name: Login to ACR
        uses: docker/login-action@v3
        with:
          registry: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com
          username: ${{ secrets.ACR_USERNAME }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Parse tag and set variables
        id: parse_tag
        run: |
          if [[ "${{ github.ref }}" == refs/tags/server/* ]]; then
            TAG_PATH="${{ github.ref }}"
            TAG_PATH="${TAG_PATH#refs/tags/}"

            IMAGE_TAG="${TAG_PATH#server/}"

            if [ -z "$IMAGE_TAG" ]; then
              echo "failed to parse image tag from $TAG_PATH" >&2
              exit 1
            fi

            echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
          else
            echo "cannot parse tag"
            exit 1
          fi

      - name: Build and push to registries
        working-directory: server
        env:
          TAG: ${{ steps.parse_tag.outputs.image_tag }}
        run: |
          chmod +x build.sh
          ./build.sh


================================================
FILE: .github/workflows/real-e2e.yml
================================================
name: Real E2E Tests

permissions:
  contents: read

on:
  pull_request:
    branches: [ main ]
    paths:
      - 'server/src/**'
      - 'components/execd/**'
      - 'components/egress/**'
      - 'sdks/code-interpreter/**'
      - 'sdks/sandbox/**'
      - 'tests/**'
  push:
    branches: [ main ]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  python-e2e:
    name: Python E2E (docker bridge)
    runs-on: self-hosted
    env:
      UV_BIN: /home/admin/.local/bin
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up uv PATH and verify
        run: |
          echo "${UV_BIN}" >> "$GITHUB_PATH"
          export PATH="${UV_BIN}:${PATH}"
          uv --version
          uv run python --version

      - name: Clean up previous E2E resources
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          # Remove root-owned files from previous sandbox runs by mounting parent dir
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true

      - name: Build local egress image
        run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile .

      - name: Run tests
        run: |
          set -e

          # Create config file
          cat <<EOF > ~/.sandbox.toml
          [server]
          host = "127.0.0.1"
          port = 8080
          log_level = "INFO"
          api_key = ""
          [runtime]
          type = "docker"
          execd_image = "opensandbox/execd:local"
          [egress]
          image = "opensandbox/egress:local"
          mode = "dns"
          [docker]
          network_mode = "bridge"
          [storage]
          allowed_host_paths = ["/tmp/opensandbox-e2e"]
          EOF

          ./scripts/python-e2e.sh

      - name: Eval server logs
        if: ${{ always() }}
        run: cat server/server.log

      - name: Upload execd logs
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: execd-log-for-python-e2e
          path: /tmp/opensandbox-e2e/logs/
          retention-days: 5

      - name: Clean up after E2E
        if: always()
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true
          pkill -f "python -m src.main" || true

  java-e2e:
    name: Java E2E (docker bridge)
    runs-on: self-hosted
    env:
      UV_BIN: /home/admin/.local/bin
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up uv PATH and verify
        run: |
          echo "${UV_BIN}" >> "$GITHUB_PATH"
          export PATH="${UV_BIN}:${PATH}"
          uv --version
          uv run python --version

      - name: Set up JDK 8
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: "8"

      - name: Set up JDK 17
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: "17"

      - name: Clean up previous E2E resources
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true

      - name: Build local egress image
        run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile .

      - name: Run tests
        env:
          GRADLE_USER_HOME: ${{ github.workspace }}/.gradle-user-home
        run: |
          set -e
          export GRADLE_OPTS="-Dorg.gradle.java.installations.auto-detect=true -Dorg.gradle.java.installations.auto-download=false -Dorg.gradle.java.installations.paths=${JAVA_HOME_8_X64},${JAVA_HOME_17_X64}"

          # Create config file
          cat <<EOF > ~/.sandbox.toml
          [server]
          host = "127.0.0.1"
          port = 8080
          log_level = "INFO"
          api_key = ""
          [runtime]
          type = "docker"
          execd_image = "opensandbox/execd:local"
          [egress]
          image = "opensandbox/egress:local"
          mode = "dns+nft"
          [docker]
          network_mode = "bridge"
          [storage]
          allowed_host_paths = ["/tmp/opensandbox-e2e"]
          EOF

          bash ./scripts/java-e2e.sh

      - name: Eval server logs
        if: ${{ always() }}
        run: cat server/server.log

      - name: Upload Test Report
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: java-test-report
          path: tests/java/build/reports/tests/test/
          retention-days: 5

      - name: Upload execd logs
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: execd-log-for-java-e2e
          path: /tmp/opensandbox-e2e/logs/
          retention-days: 5

      - name: Clean up after E2E
        if: always()
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true
          pkill -f "python -m src.main" || true

  javascript-e2e:
    name: JavaScript E2E (docker bridge)
    runs-on: self-hosted
    env:
      UV_BIN: /home/admin/.local/bin
      NODE_VERSION: "20.19.0"
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up uv PATH and verify
        run: |
          echo "${UV_BIN}" >> "$GITHUB_PATH"
          export PATH="${UV_BIN}:${PATH}"
          uv --version
          uv run python --version

      - name: Set up Node.js
        run: |
          NODE_DIR="/home/admin/.local/node-v${NODE_VERSION}-linux-x64"
          if [ -x "${NODE_DIR}/bin/node" ]; then
            echo "Node.js ${NODE_VERSION} already cached"
          else
            echo "Downloading Node.js ${NODE_VERSION}..."
            mkdir -p /home/admin/.local
            curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \
              | tar -xJ -C /home/admin/.local/
          fi
          echo "${NODE_DIR}/bin" >> "$GITHUB_PATH"
          export PATH="${NODE_DIR}/bin:${PATH}"
          node --version
          npm --version

      - name: Clean up previous E2E resources
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true

      - name: Build local egress image
        run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile .

      - name: Run tests
        run: |
          set -e

          # Create config file (match other E2E jobs)
          cat <<EOF > ~/.sandbox.toml
          [server]
          host = "127.0.0.1"
          port = 8080
          log_level = "INFO"
          api_key = ""
          [runtime]
          type = "docker"
          execd_image = "opensandbox/execd:local"
          [egress]
          image = "opensandbox/egress:local"
          [docker]
          network_mode = "bridge"
          [storage]
          allowed_host_paths = ["/tmp/opensandbox-e2e"]
          EOF

          bash ./scripts/javascript-e2e.sh

      - name: Eval server logs
        if: ${{ always() }}
        run: cat server/server.log

      - name: Upload Test Report
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: javascript-test-report
          path: tests/javascript/build/test-results/junit.xml
          retention-days: 5

      - name: Upload execd logs
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: execd-log-for-js-e2e
          path: /tmp/opensandbox-e2e/logs/
          retention-days: 5

      - name: Clean up after E2E
        if: always()
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true
          pkill -f "python -m src.main" || true

  csharp-e2e:
    name: C# E2E (docker bridge)
    runs-on: self-hosted
    env:
      UV_BIN: /home/admin/.local/bin
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up uv PATH and verify
        run: |
          echo "${UV_BIN}" >> "$GITHUB_PATH"
          export PATH="${UV_BIN}:${PATH}"
          uv --version
          uv run python --version

      - name: Set up .NET SDK
        uses: actions/setup-dotnet@v5
        env:
          DOTNET_INSTALL_DIR: /home/admin/.local/dotnet
        with:
          dotnet-version: "10.0.x"

      - name: Clean up previous E2E resources
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true

      - name: Build local egress image
        run: docker build -t opensandbox/egress:local -f components/egress/Dockerfile .

      - name: Run tests
        run: |
          set -e

          cat <<EOF > ~/.sandbox.toml
          [server]
          host = "127.0.0.1"
          port = 8080
          log_level = "INFO"
          api_key = ""
          [runtime]
          type = "docker"
          execd_image = "opensandbox/execd:local"
          [egress]
          image = "opensandbox/egress:local"
          [docker]
          network_mode = "bridge"
          [storage]
          allowed_host_paths = ["/tmp/opensandbox-e2e"]
          EOF

          bash ./scripts/csharp-e2e.sh

      - name: Eval server logs
        if: ${{ always() }}
        run: cat server/server.log

      - name: Upload Test Report
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: csharp-test-report
          path: tests/csharp/build/test-results/
          retention-days: 5

      - name: Upload execd logs
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: execd-log-for-csharp-e2e
          path: /tmp/opensandbox-e2e/logs/
          retention-days: 5

      - name: Clean up after E2E
        if: always()
        run: |
          docker ps -aq --filter "label=opensandbox" | xargs -r docker rm -f || true
          docker run --rm -v /tmp:/host_tmp alpine rm -rf /host_tmp/opensandbox-e2e || true
          pkill -f "python -m src.main" || true


================================================
FILE: .github/workflows/sandbox-k8s-e2e.yml
================================================
name: Sandbox K8S E2E Tests

on:
  pull_request:
    branches: [ main ]
    paths:
      - 'kubernetes/**'

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  GO_VERSION: '1.24'

jobs:
  e2e-k8s:
    name: E2E Tests (K8s v${{ matrix.k8s-version }})
    strategy:
      fail-fast: false
      matrix:
        k8s-version: ["1.21.1", "1.22.4", "1.24.4", "1.26.4", "1.28.6", "1.30.4", "1.32.2", "1.34.2"]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version: ${{ env.GO_VERSION }}

      - name: Run tests
        run: |
          cd kubernetes
          make test-e2e KIND_K8S_VERSION=v${{ matrix.k8s-version }}

================================================
FILE: .github/workflows/sandbox-k8s-test.yml
================================================
name: Sandbox K8S Tests

on:
  pull_request:
    branches: [ main ]
    paths:
      - 'kubernetes/**'

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Go
        uses: actions/setup-go@v6
        with:
          go-version: '1.24.0'

      - name: Run golint
        run: |
          cd kubernetes
          make lint

      - name: Build binary
        run: |
          cd kubernetes
          make build
          make task-executor-build

      - name: Run tests
        run: |
          cd kubernetes
          make test


================================================
FILE: .github/workflows/sdk-tests.yml
================================================
# Copyright 2025 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: SDK Tests

on:
  pull_request:
    branches: [main]
    paths:
      - "sdks/sandbox/**"
      - "sdks/code-interpreter/**"
      - "specs/**"
  push:
    branches: [main]
    paths:
      - "sdks/sandbox/**"
      - "sdks/code-interpreter/**"
      - "specs/**"

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  python-sdk-quality:
    name: Python SDK Quality (${{ matrix.package_name }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - package_name: sandbox
            package_dir: sdks/sandbox/python
          - package_name: code-interpreter
            package_dir: sdks/code-interpreter/python
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.11"

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "latest"

      - name: Install dependencies
        working-directory: ${{ matrix.package_dir }}
        run: |
          uv sync

      - name: Generate API
        if: matrix.package_name == 'sandbox'
        working-directory: sdks/sandbox/python
        run: |
          uv run python scripts/generate_api.py

      - name: Run ruff
        working-directory: ${{ matrix.package_dir }}
        run: |
          uv run ruff check

      - name: Run pyright
        working-directory: ${{ matrix.package_dir }}
        run: |
          uv run pyright

  python-sdk:
    name: Python SDK Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.11"

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "latest"

      - name: Generate API
        working-directory: sdks/sandbox/python
        run: |
          uv sync
          uv run python scripts/generate_api.py

      - name: Run tests
        working-directory: sdks/sandbox/python
        run: |
          uv run pytest tests/ -v

  kotlin-sdk:
    name: Kotlin SDK Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Java
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: "17"

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v5

      - name: Run tests
        working-directory: sdks/sandbox/kotlin
        run: |
          ./gradlew :sandbox:test

  csharp-sdk:
    name: C# SDK Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up .NET 10
        uses: actions/setup-dotnet@v5
        with:
          dotnet-version: "10.0.x"

      - name: Run sandbox tests
        working-directory: sdks/sandbox/csharp
        run: |
          dotnet test tests/OpenSandbox.Tests/OpenSandbox.Tests.csproj --configuration Release

      - name: Run code interpreter tests
        working-directory: sdks/code-interpreter/csharp
        run: |
          dotnet test tests/OpenSandbox.CodeInterpreter.Tests/OpenSandbox.CodeInterpreter.Tests.csproj --configuration Release


================================================
FILE: .github/workflows/server-test.yml
================================================
name: Server Tests

on:
  pull_request:
    branches: [ main ]
    paths:
      - 'server/src/**'
      - 'server/tests/**'

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.10'

      - name: Install uv
        run: |
          pip install uv

      - name: Run tests
        run: |
          cd server
          uv sync --all-groups
          uv run ruff check
          uv run pytest

  docker-smoke:
    strategy:
      matrix:
        network: [host, bridge]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.10'

      - name: Install uv
        run: |
          pip install uv

      - name: Set up Docker
        run: |
          docker --version

      - name: Run smoke test
        run: |
          set -e
          cd server
          uv sync --all-groups

          # Create config file
          cat <<EOF > ~/.sandbox.toml
          [server]
          host = "127.0.0.1"
          port = 32888
          log_level = "INFO"
          api_key = ""
          [runtime]
          type = "docker"
          execd_image = "opensandbox/execd:latest"
          [egress]
          image = "opensandbox/egress:latest"
          [docker]
          network_mode = "${{ matrix.network }}"
          [storage]
          allowed_host_paths = ["/tmp/opensandbox-e2e"]
          EOF

          # Start server in background
          uv run python -m src.main > app.log 2>&1 &

          # Wait for server to start
          sleep 10

          # Run smoke test
          chmod +x tests/smoke.sh
          ./tests/smoke.sh
      - name: Show logs
        if: always()
        run: |
          cat server/app.log


================================================
FILE: .github/workflows/verify-license.yml
================================================
name: Verify License Headers

on:
  pull_request:
    branches: [ main ]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  verify-license:
    runs-on: self-hosted
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Run license verification
        run: |
          chmod +x scripts/verify-license.sh
          ./scripts/verify-license.sh


================================================
FILE: .gitignore
================================================
# IDE and Editor files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
Thumbs.db

# Go
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool
*.out

# Dependency directories
vendor/

# Go workspace file
go.work

# Java/Kotlin
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs
hs_err_pid*
replay_pid*

# Gradle
.gradle/
build/
!**/gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar

# Node.js
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Dependency directories
node_modules/
jspm_packages/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# Yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
public
!docs/public/
!docs/public/CNAME

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Virtual environments
venv/
env/
ENV/
env.bak/
venv.bak/

# Docker
*.pid
*.seed
*.pid.lock

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Temporary files
*.tmp
*.temp
*~

# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# API keys and secrets
secrets/
*.pem
*.key
*.crt
*.p12
*.pfx

# Generated API documentation
docs/generated/
docs/.vitepress/generated/
docs/.vitepress/dist/
docs/.vitepress/cache/
apidocs/

# Test results
test-results/
coverage/
*.coverage
.nyc_output

# Backup files
*.bak
*.backup
*.old

# Flattened POM files (Maven)
.flattened-pom.xml

# Kotlin
*.kotlin_module

# JetBrains specific
.idea/
*.iml
*.ipr
*.iws
out/

# Eclipse specific
.project
.classpath
.settings/
bin/

# NetBeans specific
nbproject/
nbbuild/
nbdist/
.nb-gradle/

# Generated files
generated/
**/generated/**

# gVisor runtime binaries (downloaded dynamically)
kubernetes/test/kind/gvisor/runsc
kubernetes/test/kind/gvisor/containerd-shim-runsc-v1
bin/
obj/


================================================
FILE: .pre-commit-config.yaml
================================================
# Minimal cross-language pre-commit hooks
# Install: pip install pre-commit && pre-commit install
# Run once on all files: pre-commit run --all-files

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: mixed-line-ending
      - id: check-merge-conflict
      - id: check-yaml
      - id: detect-private-key

  # Language-specific formatters/linters can be added later, for example:
  # - repo: local
  #   hooks:
  #     - id: gofmt
  #       name: gofmt
  #       entry: gofmt
  #       language: system
  #       types: [go]
  #     - id: ruff
  #       name: ruff
  #       entry: ruff check
  #       language: system
  #       types: [python]


================================================
FILE: AGENTS.md
================================================
# Repository Guidelines

## Project Structure & Module Organization
- `server/`: Python FastAPI service, configs, and tests.
- `components/execd/`: Go execution daemon and related tests.
- `sdks/`: Multi-language SDKs (`sdks/sandbox/*`, `sdks/code-interpreter/*`).
- `sandboxes/`: Runtime sandbox implementations (e.g., `sandboxes/code-interpreter/`).
- `specs/`: OpenAPI specs (`specs/execd-api.yaml`, `specs/sandbox-lifecycle.yml`).
- `examples/`: End-to-end usage examples and integrations.
- `tests/`: Cross-component/E2E tests (`tests/python/`, `tests/java/`).
- `docs/`, `oseps/`, `scripts/`: Docs, proposals, and automation scripts.

## Build, Test, and Development Commands
- Server (Python):
  - `cd server && uv sync` installs deps.
  - `cp server/example.config.toml ~/.sandbox.toml` sets local config.
  - `cd server && uv run python -m src.main` runs the API server.
- execd (Go):
  - `cd components/execd && go build -o bin/execd .` builds the daemon.
  - `cd components/execd && make fmt` formats Go sources.
- SDKs:
  - Python: `cd sdks/sandbox/python && uv sync && uv run pytest`.
  - Kotlin: `cd sdks/sandbox/kotlin && ./gradlew build`.
- Specs: `node scripts/spec-doc/generate-spec.js` regenerates spec docs.

## Coding Style & Naming Conventions
- Python: PEP 8, `ruff` for lint/format, type hints on public APIs.
- Go: `gofmt`, explicit error handling, standard import grouping.
- Kotlin: Kotlin Coding Conventions, `ktlint` where configured.
- Naming: classes `PascalCase`, functions `snake_case` (Python) / `camelCase` (Go/Kotlin), constants `UPPER_SNAKE_CASE`.

## SDK API Implementation Conventions
- Keep a clear split between generated API transport code and handwritten SDK business/adaptor code.
- In adapter/infrastructure layers, default to integrating through generated API clients instead of handcrafted request wiring.
- Prefer generated OpenAPI clients for standard request/response endpoints; use handwritten transport only for streaming or protocol-specific paths (for example SSE).
- Do not manually edit generated client files. When specs change, regenerate first, then adapt handwritten layers.
- For handwritten streaming paths, keep wire contracts aligned with OpenAPI field names/models and cover behavior with focused tests (especially parsing and error mapping).

## Testing Guidelines
- Python tests use `pytest` (async tests common).
- Go tests use `go test` under `components/execd/pkg/...`.
- Kotlin tests use Gradle (`./gradlew test`).
- Coverage targets (from CONTRIBUTING): core packages >80%, API layer >70%.

## Commit & Pull Request Guidelines
- Commit messages follow Conventional Commits, e.g. `feat(server): add runtime`.
- Use feature branches (e.g., `feature/...`, `fix/...`) and keep PRs focused.
- PRs should include summary, testing status, and linked issues; follow the template in `CONTRIBUTING.md`.
- For major API or architectural changes, submit an OSEP (`oseps/`).

## Security & Configuration Tips
- Local server config lives in `~/.sandbox.toml` (copied from `server/example.config.toml`).
- Docker is required for local sandbox execution; keep images and keys out of commits.


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

We are committed to a welcoming, safe, and respectful community.

## Expected Behavior
- Be respectful and inclusive.
- Assume good intent; seek to understand.
- Provide constructive feedback; critique code, not people.
- Follow project guidelines and security practices.

## Unacceptable Behavior
- Harassment, personal attacks, or discriminatory language.
- Publishing private information without consent.
- Disruptive or aggressive behavior in any project space.

## Scope
This Code applies to all project spaces, including issues, pull requests, discussions, chat, and events.

## Reporting
Report incidents to: **conduct@opensandbox.io**. Include as much detail as possible (what happened, when/where, links, screenshots if applicable).

## Enforcement
Maintainers will investigate in good faith and may take appropriate action, including warnings, temporary bans, or removal from the community.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to OpenSandbox

Thank you for your interest in contributing to OpenSandbox! This guide will help you get started with contributing to the project, whether you're fixing bugs, adding features, improving documentation, or helping in other ways.

## Table of Contents

- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Development Environment Setup](#development-environment-setup)
- [Project Structure](#project-structure)
- [Development Workflow](#development-workflow)
- [Coding Standards](#coding-standards)
- [Testing Guidelines](#testing-guidelines)
- [Submitting Contributions](#submitting-contributions)
- [Communication Channels](#communication-channels)

## Code of Conduct

OpenSandbox adheres to a [Code of Conduct](CODE_OF_CONDUCT.md) that we expect all contributors to follow. Please read it before contributing to ensure a welcoming and inclusive environment for everyone.

## Getting Started

### Ways to Contribute

There are many ways to contribute to OpenSandbox:

- **Report Bugs**: Submit detailed bug reports through [GitHub Issues](https://github.com/alibaba/OpenSandbox/issues)
- **Suggest Features**: Propose new features or improvements
- **Write Code**: Fix bugs, implement features, or improve performance
- **Improve Documentation**: Enhance README files, write tutorials, or fix typos
- **Write Tests**: Add test coverage or improve existing tests
- **Review Pull Requests**: Help review and test others' contributions
- **Answer Questions**: Help other users in GitHub Discussions or Issues

### Before You Start

1. **Search Existing Issues**: Check if your bug report or feature request already exists
2. **Check Roadmap**: Review the project roadmap to see if your idea aligns with project goals
3. **Discuss Major Changes**: For significant changes, open an issue first or submit an [OSEP](oseps/README.md) to discuss your approach
4. **Review Architecture**: Read [docs/architecture.md](docs/architecture.md) to understand the system design

## Development Environment Setup

### Prerequisites

Different components have different requirements:

#### For Server (Python)

- **Python 3.10+**
- **uv** - Python package manager ([installation guide](https://github.com/astral-sh/uv))
- **Docker** - For running sandboxes locally

#### For execd (Go)

- **Go 1.24+**
- **Make** - Build automation (optional)
- **Docker** - For building container images

#### For SDKs

- **Python SDK**: Python 3.10+, uv
- **Java/Kotlin SDK**: JDK 17+, Gradle

### Quick Setup

#### Server Development

```bash
# Navigate to server directory
cd server

# Install dependencies
uv sync

# Copy example configuration
cp example.config.toml ~/.sandbox.toml

# Edit configuration for development
# Set log_level = "DEBUG" and api_key
nano ~/.sandbox.toml

# Run server
uv run python -m src.main
```

See [server/DEVELOPMENT.md](server/DEVELOPMENT.md) for detailed server development guide.

#### execd Development

```bash
# Navigate to execd directory
cd components/execd

# Download dependencies
go mod download

# Build execd
go build -o bin/execd .

# Run execd (requires Jupyter Server)
./bin/execd --jupyter-host=http://localhost:8888 --port=44772
```

See [components/execd/DEVELOPMENT.md](components/execd/DEVELOPMENT.md) for detailed execd development guide.

#### SDK Development

**Python SDK:**

```bash
cd sdks/sandbox/python
uv sync
uv run pytest
```

**Java/Kotlin SDK:**

```bash
cd sdks/sandbox/kotlin
./gradlew build
./gradlew test
```

## Project Structure

```
OpenSandbox/
├── sdks/                     # Multi-language SDKs
│   ├── code-interpreter/     # Code Interpreter SDK (Python, Kotlin)
│   └── sandbox/              # Sandbox base SDK (Python, Kotlin)
├── specs/                    # OpenAPI specifications
│   ├── execd-api.yaml        # Execution API spec
│   └── sandbox-lifecycle.yml # Lifecycle API spec
├── server/                   # Sandbox server (Python/FastAPI)
├── components/
│   └── execd/                # Execution daemon (Go/Beego)
├── sandboxes/                # Sandbox implementations
│   └── code-interpreter/     # Code Interpreter sandbox
├── examples/                 # Example integrations
├── docs/                     # Documentation
├── tests/                    # Cross-component tests
│   └── e2e/                  # End-to-end tests
└── scripts/                  # Build and utility scripts
```

## Development Workflow

### Enhancement Proposals (OSEP)

For major features, architectural changes, or modifications to the core API/security model, we follow the **OSEP (OpenSandbox Enhancement Proposals)** process.

Please read the [OSEP README](oseps/README.md) to understand when an OSEP is required and how to submit one. Small bug fixes and minor improvements do not require an OSEP.

### Branching Strategy

- **main**: Stable production branch
- **feature/[name]**: New features
- **fix/[name]**: Bug fixes
- **docs/[name]**: Documentation updates
- **refactor/[name]**: Code refactoring
- **test/[name]**: Test additions or improvements

### Creating a Feature Branch

```bash
# Update main branch
git checkout main
git pull origin main

# Create feature branch
git checkout -b feature/my-awesome-feature

# Make your changes
# ...

# Commit your changes
git add .
git commit -m "feat: add my awesome feature"

# Push to your fork
git push origin feature/my-awesome-feature
```

### Commit Message Format

We follow [Conventional Commits](https://www.conventionalcommits.org/) specification:

```
<type>(<scope>): <description>

[optional body]

[optional footer]
```

**Types:**

- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code style changes (formatting, no logic change)
- `refactor`: Code refactoring
- `test`: Adding or updating tests
- `chore`: Build process, dependencies, or tooling changes
- `perf`: Performance improvements
- `ci`: CI/CD changes

**Examples:**

```
feat(server): add Kubernetes runtime support
fix(execd): resolve memory leak in session cleanup
docs(sdk): add Python SDK usage examples
test(server): add integration tests for Docker runtime
refactor(sdk): simplify filesystem API
```

### Making Changes

1. **Write Clean Code**: Follow project coding standards (see below)
2. **Add Tests**: Ensure your changes are covered by tests
3. **Update Documentation**: Update relevant documentation files
4. **Test Locally**: Run all tests and ensure they pass
5. **Check Linting**: Run linters and fix any issues

## Coding Standards

### Python (Server, Python SDKs)

- **Style Guide**: Follow [PEP 8](https://pep8.org/)
- **Formatter**: Use `ruff` for formatting and linting
- **Type Hints**: Always use type hints for function signatures
- **Docstrings**: Use Google-style docstrings for public APIs

```python
def create_sandbox(
    image: ImageSpec,
    timeout: timedelta,
    entrypoint: Optional[List[str]] = None
) -> Sandbox:
    """Create a new sandbox instance.

    Args:
        image: Container image specification
        timeout: Sandbox timeout duration
        entrypoint: Optional custom entrypoint command

    Returns:
        Created sandbox instance

    Raises:
        ValueError: If image or timeout is invalid
    """
    # Implementation
```

**Running Linter:**

```bash
cd server
uv run ruff check src tests
uv run ruff format src tests
```

### Go (execd)

- **Style Guide**: Follow [Effective Go](https://golang.org/doc/effective_go)
- **Formatter**: Use `gofmt` for formatting
- **Imports**: Organize in three groups (stdlib, third-party, internal)
- **Error Handling**: Always handle errors explicitly

```go
// Good
result, err := someOperation()
if err != nil {
    logs.Error("operation failed: %v", err)
    return fmt.Errorf("failed to do something: %w", err)
}

// Bad - silent failure
result, _ := someOperation()
```

**Running Formatter:**

```bash
cd components/execd
gofmt -w .
# Or
make fmt
```

### Java/Kotlin (Java/Kotlin SDKs)

- **Style Guide**: Follow [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html)
- **Formatter**: Use `ktlint`
- **Null Safety**: Use Kotlin's null safety features

```kotlin
suspend fun createSandbox(
    image: ImageSpec,
    timeout: Duration,
    entrypoint: List<String>? = null
): Sandbox {
    // Implementation
}
```

### General Guidelines

- **Naming Conventions**:
  - Functions/Methods: `snake_case` (Python), `camelCase` (Go, Kotlin)
  - Classes: `PascalCase` (all languages)
  - Constants: `UPPER_SNAKE_CASE` (all languages)
  - Private members: `_leading_underscore` (Python), `unexported` (Go)

- **Comments**: Write clear, concise comments explaining "why", not "what"
- **Error Messages**: Provide actionable error messages with context
- **Logging**: Use appropriate log levels (DEBUG, INFO, WARNING, ERROR)

## Testing Guidelines

### Test Coverage Requirements

- **Core Packages**: Aim for >80% coverage
- **API Layer**: Aim for >70% coverage
- **Utilities**: Aim for >90% coverage

### Writing Tests

#### Python Tests (pytest)

```python
import pytest
from opensandbox import Sandbox

@pytest.mark.asyncio
async def test_create_sandbox():
    """Test sandbox creation with valid parameters."""
    sandbox = await Sandbox.create(
        image="python:3.11",
        timeout=timedelta(minutes=5)
    )
    assert sandbox.id is not None
    assert sandbox.status == SandboxStatus.PENDING
    await sandbox.kill()

@pytest.mark.asyncio
async def test_invalid_timeout():
    """Test sandbox creation fails with invalid timeout."""
    with pytest.raises(ValueError):
        await Sandbox.create(
            image="python:3.11",
            timeout=timedelta(seconds=-1)
        )
```

**Running Tests:**

```bash
cd server
uv run pytest
uv run pytest --cov=src --cov-report=html
```

#### Go Tests

```go
func TestController_Execute_Python(t *testing.T) {
    ctrl := NewController("http://localhost:8888", "test-token")

    req := &ExecuteCodeRequest{
        Language: Python,
        Code:     "print('hello')",
    }

    err := ctrl.Execute(req)
    assert.NoError(t, err)
}
```

**Running Tests:**

```bash
cd components/execd
go test ./pkg/...
go test -v -cover ./pkg/...
```

#### Integration Tests

Integration tests require Docker:

```bash
# Server integration tests
cd server
uv run pytest tests/integration/

# E2E tests
cd tests/e2e/python
uv run pytest
```

### Test Best Practices

- **Test Names**: Use descriptive names that explain what is being tested
- **Arrange-Act-Assert**: Structure tests clearly
- **Isolation**: Each test should be independent
- **Mocking**: Mock external dependencies appropriately
- **Cleanup**: Always clean up resources (use fixtures, context managers)

## Submitting Contributions

### Pull Request Process

1. **Create Feature Branch**: Branch from `main`
2. **Make Changes**: Implement your feature or fix
3. **Write Tests**: Add comprehensive test coverage
4. **Update Documentation**: Update relevant docs
5. **Test Locally**: Ensure all tests pass
6. **Run Linters**: Fix any style issues
7. **Commit Changes**: Use conventional commit messages
8. **Push to Fork**: Push your branch to your fork
9. **Create Pull Request**: Submit PR with detailed description

### Pull Request Template

When creating a PR, fill out the template:

```markdown
# Summary

- What is changing and why?

# Testing

- [ ] Not run (explain why)
- [ ] Unit tests
- [ ] Integration tests
- [ ] e2e / manual verification

# Breaking Changes

- [ ] None
- [ ] Yes (describe impact and migration path)

# Checklist

- [ ] Linked Issue or clearly described motivation
- [ ] Added/updated docs (if needed)
- [ ] Added/updated tests (if needed)
- [ ] Security impact considered
- [ ] Backward compatibility considered
```

### Pull Request Guidelines

**Do:**

- Keep PRs focused and reasonably sized (< 500 lines if possible)
- Write clear PR descriptions with motivation and context
- Link related issues
- Respond to review comments promptly
- Update your PR based on feedback
- Ensure CI passes before requesting review

**Don't:**

- Mix multiple unrelated changes in one PR
- Submit PRs with failing tests
- Ignore code review feedback
- Force push after reviews have started (unless necessary)
- Include commented-out code or debug statements

### Code Review Process

1. **Automated Checks**: CI runs tests, linters, and security scans
2. **Maintainer Review**: A maintainer reviews your code
3. **Feedback Loop**: Address review comments
4. **Approval**: Once approved, a maintainer will merge your PR
5. **Cleanup**: Delete your feature branch after merge

## Communication Channels

### GitHub Issues

Use GitHub Issues for:

- Bug reports
- Feature requests
- Documentation improvements
- Questions about implementation

**Bug Report Template:**

```markdown
**Description**
A clear description of the bug.

**To Reproduce**
Steps to reproduce the behavior:

1. Create sandbox with...
2. Execute command...
3. See error

**Expected Behavior**
What you expected to happen.

**Environment**

- OpenSandbox version:
- Runtime (Docker/K8s):
- OS:
- Python/Go version:

**Additional Context**
Logs, screenshots, or other relevant information.
```

### GitHub Discussions

Use GitHub Discussions for:

- General questions
- Design discussions
- Brainstorming ideas
- Community help

### Getting Help

- **Issues**: Technical problems or bugs
- **Discussions**: Questions and community support
- **Email**: For security issues, email conduct@opensandbox.io

## Additional Resources

### Documentation

- [Architecture Overview](docs/architecture.md)
- [Server Development Guide](server/DEVELOPMENT.md)
- [execd Development Guide](components/execd/DEVELOPMENT.md)
- [OpenAPI Specifications](specs/README.md)
- [Python SDK Documentation](sdks/sandbox/python/README.md)
- [Java/Kotlin SDK Documentation](sdks/sandbox/kotlin/README.md)

### Examples

Browse [examples/](examples/) for real-world usage patterns:

- Code Interpreter integration
- AI Coding Agent integrations (Claude Code, Gemini CLI, etc.)
- Browser automation (Chrome, Playwright)
- Remote development (VS Code, Desktop)

### External Resources

- [FastAPI Documentation](https://fastapi.tiangolo.com/)
- [Beego Documentation](https://beego.wiki/)
- [Jupyter Protocol](https://jupyter-client.readthedocs.io/en/stable/messaging.html)
- [OpenAPI Specification](https://swagger.io/specification/)
- [Docker API](https://docs.docker.com/engine/api/)

## Acknowledgments

Thank you for contributing to OpenSandbox! Your contributions help make this project better for everyone in the AI and developer tools community.

If you have suggestions for improving this contributing guide, please open an issue or submit a pull request.

## License

By contributing to OpenSandbox, you agree that your contributions will be licensed under the [Apache 2.0 License](LICENSE).


================================================
FILE: LICENSE
================================================
Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.md
================================================
<div align="center">
  <img src="docs/assets/logo.svg" alt="OpenSandbox logo" width="150" />

  <h1>OpenSandbox</h1>

  <p align="center">
    <a href="https://trendshift.io/repositories/21828" target="_blank">
      <img src="https://trendshift.io/api/badge/repositories/21828" alt="alibaba%2FOpenSandbox | Trendshift" style="width: 320px; height: 70px;" width="320" height="70" />
    </a>
  </p>

<p align="center">
  <a href="https://github.com/alibaba/OpenSandbox">
    <img src="https://img.shields.io/github/stars/alibaba/OpenSandbox.svg?style=social" alt="GitHub stars" />
  </a>
  <a href="https://deepwiki.com/alibaba/OpenSandbox">
    <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki" />
  </a>
  <a href="https://www.apache.org/licenses/LICENSE-2.0.html">
    <img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" alt="license" />
  </a>
  <a href="https://badge.fury.io/py/opensandbox">
    <img src="https://badge.fury.io/py/opensandbox.svg" alt="PyPI version" />
  </a>
  <a href="https://badge.fury.io/js/@alibaba-group%2Fopensandbox">
    <img src="https://badge.fury.io/js/@alibaba-group%2Fopensandbox.svg" alt="npm version" />
  </a>
  <a href="https://landscape.cncf.io/?item=orchestration-management--scheduling-orchestration--opensandbox">
    <img src="https://img.shields.io/badge/CNCF-Landscape-0C66E4" alt="CNCF Landscape" />
  </a>
  <a href="https://qr.dingtalk.com/action/joingroup?code=v1,k1,A4Bgl5q1I1eNU/r33D18YFNrMY108aFF38V+r19RJOM=&_dt_no_comment=1&origin=11">
    <img src="https://img.shields.io/badge/DingTalk-Join-0089FF?logo=dingtalk&logoColor=white" alt="DingTalk" />
  </a>
  <a href="https://github.com/alibaba/OpenSandbox/actions">
    <img src="https://github.com/alibaba/OpenSandbox/actions/workflows/real-e2e.yml/badge.svg?branch=main" alt="E2E Status" />
  </a>
</p>

  <hr />
</div>

[Documentation](https://open-sandbox.ai/) | [中文文档](https://open-sandbox.ai/zh/)

OpenSandbox is a **general-purpose sandbox platform** for AI applications, offering multi-language SDKs, unified sandbox APIs, and Docker/Kubernetes runtimes for scenarios like Coding Agents, GUI Agents, Agent Evaluation, AI Code Execution, and RL Training.

OpenSandbox is now listed in the [CNCF Landscape](https://landscape.cncf.io/?item=orchestration-management--scheduling-orchestration--opensandbox).

## Features

- **Multi-language SDKs**: Provides sandbox SDKs in Python, Java/Kotlin, JavaScript/TypeScript, C#/.NET, Go (Roadmap), and more.
- **Sandbox Protocol**: Defines sandbox lifecycle management APIs and sandbox execution APIs so you can extend custom sandbox runtimes.
- **Sandbox Runtime**: Built-in lifecycle management supporting Docker and [high-performance Kubernetes runtime](./kubernetes), enabling both local runs and large-scale distributed scheduling.
- **Sandbox Environments**: Built-in Command, Filesystem, and Code Interpreter implementations. Examples cover Coding Agents (e.g., Claude Code), browser automation (Chrome, Playwright), and desktop environments (VNC, VS Code).
- **Network Policy**: Unified [Ingress Gateway](components/ingress) with multiple routing strategies plus per-sandbox [egress controls](components/egress).
- **Strong Isolation**: Supports secure container runtimes like gVisor, Kata Containers, and Firecracker microVM for enhanced isolation between sandbox workloads and the host. See [Secure Container Runtime Guide](docs/secure-container.md) for details.

## Examples

### Basic Sandbox Operations

Requirements:

- Docker (required for local execution)
- Python 3.10+ (recommended for examples and local runtime)

#### 1. Install and Configure the Sandbox Server

```bash
uv pip install opensandbox-server
opensandbox-server init-config ~/.sandbox.toml --example docker
```

> If you prefer working from source, you can still clone the repo for development, but you no longer need to clone this repository just to start the server.
> You'll also require an instance of docker running.
> ```bash
> git clone https://github.com/alibaba/OpenSandbox.git
> cd OpenSandbox/server
> uv sync
> cp example.config.toml ~/.sandbox.toml # Copy configuration file
> uv run python -m src.main # Start the service
> ```

#### 2. Start the Sandbox Server

```bash
opensandbox-server

# Show help
opensandbox-server -h
```

#### 3. Create a Code Interpreter and Execute Commands

Install the Code Interpreter SDK

```bash
uv pip install opensandbox-code-interpreter
```

Create a sandbox and execute commands

```python
import asyncio
from datetime import timedelta

from code_interpreter import CodeInterpreter, SupportedLanguage
from opensandbox import Sandbox
from opensandbox.models import WriteEntry

async def main() -> None:
    # 1. Create a sandbox
    sandbox = await Sandbox.create(
        "opensandbox/code-interpreter:v1.0.2",
        entrypoint=["/opt/opensandbox/code-interpreter.sh"],
        env={"PYTHON_VERSION": "3.11"},
        timeout=timedelta(minutes=10),
    )

    async with sandbox:

        # 2. Execute a shell command
        execution = await sandbox.commands.run("echo 'Hello OpenSandbox!'")
        print(execution.logs.stdout[0].text)

        # 3. Write a file
        await sandbox.files.write_files([
            WriteEntry(path="/tmp/hello.txt", data="Hello World", mode=644)
        ])

        # 4. Read a file
        content = await sandbox.files.read_file("/tmp/hello.txt")
        print(f"Content: {content}") # Content: Hello World

        # 5. Create a code interpreter
        interpreter = await CodeInterpreter.create(sandbox)

        # 6. Execute Python code (single-run, pass language directly)
        result = await interpreter.codes.run(
              """
                  import sys
                  print(sys.version)
                  result = 2 + 2
                  result
              """,
              language=SupportedLanguage.PYTHON,
        )

        print(result.result[0].text) # 4
        print(result.logs.stdout[0].text) # 3.11.14

    # 7. Cleanup the sandbox
    await sandbox.kill()

if __name__ == "__main__":
    asyncio.run(main())
```

### More Examples

OpenSandbox provides examples covering SDK usage, agent integrations, browser automation, and training workloads. All example code is located in the `examples/` directory.

#### 🎯 Basic Examples

- **[code-interpreter](examples/code-interpreter/README.md)** - End-to-end Code Interpreter SDK workflow in a sandbox.
- **[aio-sandbox](examples/aio-sandbox/README.md)** - All-in-One sandbox setup using the OpenSandbox SDK.
- **[agent-sandbox](examples/agent-sandbox/README.md)** - Example integration for running OpenSandbox workloads on Kubernetes with [kubernetes-sigs/agent-sandbox](https://github.com/kubernetes-sigs/agent-sandbox).

#### 🤖 Coding Agent Integrations

- **[claude-code](examples/claude-code/README.md)** - Run Claude Code inside OpenSandbox.
- **[gemini-cli](examples/gemini-cli/README.md)** - Run Google Gemini CLI inside OpenSandbox.
- **[codex-cli](examples/codex-cli/README.md)** - Run OpenAI Codex CLI inside OpenSandbox.
- **[kimi-cli](examples/kimi-cli/README.md)** - Run [Kimi CLI](https://github.com/MoonshotAI/kimi-cli) (Moonshot AI) inside OpenSandbox.
- **[langgraph](examples/langgraph/README.md)** - LangGraph state-machine workflow that creates/runs a sandbox job with fallback retry.
- **[google-adk](examples/google-adk/README.md)** - Google ADK agent using OpenSandbox tools to write/read files and run commands.
- **[nullclaw](examples/nullclaw/README.md)** - Launch a [Nullclaw](https://github.com/nullclaw/nullclaw) Gateway inside a sandbox.
- **[openclaw](examples/openclaw/README.md)** - Launch an OpenClaw Gateway inside a sandbox.

#### 🌐 Browser and Desktop Environments

- **[chrome](examples/chrome/README.md)** - Chromium sandbox with VNC and DevTools access for automation and debugging.
- **[playwright](examples/playwright/README.md)** - Playwright + Chromium headless scraping and testing example.
- **[desktop](examples/desktop/README.md)** - Full desktop environment in a sandbox with VNC access.
- **[vscode](examples/vscode/README.md)** - code-server (VS Code Web) running inside a sandbox for remote dev.

#### 🧠 ML and Training

- **[rl-training](examples/rl-training/README.md)** - DQN CartPole training in a sandbox with checkpoints and summary output.

For more details, please refer to [examples](examples/README.md) and the README files in each example directory.

## Project Structure

| Directory | Description                                                      |
|-----------|------------------------------------------------------------------|
| [`sdks/`](sdks/) | Multi-language SDKs (Python, Java/Kotlin, TypeScript/JavaScript, C#/.NET) |
| [`specs/`](specs/README.md) | OpenAPI specs and lifecycle specifications                      |
| [`server/`](server/README.md) | Python FastAPI sandbox lifecycle server                          |
| [`kubernetes/`](kubernetes/README.md) | Kubernetes deployment and examples                               |
| [`components/execd/`](components/execd/README.md) | Sandbox execution daemon (commands and file operations)          |
| [`components/ingress/`](components/ingress/README.md) | Sandbox traffic ingress proxy                                    |
| [`components/egress/`](components/egress/README.md) | Sandbox network egress control                                   |
| [`sandboxes/`](sandboxes/) | Runtime sandbox implementations                                   |
| [`examples/`](examples/README.md) | Integration examples and use cases                               |
| [`oseps/`](oseps/README.md) | OpenSandbox Enhancement Proposals                                |
| [`docs/`](docs/) | Architecture and design documentation                            |
| [`tests/`](tests/) | Cross-component E2E tests                                        |
| [`scripts/`](scripts/) | Development and maintenance scripts                              |

For detailed architecture, see [docs/architecture.md](docs/architecture.md).

## Documentation

- [docs/architecture.md](docs/architecture.md) – Overall architecture & design philosophy
- [oseps/README.md](oseps/README.md) – OpenSandbox Enhancement Proposals
- SDK
  - Sandbox base SDK ([Java/Kotlin SDK](sdks/sandbox/kotlin/README.md), [Python SDK](sdks/sandbox/python/README.md), [JavaScript/TypeScript SDK](sdks/sandbox/javascript/README.md), [C#/.NET SDK](sdks/sandbox/csharp/README.md)) - includes sandbox lifecycle, command execution, file operations
  - Code Interpreter SDK ([Java/Kotlin SDK](sdks/code-interpreter/kotlin/README.md), [Python SDK](sdks/code-interpreter/python/README.md), [JavaScript/TypeScript SDK](sdks/code-interpreter/javascript/README.md), [C#/.NET SDK](sdks/code-interpreter/csharp/README.md)) - code interpreter
- [specs/README.md](specs/README.md) - OpenAPI definitions for sandbox lifecycle API and sandbox execution API
- [server/README.md](server/README.md) - Sandbox server startup and configuration; supports Docker and Kubernetes runtimes

## License

This project is open source under the [Apache 2.0 License](LICENSE).

## Roadmap [2026.03]

### SDK

- **Sandbox client connection pool** - Client-side sandbox connection pool management, providing pre-provisioned sandboxes to obtain an environment at X ms.
- **Go SDK** - Go client SDK for sandbox lifecycle management, command execution, and file operations.

### Sandbox Runtime

- **Persistent volumes** - Mountable persistent volumes for sandboxes (see [Proposal 0003](oseps/0003-volume-and-volumebinding-support.md)).
- **Local lightweight sandbox** - Lightweight sandbox for AI tools running directly on PCs.
- **Secure Container** - Secure sandbox for AI Agents running inside container.

### Deployment

- **Guide** - Deployment guide for self-hosted Kubernetes cluster.

## Contact and Discussion

- Issues: Submit bugs, feature requests, or design discussions through GitHub Issues
- DingTalk: Join the [OpenSandbox technical discussion group](https://qr.dingtalk.com/action/joingroup?code=v1,k1,A4Bgl5q1I1eNU/r33D18YFNrMY108aFF38V+r19RJOM=&_dt_no_comment=1&origin=11)
## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=alibaba/OpenSandbox&type=date&legend=top-left)](https://www.star-history.com/#alibaba/OpenSandbox&type=date&legend=top-left)


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Reporting Security Issues

The OpenSandbox team takes security seriously. If you discover a security vulnerability, please report it responsibly.

### How to Report

- **GitHub Security Advisories**: Open a private security advisory on GitHub
- **Email**: Contact the maintainers directly with "[SECURITY]" in the subject

### What to Include

- Clear description of the vulnerability
- Steps to reproduce
- Potential impact and scope
- Suggested remediation (if available)

## Response Process

1. Acknowledgment within 48 hours
2. Investigation and validation
3. Fix development and testing
4. Coordinated disclosure

## Supported Versions

Only the latest release and main branch are actively supported with security updates.

## Security Best Practices

When deploying OpenSandbox:
- Keep dependencies up to date
- Use network policies to restrict sandbox egress
- Monitor audit logs regularly
- Follow principle of least privilege


================================================
FILE: cli/README.md
================================================
# OpenSandbox CLI

A command-line interface for managing OpenSandbox environments from your terminal. Built on top of the [OpenSandbox Python SDK](../sdks/sandbox/python/README.md), the CLI provides intuitive commands for sandbox lifecycle management, file operations, command execution, and code interpretation.

## Installation

### pip

```bash
pip install opensandbox-cli
```

### uv

```bash
uv add opensandbox-cli
```

### pipx (recommended for global CLI usage)

```bash
pipx install opensandbox-cli
```

## Overview

```bash
osb --help
```

![CLI Help](assets/cli_help.png)

## Quick Start

### Step 0: Start the OpenSandbox Server

Before using the CLI, make sure the OpenSandbox server is running. See the root [README.md](../README.md) for startup instructions.

```bash
opensandbox-server
```

![Start OpenSandbox Server](assets/start_opensandbox_server.png)

### Step 1: Install the CLI

```bash
cd cli
uv pip install -e .
```

![Install CLI](assets/install_cli.png)

### Step 2: Initialize Configuration

```bash
osb config init
osb config set connection.domain localhost:8080
osb config set connection.protocol http
```

![Init CLI](assets/init_cli.png)

### Step 3: Create a Sandbox

```bash
osb sandbox create --image python:3.12
```

![Create Sandbox](assets/cli_create_sandbox.png)

### Step 4: List Sandboxes

```bash
# Table output (default)
osb sandbox list

# JSON output for scripting
osb -o json sandbox list
```

![List Sandboxes](assets/cli_list_sandbox.png)

![List Sandboxes JSON](assets/cli_list_sandbox_json.png)

### Short ID Matching

Like Docker, you don't need to type the full sandbox ID — just enough characters to uniquely identify the target sandbox:

```bash
# Full ID
osb sandbox get db027570-4f86-45f8-b1a8-c31a2dd90da8

# Short prefix — as long as it's unambiguous
osb sandbox get db02
osb exec db02 -- echo "hello"
```

If the prefix matches multiple sandboxes, the CLI will report an error listing the matches so you can be more specific.

![Short ID Matching](assets/cli_sandbox_search.png)

### Step 5: Execute Commands

```bash
osb exec <sandbox-id> -- echo "hello world"
osb exec <sandbox-id> -- python -c "print(1+1)"
```

![Execute Commands](assets/cli_sandbox_exec.png)

### Step 6: File Operations

```bash
# Write a file
osb file write <sandbox-id> /tmp/test.txt -c "hello"

# Read it back
osb file cat <sandbox-id> /tmp/test.txt
```

![File Operations](assets/cli_sandbox_file.png)

### Step 7: Cleanup

```bash
osb sandbox kill <sandbox-id>
osb sandbox list
```

![Kill Sandbox](assets/cli_kill_sandbox.png)

## Command Reference

### `osb sandbox` — Lifecycle Management

| Command    | Description                                 |
| ---------- | ------------------------------------------- |
| `create`   | Create a new sandbox                        |
| `list`     | List sandboxes (with optional filters)      |
| `get`      | Get sandbox details by ID                   |
| `kill`     | Terminate one or more sandboxes             |
| `pause`    | Pause a running sandbox                     |
| `resume`   | Resume a paused sandbox                     |
| `renew`    | Renew sandbox expiration                    |
| `endpoint` | Get public endpoint for a sandbox port      |
| `health`   | Check sandbox health                        |
| `metrics`  | Get sandbox resource metrics (CPU, memory)  |

### `osb command` — Command Execution

| Command     | Description                               |
| ----------- | ----------------------------------------- |
| `run`       | Run a shell command in the sandbox        |
| `status`    | Get command execution status              |
| `logs`      | Get background command logs               |
| `interrupt` | Interrupt a running command               |

### `osb exec` — Quick Command Shortcut

```bash
osb exec <sandbox-id> -- <command>
```

Shortcut for `osb command run`. Everything after `--` is passed as the command.

### `osb file` — File Operations

| Command    | Description                                |
| ---------- | ------------------------------------------ |
| `cat`      | Read file contents                         |
| `write`    | Write content to a file                    |
| `upload`   | Upload a local file to the sandbox         |
| `download` | Download a file from the sandbox           |
| `rm`       | Delete files                               |
| `mv`       | Move or rename a file                      |
| `mkdir`    | Create directories                         |
| `rmdir`    | Remove directories                         |
| `search`   | Search for files by pattern                |
| `info`     | Get file/directory metadata                |
| `chmod`    | Set file permissions                       |
| `replace`  | Find and replace content in a file         |

### `osb code` — Code Interpreter

| Command     | Description                               |
| ----------- | ----------------------------------------- |
| `run`       | Execute code in a sandbox                 |
| `context`   | Manage code execution contexts            |
| `interrupt` | Interrupt a running code execution        |

### `osb config` — Configuration

| Command | Description                                |
| ------- | ------------------------------------------ |
| `init`  | Create a default config file               |
| `show`  | Show resolved configuration                |

## Configuration

The CLI resolves configuration from multiple sources with the following priority (highest to lowest):

1. **CLI flags** — `--api-key`, `--domain`, `--protocol`, `--timeout`
2. **Environment variables** — `OPEN_SANDBOX_API_KEY`, `OPEN_SANDBOX_DOMAIN`, `OPEN_SANDBOX_PROTOCOL`, `OPEN_SANDBOX_REQUEST_TIMEOUT`, `OPEN_SANDBOX_OUTPUT`
3. **Config file** — `~/.opensandbox/config.toml` (or path specified via `--config`)
4. **SDK defaults**

### Config File Format

```toml
[connection]
api_key = "your-api-key"
domain = "localhost:8080"
protocol = "http"
request_timeout = 30

[output]
format = "table"    # table | json | yaml
color = true

[defaults]
image = "python:3.11"
timeout = "10m"
```

## Global Options

| Option                        | Description                      |
| ----------------------------- | -------------------------------- |
| `--api-key TEXT`              | API key for authentication       |
| `--domain TEXT`               | API server domain                |
| `--protocol [http\|https]`    | Protocol                         |
| `--timeout INTEGER`           | Request timeout in seconds       |
| `-o, --output [table\|json\|yaml]` | Output format              |
| `--config PATH`               | Config file path                 |
| `-v, --verbose`               | Enable debug output              |
| `--no-color`                  | Disable colored output           |
| `--version`                   | Show version                     |

## Output Formats

The CLI supports three output formats via the `-o` / `--output` flag:

- **`table`** (default) — Human-friendly tables powered by [Rich](https://github.com/Textualize/rich)
- **`json`** — Machine-readable JSON
- **`yaml`** — YAML output

```bash
# Table (default)
osb sandbox list

# JSON for scripting
osb -o json sandbox list

# YAML
osb -o yaml sandbox list
```


================================================
FILE: cli/pyproject.toml
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

[project]
name = "opensandbox-cli"
dynamic = ["version"]
description = "OpenSandbox CLI - Command-line interface for managing sandboxes"
authors = [
    { name = "OpenSandbox Team", email = "ninan.nn@alibaba-inc.com" }
]
license = { file = "LICENSE" }
readme = "README.md"
requires-python = ">=3.10"
keywords = ["sandbox", "cli", "opensandbox"]
classifiers = [
    "Development Status :: 3 - Alpha",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: Apache Software License",
    "Operating System :: OS Independent",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Topic :: Software Development :: Libraries",
]
dependencies = [
    "opensandbox>=0.1.4,<0.2.0",
    "opensandbox-code-interpreter>=0.1.0,<0.2.0",
    "click>=8.1.0,<9.0",
    "rich>=13.0.0,<14.0",
    "pyyaml>=6.0,<7.0",
    "tomli>=2.0.0; python_version < '3.11'",
]

[project.urls]
Homepage = "https://open-sandbox.ai"
Repository = "https://github.com/alibaba/OpenSandbox"
Documentation = "https://open-sandbox.ai"
Issues = "https://github.com/alibaba/OpenSandbox/issues"

[project.scripts]
opensandbox = "opensandbox_cli.main:cli"
osb = "opensandbox_cli.main:cli"

[tool.hatch.version]
source = "vcs"

[tool.hatch.version.raw-options]
root = ".."
tag_regex = "^python/cli/v(?P<version>\\d+\\.\\d+\\.\\d+(?:[\\.\\w\\+\\-]*)?)$"
git_describe_command = 'git describe --dirty --tags --long --match "python/cli/v*"'
fallback_version = "0.1.0"

[tool.hatch.build]
include = [
    "LICENSE",
    "src/**/py.typed",
    "src/opensandbox_cli",
]

[tool.hatch.build.targets.wheel]
packages = ["src/opensandbox_cli"]

[dependency-groups]
dev = [
    "pytest>=7.0.0",
    "pytest-cov>=4.0.0",
    "ruff>=0.14.8",
    "pyright>=1.1.0",
]

[tool.ruff]
target-version = "py310"
line-length = 88

[tool.ruff.lint]
select = [
    "E",  # pycodestyle errors
    "W",  # pycodestyle warnings
    "F",  # pyflakes
    "I",  # isort
    "B",  # flake8-bugbear
    "C4", # flake8-comprehensions
    "UP", # pyupgrade
]
ignore = [
    "E501", # line too long, handled by formatter
    "B008", # do not perform function calls in argument defaults
    "C901", # too complex
]

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]

[tool.pyright]
typeCheckingMode = "standard"
pythonVersion = "3.10"
pythonPlatform = "All"
include = ["src"]
exclude = [
    "**/node_modules",
    "**/__pycache__",
]
reportMissingImports = true
reportMissingTypeStubs = false

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q --strict-markers --strict-config"
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]

[tool.coverage.run]
source = ["src"]
branch = true

[tool.uv.sources]
opensandbox = { path = "../sdks/sandbox/python", editable = true }
opensandbox-code-interpreter = { path = "../sdks/code-interpreter/python", editable = true }


================================================
FILE: cli/src/opensandbox_cli/__init__.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

try:
    from importlib.metadata import version

    __version__ = version("opensandbox-cli")
except Exception:
    __version__ = "0.0.0-dev"


================================================
FILE: cli/src/opensandbox_cli/__main__.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Allow running as ``python -m opensandbox_cli``."""

from opensandbox_cli.main import cli

if __name__ == "__main__":
    cli()


================================================
FILE: cli/src/opensandbox_cli/client.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""SDK client factory stored in Click context."""

from __future__ import annotations

import re
from dataclasses import dataclass, field
from datetime import timedelta
from typing import Any

import click

from opensandbox.config.connection_sync import ConnectionConfigSync
from opensandbox.models.sandboxes import SandboxFilter
from opensandbox.sync.manager import SandboxManagerSync
from opensandbox.sync.sandbox import SandboxSync

from opensandbox_cli.output import OutputFormatter

# Full UUID pattern: 8-4-4-4-12 hex characters
_UUID_RE = re.compile(
    r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
)


@dataclass
class ClientContext:
    """Shared context passed via ``ctx.obj`` to all Click commands."""

    resolved_config: dict[str, Any]
    output: OutputFormatter
    _connection_config: ConnectionConfigSync | None = field(
        default=None, init=False, repr=False
    )
    _manager: SandboxManagerSync | None = field(
        default=None, init=False, repr=False
    )

    @property
    def connection_config(self) -> ConnectionConfigSync:
        if self._connection_config is None:
            cfg = self.resolved_config
            self._connection_config = ConnectionConfigSync(
                api_key=cfg.get("api_key"),
                domain=cfg.get("domain"),
                protocol=cfg.get("protocol", "http"),
                request_timeout=timedelta(seconds=cfg.get("request_timeout", 30)),
            )
        return self._connection_config

    def get_manager(self) -> SandboxManagerSync:
        """Return a lazily-created ``SandboxManagerSync``."""
        if self._manager is None:
            self._manager = SandboxManagerSync.create(self.connection_config)
        return self._manager

    def resolve_sandbox_id(self, prefix: str) -> str:
        """Resolve a sandbox ID prefix to the full ID (Docker-style).

        If *prefix* looks like a complete UUID, it is returned as-is without
        querying the server.  Otherwise **all pages** of sandboxes are fetched
        so that prefix collisions on later pages are never missed.
        """
        # Skip resolution for full UUIDs
        if _UUID_RE.match(prefix):
            return prefix

        mgr = self.get_manager()
        matches: list[str] = []
        page = 0

        while True:
            result = mgr.list_sandbox_infos(
                SandboxFilter(page=page, page_size=100)
            )
            if result.sandbox_infos:
                matches.extend(
                    info.id
                    for info in result.sandbox_infos
                    if info.id.startswith(prefix)
                )
            # Stop early if we already found >1 match (ambiguous)
            if len(matches) > 1:
                break
            if not result.pagination.has_next_page:
                break
            page += 1

        if len(matches) == 1:
            return matches[0]
        elif len(matches) == 0:
            raise click.ClickException(
                f"No sandbox found with ID prefix '{prefix}'"
            )
        else:
            ids_str = ", ".join(matches[:5])
            if len(matches) > 5:
                ids_str += ", ..."
            raise click.ClickException(
                f"Ambiguous ID prefix '{prefix}' matches {len(matches)} sandboxes: {ids_str}"
            )

    def connect_sandbox(
        self, sandbox_id: str, *, skip_health_check: bool = True
    ) -> SandboxSync:
        """Connect to an existing sandbox by ID (supports prefix matching)."""
        sandbox_id = self.resolve_sandbox_id(sandbox_id)
        return SandboxSync.connect(
            sandbox_id,
            connection_config=self.connection_config,
            skip_health_check=skip_health_check,
        )

    def close(self) -> None:
        """Release resources."""
        if self._manager is not None:
            self._manager.close()
            self._manager = None
        if self._connection_config is not None:
            self._connection_config.close_transport_if_owned()
            self._connection_config = None


================================================
FILE: cli/src/opensandbox_cli/commands/__init__.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


================================================
FILE: cli/src/opensandbox_cli/commands/code.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Code execution commands: run, context management, interrupt."""

from __future__ import annotations

import sys

import click

from opensandbox.models.execd import OutputMessage
from opensandbox.models.execd_sync import ExecutionHandlersSync

from opensandbox_cli.client import ClientContext
from opensandbox_cli.utils import handle_errors


@click.group("code", invoke_without_command=True)
@click.pass_context
def code_group(ctx: click.Context) -> None:
    """💻 Execute code in a sandbox (via Code Interpreter)."""
    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())


# ---- run ------------------------------------------------------------------

@code_group.command("run")
@click.argument("sandbox_id")
@click.option("--language", "-l", required=True, help="Language (python, javascript, java, go, bash, ...).")
@click.option("--code", "-c", default=None, help="Code to execute. Reads from stdin if not provided.")
@click.option("--context-id", default=None, help="Execution context ID for stateful sessions.")
@click.pass_obj
@handle_errors
def code_run(
    obj: ClientContext,
    sandbox_id: str,
    language: str,
    code: str | None,
    context_id: str | None,
) -> None:
    """Execute code in a sandbox."""
    from code_interpreter.sync.code_interpreter import CodeInterpreterSync

    if code is None:
        if sys.stdin.isatty():
            click.echo("Reading code from stdin (Ctrl+D to finish):", err=True)
        code = sys.stdin.read()

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        interpreter = CodeInterpreterSync.create(sandbox)

        kwargs: dict = {}
        if context_id:
            ctx = interpreter.codes.get_context(context_id)
            kwargs["context"] = ctx

        def on_stdout(msg: OutputMessage) -> None:
            sys.stdout.write(msg.text)
            sys.stdout.flush()

        def on_stderr(msg: OutputMessage) -> None:
            sys.stderr.write(msg.text)
            sys.stderr.flush()

        handlers = ExecutionHandlersSync(on_stdout=on_stdout, on_stderr=on_stderr)
        execution = interpreter.codes.run(
            code, language=language, handlers=handlers, **kwargs
        )

        if execution.error:
            obj.output.error(
                f"{execution.error.name}: {execution.error.value}"
            )
            sys.exit(1)
    finally:
        sandbox.close()


# ---- context group --------------------------------------------------------

@code_group.group("context", invoke_without_command=True)
@click.pass_context
def context_group(ctx: click.Context) -> None:
    """Manage code execution contexts."""
    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())


@context_group.command("create")
@click.argument("sandbox_id")
@click.option("--language", "-l", required=True, help="Language for the context.")
@click.pass_obj
@handle_errors
def context_create(obj: ClientContext, sandbox_id: str, language: str) -> None:
    """Create a new code execution context."""
    from code_interpreter.sync.code_interpreter import CodeInterpreterSync

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        interpreter = CodeInterpreterSync.create(sandbox)
        ctx = interpreter.codes.create_context(language)
        obj.output.success_panel(
            {"context_id": ctx.id, "language": language},
            title="Context Created",
        )
    finally:
        sandbox.close()


@context_group.command("list")
@click.argument("sandbox_id")
@click.option("--language", "-l", required=True, help="Language to list contexts for.")
@click.pass_obj
@handle_errors
def context_list(obj: ClientContext, sandbox_id: str, language: str) -> None:
    """List code execution contexts."""
    from code_interpreter.sync.code_interpreter import CodeInterpreterSync

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        interpreter = CodeInterpreterSync.create(sandbox)
        contexts = interpreter.codes.list_contexts(language)
        for ctx in contexts:
            click.echo(f"{ctx.id}")
    finally:
        sandbox.close()


@context_group.command("delete")
@click.argument("sandbox_id")
@click.argument("context_id")
@click.pass_obj
@handle_errors
def context_delete(obj: ClientContext, sandbox_id: str, context_id: str) -> None:
    """Delete a code execution context."""
    from code_interpreter.sync.code_interpreter import CodeInterpreterSync

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        interpreter = CodeInterpreterSync.create(sandbox)
        interpreter.codes.delete_context(context_id)
        obj.output.success(f"Deleted context: {context_id}")
    finally:
        sandbox.close()


@context_group.command("delete-all")
@click.argument("sandbox_id")
@click.option("--language", "-l", required=True, help="Language to delete all contexts for.")
@click.pass_obj
@handle_errors
def context_delete_all(obj: ClientContext, sandbox_id: str, language: str) -> None:
    """Delete all code execution contexts for a language."""
    from code_interpreter.sync.code_interpreter import CodeInterpreterSync

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        interpreter = CodeInterpreterSync.create(sandbox)
        interpreter.codes.delete_contexts(language)
        obj.output.success(f"Deleted all {language} contexts")
    finally:
        sandbox.close()


# ---- interrupt ------------------------------------------------------------

@code_group.command("interrupt")
@click.argument("sandbox_id")
@click.argument("execution_id")
@click.pass_obj
@handle_errors
def code_interrupt(obj: ClientContext, sandbox_id: str, execution_id: str) -> None:
    """Interrupt a running code execution."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.commands.interrupt(execution_id)
        obj.output.success(f"Interrupted: {execution_id}")
    finally:
        sandbox.close()


================================================
FILE: cli/src/opensandbox_cli/commands/command.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Command execution commands: run, status, logs, interrupt + top-level exec alias."""

from __future__ import annotations

import shlex
import sys
from datetime import timedelta

import click

from opensandbox.models.execd import OutputMessage, RunCommandOpts
from opensandbox.models.execd_sync import ExecutionHandlersSync

from opensandbox_cli.client import ClientContext
from opensandbox_cli.utils import DURATION, handle_errors


@click.group("command", invoke_without_command=True)
@click.pass_context
def command_group(ctx: click.Context) -> None:
    """⚡ Execute commands in a sandbox."""
    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())


# ---- run ------------------------------------------------------------------

def _run_command(
    obj: ClientContext,
    sandbox_id: str,
    command: tuple[str, ...],
    background: bool,
    workdir: str | None,
    timeout: timedelta | None,
) -> None:
    """Shared implementation for 'command run' and top-level 'exec'."""
    cmd_str = " ".join(shlex.quote(arg) for arg in command)
    sandbox = obj.connect_sandbox(sandbox_id)

    try:
        opts = RunCommandOpts(
            background=background,
            working_directory=workdir,
            timeout=timeout,
        )

        if background:
            execution = sandbox.commands.run(cmd_str, opts=opts)
            obj.output.success_panel(
                {
                    "execution_id": execution.id,
                    "sandbox_id": sandbox_id,
                    "mode": "background",
                },
                title="Background Command Started",
            )
            return

        # Foreground: stream stdout/stderr to terminal
        last_text = ""

        def on_stdout(msg: OutputMessage) -> None:
            nonlocal last_text
            last_text = msg.text
            sys.stdout.write(msg.text)
            sys.stdout.flush()

        def on_stderr(msg: OutputMessage) -> None:
            nonlocal last_text
            last_text = msg.text
            sys.stderr.write(msg.text)
            sys.stderr.flush()

        handlers = ExecutionHandlersSync(on_stdout=on_stdout, on_stderr=on_stderr)
        execution = sandbox.commands.run(cmd_str, opts=opts, handlers=handlers)

        # Ensure terminal prompt starts on a new line
        if last_text and not last_text.endswith("\n"):
            sys.stdout.write("\n")
            sys.stdout.flush()

        if execution.error:
            obj.output.error_panel(
                f"{execution.error.name}: {execution.error.value}",
                title="Execution Error",
            )
            sys.exit(1)
    finally:
        sandbox.close()


@command_group.command("run")
@click.argument("sandbox_id")
@click.argument("command", nargs=-1, required=True)
@click.option("-d", "--background", is_flag=True, default=False, help="Run in background.")
@click.option("-w", "--workdir", default=None, help="Working directory.")
@click.option("-t", "--timeout", type=DURATION, default=None, help="Command timeout (e.g. 30s, 5m).")
@click.pass_obj
@handle_errors
def command_run(
    obj: ClientContext,
    sandbox_id: str,
    command: tuple[str, ...],
    background: bool,
    workdir: str | None,
    timeout: timedelta | None,
) -> None:
    """Run a command in a sandbox."""
    _run_command(obj, sandbox_id, command, background, workdir, timeout)


# ---- status ---------------------------------------------------------------

@command_group.command("status")
@click.argument("sandbox_id")
@click.argument("execution_id")
@click.pass_obj
@handle_errors
def command_status(obj: ClientContext, sandbox_id: str, execution_id: str) -> None:
    """Get command execution status."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        status = sandbox.commands.get_command_status(execution_id)
        obj.output.print_model(status, title="Command Status")
    finally:
        sandbox.close()


# ---- logs -----------------------------------------------------------------

@command_group.command("logs")
@click.argument("sandbox_id")
@click.argument("execution_id")
@click.option("--cursor", type=int, default=None, help="Cursor for incremental reads.")
@click.pass_obj
@handle_errors
def command_logs(
    obj: ClientContext, sandbox_id: str, execution_id: str, cursor: int | None
) -> None:
    """Get background command logs."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        logs = sandbox.commands.get_background_command_logs(execution_id, cursor=cursor)
        if obj.output.fmt in ("json", "yaml"):
            obj.output.print_model(logs, title="Command Logs")
        else:
            click.echo(logs.content)
    finally:
        sandbox.close()


# ---- interrupt ------------------------------------------------------------

@command_group.command("interrupt")
@click.argument("sandbox_id")
@click.argument("execution_id")
@click.pass_obj
@handle_errors
def command_interrupt(obj: ClientContext, sandbox_id: str, execution_id: str) -> None:
    """Interrupt a running command."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.commands.interrupt(execution_id)
        obj.output.success(f"Interrupted: {execution_id}")
    finally:
        sandbox.close()


# ---- top-level exec alias ------------------------------------------------

@click.command("exec")
@click.argument("sandbox_id")
@click.argument("command", nargs=-1, required=True)
@click.option("-d", "--background", is_flag=True, default=False, help="Run in background.")
@click.option("-w", "--workdir", default=None, help="Working directory.")
@click.option("-t", "--timeout", type=DURATION, default=None, help="Command timeout (e.g. 30s, 5m).")
@click.pass_obj
@handle_errors
def exec_cmd(
    obj: ClientContext,
    sandbox_id: str,
    command: tuple[str, ...],
    background: bool,
    workdir: str | None,
    timeout: timedelta | None,
) -> None:
    """🚀 Execute a command in a sandbox (shortcut for 'command run')."""
    _run_command(obj, sandbox_id, command, background, workdir, timeout)


================================================
FILE: cli/src/opensandbox_cli/commands/config_cmd.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Config management commands: init, show, set."""

from __future__ import annotations

from pathlib import Path

import click

from opensandbox_cli.client import ClientContext
from opensandbox_cli.config import DEFAULT_CONFIG_PATH, init_config_file
from opensandbox_cli.utils import handle_errors


@click.group("config", invoke_without_command=True)
@click.pass_context
def config_group(ctx: click.Context) -> None:
    """⚙️  Manage CLI configuration."""
    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())


# ---- init -----------------------------------------------------------------

@config_group.command("init")
@click.option("--force", is_flag=True, default=False, help="Overwrite existing config file.")
@click.option("--path", "config_path", type=click.Path(path_type=Path), default=None, help="Config file path.")
@handle_errors
def config_init(force: bool, config_path: Path | None) -> None:
    """Create a default configuration file."""
    # config_init doesn't have @click.pass_obj, get formatter from context
    ctx = click.get_current_context(silent=True)
    obj = getattr(ctx, "obj", None) if ctx else None
    output = getattr(obj, "output", None) if obj else None

    try:
        path = init_config_file(config_path, force=force)
        if output:
            output.success(f"Config file created: {path}")
        else:
            click.echo(f"Config file created: {path}")
    except FileExistsError as exc:
        if output:
            output.warning(str(exc))
        else:
            click.secho(str(exc), fg="yellow", err=True)


# ---- show -----------------------------------------------------------------

@config_group.command("show")
@click.pass_obj
@handle_errors
def config_show(obj: ClientContext) -> None:
    """Show the resolved configuration."""
    obj.output.print_dict(obj.resolved_config, title="Resolved Configuration")


# ---- set ------------------------------------------------------------------

@config_group.command("set")
@click.argument("key")
@click.argument("value")
@click.option("--path", "config_path", type=click.Path(path_type=Path), default=None, help="Config file path.")
@handle_errors
def config_set(key: str, value: str, config_path: Path | None) -> None:
    """Set a configuration value (e.g. 'connection.domain' 'localhost:9090')."""
    path = config_path or DEFAULT_CONFIG_PATH
    if not path.exists():
        click.secho(f"Config file not found: {path}. Run 'osb config init' first.", fg="red", err=True)
        return

    content = path.read_text()

    # Simple key replacement in TOML
    # Supports dotted keys like connection.domain
    parts = key.split(".", 1)
    if len(parts) == 2:
        section, field = parts
        # Try to find and update existing value
        import re

        section_pattern = rf"(\[{re.escape(section)}\].*?)(?=\n\[|\Z)"
        section_match = re.search(section_pattern, content, re.DOTALL)

        # Infer TOML value type: bool > int > float > string
        def _toml_value(raw: str) -> str:
            if raw.lower() in ("true", "false"):
                return raw.lower()
            try:
                int(raw)
                return raw
            except ValueError:
                pass
            try:
                float(raw)
                return raw
            except ValueError:
                pass
            return f'"{raw}"'

        toml_val = _toml_value(value)

        if section_match:
            section_text = section_match.group(1)
            field_pattern = rf'^(#?\s*{re.escape(field)}\s*=\s*).*$'
            field_match = re.search(field_pattern, section_text, re.MULTILINE)
            if field_match:
                new_line = f'{field} = {toml_val}'
                new_section = section_text[:field_match.start()] + new_line + section_text[field_match.end():]
                content = content[:section_match.start()] + new_section + content[section_match.end():]
            else:
                # Add field to section
                insert_pos = section_match.end()
                content = content[:insert_pos] + f'\n{field} = {toml_val}' + content[insert_pos:]
        else:
            # Add new section
            content += f'\n[{section}]\n{field} = {toml_val}\n'
    else:
        click.secho("Key must be in 'section.field' format (e.g. connection.domain).", fg="red", err=True)
        return

    path.write_text(content)

    # config_set doesn't have @click.pass_obj, get formatter from context
    ctx = click.get_current_context(silent=True)
    obj = getattr(ctx, "obj", None) if ctx else None
    output = getattr(obj, "output", None) if obj else None
    if output:
        output.success(f"Set {key} = {value}")
    else:
        click.echo(f"Set {key} = {value}")


================================================
FILE: cli/src/opensandbox_cli/commands/file.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""File operation commands: cat, write, upload, download, rm, mv, mkdir, rmdir, search, info, chmod, replace."""

from __future__ import annotations

import sys
from pathlib import Path

import click

from opensandbox_cli.client import ClientContext
from opensandbox_cli.utils import handle_errors


@click.group("file", invoke_without_command=True)
@click.pass_context
def file_group(ctx: click.Context) -> None:
    """📁 File operations on a sandbox."""
    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())


# ---- cat (read) -----------------------------------------------------------

@file_group.command("cat")
@click.argument("sandbox_id")
@click.argument("path")
@click.option("--encoding", default="utf-8", help="File encoding.")
@click.pass_obj
@handle_errors
def file_cat(obj: ClientContext, sandbox_id: str, path: str, encoding: str) -> None:
    """Read a file from the sandbox."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        content = sandbox.files.read_file(path, encoding=encoding)
        click.echo(content, nl=False)
    finally:
        sandbox.close()


# ---- write ----------------------------------------------------------------

@file_group.command("write")
@click.argument("sandbox_id")
@click.argument("path")
@click.option("--content", "-c", default=None, help="Content to write. Reads from stdin if not provided.")
@click.option("--encoding", default="utf-8", help="File encoding.")
@click.option("--mode", default=None, help="File permission mode (e.g. 0644).")
@click.option("--owner", default=None, help="File owner.")
@click.option("--group", default=None, help="File group.")
@click.pass_obj
@handle_errors
def file_write(
    obj: ClientContext,
    sandbox_id: str,
    path: str,
    content: str | None,
    encoding: str,
    mode: str | None,
    owner: str | None,
    group: str | None,
) -> None:
    """Write content to a file in the sandbox."""
    if content is None:
        if sys.stdin.isatty():
            click.echo("Reading from stdin (Ctrl+D to finish):", err=True)
        content = sys.stdin.read()

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        kwargs: dict = {"encoding": encoding}
        if mode is not None:
            kwargs["mode"] = mode
        if owner is not None:
            kwargs["owner"] = owner
        if group is not None:
            kwargs["group"] = group
        sandbox.files.write_file(path, content, **kwargs)
        obj.output.success(f"Written: {path}")
    finally:
        sandbox.close()


# ---- upload ---------------------------------------------------------------

@file_group.command("upload")
@click.argument("sandbox_id")
@click.argument("local_path", type=click.Path(exists=True))
@click.argument("remote_path")
@click.pass_obj
@handle_errors
def file_upload(
    obj: ClientContext, sandbox_id: str, local_path: str, remote_path: str
) -> None:
    """Upload a local file to the sandbox."""
    data = Path(local_path).read_bytes()
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.files.write_file(remote_path, data)
        obj.output.success(f"Uploaded: {local_path} → {remote_path}")
    finally:
        sandbox.close()


# ---- download -------------------------------------------------------------

@file_group.command("download")
@click.argument("sandbox_id")
@click.argument("remote_path")
@click.argument("local_path", type=click.Path())
@click.pass_obj
@handle_errors
def file_download(
    obj: ClientContext, sandbox_id: str, remote_path: str, local_path: str
) -> None:
    """Download a file from the sandbox to local disk."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        content = sandbox.files.read_bytes(remote_path)
        Path(local_path).write_bytes(content)
        obj.output.success(f"Downloaded: {remote_path} → {local_path}")
    finally:
        sandbox.close()


# ---- rm (delete) ----------------------------------------------------------

@file_group.command("rm")
@click.argument("sandbox_id")
@click.argument("paths", nargs=-1, required=True)
@click.pass_obj
@handle_errors
def file_rm(obj: ClientContext, sandbox_id: str, paths: tuple[str, ...]) -> None:
    """Delete files from the sandbox."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.files.delete_files(list(paths))
        for p in paths:
            obj.output.success(f"Deleted: {p}")
    finally:
        sandbox.close()


# ---- mv (move) ------------------------------------------------------------

@file_group.command("mv")
@click.argument("sandbox_id")
@click.argument("source")
@click.argument("destination")
@click.pass_obj
@handle_errors
def file_mv(
    obj: ClientContext, sandbox_id: str, source: str, destination: str
) -> None:
    """Move/rename a file in the sandbox."""
    from opensandbox.models.filesystem import MoveEntry

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.files.move_files([MoveEntry(source=source, destination=destination)])
        obj.output.success(f"Moved: {source} → {destination}")
    finally:
        sandbox.close()


# ---- mkdir ----------------------------------------------------------------

@file_group.command("mkdir")
@click.argument("sandbox_id")
@click.argument("paths", nargs=-1, required=True)
@click.option("--mode", default=None, help="Directory permission mode.")
@click.option("--owner", default=None, help="Directory owner.")
@click.option("--group", default=None, help="Directory group.")
@click.pass_obj
@handle_errors
def file_mkdir(
    obj: ClientContext,
    sandbox_id: str,
    paths: tuple[str, ...],
    mode: str | None,
    owner: str | None,
    group: str | None,
) -> None:
    """Create directories in the sandbox."""
    from opensandbox.models.filesystem import WriteEntry

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        entries = []
        for p in paths:
            kwargs: dict = {"path": p}
            if mode is not None:
                kwargs["mode"] = mode
            if owner is not None:
                kwargs["owner"] = owner
            if group is not None:
                kwargs["group"] = group
            entries.append(WriteEntry(**kwargs))
        sandbox.files.create_directories(entries)
        for p in paths:
            obj.output.success(f"Created: {p}")
    finally:
        sandbox.close()


# ---- rmdir ----------------------------------------------------------------

@file_group.command("rmdir")
@click.argument("sandbox_id")
@click.argument("paths", nargs=-1, required=True)
@click.pass_obj
@handle_errors
def file_rmdir(obj: ClientContext, sandbox_id: str, paths: tuple[str, ...]) -> None:
    """Delete directories from the sandbox."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.files.delete_directories(list(paths))
        for p in paths:
            obj.output.success(f"Removed: {p}")
    finally:
        sandbox.close()


# ---- search ---------------------------------------------------------------

@file_group.command("search")
@click.argument("sandbox_id")
@click.argument("path")
@click.option("--pattern", "-p", required=True, help="Glob pattern to search for.")
@click.pass_obj
@handle_errors
def file_search(
    obj: ClientContext, sandbox_id: str, path: str, pattern: str
) -> None:
    """Search for files in the sandbox."""
    from opensandbox.models.filesystem import SearchEntry

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        results = sandbox.files.search(SearchEntry(path=path, pattern=pattern))
        if not results:
            if obj.output.fmt in ("json", "yaml"):
                obj.output.print_models([], columns=[])
            else:
                obj.output.info("No files found.")
            return
        if obj.output.fmt in ("json", "yaml"):
            obj.output.print_models(results, columns=["path", "size", "mode", "owner", "modified_at"])
        else:
            obj.output.print_models(results, columns=["path", "size", "owner"], title="Search Results")
    finally:
        sandbox.close()


# ---- info (stat) ----------------------------------------------------------

@file_group.command("info")
@click.argument("sandbox_id")
@click.argument("paths", nargs=-1, required=True)
@click.pass_obj
@handle_errors
def file_info(obj: ClientContext, sandbox_id: str, paths: tuple[str, ...]) -> None:
    """Get file/directory info."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        info_map = sandbox.files.get_file_info(list(paths))
        for path, entry in info_map.items():
            obj.output.print_dict(
                {"path": path, **entry.model_dump(mode="json")},
                title=path,
            )
    finally:
        sandbox.close()


# ---- chmod ----------------------------------------------------------------

@file_group.command("chmod")
@click.argument("sandbox_id")
@click.argument("path")
@click.option("--mode", required=True, help="Permission mode (e.g. 0755).")
@click.option("--owner", default=None, help="File owner.")
@click.option("--group", default=None, help="File group.")
@click.pass_obj
@handle_errors
def file_chmod(
    obj: ClientContext,
    sandbox_id: str,
    path: str,
    mode: str,
    owner: str | None,
    group: str | None,
) -> None:
    """Set file permissions."""
    from opensandbox.models.filesystem import SetPermissionEntry

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.files.set_permissions(
            [SetPermissionEntry(path=path, mode=mode, owner=owner, group=group)]
        )
        obj.output.success(f"Permissions set: {path}")
    finally:
        sandbox.close()


# ---- replace --------------------------------------------------------------

@file_group.command("replace")
@click.argument("sandbox_id")
@click.argument("path")
@click.option("--old", required=True, help="Text to search for.")
@click.option("--new", required=True, help="Replacement text.")
@click.pass_obj
@handle_errors
def file_replace(
    obj: ClientContext, sandbox_id: str, path: str, old: str, new: str
) -> None:
    """Replace content in a file."""
    from opensandbox.models.filesystem import ContentReplaceEntry

    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        sandbox.files.replace_contents(
            [ContentReplaceEntry(path=path, old_content=old, new_content=new)]
        )
        obj.output.success(f"Replaced in: {path}")
    finally:
        sandbox.close()


================================================
FILE: cli/src/opensandbox_cli/commands/sandbox.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Sandbox lifecycle commands: create, list, get, kill, pause, resume, renew, endpoint, health, metrics."""

from __future__ import annotations

import json
from datetime import timedelta

import click

from opensandbox.models.sandboxes import NetworkPolicy, SandboxFilter

from opensandbox_cli.client import ClientContext
from opensandbox_cli.utils import DURATION, KEY_VALUE, handle_errors


@click.group("sandbox", invoke_without_command=True)
@click.pass_context
def sandbox_group(ctx: click.Context) -> None:
    """📦 Manage sandbox lifecycle."""
    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())


# Alias: osb sb ...
sandbox_group.name = "sandbox"


# ---- create ---------------------------------------------------------------

@sandbox_group.command("create")
@click.option("--image", "-i", required=True, help="Container image (e.g. python:3.11).")
@click.option("--timeout", "-t", "timeout", type=DURATION, default=None, help="Sandbox lifetime (e.g. 10m, 1h).")
@click.option("--env", "-e", "envs", multiple=True, type=KEY_VALUE, help="Environment variable (KEY=VALUE). Repeatable.")
@click.option("--metadata", "-m", "metadata_kv", multiple=True, type=KEY_VALUE, help="Metadata (KEY=VALUE). Repeatable.")
@click.option("--resource", "resources_kv", multiple=True, type=KEY_VALUE, help="Resource limit (e.g. cpu=1 memory=2Gi). Repeatable.")
@click.option("--entrypoint", default=None, help="Entrypoint command (JSON array or shell string).")
@click.option("--network-policy-file", type=click.Path(exists=True), default=None, help="Network policy JSON file.")
@click.option("--skip-health-check", is_flag=True, default=False, help="Skip waiting for sandbox readiness.")
@click.option("--ready-timeout", type=DURATION, default=None, help="Max wait time for sandbox readiness (e.g. 30s).")
@click.pass_obj
@handle_errors
def sandbox_create(
    obj: ClientContext,
    image: str,
    timeout: timedelta | None,
    envs: tuple[tuple[str, str], ...],
    metadata_kv: tuple[tuple[str, str], ...],
    resources_kv: tuple[tuple[str, str], ...],
    entrypoint: str | None,
    network_policy_file: str | None,
    skip_health_check: bool,
    ready_timeout: timedelta | None,
) -> None:
    """Create a new sandbox."""
    from opensandbox.sync.sandbox import SandboxSync

    kwargs: dict = {
        "connection_config": obj.connection_config,
        "skip_health_check": skip_health_check,
    }
    if timeout is not None:
        kwargs["timeout"] = timeout
    if ready_timeout is not None:
        kwargs["ready_timeout"] = ready_timeout
    if envs:
        kwargs["env"] = dict(envs)
    if metadata_kv:
        kwargs["metadata"] = dict(metadata_kv)
    if resources_kv:
        kwargs["resource"] = dict(resources_kv)
    if entrypoint:
        try:
            kwargs["entrypoint"] = json.loads(entrypoint)
        except json.JSONDecodeError:
            kwargs["entrypoint"] = ["sh", "-c", entrypoint]
    if network_policy_file:
        with open(network_policy_file) as f:
            kwargs["network_policy"] = NetworkPolicy(**json.load(f))

    with obj.output.spinner("Creating sandbox..."):
        sandbox = SandboxSync.create(image, **kwargs)
    obj.output.success_panel(
        {"id": sandbox.id, "image": image, "status": "created"},
        title="Sandbox Created",
    )


# ---- list -----------------------------------------------------------------

@sandbox_group.command("list")
@click.option("--state", "-s", "states", multiple=True, help="Filter by state (Pending, Running, Paused, ...). Repeatable.")
@click.option("--metadata", "-m", "metadata_kv", multiple=True, type=KEY_VALUE, help="Metadata filter (KEY=VALUE). Repeatable.")
@click.option("--page", type=int, default=None, help="Page number (0-indexed).")
@click.option("--page-size", type=int, default=None, help="Items per page.")
@click.pass_obj
@handle_errors
def sandbox_list(
    obj: ClientContext,
    states: tuple[str, ...],
    metadata_kv: tuple[tuple[str, str], ...],
    page: int | None,
    page_size: int | None,
) -> None:
    """List sandboxes."""
    mgr = obj.get_manager()
    filt = SandboxFilter(
        states=list(states) if states else None,
        metadata=dict(metadata_kv) if metadata_kv else None,
        page=page,
        page_size=page_size,
    )
    with obj.output.spinner("Fetching sandboxes..."):
        result = mgr.list_sandbox_infos(filt)
    if not result.sandbox_infos:
        if obj.output.fmt in ("json", "yaml"):
            obj.output.print_rows(
                [], columns=["id", "status", "image", "created_at", "expires_at"],
                title="Sandboxes",
            )
        else:
            obj.output.info("No sandboxes found.")
        return

    raw_rows = [info.model_dump(mode="json") for info in result.sandbox_infos]

    # For machine-readable formats, preserve the original structure
    if obj.output.fmt in ("json", "yaml"):
        obj.output.print_rows(
            raw_rows,
            columns=["id", "status", "image", "created_at", "expires_at"],
            title="Sandboxes",
        )
        return

    # Flatten nested status/image objects for clean table display
    rows = []
    for d in raw_rows:
        flat = dict(d)
        status_val = flat.get("status")
        if isinstance(status_val, dict):
            flat["status"] = status_val.get("state", str(status_val))
        image_val = flat.get("image")
        if isinstance(image_val, dict):
            flat["image"] = image_val.get("image", str(image_val))
        rows.append(flat)

    obj.output.print_rows(
        rows,
        columns=["id", "status", "image", "created_at", "expires_at"],
        title="Sandboxes",
    )


# ---- get ------------------------------------------------------------------

@sandbox_group.command("get")
@click.argument("sandbox_id")
@click.pass_obj
@handle_errors
def sandbox_get(obj: ClientContext, sandbox_id: str) -> None:
    """Get sandbox details."""
    sandbox_id = obj.resolve_sandbox_id(sandbox_id)
    mgr = obj.get_manager()
    info = mgr.get_sandbox_info(sandbox_id)
    d = info.model_dump(mode="json")

    # For machine-readable formats, preserve the original structure
    if obj.output.fmt in ("json", "yaml"):
        obj.output.print_dict(d, title="Sandbox Info")
        return

    # Flatten nested objects for clean table display
    status_val = d.get("status")
    if isinstance(status_val, dict):
        d["status"] = status_val.get("state", str(status_val))
        if status_val.get("reason"):
            d["status_reason"] = status_val["reason"]
        if status_val.get("message"):
            d["status_message"] = status_val["message"]
    image_val = d.get("image")
    if isinstance(image_val, dict):
        d["image"] = image_val.get("image", str(image_val))
    obj.output.print_dict(d, title="Sandbox Info")


# ---- kill -----------------------------------------------------------------

@sandbox_group.command("kill")
@click.argument("sandbox_ids", nargs=-1, required=True)
@click.pass_obj
@handle_errors
def sandbox_kill(obj: ClientContext, sandbox_ids: tuple[str, ...]) -> None:
    """Terminate one or more sandboxes."""
    mgr = obj.get_manager()
    for sid in sandbox_ids:
        resolved = obj.resolve_sandbox_id(sid)
        with obj.output.spinner(f"Killing sandbox {resolved}..."):
            mgr.kill_sandbox(resolved)
        obj.output.success(f"Sandbox terminated: {resolved}")


# ---- pause ----------------------------------------------------------------

@sandbox_group.command("pause")
@click.argument("sandbox_id")
@click.pass_obj
@handle_errors
def sandbox_pause(obj: ClientContext, sandbox_id: str) -> None:
    """Pause a running sandbox."""
    sandbox_id = obj.resolve_sandbox_id(sandbox_id)
    mgr = obj.get_manager()
    with obj.output.spinner("Pausing sandbox..."):
        mgr.pause_sandbox(sandbox_id)
    obj.output.success(f"Sandbox paused: {sandbox_id}")


# ---- resume ---------------------------------------------------------------

@sandbox_group.command("resume")
@click.argument("sandbox_id")
@click.pass_obj
@handle_errors
def sandbox_resume(obj: ClientContext, sandbox_id: str) -> None:
    """Resume a paused sandbox."""
    sandbox_id = obj.resolve_sandbox_id(sandbox_id)
    mgr = obj.get_manager()
    with obj.output.spinner("Resuming sandbox..."):
        mgr.resume_sandbox(sandbox_id)
    obj.output.success(f"Sandbox resumed: {sandbox_id}")


# ---- renew ----------------------------------------------------------------

@sandbox_group.command("renew")
@click.argument("sandbox_id")
@click.option("--timeout", "-t", required=True, type=DURATION, help="New TTL duration (e.g. 30m, 2h).")
@click.pass_obj
@handle_errors
def sandbox_renew(obj: ClientContext, sandbox_id: str, timeout: timedelta) -> None:
    """Renew sandbox expiration."""
    sandbox_id = obj.resolve_sandbox_id(sandbox_id)
    mgr = obj.get_manager()
    with obj.output.spinner("Renewing sandbox..."):
        resp = mgr.renew_sandbox(sandbox_id, timeout)
    obj.output.success_panel(
        {"sandbox_id": sandbox_id, "expires_at": str(resp.expires_at)},
        title="Sandbox Renewed",
    )


# ---- endpoint -------------------------------------------------------------

@sandbox_group.command("endpoint")
@click.argument("sandbox_id")
@click.option("--port", "-p", required=True, type=int, help="Port number.")
@click.pass_obj
@handle_errors
def sandbox_endpoint(obj: ClientContext, sandbox_id: str, port: int) -> None:
    """Get the public endpoint for a sandbox port."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        ep = sandbox.get_endpoint(port)
        obj.output.print_model(ep, title="Sandbox Endpoint")
    finally:
        sandbox.close()


# ---- health ---------------------------------------------------------------

@sandbox_group.command("health")
@click.argument("sandbox_id")
@click.pass_obj
@handle_errors
def sandbox_health(obj: ClientContext, sandbox_id: str) -> None:
    """Check sandbox health."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        healthy = sandbox.is_healthy()
        if obj.output.fmt == "table":
            if healthy:
                obj.output.success(f"Sandbox {sandbox_id} is healthy")
            else:
                obj.output.error(f"Sandbox {sandbox_id} is unhealthy")
        else:
            obj.output.print_dict(
                {"sandbox_id": sandbox_id, "healthy": healthy},
                title="Health Check",
            )
    finally:
        sandbox.close()


# ---- metrics --------------------------------------------------------------

@sandbox_group.command("metrics")
@click.argument("sandbox_id")
@click.pass_obj
@handle_errors
def sandbox_metrics(obj: ClientContext, sandbox_id: str) -> None:
    """Get sandbox resource metrics."""
    sandbox = obj.connect_sandbox(sandbox_id)
    try:
        m = sandbox.get_metrics()
        obj.output.print_model(m, title="Sandbox Metrics")
    finally:
        sandbox.close()


================================================
FILE: cli/src/opensandbox_cli/config.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""CLI configuration loading and management.

Priority (highest to lowest):
  1. CLI flags
  2. Environment variables
  3. Config file (~/.opensandbox/config.toml)
  4. SDK defaults
"""

from __future__ import annotations

import os
import sys
from pathlib import Path
from typing import Any

if sys.version_info >= (3, 11):
    import tomllib
else:
    try:
        import tomli as tomllib  # type: ignore[no-redef]
    except ModuleNotFoundError:  # pragma: no cover
        tomllib = None  # type: ignore[assignment]


DEFAULT_CONFIG_DIR = Path.home() / ".opensandbox"
DEFAULT_CONFIG_PATH = DEFAULT_CONFIG_DIR / "config.toml"

DEFAULT_CONFIG_TEMPLATE = """\
# OpenSandbox CLI configuration
# Priority: CLI flags > environment variables > this file > SDK defaults

[connection]
# api_key = "your-api-key"
# domain = "localhost:8080"
# protocol = "http"
# request_timeout = 30

[output]
# format = "table"    # table | json | yaml
# color = true

[defaults]
# image = "python:3.11"
# timeout = "10m"
"""


def load_config_file(config_path: Path | None = None) -> dict[str, Any]:
    """Load and parse the TOML config file.

    Returns an empty dict if the file doesn't exist or tomllib is unavailable.
    """
    path = config_path or DEFAULT_CONFIG_PATH
    if not path.exists():
        return {}
    if tomllib is None:
        return {}
    with open(path, "rb") as f:
        return tomllib.load(f)


def resolve_config(
    *,
    cli_api_key: str | None = None,
    cli_domain: str | None = None,
    cli_protocol: str | None = None,
    cli_timeout: int | None = None,
    cli_output: str | None = None,
    config_path: Path | None = None,
) -> dict[str, Any]:
    """Merge config from all sources and return a flat dict.

    Keys returned:
      - api_key, domain, protocol, request_timeout (int seconds)
      - output_format ("table" | "json" | "yaml")
      - default_image, default_timeout (str like "10m")
    """
    file_cfg = load_config_file(config_path)
    conn = file_cfg.get("connection", {})
    output_cfg = file_cfg.get("output", {})
    defaults = file_cfg.get("defaults", {})

    return {
        "api_key": cli_api_key
        or os.getenv("OPEN_SANDBOX_API_KEY")
        or conn.get("api_key"),
        "domain": cli_domain
        or os.getenv("OPEN_SANDBOX_DOMAIN")
        or conn.get("domain"),
        "protocol": cli_protocol
        or os.getenv("OPEN_SANDBOX_PROTOCOL")
        or conn.get("protocol")
        or "http",
        "request_timeout": cli_timeout
        or _int_or_none(os.getenv("OPEN_SANDBOX_REQUEST_TIMEOUT"))
        or conn.get("request_timeout")
        or 30,
        "output_format": cli_output
        or os.getenv("OPEN_SANDBOX_OUTPUT")
        or output_cfg.get("format")
        or "table",
        "color": output_cfg.get("color", True),
        "default_image": defaults.get("image"),
        "default_timeout": defaults.get("timeout"),
    }


def init_config_file(config_path: Path | None = None, *, force: bool = False) -> Path:
    """Create a default config file. Returns the path written."""
    path = config_path or DEFAULT_CONFIG_PATH
    if path.exists() and not force:
        raise FileExistsError(
            f"Config file already exists at {path}. Use --force to overwrite."
        )
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(DEFAULT_CONFIG_TEMPLATE)
    return path


def _int_or_none(value: str | None) -> int | None:
    if value is None:
        return None
    try:
        return int(value)
    except ValueError:
        return None


================================================
FILE: cli/src/opensandbox_cli/main.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Root Click group with global options."""

from __future__ import annotations

from pathlib import Path

import click
from rich.console import Console
from rich.text import Text

from opensandbox_cli import __version__
from opensandbox_cli.client import ClientContext
from opensandbox_cli.commands.code import code_group
from opensandbox_cli.commands.command import command_group, exec_cmd
from opensandbox_cli.commands.config_cmd import config_group
from opensandbox_cli.commands.file import file_group
from opensandbox_cli.commands.sandbox import sandbox_group
from opensandbox_cli.config import resolve_config
from opensandbox_cli.output import OutputFormatter

# ---------------------------------------------------------------------------
# Banner
# ---------------------------------------------------------------------------

BANNER = r"""[bold cyan]
   ____                   _____                 _ _
  / __ \                 / ____|               | | |
 | |  | |_ __   ___ _ _| (___   __ _ _ __   __| | |__   _____  __
 | |  | | '_ \ / _ \ '_ \___ \ / _` | '_ \ / _` | '_ \ / _ \ \/ /
 | |__| | |_) |  __/ | | |___) | (_| | | | | (_| | |_) | (_) >  <
  \____/| .__/ \___|_| |_|____/ \__,_|_| |_|\__,_|_.__/ \___/_/\_\
        | |
        |_|[/]  [dim]v{version}[/]
"""


class BannerGroup(click.Group):
    """Custom Click group that shows a banner before help text."""

    def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
        console = Console(stderr=False)
        console.print(BANNER.format(version=__version__))
        super().format_help(ctx, formatter)


@click.group(cls=BannerGroup, context_settings={"help_option_names": ["-h", "--help"]})
@click.option("--api-key", envvar="OPEN_SANDBOX_API_KEY", default=None, help="API key for authentication.")
@click.option("--domain", envvar="OPEN_SANDBOX_DOMAIN", default=None, help="API server domain (e.g. localhost:8080).")
@click.option("--protocol", type=click.Choice(["http", "https"]), default=None, help="Protocol (http/https).")
@click.option("--timeout", "request_timeout", type=int, default=None, help="Request timeout in seconds.")
@click.option("-o", "--output", "output_format", type=click.Choice(["table", "json", "yaml"]), default=None, help="Output format.")
@click.option("--config", "config_path", type=click.Path(exists=False, path_type=Path), default=None, help="Config file path.")
@click.option("-v", "--verbose", is_flag=True, default=False, help="Enable verbose/debug output.")
@click.option("--no-color", is_flag=True, default=False, help="Disable colored output.")
@click.version_option(version=__version__, prog_name="opensandbox")
@click.pass_context
def cli(
    ctx: click.Context,
    api_key: str | None,
    domain: str | None,
    protocol: str | None,
    request_timeout: int | None,
    output_format: str | None,
    config_path: Path | None,
    verbose: bool,
    no_color: bool,
) -> None:
    """OpenSandbox CLI — manage sandboxes from your terminal."""
    if verbose:
        import logging

        logging.basicConfig(level=logging.DEBUG)

    resolved = resolve_config(
        cli_api_key=api_key,
        cli_domain=domain,
        cli_protocol=protocol,
        cli_timeout=request_timeout,
        cli_output=output_format,
        config_path=config_path,
    )

    formatter = OutputFormatter(
        resolved["output_format"],
        color=not no_color and resolved.get("color", True),
    )

    ctx.obj = ClientContext(resolved_config=resolved, output=formatter)
    ctx.call_on_close(lambda: ctx.obj.close())


# Register sub-command groups
cli.add_command(sandbox_group)
cli.add_command(command_group)
cli.add_command(exec_cmd)
cli.add_command(file_group)
cli.add_command(code_group)
cli.add_command(config_group)


================================================
FILE: cli/src/opensandbox_cli/output.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Output formatting: table (rich), JSON, YAML."""

from __future__ import annotations

import json
import sys
from contextlib import contextmanager
from typing import Any, Generator, Sequence

import click

try:
    import yaml
except ImportError:  # pragma: no cover
    yaml = None  # type: ignore[assignment]

from pydantic import BaseModel
from rich import box
from rich.console import Console
from rich.panel import Panel
from rich.status import Status
from rich.table import Table
from rich.text import Text

# ---------------------------------------------------------------------------
# Status badge styling  (sandbox state → color + icon)
# ---------------------------------------------------------------------------

_STATUS_STYLES: dict[str, tuple[str, str]] = {
    # state → (rich style, icon)
    "running": ("bold green", "●"),
    "ready": ("bold green", "●"),
    "healthy": ("bold green", "●"),
    "pending": ("bold yellow", "◐"),
    "creating": ("bold yellow", "◐"),
    "starting": ("bold yellow", "◐"),
    "paused": ("bold blue", "⏸"),
    "stopped": ("dim", "○"),
    "terminated": ("dim", "○"),
    "killed": ("dim", "○"),
    "error": ("bold red", "✗"),
    "failed": ("bold red", "✗"),
    "unhealthy": ("bold red", "✗"),
    "created": ("bold cyan", "✦"),
}

# Columns that contain status-like values
_STATUS_COLUMNS = {"status", "state", "healthy"}

# Columns that should be rendered in a dimmer style (long IDs, timestamps)
_DIM_COLUMNS = {"created_at", "expires_at", "modified_at", "updated_at"}

# Columns that are primary identifiers
_ID_COLUMNS = {"id", "sandbox_id", "execution_id", "context_id"}


def _style_value(col: str, value: str) -> Text:
    """Apply contextual styling to a cell value."""
    lower = value.lower()

    if col in _STATUS_COLUMNS:
        style, icon = _STATUS_STYLES.get(lower, ("", ""))
        if style:
            return Text(f"{icon} {value}", style=style)

    if col in _DIM_COLUMNS:
        return Text(value, style="dim")

    if col in _ID_COLUMNS:
        return Text(value, style="bold cyan")

    return Text(value)


class OutputFormatter:
    """Renders data in table / json / yaml format."""

    def __init__(self, fmt: str = "table", *, color: bool = True) -> None:
        self.fmt = fmt
        self.color = color
        self.console = Console(
            stderr=False, no_color=not color, force_terminal=None
        )
        self._err_console = Console(
            stderr=True, no_color=not color, force_terminal=None
        )

    # ------------------------------------------------------------------
    # Status messages with icons
    # ------------------------------------------------------------------

    def success(self, msg: str) -> None:
        """Print a success message with ✅ icon."""
        if self.color:
            self.console.print(f"  [bold green]✅ {msg}[/]")
        else:
            click.echo(f"OK: {msg}")

    def info(self, msg: str) -> None:
        """Print an info message with ℹ️  icon."""
        if self.color:
            self.console.print(f"  [bold blue]ℹ️  {msg}[/]")
        else:
            click.echo(f"INFO: {msg}")

    def warning(self, msg: str) -> None:
        """Print a warning message with ⚠️  icon."""
        if self.color:
            self._err_console.print(f"  [bold yellow]⚠️  {msg}[/]")
        else:
            click.echo(f"WARN: {msg}", err=True)

    def error(self, msg: str) -> None:
        """Print an error message with ❌ icon."""
        if self.color:
            self._err_console.print(f"  [bold red]❌ {msg}[/]")
        else:
            click.echo(f"ERROR: {msg}", err=True)

    def error_panel(self, msg: str, title: str = "Error") -> None:
        """Print an error with a bold header and message."""
        if self.color:
            self._err_console.print()
            self._err_console.print(f"  [bold red]{title}[/]")
            self._err_console.print(f"  [dim]{'─' * (len(title) + 2)}[/]")
            for line in msg.splitlines():
                self._err_console.print(f"  {line}")
            self._err_console.print()
        else:
            click.echo(f"ERROR [{title}]: {msg}", err=True)

    # ------------------------------------------------------------------
    # Spinner for long-running operations
    # ------------------------------------------------------------------

    @contextmanager
    def spinner(self, msg: str) -> Generator[Status, None, None]:
        """Context manager that shows a spinner while work is in progress."""
        if self.color and self.fmt == "table":
            with self._err_console.status(f"[bold cyan]⏳ {msg}[/]", spinner="dots") as status:
                yield status
        else:
            # No spinner in non-color or non-table mode
            yield None  # type: ignore[arg-type]

    # ------------------------------------------------------------------
    # Panel output
    # ------------------------------------------------------------------

    def panel(self, content: str, *, title: str | None = None, style: str = "cyan") -> None:
        """Print content inside a styled panel."""
        if self.color:
            self.console.print(Panel(
                content,
                title=title,
                title_align="left",
                border_style=style,
                box=box.ROUNDED,
                padding=(0, 1),
            ))
        else:
            if title:
                click.echo(f"--- {title} ---")
            click.echo(content)

    def success_panel(self, data: dict[str, Any], *, title: str = "Success") -> None:
        """Print a success result with a header and indented key-value pairs."""
        if self.fmt != "table":
            if self.fmt == "json":
                self._print_json(data)
            elif self.fmt == "yaml":
                self._print_yaml(data)
            return

        if self.color:
            self.console.print()
            self.console.print(f"  [bold green]✓ {title}[/]")
            self.console.print(f"  [dim]{'─' * (len(title) + 2)}[/]")
            for k, v in data.items():
                self.console.print(f"  [bold]{k}:[/] [cyan]{v}[/]")
            self.console.print()
        else:
            click.echo(f"--- {title} ---")
            for k, v in data.items():
                click.echo(f"  {k}: {v}")

    # ------------------------------------------------------------------
    # Public helpers
    # ------------------------------------------------------------------

    def print_model(self, model: BaseModel, title: str | None = None) -> None:
        """Print a single Pydantic model as key-value panel or JSON/YAML."""
        data = _model_to_dict(model)
        if self.fmt == "json":
            self._print_json(data)
        elif self.fmt == "yaml":
            self._print_yaml(data)
        else:
            self._print_kv_table(data, title=title)

    def print_models(
        self,
        models: Sequence[BaseModel],
        columns: list[str],
        *,
        title: str | None = None,
    ) -> None:
        """Print a list of Pydantic models as a table or JSON/YAML."""
        rows = [_model_to_dict(m) for m in models]
        if self.fmt == "json":
            self._print_json(rows)
        elif self.fmt == "yaml":
            self._print_yaml(rows)
        else:
            self._print_table(rows, columns, title=title)

    def print_rows(
        self,
        rows: list[dict[str, Any]],
        columns: list[str],
        *,
        title: str | None = None,
    ) -> None:
        """Print pre-processed rows (list of dicts) as a table or JSON/YAML."""
        if self.fmt == "json":
            self._print_json(rows)
        elif self.fmt == "yaml":
            self._print_yaml(rows)
        else:
            self._print_table(rows, columns, title=title)

    def print_dict(self, data: dict[str, Any], title: str | None = None) -> None:
        """Print a flat dict."""
        if self.fmt == "json":
            self._print_json(data)
        elif self.fmt == "yaml":
            self._print_yaml(data)
        else:
            self._print_kv_table(data, title=title)

    def print_text(self, text: str) -> None:
        """Print raw text (ignores format)."""
        click.echo(text)

    # ------------------------------------------------------------------
    # Internal renderers
    # ------------------------------------------------------------------

    def _print_json(self, data: Any) -> None:
        if self.color:
            self.console.print_json(json.dumps(data, default=str))
        else:
            click.echo(json.dumps(data, indent=2, default=str))

    def _print_yaml(self, data: Any) -> None:
        if yaml is None:
            click.secho(
                "PyYAML is not installed. Use --output json instead.", fg="red", err=True
            )
            sys.exit(1)
        click.echo(yaml.dump(data, default_flow_style=False, allow_unicode=True).rstrip())

    def _print_kv_table(self, data: dict[str, Any], *, title: str | None = None) -> None:
        table = Table(
            title=title,
            show_header=True,
            header_style="bold magenta",
            title_style="bold cyan",
            box=box.ROUNDED,
            border_style="bright_black",
            padding=(0, 1),
            show_lines=True,
        )
        table.add_column("Key", style="bold cyan", no_wrap=True)
        table.add_column("Value")
        for k, v in data.items():
            val_text = _style_value(k, str(v)) if v is not None else Text("-", style="dim")
            table.add_row(str(k), val_text)
        self.console.print(table)

    def _print_table(
        self,
        rows: list[dict[str, Any]],
        columns: list[str],
        *,
        title: str | None = None,
    ) -> None:
        table = Table(
            title=title,
            show_header=True,
            header_style="bold magenta",
            title_style="bold cyan",
            box=box.ROUNDED,
            border_style="bright_black",
            padding=(0, 1),
            row_styles=["", "dim"],
        )
        for col in columns:
            style = ""
            if col in _ID_COLUMNS:
                style = "bold cyan"
            elif col in _DIM_COLUMNS:
                style = "dim"
            table.add_column(col.upper(), style=style, no_wrap=(col in _ID_COLUMNS))

        for row in rows:
            cells: list[Text | str] = []
            for col in columns:
                val = str(row.get(col, "-"))
                if col in _STATUS_COLUMNS:
                    cells.append(_style_value(col, val))
                else:
                    cells.append(val)
            table.add_row(*cells)
        self.console.print(table)


# ------------------------------------------------------------------
# Helpers
# ------------------------------------------------------------------


def _model_to_dict(model: BaseModel) -> dict[str, Any]:
    return model.model_dump(mode="json")


================================================
FILE: cli/src/opensandbox_cli/utils.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Shared CLI utilities: duration parsing, error handling, key-value parsing."""

from __future__ import annotations

import functools
import re
import sys
from datetime import timedelta

import click


# ---------------------------------------------------------------------------
# Duration parsing  (e.g. "10m", "1h30m", "90s", "2h")
# ---------------------------------------------------------------------------

_DURATION_RE = re.compile(
    r"^(?:(?P<hours>\d+)h)?(?:(?P<minutes>\d+)m)?(?:(?P<seconds>\d+)s)?$"
)


def parse_duration(value: str) -> timedelta:
    """Parse a human-friendly duration string into a ``timedelta``.

    Supported formats: ``10m``, ``1h30m``, ``90s``, ``2h``, ``1h30m45s``.
    A plain integer is treated as seconds.
    """
    value = value.strip()
    if not value:
        raise click.BadParameter("Duration cannot be empty")

    # Plain integer → seconds
    if value.isdigit():
        return timedelta(seconds=int(value))

    m = _DURATION_RE.match(value)
    if not m or not m.group(0):
        raise click.BadParameter(
            f"Invalid duration '{value}'. Use format like 10m, 1h30m, 90s."
        )

    hours = int(m.group("hours") or 0)
    minutes = int(m.group("minutes") or 0)
    seconds = int(m.group("seconds") or 0)
    return timedelta(hours=hours, minutes=minutes, seconds=seconds)


class DurationType(click.ParamType):
    """Click parameter type for duration strings."""

    name = "duration"

    def convert(
        self, value: str, param: click.Parameter | None, ctx: click.Context | None
    ) -> timedelta:
        if isinstance(value, timedelta):
            return value
        try:
            return parse_duration(value)
        except click.BadParameter:
            self.fail(
                f"Invalid duration '{value}'. Use format like 10m, 1h30m, 90s.",
                param,
                ctx,
            )


DURATION = DurationType()


# ---------------------------------------------------------------------------
# Key=Value parsing  (e.g. --env FOO=bar)
# ---------------------------------------------------------------------------


class KeyValueType(click.ParamType):
    """Click parameter type that parses ``KEY=VALUE`` strings into a tuple."""

    name = "KEY=VALUE"

    def convert(
        self, value: str, param: click.Parameter | None, ctx: click.Context | None
    ) -> tuple[str, str]:
        if isinstance(value, tuple):
            return value
        if "=" not in value:
            self.fail(f"Expected KEY=VALUE format, got '{value}'", param, ctx)
        key, _, val = value.partition("=")
        return (key, val)


KEY_VALUE = KeyValueType()


# ---------------------------------------------------------------------------
# Error handling decorator
# ---------------------------------------------------------------------------


def handle_errors(fn):  # type: ignore[no-untyped-def]
    """Decorator that catches SDK / HTTP exceptions and prints a friendly message."""

    @functools.wraps(fn)
    def wrapper(*args, **kwargs):  # type: ignore[no-untyped-def]
        try:
            return fn(*args, **kwargs)
        except click.exceptions.Exit:
            raise
        except click.ClickException:
            raise
        except Exception as exc:
            # Import here to avoid circular imports at module level
            from opensandbox.exceptions import SandboxException

            # Try to get the OutputFormatter from the Click context
            ctx = click.get_current_context(silent=True)
            obj = getattr(ctx, "obj", None) if ctx else None
            output = getattr(obj, "output", None) if obj else None

            if output and hasattr(output, "error_panel"):
                if isinstance(exc, SandboxException):
                    output.error_panel(str(exc), title="Sandbox Error")
                else:
                    output.error_panel(
                        f"{str(exc)}\n\n[dim]Type: {type(exc).__qualname__}[/]",
                        title=type(exc).__name__,
                    )
            else:
                click.secho(f"Error: {exc}", fg="red", err=True)
            sys.exit(1)

    return wrapper


================================================
FILE: cli/tests/__init__.py
================================================


================================================
FILE: cli/tests/conftest.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Shared test fixtures."""

from __future__ import annotations

from unittest.mock import MagicMock

import pytest
from click.testing import CliRunner

from opensandbox_cli.output import OutputFormatter


@pytest.fixture()
def runner() -> CliRunner:
    return CliRunner()


@pytest.fixture()
def mock_manager() -> MagicMock:
    return MagicMock()


@pytest.fixture()
def mock_sandbox() -> MagicMock:
    return MagicMock()


@pytest.fixture()
def mock_client_context(mock_manager: MagicMock, mock_sandbox: MagicMock) -> MagicMock:
    """A mock ClientContext that avoids real SDK/HTTP calls."""
    ctx = MagicMock()
    ctx.resolved_config = {
        "api_key": "test-key",
        "domain": "localhost:8080",
        "protocol": "http",
        "request_timeout": 30,
        "output_format": "json",
        "color": False,
        "default_image": None,
        "default_timeout": None,
    }
    ctx.output = OutputFormatter("json", color=False)
    ctx.get_manager.return_value = mock_manager
    ctx.connect_sandbox.return_value = mock_sandbox
    ctx.connection_config = MagicMock()
    ctx.close = MagicMock()
    return ctx


================================================
FILE: cli/tests/test_cli_help.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests that all CLI commands register correctly and --help exits cleanly."""

from __future__ import annotations

import pytest
from click.testing import CliRunner

from opensandbox_cli.main import cli


@pytest.fixture()
def runner() -> CliRunner:
    return CliRunner()


# ---------------------------------------------------------------------------
# Root
# ---------------------------------------------------------------------------


class TestRootCLI:
    def test_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["--help"])
        assert result.exit_code == 0
        assert "OpenSandbox CLI" in result.output

    def test_version(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["--version"])
        assert result.exit_code == 0
        assert "opensandbox" in result.output

    def test_root_lists_commands(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["--help"])
        for cmd in ("sandbox", "command", "exec", "file", "code", "config"):
            assert cmd in result.output


# ---------------------------------------------------------------------------
# Sandbox sub-commands
# ---------------------------------------------------------------------------


class TestSandboxHelp:
    def test_sandbox_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["sandbox", "--help"])
        assert result.exit_code == 0
        for subcmd in ("create", "list", "get", "kill", "pause", "resume", "renew", "endpoint", "health", "metrics"):
            assert subcmd in result.output

    @pytest.mark.parametrize(
        "subcmd",
        ["create", "list", "get", "kill", "pause", "resume", "renew", "endpoint", "health", "metrics"],
    )
    def test_sandbox_subcommand_help(self, runner: CliRunner, subcmd: str) -> None:
        result = runner.invoke(cli, ["sandbox", subcmd, "--help"])
        assert result.exit_code == 0
        assert subcmd in result.output.lower() or "usage" in result.output.lower()


# ---------------------------------------------------------------------------
# Command sub-commands
# ---------------------------------------------------------------------------


class TestCommandHelp:
    def test_command_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["command", "--help"])
        assert result.exit_code == 0
        for subcmd in ("run", "status", "logs", "interrupt"):
            assert subcmd in result.output

    @pytest.mark.parametrize("subcmd", ["run", "status", "logs", "interrupt"])
    def test_command_subcommand_help(self, runner: CliRunner, subcmd: str) -> None:
        result = runner.invoke(cli, ["command", subcmd, "--help"])
        assert result.exit_code == 0


# ---------------------------------------------------------------------------
# exec (top-level shortcut)
# ---------------------------------------------------------------------------


class TestExecHelp:
    def test_exec_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["exec", "--help"])
        assert result.exit_code == 0
        assert "shortcut" in result.output.lower() or "command" in result.output.lower()


# ---------------------------------------------------------------------------
# File sub-commands
# ---------------------------------------------------------------------------


class TestFileHelp:
    def test_file_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["file", "--help"])
        assert result.exit_code == 0
        for subcmd in ("cat", "write", "upload", "download", "rm", "mv", "mkdir", "rmdir", "search", "info", "chmod", "replace"):
            assert subcmd in result.output

    @pytest.mark.parametrize(
        "subcmd",
        ["cat", "write", "upload", "download", "rm", "mv", "mkdir", "rmdir", "search", "info", "chmod", "replace"],
    )
    def test_file_subcommand_help(self, runner: CliRunner, subcmd: str) -> None:
        result = runner.invoke(cli, ["file", subcmd, "--help"])
        assert result.exit_code == 0


# ---------------------------------------------------------------------------
# Code sub-commands
# ---------------------------------------------------------------------------


class TestCodeHelp:
    def test_code_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["code", "--help"])
        assert result.exit_code == 0
        for subcmd in ("run", "context", "interrupt"):
            assert subcmd in result.output

    def test_code_context_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["code", "context", "--help"])
        assert result.exit_code == 0
        for subcmd in ("create", "list", "delete", "delete-all"):
            assert subcmd in result.output


# ---------------------------------------------------------------------------
# Config sub-commands
# ---------------------------------------------------------------------------


class TestConfigHelp:
    def test_config_help(self, runner: CliRunner) -> None:
        result = runner.invoke(cli, ["config", "--help"])
        assert result.exit_code == 0
        for subcmd in ("init", "show", "set"):
            assert subcmd in result.output

    @pytest.mark.parametrize("subcmd", ["init", "show", "set"])
    def test_config_subcommand_help(self, runner: CliRunner, subcmd: str) -> None:
        result = runner.invoke(cli, ["config", subcmd, "--help"])
        assert result.exit_code == 0


================================================
FILE: cli/tests/test_commands.py
================================================
# Copyright 2026 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for CLI commands with mocked SDK calls.

Strategy: patch ``opensandbox_cli.main.ClientContext`` and ``resolve_config``
so the root ``cli`` callback creates our mock instead of a real SDK client.
"""

from __future__ import annotations

import json
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest
from click.testing import CliRunner

from opensandbox_cli.main import cli
from opensandbox_cli.output import OutputFormatter


@pytest.fixture()
def runner() -> CliRunner:
    return CliRunner()


def _build_mock_client_context(
    *,
    manager: MagicMock | None = None,
    sandbox: MagicMock | None = None,
    output_format: str = "json",
) -> MagicMock:
    ctx = MagicMock()
    ctx.resolved_config = {
        "api_key": "test-key",
        "domain": "localhost:8080",
        "protocol": "http",
        "request_timeout": 30,
        "output_format": output_format,
        "color": False,
        "default_image": None,
        "default_timeout": None,
    }
    ctx.output = OutputFormatter(output_format, color=False)
    ctx.get_manager.return_value = manager or MagicMock()
    ctx.connect_sandbox.return_value = sandbox or MagicMock()
    ctx.resolve_sandbox_id.side_effect = lambda prefix: prefix  # passthrough
    ctx.connection_config = MagicMock(
Download .txt
gitextract_ee6cl8k3/

├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── FEATURE_REQUEST.md
│   │   └── config.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── deploy-docs-pages.yml
│       ├── egress-test.yaml.yml
│       ├── execd-test.yml
│       ├── ingress-test.yaml
│       ├── publish-components.yml
│       ├── publish-csharp-sdks.yml
│       ├── publish-helm-chart.yml
│       ├── publish-java-sdks.yml
│       ├── publish-js-sdks.yml
│       ├── publish-python-sdks.yml
│       ├── publish-server.yml
│       ├── real-e2e.yml
│       ├── sandbox-k8s-e2e.yml
│       ├── sandbox-k8s-test.yml
│       ├── sdk-tests.yml
│       ├── server-test.yml
│       └── verify-license.yml
├── .gitignore
├── .pre-commit-config.yaml
├── AGENTS.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── cli/
│   ├── README.md
│   ├── pyproject.toml
│   ├── src/
│   │   └── opensandbox_cli/
│   │       ├── __init__.py
│   │       ├── __main__.py
│   │       ├── client.py
│   │       ├── commands/
│   │       │   ├── __init__.py
│   │       │   ├── code.py
│   │       │   ├── command.py
│   │       │   ├── config_cmd.py
│   │       │   ├── file.py
│   │       │   └── sandbox.py
│   │       ├── config.py
│   │       ├── main.py
│   │       ├── output.py
│   │       └── utils.py
│   └── tests/
│       ├── __init__.py
│       ├── conftest.py
│       ├── test_cli_help.py
│       ├── test_commands.py
│       ├── test_config.py
│       ├── test_output.py
│       ├── test_resolve_id.py
│       └── test_utils.py
├── components/
│   ├── egress/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── TODO.md
│   │   ├── build.sh
│   │   ├── docs/
│   │   │   └── benchmark.md
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   ├── nameserver.go
│   │   ├── nameserver_test.go
│   │   ├── nft.go
│   │   ├── pkg/
│   │   │   ├── constants/
│   │   │   │   ├── configuration.go
│   │   │   │   └── constants.go
│   │   │   ├── dnsproxy/
│   │   │   │   ├── exempt.go
│   │   │   │   ├── exempt_test.go
│   │   │   │   ├── proxy.go
│   │   │   │   ├── proxy_linux.go
│   │   │   │   ├── proxy_other.go
│   │   │   │   └── proxy_test.go
│   │   │   ├── events/
│   │   │   │   ├── broadcaster.go
│   │   │   │   ├── events_test.go
│   │   │   │   └── webhook.go
│   │   │   ├── iptables/
│   │   │   │   └── redirect.go
│   │   │   ├── log/
│   │   │   │   └── logger.go
│   │   │   ├── nftables/
│   │   │   │   ├── dynamic.go
│   │   │   │   ├── manager.go
│   │   │   │   └── manager_test.go
│   │   │   └── policy/
│   │   │       ├── policy.go
│   │   │       └── policy_test.go
│   │   ├── policy_server.go
│   │   ├── policy_server_test.go
│   │   └── tests/
│   │       ├── bench-dns-nft.sh
│   │       ├── egress-in-webhook.sh
│   │       ├── hostname.txt
│   │       ├── smoke-dns.sh
│   │       ├── smoke-dynamic-ip.sh
│   │       ├── smoke-nft.sh
│   │       └── webhook-server.py
│   ├── execd/
│   │   ├── .golangci.yml
│   │   ├── DEVELOPMENT.md
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   ├── bootstrap.sh
│   │   ├── build.sh
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   ├── pkg/
│   │   │   ├── flag/
│   │   │   │   ├── flags.go
│   │   │   │   └── parser.go
│   │   │   ├── jupyter/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── auth.go
│   │   │   │   │   ├── auth_test.go
│   │   │   │   │   ├── client.go
│   │   │   │   │   └── types.go
│   │   │   │   ├── client.go
│   │   │   │   ├── debug_integration_test.go
│   │   │   │   ├── execute/
│   │   │   │   │   ├── events.json
│   │   │   │   │   ├── execute.go
│   │   │   │   │   ├── execute_test.go
│   │   │   │   │   ├── executor.go
│   │   │   │   │   ├── types.go
│   │   │   │   │   └── zz_generated.deepcopy.go
│   │   │   │   ├── integration_test.go
│   │   │   │   ├── kernel/
│   │   │   │   │   ├── kernel.go
│   │   │   │   │   ├── kernelspecs.json
│   │   │   │   │   └── types.go
│   │   │   │   ├── live_integration_test.go
│   │   │   │   ├── session/
│   │   │   │   │   ├── session.go
│   │   │   │   │   ├── session_test.go
│   │   │   │   │   ├── sessions.json
│   │   │   │   │   └── types.go
│   │   │   │   └── transport.go
│   │   │   ├── log/
│   │   │   │   └── log.go
│   │   │   ├── runtime/
│   │   │   │   ├── bash_session.go
│   │   │   │   ├── bash_session_test.go
│   │   │   │   ├── bash_session_windows.go
│   │   │   │   ├── command.go
│   │   │   │   ├── command_common.go
│   │   │   │   ├── command_status.go
│   │   │   │   ├── command_status_test.go
│   │   │   │   ├── command_test.go
│   │   │   │   ├── command_windows.go
│   │   │   │   ├── context.go
│   │   │   │   ├── context_test.go
│   │   │   │   ├── ctrl.go
│   │   │   │   ├── env.go
│   │   │   │   ├── env_test.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── helpers_test.go
│   │   │   │   ├── interrupt.go
│   │   │   │   ├── interrupt_windows.go
│   │   │   │   ├── jupyter.go
│   │   │   │   ├── language.go
│   │   │   │   ├── sql.go
│   │   │   │   ├── sql_test.go
│   │   │   │   ├── types.go
│   │   │   │   └── types_test.go
│   │   │   ├── util/
│   │   │   │   ├── glob/
│   │   │   │   │   ├── index.go
│   │   │   │   │   ├── match.go
│   │   │   │   │   ├── match_benchmark_test.go
│   │   │   │   │   ├── match_test.go
│   │   │   │   │   └── pattern.go
│   │   │   │   └── safego/
│   │   │   │       ├── safe.go
│   │   │   │       └── safe_test.go
│   │   │   └── web/
│   │   │       ├── controller/
│   │   │       │   ├── basic.go
│   │   │       │   ├── basic_test.go
│   │   │       │   ├── codeinterpreting.go
│   │   │       │   ├── codeinterpreting_test.go
│   │   │       │   ├── command.go
│   │   │       │   ├── command_test.go
│   │   │       │   ├── filesystem.go
│   │   │       │   ├── filesystem_download.go
│   │   │       │   ├── filesystem_test.go
│   │   │       │   ├── filesystem_upload.go
│   │   │       │   ├── filesystem_windows.go
│   │   │       │   ├── metric.go
│   │   │       │   ├── metric_test.go
│   │   │       │   ├── mock_test.go
│   │   │       │   ├── ping.go
│   │   │       │   ├── sse.go
│   │   │       │   ├── syscall_linux.go
│   │   │       │   ├── syscall_others.go
│   │   │       │   ├── test_helpers.go
│   │   │       │   ├── utils.go
│   │   │       │   ├── utils_test.go
│   │   │       │   └── utils_windows.go
│   │   │       ├── model/
│   │   │       │   ├── codeinterpreting.go
│   │   │       │   ├── codeinterpreting_test.go
│   │   │       │   ├── command.go
│   │   │       │   ├── error.go
│   │   │       │   ├── filesystem.go
│   │   │       │   ├── header.go
│   │   │       │   ├── metric.go
│   │   │       │   └── session.go
│   │   │       ├── proxy.go
│   │   │       └── router.go
│   │   └── tests/
│   │       ├── jupyter.sh
│   │       ├── smoke.sh
│   │       └── smoke_api.py
│   ├── ingress/
│   │   ├── .golangci.yml
│   │   ├── DEVELOPMENT.md
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── build.sh
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   └── pkg/
│   │       ├── flag/
│   │       │   ├── flags.go
│   │       │   └── parser.go
│   │       ├── proxy/
│   │       │   ├── header.go
│   │       │   ├── healthz.go
│   │       │   ├── healthz_test.go
│   │       │   ├── host.go
│   │       │   ├── http.go
│   │       │   ├── http_test.go
│   │       │   ├── logger.go
│   │       │   ├── proxy.go
│   │       │   ├── proxy_test.go
│   │       │   ├── websocket.go
│   │       │   └── websocket_test.go
│   │       ├── renewintent/
│   │       │   ├── intent.go
│   │       │   ├── intent_test.go
│   │       │   ├── publisher.go
│   │       │   ├── redis.go
│   │       │   └── redis_bench_test.go
│   │       └── sandbox/
│   │           ├── agent_sandbox_provider.go
│   │           ├── agent_sandbox_provider_test.go
│   │           ├── batchsandbox_provider.go
│   │           ├── batchsandbox_provider_test.go
│   │           ├── errors_test.go
│   │           ├── factory.go
│   │           └── provider.go
│   └── internal/
│       ├── go.mod
│       ├── go.sum
│       ├── logger/
│       │   ├── logger.go
│       │   └── zap.go
│       └── version/
│           └── version.go
├── docs/
│   ├── .nvmrc
│   ├── .vitepress/
│   │   ├── config.mts
│   │   ├── scripts/
│   │   │   └── docs-manifest.mjs
│   │   └── theme/
│   │       ├── index.ts
│   │       └── styles.css
│   ├── README.md
│   ├── README_zh.md
│   ├── RELEASE_NOTE_TEMPLATE.md
│   ├── architecture.md
│   ├── index.md
│   ├── manual-cleanup-refactor-guide.md
│   ├── package.json
│   ├── secure-container.md
│   ├── single_host_network.md
│   └── zh/
│       └── index.md
├── examples/
│   ├── README.md
│   ├── agent-sandbox/
│   │   ├── README.md
│   │   └── main.py
│   ├── aio-sandbox/
│   │   ├── README.md
│   │   └── main.py
│   ├── chrome/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build.sh
│   │   ├── chrome.sh
│   │   ├── go.mod
│   │   ├── go.sum
│   │   ├── main.go
│   │   └── main.py
│   ├── claude-code/
│   │   ├── README.md
│   │   └── main.py
│   ├── code-interpreter/
│   │   ├── README.md
│   │   ├── main.py
│   │   └── main_use_pool.py
│   ├── codex-cli/
│   │   ├── README.md
│   │   └── main.py
│   ├── desktop/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build.sh
│   │   └── main.py
│   ├── docker-ossfs-volume-mount/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── docker-pvc-volume-mount/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── gemini-cli/
│   │   ├── README.md
│   │   └── main.py
│   ├── google-adk/
│   │   ├── README.md
│   │   └── main.py
│   ├── host-volume-mount/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── kimi-cli/
│   │   ├── README.md
│   │   └── main.py
│   ├── kubernetes-pvc-volume-mount/
│   │   ├── README.md
│   │   └── main.py
│   ├── langgraph/
│   │   ├── README.md
│   │   └── main.py
│   ├── nullclaw/
│   │   ├── README.md
│   │   └── main.py
│   ├── openclaw/
│   │   ├── README.md
│   │   ├── README_zh.md
│   │   └── main.py
│   ├── playwright/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build.sh
│   │   └── main.py
│   ├── rl-training/
│   │   ├── README.md
│   │   ├── main.py
│   │   └── requirements.txt
│   └── vscode/
│       ├── Dockerfile
│       ├── README.md
│       ├── build.sh
│       └── main.py
├── kubernetes/
│   ├── .golangci.yml
│   ├── Dockerfile
│   ├── Dockerfile.debug
│   ├── Makefile
│   ├── PROJECT
│   ├── README-ZH.md
│   ├── README.md
│   ├── apis/
│   │   └── sandbox/
│   │       └── v1alpha1/
│   │           ├── batchsandbox_types.go
│   │           ├── doc.go
│   │           ├── groupversion_info.go
│   │           ├── pool_types.go
│   │           └── zz_generated.deepcopy.go
│   ├── build.sh
│   ├── charts/
│   │   ├── opensandbox-controller/
│   │   │   ├── .helmignore
│   │   │   ├── Chart.yaml
│   │   │   ├── README.md
│   │   │   ├── templates/
│   │   │   │   ├── NOTES.txt
│   │   │   │   ├── _helpers.tpl
│   │   │   │   ├── clusterrole.yaml
│   │   │   │   ├── clusterrolebinding.yaml
│   │   │   │   ├── crds/
│   │   │   │   │   ├── batchsandboxes.yaml
│   │   │   │   │   └── pools.yaml
│   │   │   │   ├── deployment.yaml
│   │   │   │   └── serviceaccount.yaml
│   │   │   └── values.yaml
│   │   └── opensandbox-server/
│   │       ├── .helmignore
│   │       ├── Chart.yaml
│   │       ├── README.md
│   │       ├── templates/
│   │       │   ├── NOTES.txt
│   │       │   ├── _helpers.tpl
│   │       │   ├── ingress-gateway.yaml
│   │       │   └── server.yaml
│   │       └── values.yaml
│   ├── cmd/
│   │   ├── controller/
│   │   │   └── main.go
│   │   └── task-executor/
│   │       └── main.go
│   ├── config/
│   │   ├── crd/
│   │   │   ├── bases/
│   │   │   │   ├── sandbox.opensandbox.io_batchsandboxes.yaml
│   │   │   │   └── sandbox.opensandbox.io_pools.yaml
│   │   │   ├── kustomization.yaml
│   │   │   └── kustomizeconfig.yaml
│   │   ├── default/
│   │   │   ├── cert_metrics_manager_patch.yaml
│   │   │   ├── kustomization.yaml
│   │   │   ├── manager_metrics_patch.yaml
│   │   │   └── metrics_service.yaml
│   │   ├── manager/
│   │   │   ├── kustomization.yaml
│   │   │   └── manager.yaml
│   │   ├── manifests/
│   │   │   └── kustomization.yaml
│   │   ├── network-policy/
│   │   │   ├── allow-metrics-traffic.yaml
│   │   │   └── kustomization.yaml
│   │   ├── prometheus/
│   │   │   ├── kustomization.yaml
│   │   │   ├── monitor.yaml
│   │   │   └── monitor_tls_patch.yaml
│   │   ├── rbac/
│   │   │   ├── batchsandbox_admin_role.yaml
│   │   │   ├── batchsandbox_editor_role.yaml
│   │   │   ├── batchsandbox_viewer_role.yaml
│   │   │   ├── kustomization.yaml
│   │   │   ├── leader_election_role.yaml
│   │   │   ├── leader_election_role_binding.yaml
│   │   │   ├── metrics_auth_role.yaml
│   │   │   ├── metrics_auth_role_binding.yaml
│   │   │   ├── metrics_reader_role.yaml
│   │   │   ├── pool_admin_role.yaml
│   │   │   ├── pool_editor_role.yaml
│   │   │   ├── pool_viewer_role.yaml
│   │   │   ├── role.yaml
│   │   │   ├── role_binding.yaml
│   │   │   └── service_account.yaml
│   │   ├── samples/
│   │   │   ├── kustomization.yaml
│   │   │   ├── sandbox_v1alpha1_batchsandbox-with-task.yaml
│   │   │   ├── sandbox_v1alpha1_batchsandbox.yaml
│   │   │   ├── sandbox_v1alpha1_pool.yaml
│   │   │   └── sandbox_v1alpha1_pooled_batchsandbox.yaml
│   │   └── scorecard/
│   │       ├── bases/
│   │       │   └── config.yaml
│   │       ├── kustomization.yaml
│   │       └── patches/
│   │           ├── basic.config.yaml
│   │           └── olm.config.yaml
│   ├── docs/
│   │   ├── BUILD-IMAGES.md
│   │   ├── HELM-DEPLOYMENT.md
│   │   └── logging.md
│   ├── examples/
│   │   ├── controller/
│   │   │   ├── README-ZH.md
│   │   │   ├── README.md
│   │   │   └── main.go
│   │   └── task-executor/
│   │       ├── README.md
│   │       ├── README_zh-CN.md
│   │       └── main.go
│   ├── go.mod
│   ├── go.sum
│   ├── hack/
│   │   ├── boilerplate.go.txt
│   │   ├── debug-task.sh
│   │   ├── pool-perf.py
│   │   └── update-codegen.sh
│   ├── internal/
│   │   ├── controller/
│   │   │   ├── allocator.go
│   │   │   ├── allocator_mock.go
│   │   │   ├── allocator_test.go
│   │   │   ├── apis.go
│   │   │   ├── batchsandbox_controller.go
│   │   │   ├── batchsandbox_controller_test.go
│   │   │   ├── pool_controller.go
│   │   │   ├── pool_controller_test.go
│   │   │   ├── strategy/
│   │   │   │   ├── pool_strategy.go
│   │   │   │   ├── pool_strategy_default.go
│   │   │   │   ├── pool_strategy_factory.go
│   │   │   │   ├── pool_strategy_test.go
│   │   │   │   ├── task_scheduling_strategy.go
│   │   │   │   ├── task_scheduling_strategy_default.go
│   │   │   │   ├── task_scheduling_strategy_default_test.go
│   │   │   │   └── task_scheduling_strategy_factory.go
│   │   │   └── suite_test.go
│   │   ├── scheduler/
│   │   │   ├── default_scheduler.go
│   │   │   ├── default_scheduler_mock.go
│   │   │   ├── default_scheduler_test.go
│   │   │   ├── interface.go
│   │   │   ├── mock/
│   │   │   │   ├── interface.go
│   │   │   │   └── types.go
│   │   │   ├── recovery.go
│   │   │   ├── recovery_test.go
│   │   │   ├── status_collector.go
│   │   │   ├── status_collector_mock.go
│   │   │   └── types.go
│   │   ├── task-executor/
│   │   │   ├── config/
│   │   │   │   └── config.go
│   │   │   ├── manager/
│   │   │   │   ├── interface.go
│   │   │   │   ├── task_manager.go
│   │   │   │   └── task_manager_test.go
│   │   │   ├── runtime/
│   │   │   │   ├── composite.go
│   │   │   │   ├── container.go
│   │   │   │   ├── interface.go
│   │   │   │   ├── process.go
│   │   │   │   └── process_test.go
│   │   │   ├── server/
│   │   │   │   ├── handler.go
│   │   │   │   ├── handler_test.go
│   │   │   │   └── router.go
│   │   │   ├── storage/
│   │   │   │   ├── file_store.go
│   │   │   │   ├── file_store_test.go
│   │   │   │   └── interface.go
│   │   │   ├── types/
│   │   │   │   └── task.go
│   │   │   └── utils/
│   │   │       ├── pathutil.go
│   │   │       └── pathutil_test.go
│   │   └── utils/
│   │       ├── controller/
│   │       │   └── util.go
│   │       ├── expectations/
│   │       │   ├── init.go
│   │       │   ├── resource_version_expectation.go
│   │       │   ├── resource_version_expectation_test.go
│   │       │   ├── scale_expectations.go
│   │       │   └── scale_expectations_test.go
│   │       ├── fieldindex/
│   │       │   └── register.go
│   │       ├── finalizer.go
│   │       ├── helper.go
│   │       ├── json.go
│   │       ├── logging/
│   │       │   └── logger.go
│   │       ├── pod.go
│   │       ├── pod_test.go
│   │       └── requeueduration/
│   │           └── duration.go
│   ├── pkg/
│   │   ├── client/
│   │   │   ├── clientset/
│   │   │   │   └── versioned/
│   │   │   │       ├── clientset.go
│   │   │   │       ├── fake/
│   │   │   │       │   ├── clientset_generated.go
│   │   │   │       │   ├── doc.go
│   │   │   │       │   └── register.go
│   │   │   │       ├── scheme/
│   │   │   │       │   ├── doc.go
│   │   │   │       │   └── register.go
│   │   │   │       └── typed/
│   │   │   │           └── sandbox/
│   │   │   │               └── v1alpha1/
│   │   │   │                   ├── batchsandbox.go
│   │   │   │                   ├── doc.go
│   │   │   │                   ├── fake/
│   │   │   │                   │   ├── doc.go
│   │   │   │                   │   ├── fake_batchsandbox.go
│   │   │   │                   │   ├── fake_pool.go
│   │   │   │                   │   └── fake_sandbox_client.go
│   │   │   │                   ├── generated_expansion.go
│   │   │   │                   ├── pool.go
│   │   │   │                   └── sandbox_client.go
│   │   │   ├── informers/
│   │   │   │   └── externalversions/
│   │   │   │       ├── factory.go
│   │   │   │       ├── generic.go
│   │   │   │       ├── internalinterfaces/
│   │   │   │       │   └── factory_interfaces.go
│   │   │   │       └── sandbox/
│   │   │   │           ├── interface.go
│   │   │   │           └── v1alpha1/
│   │   │   │               ├── batchsandbox.go
│   │   │   │               ├── interface.go
│   │   │   │               └── pool.go
│   │   │   └── listers/
│   │   │       └── sandbox/
│   │   │           └── v1alpha1/
│   │   │               ├── batchsandbox.go
│   │   │               ├── expansion_generated.go
│   │   │               └── pool.go
│   │   ├── task-executor/
│   │   │   ├── client.go
│   │   │   └── types.go
│   │   └── utils/
│   │       ├── endpoints.go
│   │       └── endpoints_test.go
│   └── test/
│       ├── e2e/
│       │   ├── e2e_suite_test.go
│       │   ├── e2e_test.go
│       │   └── testdata/
│       │       ├── batchsandbox-non-pooled-expire.yaml
│       │       ├── batchsandbox-non-pooled.yaml
│       │       ├── batchsandbox-pooled-no-expire.yaml
│       │       ├── batchsandbox-pooled.yaml
│       │       ├── batchsandbox-with-process-task.yaml
│       │       ├── pool-basic.yaml
│       │       ├── pool-with-env.yaml
│       │       ├── pool-with-task-executor.yaml
│       │       └── runtimeclass/
│       │           └── gvisor.yaml
│       ├── e2e_runtime/
│       │   └── gvisor/
│       │       ├── gvisor_test.go
│       │       ├── suite_test.go
│       │       └── testdata/
│       │           ├── gvisor.yaml.tmpl
│       │           └── runtimeclass.yaml
│       ├── e2e_task/
│       │   ├── suite_test.go
│       │   └── task_e2e_test.go
│       └── utils/
│           ├── image.go
│           └── utils.go
├── oseps/
│   ├── 0001-fqdn-based-egress-control.md
│   ├── 0002-kubernetes-sigs-agent-sandbox-support.md
│   ├── 0003-volume-and-volumebinding-support.md
│   ├── 0004-secure-container-runtime.md
│   ├── 0005-client-side-sandbox-pool.md
│   ├── 0006-developer-console.md
│   ├── 0007-fast-sandbox-runtime-support.md
│   ├── 0008-pause-resume-rootfs-snapshot.md
│   ├── 0009-auto-renew-sandbox-on-ingress-access.md
│   ├── 0010-opentelemetry-instrumentation.md
│   ├── CONTRIBUTING.md
│   ├── README.md
│   ├── init-osep.sh
│   └── osep-template.md.template
├── sandboxes/
│   └── code-interpreter/
│       ├── Dockerfile
│       ├── Dockerfile_base
│       ├── README.md
│       ├── README_zh.md
│       ├── build.sh
│       └── scripts/
│           ├── code-interpreter-env.sh
│           ├── code-interpreter.sh
│           └── jupyter_notebook_config.py
├── scripts/
│   ├── add-license.sh
│   ├── bump-component-version.sh
│   ├── csharp-e2e.sh
│   ├── java-e2e.sh
│   ├── javascript-e2e.sh
│   ├── python-e2e.sh
│   ├── spec-doc/
│   │   ├── generate-spec.js
│   │   └── index.html
│   └── verify-license.sh
├── sdks/
│   ├── Directory.Build.props
│   ├── code-interpreter/
│   │   ├── csharp/
│   │   │   ├── OpenSandbox.CodeInterpreter.sln
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── src/
│   │   │   │   └── OpenSandbox.CodeInterpreter/
│   │   │   │       ├── Adapters/
│   │   │   │       │   └── CodesAdapter.cs
│   │   │   │       ├── CodeInterpreter.cs
│   │   │   │       ├── Factory/
│   │   │   │       │   ├── DefaultCodeInterpreterAdapterFactory.cs
│   │   │   │       │   └── ICodeInterpreterAdapterFactory.cs
│   │   │   │       ├── Models/
│   │   │   │       │   └── CodeModels.cs
│   │   │   │       ├── OpenSandbox.CodeInterpreter.csproj
│   │   │   │       └── Services/
│   │   │   │           └── ICodes.cs
│   │   │   └── tests/
│   │   │       └── OpenSandbox.CodeInterpreter.Tests/
│   │   │           ├── CodeInterpreterTests.cs
│   │   │           ├── CodesAdapterTests.cs
│   │   │           ├── FactoryTests.cs
│   │   │           ├── ModelsTests.cs
│   │   │           └── OpenSandbox.CodeInterpreter.Tests.csproj
│   │   ├── javascript/
│   │   │   ├── .nvmrc
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── eslint.config.mjs
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── adapters/
│   │   │   │   │   ├── codesAdapter.ts
│   │   │   │   │   ├── openapiError.ts
│   │   │   │   │   └── sse.ts
│   │   │   │   ├── factory/
│   │   │   │   │   ├── adapterFactory.ts
│   │   │   │   │   └── defaultAdapterFactory.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interpreter.ts
│   │   │   │   ├── models.ts
│   │   │   │   └── services/
│   │   │   │       └── codes.ts
│   │   │   ├── tests/
│   │   │   │   ├── defaultAdapterFactory.headers.test.mjs
│   │   │   │   └── interpreter.headers.test.mjs
│   │   │   ├── tsconfig.json
│   │   │   └── tsup.config.ts
│   │   ├── kotlin/
│   │   │   ├── LICENSE
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── build.gradle.kts
│   │   │   ├── code-interpreter/
│   │   │   │   ├── build.gradle.kts
│   │   │   │   └── src/
│   │   │   │       ├── main/
│   │   │   │       │   └── kotlin/
│   │   │   │       │       └── com/
│   │   │   │       │           └── alibaba/
│   │   │   │       │               └── opensandbox/
│   │   │   │       │                   └── codeinterpreter/
│   │   │   │       │                       ├── CodeInterpreter.kt
│   │   │   │       │                       ├── domain/
│   │   │   │       │                       │   ├── models/
│   │   │   │       │                       │   │   └── execd/
│   │   │   │       │                       │   │       └── executions/
│   │   │   │       │                       │   │           └── CodeModels.kt
│   │   │   │       │                       │   └── services/
│   │   │   │       │                       │       └── Codes.kt
│   │   │   │       │                       └── infrastructure/
│   │   │   │       │                           ├── adapters/
│   │   │   │       │                           │   ├── converter/
│   │   │   │       │                           │   │   └── CodeExecutionConverter.kt
│   │   │   │       │                           │   └── service/
│   │   │   │       │                           │       └── CodesAdapter.kt
│   │   │   │       │                           └── factory/
│   │   │   │       │                               └── AdapterFactory.kt
│   │   │   │       └── test/
│   │   │   │           └── kotlin/
│   │   │   │               └── com/
│   │   │   │                   └── alibaba/
│   │   │   │                       └── opensandbox/
│   │   │   │                           └── codeinterpreter/
│   │   │   │                               ├── CodeInterpreterTest.kt
│   │   │   │                               └── infrastructure/
│   │   │   │                                   └── adapters/
│   │   │   │                                       └── service/
│   │   │   │                                           └── CodesAdapterTest.kt
│   │   │   ├── code-interpreter-bom/
│   │   │   │   └── build.gradle.kts
│   │   │   ├── gradle/
│   │   │   │   ├── libs.versions.toml
│   │   │   │   └── wrapper/
│   │   │   │       ├── gradle-wrapper.jar
│   │   │   │       └── gradle-wrapper.properties
│   │   │   ├── gradle.properties
│   │   │   ├── gradlew
│   │   │   └── settings.gradle.kts
│   │   └── python/
│   │       ├── LICENSE
│   │       ├── Makefile
│   │       ├── README.md
│   │       ├── README_zh.md
│   │       ├── pyproject.toml
│   │       ├── src/
│   │       │   └── code_interpreter/
│   │       │       ├── __init__.py
│   │       │       ├── adapters/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── code_adapter.py
│   │       │       │   ├── converter/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   └── code_execution_converter.py
│   │       │       │   └── factory.py
│   │       │       ├── code_interpreter.py
│   │       │       ├── models/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── code.py
│   │       │       │   └── code_sync.py
│   │       │       ├── py.typed
│   │       │       ├── services/
│   │       │       │   ├── __init__.py
│   │       │       │   └── code.py
│   │       │       └── sync/
│   │       │           ├── __init__.py
│   │       │           ├── adapters/
│   │       │           │   ├── __init__.py
│   │       │           │   ├── code_adapter.py
│   │       │           │   └── factory.py
│   │       │           ├── code_interpreter.py
│   │       │           └── services/
│   │       │               ├── __init__.py
│   │       │               └── code.py
│   │       └── tests/
│   │           ├── test_adapter_eager_init.py
│   │           ├── test_code_interpreter_create_and_delegation.py
│   │           ├── test_code_service_adapter_openapi_calls.py
│   │           └── test_code_service_adapter_streaming.py
│   ├── eslint.base.mjs
│   ├── mcp/
│   │   └── sandbox/
│   │       └── python/
│   │           ├── LICENSE
│   │           ├── README.md
│   │           ├── README_zh.md
│   │           ├── pyproject.toml
│   │           └── src/
│   │               └── opensandbox_mcp/
│   │                   ├── __init__.py
│   │                   ├── __main__.py
│   │                   ├── py.typed
│   │                   └── server.py
│   ├── package.json
│   ├── pnpm-workspace.yaml
│   ├── sandbox/
│   │   ├── csharp/
│   │   │   ├── .editorconfig
│   │   │   ├── Directory.Build.props
│   │   │   ├── OpenSandbox.sln
│   │   │   ├── OpenSandbox.sln.DotSettings.user
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── src/
│   │   │   │   └── OpenSandbox/
│   │   │   │       ├── Adapters/
│   │   │   │       │   ├── CommandsAdapter.cs
│   │   │   │       │   ├── EgressAdapter.cs
│   │   │   │       │   ├── FilesystemAdapter.cs
│   │   │   │       │   ├── HealthAdapter.cs
│   │   │   │       │   ├── MetricsAdapter.cs
│   │   │   │       │   ├── SandboxesAdapter.cs
│   │   │   │       │   └── SseParser.cs
│   │   │   │       ├── Config/
│   │   │   │       │   ├── ConnectionConfig.cs
│   │   │   │       │   └── DiagnosticsOptions.cs
│   │   │   │       ├── Core/
│   │   │   │       │   ├── Constants.cs
│   │   │   │       │   └── Exceptions.cs
│   │   │   │       ├── Factory/
│   │   │   │       │   ├── DefaultAdapterFactory.cs
│   │   │   │       │   └── IAdapterFactory.cs
│   │   │   │       ├── HttpClientProvider.cs
│   │   │   │       ├── Internal/
│   │   │   │       │   ├── ExecutionEventDispatcher.cs
│   │   │   │       │   └── HttpClientWrapper.cs
│   │   │   │       ├── Models/
│   │   │   │       │   ├── Execd.cs
│   │   │   │       │   ├── Execution.cs
│   │   │   │       │   ├── Filesystem.cs
│   │   │   │       │   └── Sandboxes.cs
│   │   │   │       ├── OpenSandbox.csproj
│   │   │   │       ├── Options.cs
│   │   │   │       ├── Sandbox.cs
│   │   │   │       ├── SandboxManager.cs
│   │   │   │       └── Services/
│   │   │   │           ├── IEgress.cs
│   │   │   │           ├── IExecdCommands.cs
│   │   │   │           ├── IExecdHealth.cs
│   │   │   │           ├── IExecdMetrics.cs
│   │   │   │           ├── ISandboxFiles.cs
│   │   │   │           └── ISandboxes.cs
│   │   │   └── tests/
│   │   │       └── OpenSandbox.Tests/
│   │   │           ├── CommandsAdapterTests.cs
│   │   │           ├── ConnectionConfigTests.cs
│   │   │           ├── ConstantsTests.cs
│   │   │           ├── ExceptionTests.cs
│   │   │           ├── ModelsTests.cs
│   │   │           ├── OpenSandbox.Tests.csproj
│   │   │           ├── OptionsTests.cs
│   │   │           ├── SandboxEgressLifecycleTests.cs
│   │   │           ├── SandboxReadinessDiagnosticsTests.cs
│   │   │           ├── SandboxesAdapterTests.cs
│   │   │           └── SseParserTests.cs
│   │   ├── javascript/
│   │   │   ├── .nvmrc
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── eslint.config.mjs
│   │   │   ├── package.json
│   │   │   ├── scripts/
│   │   │   │   └── generate-api.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapters/
│   │   │   │   │   ├── commandsAdapter.ts
│   │   │   │   │   ├── egressAdapter.ts
│   │   │   │   │   ├── filesystemAdapter.ts
│   │   │   │   │   ├── healthAdapter.ts
│   │   │   │   │   ├── metricsAdapter.ts
│   │   │   │   │   ├── openapiError.ts
│   │   │   │   │   ├── sandboxesAdapter.ts
│   │   │   │   │   └── sse.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── egress.ts
│   │   │   │   │   ├── execd.ts
│   │   │   │   │   └── lifecycle.ts
│   │   │   │   ├── config/
│   │   │   │   │   └── connection.ts
│   │   │   │   ├── core/
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   └── exceptions.ts
│   │   │   │   ├── factory/
│   │   │   │   │   ├── adapterFactory.ts
│   │   │   │   │   └── defaultAdapterFactory.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── internal.ts
│   │   │   │   ├── manager.ts
│   │   │   │   ├── models/
│   │   │   │   │   ├── execd.ts
│   │   │   │   │   ├── execution.ts
│   │   │   │   │   ├── executionEventDispatcher.ts
│   │   │   │   │   ├── filesystem.ts
│   │   │   │   │   └── sandboxes.ts
│   │   │   │   ├── openapi/
│   │   │   │   │   ├── egressClient.ts
│   │   │   │   │   ├── execdClient.ts
│   │   │   │   │   └── lifecycleClient.ts
│   │   │   │   ├── sandbox.ts
│   │   │   │   └── services/
│   │   │   │       ├── egress.ts
│   │   │   │       ├── execdCommands.ts
│   │   │   │       ├── execdHealth.ts
│   │   │   │       ├── execdMetrics.ts
│   │   │   │       ├── filesystem.ts
│   │   │   │       └── sandboxes.ts
│   │   │   ├── tests/
│   │   │   │   └── sandbox.create.test.mjs
│   │   │   ├── tsconfig.json
│   │   │   └── tsup.config.ts
│   │   ├── kotlin/
│   │   │   ├── LICENSE
│   │   │   ├── README.md
│   │   │   ├── README_zh.md
│   │   │   ├── build.gradle.kts
│   │   │   ├── gradle/
│   │   │   │   ├── libs.versions.toml
│   │   │   │   └── wrapper/
│   │   │   │       ├── gradle-wrapper.jar
│   │   │   │       └── gradle-wrapper.properties
│   │   │   ├── gradle.properties
│   │   │   ├── gradlew
│   │   │   ├── sandbox/
│   │   │   │   ├── Module.md
│   │   │   │   ├── build.gradle.kts
│   │   │   │   └── src/
│   │   │   │       ├── main/
│   │   │   │       │   └── kotlin/
│   │   │   │       │       └── com/
│   │   │   │       │           └── alibaba/
│   │   │   │       │               └── opensandbox/
│   │   │   │       │                   └── sandbox/
│   │   │   │       │                       ├── HttpClientProvider.kt
│   │   │   │       │                       ├── Sandbox.kt
│   │   │   │       │                       ├── SandboxManager.kt
│   │   │   │       │                       ├── config/
│   │   │   │       │                       │   └── ConnectionConfig.kt
│   │   │   │       │                       ├── domain/
│   │   │   │       │                       │   ├── exceptions/
│   │   │   │       │                       │   │   └── SandboxException.kt
│   │   │   │       │                       │   ├── models/
│   │   │   │       │                       │   │   ├── execd/
│   │   │   │       │                       │   │   │   ├── Constants.kt
│   │   │   │       │                       │   │   │   ├── executions/
│   │   │   │       │                       │   │   │   │   ├── CommandModels.kt
│   │   │   │       │                       │   │   │   │   ├── ExecutionModels.kt
│   │   │   │       │                       │   │   │   │   └── RunCommandRequest.kt
│   │   │   │       │                       │   │   │   └── filesystem/
│   │   │   │       │                       │   │   │       └── FilesystemModels.kt
│   │   │   │       │                       │   │   └── sandboxes/
│   │   │   │       │                       │   │       └── SandboxModels.kt
│   │   │   │       │                       │   └── services/
│   │   │   │       │                       │       ├── Commands.kt
│   │   │   │       │                       │       ├── Egress.kt
│   │   │   │       │                       │       ├── Filesystem.kt
│   │   │   │       │                       │       ├── Health.kt
│   │   │   │       │                       │       ├── Metrics.kt
│   │   │   │       │                       │       └── Sandboxes.kt
│   │   │   │       │                       └── infrastructure/
│   │   │   │       │                           ├── adapters/
│   │   │   │       │                           │   ├── converter/
│   │   │   │       │                           │   │   ├── ExceptionConverter.kt
│   │   │   │       │                           │   │   ├── ExecutionConverter.kt
│   │   │   │       │                           │   │   ├── ExecutionEventDispatcher.kt
│   │   │   │       │                           │   │   ├── FilesystemConverter.kt
│   │   │   │       │                           │   │   ├── SandboxModelConverter.kt
│   │   │   │       │                           │   │   └── Serializer.kt
│   │   │   │       │                           │   └── service/
│   │   │   │       │                           │       ├── CommandsAdapter.kt
│   │   │   │       │                           │       ├── EgressAdapter.kt
│   │   │   │       │                           │       ├── FilesystemAdapter.kt
│   │   │   │       │                           │       ├── HealthAdapter.kt
│   │   │   │       │                           │       ├── MetricsAdapter.kt
│   │   │   │       │                           │       └── SandboxesAdapter.kt
│   │   │   │       │                           └── factory/
│   │   │   │       │                               └── AdapterFactory.kt
│   │   │   │       └── test/
│   │   │   │           └── kotlin/
│   │   │   │               └── com/
│   │   │   │                   └── alibaba/
│   │   │   │                       └── opensandbox/
│   │   │   │                           └── sandbox/
│   │   │   │                               ├── SandboxManagerTest.kt
│   │   │   │                               ├── SandboxTest.kt
│   │   │   │                               ├── domain/
│   │   │   │                               │   ├── exceptions/
│   │   │   │                               │   │   └── SandboxExceptionCompatibilityTest.kt
│   │   │   │                               │   └── models/
│   │   │   │                               │       └── VolumeModelsTest.kt
│   │   │   │                               └── infrastructure/
│   │   │   │                                   └── adapters/
│   │   │   │                                       └── service/
│   │   │   │                                           ├── CommandsAdapterTest.kt
│   │   │   │                                           └── SandboxesAdapterTest.kt
│   │   │   ├── sandbox-api/
│   │   │   │   ├── build.gradle.kts
│   │   │   │   └── src/
│   │   │   │       └── main/
│   │   │   │           └── kotlin/
│   │   │   │               └── com/
│   │   │   │                   └── alibaba/
│   │   │   │                       └── opensandbox/
│   │   │   │                           └── sandbox/
│   │   │   │                               └── api/
│   │   │   │                                   ├── models/
│   │   │   │                                   │   └── execd/
│   │   │   │                                   │       └── ExecutionModels.kt
│   │   │   │                                   └── openapitools.json
│   │   │   ├── sandbox-bom/
│   │   │   │   └── build.gradle.kts
│   │   │   └── settings.gradle.kts
│   │   └── python/
│   │       ├── LICENSE
│   │       ├── Makefile
│   │       ├── README.md
│   │       ├── README_zh.md
│   │       ├── pyproject.toml
│   │       ├── scripts/
│   │       │   ├── generate_api.py
│   │       │   ├── openapi_egress_config.yaml
│   │       │   ├── openapi_execd_config.yaml
│   │       │   └── openapi_lifecycle_config.yaml
│   │       ├── src/
│   │       │   └── opensandbox/
│   │       │       ├── __init__.py
│   │       │       ├── adapters/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── command_adapter.py
│   │       │       │   ├── converter/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   ├── command_model_converter.py
│   │       │       │   │   ├── event_node.py
│   │       │       │   │   ├── exception_converter.py
│   │       │       │   │   ├── execution_converter.py
│   │       │       │   │   ├── execution_event_dispatcher.py
│   │       │       │   │   ├── filesystem_model_converter.py
│   │       │       │   │   ├── metrics_model_converter.py
│   │       │       │   │   ├── response_handler.py
│   │       │       │   │   └── sandbox_model_converter.py
│   │       │       │   ├── egress_adapter.py
│   │       │       │   ├── factory.py
│   │       │       │   ├── filesystem_adapter.py
│   │       │       │   ├── health_adapter.py
│   │       │       │   ├── metrics_adapter.py
│   │       │       │   └── sandboxes_adapter.py
│   │       │       ├── api/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── egress/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   ├── api/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   └── policy/
│   │       │       │   │   │       ├── __init__.py
│   │       │       │   │   │       ├── get_policy.py
│   │       │       │   │   │       └── patch_policy.py
│   │       │       │   │   ├── client.py
│   │       │       │   │   ├── errors.py
│   │       │       │   │   ├── models/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   ├── network_policy.py
│   │       │       │   │   │   ├── network_policy_default_action.py
│   │       │       │   │   │   ├── network_rule.py
│   │       │       │   │   │   ├── network_rule_action.py
│   │       │       │   │   │   └── policy_status_response.py
│   │       │       │   │   ├── py.typed
│   │       │       │   │   └── types.py
│   │       │       │   ├── execd/
│   │       │       │   │   ├── __init__.py
│   │       │       │   │   ├── api/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   ├── code_interpreting/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   ├── create_code_context.py
│   │       │       │   │   │   │   ├── delete_context.py
│   │       │       │   │   │   │   ├── delete_contexts_by_language.py
│   │       │       │   │   │   │   ├── get_context.py
│   │       │       │   │   │   │   ├── interrupt_code.py
│   │       │       │   │   │   │   ├── list_contexts.py
│   │       │       │   │   │   │   └── run_code.py
│   │       │       │   │   │   ├── command/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   ├── get_background_command_logs.py
│   │       │       │   │   │   │   ├── get_command_status.py
│   │       │       │   │   │   │   ├── interrupt_command.py
│   │       │       │   │   │   │   └── run_command.py
│   │       │       │   │   │   ├── filesystem/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   ├── chmod_files.py
│   │       │       │   │   │   │   ├── download_file.py
│   │       │       │   │   │   │   ├── get_files_info.py
│   │       │       │   │   │   │   ├── make_dirs.py
│   │       │       │   │   │   │   ├── remove_dirs.py
│   │       │       │   │   │   │   ├── remove_files.py
│   │       │       │   │   │   │   ├── rename_files.py
│   │       │       │   │   │   │   ├── replace_content.py
│   │       │       │   │   │   │   ├── search_files.py
│   │       │       │   │   │   │   └── upload_file.py
│   │       │       │   │   │   ├── health/
│   │       │       │   │   │   │   ├── __init__.py
│   │       │       │   │   │   │   └── ping.py
│   │       │       │   │   │   └── metric/
│   │       │       │   │   │       ├── __init__.py
│   │       │       │   │   │       ├── get_metrics.py
│   │       │       │   │   │       └── watch_metrics.py
│   │       │       │   │   ├── client.py
│   │       │       │   │   ├── errors.py
│   │       │       │   │   ├── models/
│   │       │       │   │   │   ├── __init__.py
│   │       │       │   │   │   ├── chmod_files_body.py
│   │       │       │   │   │   ├── code_context.py
│   │       │       │   │   │   ├── code_context_request.py
│   │       │       │   │   │   ├── command_status_response.py
│   │       │       │   │   │   ├── error_response.py
│   │       │       │   │   │   ├── file_info.py
│   │       │       │   │   │   ├── file_metadata.py
│   │       │       │   │   │   ├── get_files_info_response_200.py
│   │       │       │   │   │   ├── make_dirs_body.py
│   │       │       │   │   │   ├── metrics.py
│   │       │       │   │   │   ├── permission.py
│   │       │       │   │   │   ├── rename_file_item.py
│   │       │       │   │   │   ├── replace_content_body.py
│   │       │       │   │   │   ├── replace_file_content_item.py
│   │       │       │   │   │   ├── run_code_request.py
│   │       │       │   │   │   ├── run_command_request.py
│   │       │       │   │   │   ├── run_command_request_envs.py
│   │       │       │   │   │   ├── server_stream_event.py
│   │       │       │   │   │   ├── server_stream_event_error.py
│   │       │       │   │   │   ├── server_stream_event_results.py
│   │       │       │   │   │   ├── server_stream_event_type.py
│   │       │       │   │   │   └── upload_file_body.py
│   │       │       │   │   ├── py.typed
│   │       │       │   │   └── types.py
│   │       │       │   └── lifecycle/
│   │       │       │       ├── __init__.py
│   │       │       │       ├── api/
│   │       │       │       │   ├── __init__.py
│   │       │       │       │   └── sandboxes/
│   │       │       │       │       ├── __init__.py
│   │       │       │       │       ├── delete_sandboxes_sandbox_id.py
│   │       │       │       │       ├── get_sandboxes.py
│   │       │       │       │       ├── get_sandboxes_sandbox_id.py
│   │       │       │       │       ├── get_sandboxes_sandbox_id_endpoints_port.py
│   │       │       │       │       ├── post_sandboxes.py
│   │       │       │       │       ├── post_sandboxes_sandbox_id_pause.py
│   │       │       │       │       ├── post_sandboxes_sandbox_id_renew_expiration.py
│   │       │       │       │       └── post_sandboxes_sandbox_id_resume.py
│   │       │       │       ├── client.py
│   │       │       │       ├── errors.py
│   │       │       │       ├── models/
│   │       │       │       │   ├── __init__.py
│   │       │       │       │   ├── create_sandbox_request.py
│   │       │       │       │   ├── create_sandbox_request_env.py
│   │       │       │       │   ├── create_sandbox_request_extensions.py
│   │       │       │       │   ├── create_sandbox_request_metadata.py
│   │       │       │       │   ├── create_sandbox_response.py
│   │       │       │       │   ├── create_sandbox_response_metadata.py
│   │       │       │       │   ├── endpoint.py
│   │       │       │       │   ├── endpoint_headers.py
│   │       │       │       │   ├── error_response.py
│   │       │       │       │   ├── host.py
│   │       │       │       │   ├── image_spec.py
│   │       │       │       │   ├── image_spec_auth.py
│   │       │       │       │   ├── list_sandboxes_response.py
│   │       │       │       │   ├── network_policy.py
│   │       │       │       │   ├── network_policy_default_action.py
│   │       │       │       │   ├── network_rule.py
│   │       │       │       │   ├── network_rule_action.py
│   │       │       │       │   ├── ossfs.py
│   │       │       │       │   ├── ossfs_version.py
│   │       │       │       │   ├── pagination_info.py
│   │       │       │       │   ├── pvc.py
│   │       │       │       │   ├── renew_sandbox_expiration_request.py
│   │       │       │       │   ├── renew_sandbox_expiration_response.py
│   │       │       │       │   ├── resource_limits.py
│   │       │       │       │   ├── sandbox.py
│   │       │       │       │   ├── sandbox_metadata.py
│   │       │       │       │   ├── sandbox_status.py
│   │       │       │       │   └── volume.py
│   │       │       │       ├── py.typed
│   │       │       │       └── types.py
│   │       │       ├── config/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── connection.py
│   │       │       │   └── connection_sync.py
│   │       │       ├── constants.py
│   │       │       ├── exceptions/
│   │       │       │   ├── __init__.py
│   │       │       │   └── sandbox.py
│   │       │       ├── manager.py
│   │       │       ├── models/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── execd.py
│   │       │       │   ├── execd_sync.py
│   │       │       │   ├── filesystem.py
│   │       │       │   └── sandboxes.py
│   │       │       ├── py.typed
│   │       │       ├── sandbox.py
│   │       │       ├── services/
│   │       │       │   ├── __init__.py
│   │       │       │   ├── command.py
│   │       │       │   ├── egress.py
│   │       │       │   ├── filesystem.py
│   │       │       │   ├── health.py
│   │       │       │   ├── metrics.py
│   │       │       │   └── sandbox.py
│   │       │       └── sync/
│   │       │           ├── __init__.py
│   │       │           ├── adapters/
│   │       │           │   ├── __init__.py
│   │       │           │   ├── command_adapter.py
│   │       │           │   ├── converter/
│   │       │           │   │   ├── __init__.py
│   │       │           │   │   └── execution_event_dispatcher.py
│   │       │           │   ├── egress_adapter.py
│   │       │           │   ├── factory.py
│   │       │           │   ├── filesystem_adapter.py
│   │       │           │   ├── health_adapter.py
│   │       │           │   ├── metrics_adapter.py
│   │       │           │   └── sandboxes_adapter.py
│   │       │           ├── manager.py
│   │       │           ├── sandbox.py
│   │       │           └── services/
│   │       │               ├── __init__.py
│   │       │               ├── command.py
│   │       │               ├── egress.py
│   │       │               ├── filesystem.py
│   │       │               ├── health.py
│   │       │               ├── metrics.py
│   │       │               └── sandbox.py
│   │       └── tests/
│   │           ├── test_adapters_eager_init.py
│   │           ├── test_command_service_adapter_streaming.py
│   │           ├── test_command_service_sse_client_config.py
│   │           ├── test_connection_config.py
│   │           ├── test_connection_config_env_and_timeout.py
│   │           ├── test_converters_and_error_handling.py
│   │           ├── test_filesystem_search_error_handling.py
│   │           ├── test_models_stability.py
│   │           ├── test_sandbox_business_logic.py
│   │           ├── test_sandbox_close_and_connect_validation.py
│   │           ├── test_sandbox_manager_business_logic.py
│   │           ├── test_sandbox_manager_sync_business_logic.py
│   │           ├── test_sandbox_service_adapter_lifecycle.py
│   │           └── test_sandbox_sync_business_logic.py
│   └── tsconfig.base.json
├── server/
│   ├── .python-version
│   ├── DEVELOPMENT.md
│   ├── Dockerfile
│   ├── LICENSE
│   ├── README.md
│   ├── README_zh.md
│   ├── TROUBLESHOOTING.md
│   ├── TROUBLESHOOTING_zh.md
│   ├── build.sh
│   ├── docker-compose.example.yaml
│   ├── example.batchsandbox-template.yaml
│   ├── example.config.k8s.toml
│   ├── example.config.k8s.zh.toml
│   ├── example.config.toml
│   ├── example.config.zh.toml
│   ├── pyproject.toml
│   ├── src/
│   │   ├── __init__.py
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── lifecycle.py
│   │   │   └── schema.py
│   │   ├── cli.py
│   │   ├── config.py
│   │   ├── main.py
│   │   ├── middleware/
│   │   │   ├── __init__.py
│   │   │   ├── auth.py
│   │   │   └── request_id.py
│   │   ├── py.typed
│   │   └── services/
│   │       ├── __init__.py
│   │       ├── constants.py
│   │       ├── docker.py
│   │       ├── endpoint_auth.py
│   │       ├── factory.py
│   │       ├── helpers.py
│   │       ├── k8s/
│   │       │   ├── __init__.py
│   │       │   ├── agent_sandbox_provider.py
│   │       │   ├── agent_sandbox_template.py
│   │       │   ├── batchsandbox_provider.py
│   │       │   ├── batchsandbox_template.py
│   │       │   ├── client.py
│   │       │   ├── egress_helper.py
│   │       │   ├── image_pull_secret_helper.py
│   │       │   ├── informer.py
│   │       │   ├── kubernetes_service.py
│   │       │   ├── provider_factory.py
│   │       │   ├── rate_limiter.py
│   │       │   ├── security_context.py
│   │       │   ├── template_manager.py
│   │       │   ├── volume_helper.py
│   │       │   └── workload_provider.py
│   │       ├── ossfs_mixin.py
│   │       ├── runtime_resolver.py
│   │       ├── sandbox_service.py
│   │       └── validators.py
│   └── tests/
│       ├── __init__.py
│       ├── conftest.py
│       ├── k8s/
│       │   ├── __init__.py
│       │   ├── conftest.py
│       │   ├── fixtures/
│       │   │   ├── __init__.py
│       │   │   └── k8s_fixtures.py
│       │   ├── test_agent_sandbox_provider.py
│       │   ├── test_agent_sandbox_template.py
│       │   ├── test_batchsandbox_provider.py
│       │   ├── test_batchsandbox_template.py
│       │   ├── test_egress_helper.py
│       │   ├── test_image_pull_secret_helper.py
│       │   ├── test_informer.py
│       │   ├── test_k8s_client.py
│       │   ├── test_kubernetes_service.py
│       │   ├── test_provider_factory.py
│       │   └── test_rate_limiter.py
│       ├── smoke.sh
│       ├── test_agent_sandbox_service.py
│       ├── test_auth_middleware.py
│       ├── test_config.py
│       ├── test_docker_endpoint.py
│       ├── test_docker_path_fix.py
│       ├── test_docker_service.py
│       ├── test_endpoint.py
│       ├── test_endpoint_auth.py
│       ├── test_helpers.py
│       ├── test_ingress.py
│       ├── test_routes.py
│       ├── test_routes_create_delete.py
│       ├── test_routes_endpoint_behavior.py
│       ├── test_routes_get_sandbox.py
│       ├── test_routes_list_sandboxes.py
│       ├── test_routes_pause_resume.py
│       ├── test_routes_proxy.py
│       ├── test_routes_renew_expiration.py
│       ├── test_schema.py
│       ├── test_validators.py
│       └── testdata/
│           ├── config.toml
│           └── k8s_config.toml
├── specs/
│   ├── README.md
│   ├── README_zh.md
│   ├── egress-api.yaml
│   ├── execd-api.yaml
│   └── sandbox-lifecycle.yml
└── tests/
    ├── csharp/
    │   └── OpenSandbox.E2ETests/
    │       ├── CodeInterpreterE2ETests.cs
    │       ├── E2ETestFixture.cs
    │       ├── OpenSandbox.E2ETests.csproj
    │       ├── SandboxE2ETests.cs
    │       └── SandboxManagerE2ETests.cs
    ├── java/
    │   ├── build.gradle.kts
    │   ├── gradle/
    │   │   ├── libs.versions.toml
    │   │   └── wrapper/
    │   │       ├── gradle-wrapper.jar
    │   │       └── gradle-wrapper.properties
    │   ├── gradle.properties
    │   ├── gradlew
    │   ├── settings.gradle.kts
    │   └── src/
    │       └── test/
    │           ├── java/
    │           │   └── com/
    │           │       └── alibaba/
    │           │           └── opensandbox/
    │           │               └── e2e/
    │           │                   ├── BaseE2ETest.java
    │           │                   ├── CodeInterpreterE2ETest.java
    │           │                   ├── SandboxE2ETest.java
    │           │                   └── SandboxManagerE2ETest.java
    │           └── resources/
    │               └── test.properties
    ├── javascript/
    │   ├── README.md
    │   ├── eslint.config.mjs
    │   ├── package.json
    │   ├── tests/
    │   │   ├── base_e2e.ts
    │   │   ├── test_code_interpreter_e2e.test.ts
    │   │   ├── test_sandbox_e2e.test.ts
    │   │   ├── test_sandbox_manager_e2e.test.ts
    │   │   └── test_wait_until_ready_diagnostics.test.ts
    │   ├── tsconfig.json
    │   └── vitest.config.ts
    └── python/
        ├── Makefile
        ├── README.md
        ├── pyproject.toml
        └── tests/
            ├── __init__.py
            ├── base_e2e_test.py
            ├── test_code_interpreter_e2e.py
            ├── test_code_interpreter_e2e_sync.py
            ├── test_sandbox_e2e.py
            ├── test_sandbox_e2e_sync.py
            ├── test_sandbox_manager_e2e.py
            └── test_sandbox_manager_e2e_sync.py
Download .txt
Showing preview only (514K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5263 symbols across 634 files)

FILE: cli/src/opensandbox_cli/client.py
  class ClientContext (line 40) | class ClientContext:
    method connection_config (line 53) | def connection_config(self) -> ConnectionConfigSync:
    method get_manager (line 64) | def get_manager(self) -> SandboxManagerSync:
    method resolve_sandbox_id (line 70) | def resolve_sandbox_id(self, prefix: str) -> str:
    method connect_sandbox (line 116) | def connect_sandbox(
    method close (line 127) | def close(self) -> None:

FILE: cli/src/opensandbox_cli/commands/code.py
  function code_group (line 32) | def code_group(ctx: click.Context) -> None:
  function code_run (line 47) | def code_run(
  function context_group (line 97) | def context_group(ctx: click.Context) -> None:
  function context_create (line 108) | def context_create(obj: ClientContext, sandbox_id: str, language: str) -...
  function context_list (line 129) | def context_list(obj: ClientContext, sandbox_id: str, language: str) -> ...
  function context_delete (line 148) | def context_delete(obj: ClientContext, sandbox_id: str, context_id: str)...
  function context_delete_all (line 166) | def context_delete_all(obj: ClientContext, sandbox_id: str, language: st...
  function code_interrupt (line 186) | def code_interrupt(obj: ClientContext, sandbox_id: str, execution_id: st...

FILE: cli/src/opensandbox_cli/commands/command.py
  function command_group (line 34) | def command_group(ctx: click.Context) -> None:
  function _run_command (line 42) | def _run_command(
  function command_run (line 114) | def command_run(
  function command_status (line 133) | def command_status(obj: ClientContext, sandbox_id: str, execution_id: st...
  function command_logs (line 151) | def command_logs(
  function command_interrupt (line 173) | def command_interrupt(obj: ClientContext, sandbox_id: str, execution_id:...
  function exec_cmd (line 193) | def exec_cmd(

FILE: cli/src/opensandbox_cli/commands/config_cmd.py
  function config_group (line 30) | def config_group(ctx: click.Context) -> None:
  function config_init (line 42) | def config_init(force: bool, config_path: Path | None) -> None:
  function config_show (line 67) | def config_show(obj: ClientContext) -> None:
  function config_set (line 79) | def config_set(key: str, value: str, config_path: Path | None) -> None:

FILE: cli/src/opensandbox_cli/commands/file.py
  function file_group (line 30) | def file_group(ctx: click.Context) -> None:
  function file_cat (line 44) | def file_cat(obj: ClientContext, sandbox_id: str, path: str, encoding: s...
  function file_write (line 66) | def file_write(
  function file_upload (line 105) | def file_upload(
  function file_download (line 126) | def file_download(
  function file_rm (line 146) | def file_rm(obj: ClientContext, sandbox_id: str, paths: tuple[str, ...])...
  function file_mv (line 165) | def file_mv(
  function file_mkdir (line 189) | def file_mkdir(
  function file_rmdir (line 226) | def file_rmdir(obj: ClientContext, sandbox_id: str, paths: tuple[str, .....
  function file_search (line 245) | def file_search(
  function file_info (line 275) | def file_info(obj: ClientContext, sandbox_id: str, paths: tuple[str, ......
  function file_chmod (line 299) | def file_chmod(
  function file_replace (line 329) | def file_replace(

FILE: cli/src/opensandbox_cli/commands/sandbox.py
  function sandbox_group (line 32) | def sandbox_group(ctx: click.Context) -> None:
  function sandbox_create (line 56) | def sandbox_create(
  function sandbox_list (line 111) | def sandbox_list(
  function sandbox_get (line 174) | def sandbox_get(obj: ClientContext, sandbox_id: str) -> None:
  function sandbox_kill (line 206) | def sandbox_kill(obj: ClientContext, sandbox_ids: tuple[str, ...]) -> None:
  function sandbox_pause (line 222) | def sandbox_pause(obj: ClientContext, sandbox_id: str) -> None:
  function sandbox_resume (line 237) | def sandbox_resume(obj: ClientContext, sandbox_id: str) -> None:
  function sandbox_renew (line 253) | def sandbox_renew(obj: ClientContext, sandbox_id: str, timeout: timedelt...
  function sandbox_endpoint (line 272) | def sandbox_endpoint(obj: ClientContext, sandbox_id: str, port: int) -> ...
  function sandbox_health (line 288) | def sandbox_health(obj: ClientContext, sandbox_id: str) -> None:
  function sandbox_metrics (line 313) | def sandbox_metrics(obj: ClientContext, sandbox_id: str) -> None:

FILE: cli/src/opensandbox_cli/config.py
  function load_config_file (line 63) | def load_config_file(config_path: Path | None = None) -> dict[str, Any]:
  function resolve_config (line 77) | def resolve_config(
  function init_config_file (line 123) | def init_config_file(config_path: Path | None = None, *, force: bool = F...
  function _int_or_none (line 135) | def _int_or_none(value: str | None) -> int | None:

FILE: cli/src/opensandbox_cli/main.py
  class BannerGroup (line 51) | class BannerGroup(click.Group):
    method format_help (line 54) | def format_help(self, ctx: click.Context, formatter: click.HelpFormatt...
  function cli (line 71) | def cli(

FILE: cli/src/opensandbox_cli/output.py
  function _style_value (line 71) | def _style_value(col: str, value: str) -> Text:
  class OutputFormatter (line 89) | class OutputFormatter:
    method __init__ (line 92) | def __init__(self, fmt: str = "table", *, color: bool = True) -> None:
    method success (line 106) | def success(self, msg: str) -> None:
    method info (line 113) | def info(self, msg: str) -> None:
    method warning (line 120) | def warning(self, msg: str) -> None:
    method error (line 127) | def error(self, msg: str) -> None:
    method error_panel (line 134) | def error_panel(self, msg: str, title: str = "Error") -> None:
    method spinner (line 151) | def spinner(self, msg: str) -> Generator[Status, None, None]:
    method panel (line 164) | def panel(self, content: str, *, title: str | None = None, style: str ...
    method success_panel (line 180) | def success_panel(self, data: dict[str, Any], *, title: str = "Success...
    method print_model (line 205) | def print_model(self, model: BaseModel, title: str | None = None) -> N...
    method print_models (line 215) | def print_models(
    method print_rows (line 231) | def print_rows(
    method print_dict (line 246) | def print_dict(self, data: dict[str, Any], title: str | None = None) -...
    method print_text (line 255) | def print_text(self, text: str) -> None:
    method _print_json (line 263) | def _print_json(self, data: Any) -> None:
    method _print_yaml (line 269) | def _print_yaml(self, data: Any) -> None:
    method _print_kv_table (line 277) | def _print_kv_table(self, data: dict[str, Any], *, title: str | None =...
    method _print_table (line 295) | def _print_table(
  function _model_to_dict (line 337) | def _model_to_dict(model: BaseModel) -> dict[str, Any]:

FILE: cli/src/opensandbox_cli/utils.py
  function parse_duration (line 36) | def parse_duration(value: str) -> timedelta:
  class DurationType (line 62) | class DurationType(click.ParamType):
    method convert (line 67) | def convert(
  class KeyValueType (line 90) | class KeyValueType(click.ParamType):
    method convert (line 95) | def convert(
  function handle_errors (line 114) | def handle_errors(fn):  # type: ignore[no-untyped-def]

FILE: cli/tests/conftest.py
  function runner (line 28) | def runner() -> CliRunner:
  function mock_manager (line 33) | def mock_manager() -> MagicMock:
  function mock_sandbox (line 38) | def mock_sandbox() -> MagicMock:
  function mock_client_context (line 43) | def mock_client_context(mock_manager: MagicMock, mock_sandbox: MagicMock...

FILE: cli/tests/test_cli_help.py
  function runner (line 26) | def runner() -> CliRunner:
  class TestRootCLI (line 35) | class TestRootCLI:
    method test_help (line 36) | def test_help(self, runner: CliRunner) -> None:
    method test_version (line 41) | def test_version(self, runner: CliRunner) -> None:
    method test_root_lists_commands (line 46) | def test_root_lists_commands(self, runner: CliRunner) -> None:
  class TestSandboxHelp (line 57) | class TestSandboxHelp:
    method test_sandbox_help (line 58) | def test_sandbox_help(self, runner: CliRunner) -> None:
    method test_sandbox_subcommand_help (line 68) | def test_sandbox_subcommand_help(self, runner: CliRunner, subcmd: str)...
  class TestCommandHelp (line 79) | class TestCommandHelp:
    method test_command_help (line 80) | def test_command_help(self, runner: CliRunner) -> None:
    method test_command_subcommand_help (line 87) | def test_command_subcommand_help(self, runner: CliRunner, subcmd: str)...
  class TestExecHelp (line 97) | class TestExecHelp:
    method test_exec_help (line 98) | def test_exec_help(self, runner: CliRunner) -> None:
  class TestFileHelp (line 109) | class TestFileHelp:
    method test_file_help (line 110) | def test_file_help(self, runner: CliRunner) -> None:
    method test_file_subcommand_help (line 120) | def test_file_subcommand_help(self, runner: CliRunner, subcmd: str) ->...
  class TestCodeHelp (line 130) | class TestCodeHelp:
    method test_code_help (line 131) | def test_code_help(self, runner: CliRunner) -> None:
    method test_code_context_help (line 137) | def test_code_context_help(self, runner: CliRunner) -> None:
  class TestConfigHelp (line 149) | class TestConfigHelp:
    method test_config_help (line 150) | def test_config_help(self, runner: CliRunner) -> None:
    method test_config_subcommand_help (line 157) | def test_config_subcommand_help(self, runner: CliRunner, subcmd: str) ...

FILE: cli/tests/test_commands.py
  function runner (line 35) | def runner() -> CliRunner:
  function _build_mock_client_context (line 39) | def _build_mock_client_context(
  function _invoke (line 65) | def _invoke(
  class TestConfigInit (line 91) | class TestConfigInit:
    method test_init_creates_file (line 92) | def test_init_creates_file(self, runner: CliRunner, tmp_path: Path) ->...
    method test_init_refuses_overwrite (line 98) | def test_init_refuses_overwrite(self, runner: CliRunner, tmp_path: Pat...
    method test_init_force_overwrites (line 104) | def test_init_force_overwrites(self, runner: CliRunner, tmp_path: Path...
  class TestConfigShow (line 112) | class TestConfigShow:
    method test_show_json_output (line 113) | def test_show_json_output(self, runner: CliRunner) -> None:
    method test_show_table_output (line 119) | def test_show_table_output(self, runner: CliRunner) -> None:
  class TestConfigSet (line 125) | class TestConfigSet:
    method test_set_updates_existing_field (line 126) | def test_set_updates_existing_field(self, runner: CliRunner, tmp_path:...
    method test_set_rejects_flat_key (line 133) | def test_set_rejects_flat_key(self, runner: CliRunner, tmp_path: Path)...
  class TestSandboxList (line 145) | class TestSandboxList:
    method test_list_invokes_manager (line 146) | def test_list_invokes_manager(self, runner: CliRunner) -> None:
  class TestSandboxKill (line 157) | class TestSandboxKill:
    method test_kill_multiple (line 158) | def test_kill_multiple(self, runner: CliRunner) -> None:
  class TestSandboxPause (line 167) | class TestSandboxPause:
    method test_pause_calls_manager (line 168) | def test_pause_calls_manager(self, runner: CliRunner) -> None:
  class TestSandboxResume (line 176) | class TestSandboxResume:
    method test_resume_calls_manager (line 177) | def test_resume_calls_manager(self, runner: CliRunner) -> None:
  class TestFileCat (line 190) | class TestFileCat:
    method test_cat_outputs_content (line 191) | def test_cat_outputs_content(self, runner: CliRunner) -> None:
  class TestFileWrite (line 200) | class TestFileWrite:
    method test_write_with_content_flag (line 201) | def test_write_with_content_flag(self, runner: CliRunner) -> None:
  class TestFileRm (line 213) | class TestFileRm:
    method test_rm_deletes_files (line 214) | def test_rm_deletes_files(self, runner: CliRunner) -> None:
  class TestFileMv (line 223) | class TestFileMv:
    method test_mv_moves_file (line 224) | def test_mv_moves_file(self, runner: CliRunner) -> None:
  class TestFileMkdir (line 233) | class TestFileMkdir:
    method test_mkdir_creates_dirs (line 234) | def test_mkdir_creates_dirs(self, runner: CliRunner) -> None:
  class TestFileRmdir (line 244) | class TestFileRmdir:
    method test_rmdir_removes_dirs (line 245) | def test_rmdir_removes_dirs(self, runner: CliRunner) -> None:
  class TestCommandRun (line 259) | class TestCommandRun:
    method test_background_run (line 260) | def test_background_run(self, runner: CliRunner) -> None:
  class TestExecShortcut (line 277) | class TestExecShortcut:
    method test_exec_passes_to_run (line 278) | def test_exec_passes_to_run(self, runner: CliRunner) -> None:
  class TestCommandInterrupt (line 293) | class TestCommandInterrupt:
    method test_interrupt_calls_sdk (line 294) | def test_interrupt_calls_sdk(self, runner: CliRunner) -> None:

FILE: cli/tests/test_config.py
  class TestLoadConfigFile (line 37) | class TestLoadConfigFile:
    method test_returns_empty_when_file_missing (line 38) | def test_returns_empty_when_file_missing(self, tmp_path: Path) -> None:
    method test_parses_toml_file (line 42) | def test_parses_toml_file(self, tmp_path: Path) -> None:
    method test_parses_all_sections (line 51) | def test_parses_all_sections(self, tmp_path: Path) -> None:
  class TestResolveConfig (line 70) | class TestResolveConfig:
    method test_defaults_when_nothing_configured (line 71) | def test_defaults_when_nothing_configured(self, tmp_path: Path) -> None:
    method test_file_values_override_defaults (line 82) | def test_file_values_override_defaults(self, tmp_path: Path) -> None:
    method test_env_overrides_file (line 100) | def test_env_overrides_file(self, tmp_path: Path, monkeypatch: pytest....
    method test_cli_overrides_everything (line 117) | def test_cli_overrides_everything(self, tmp_path: Path, monkeypatch: p...
    method test_invalid_timeout_env_falls_through (line 136) | def test_invalid_timeout_env_falls_through(self, tmp_path: Path, monke...
  class TestInitConfigFile (line 150) | class TestInitConfigFile:
    method test_creates_default_config (line 151) | def test_creates_default_config(self, tmp_path: Path) -> None:
    method test_refuses_overwrite_without_force (line 161) | def test_refuses_overwrite_without_force(self, tmp_path: Path) -> None:
    method test_force_overwrites (line 167) | def test_force_overwrites(self, tmp_path: Path) -> None:
    method test_creates_parent_directories (line 173) | def test_creates_parent_directories(self, tmp_path: Path) -> None:

FILE: cli/tests/test_output.py
  class FakeItem (line 32) | class FakeItem(BaseModel):
  class TestJsonOutput (line 43) | class TestJsonOutput:
    method test_print_dict (line 44) | def test_print_dict(self, capsys: pytest.CaptureFixture[str]) -> None:
    method test_print_model (line 51) | def test_print_model(self, capsys: pytest.CaptureFixture[str]) -> None:
    method test_print_models (line 61) | def test_print_models(self, capsys: pytest.CaptureFixture[str]) -> None:
  class TestYamlOutput (line 80) | class TestYamlOutput:
    method test_print_dict (line 81) | def test_print_dict(self, capsys: pytest.CaptureFixture[str]) -> None:
    method test_print_model (line 87) | def test_print_model(self, capsys: pytest.CaptureFixture[str]) -> None:
  class TestTableOutput (line 102) | class TestTableOutput:
    method test_print_dict_contains_values (line 103) | def test_print_dict_contains_values(self, capsys: pytest.CaptureFixtur...
    method test_print_dict_none_renders_dash (line 111) | def test_print_dict_none_renders_dash(self, capsys: pytest.CaptureFixt...
    method test_print_models_shows_headers (line 117) | def test_print_models_shows_headers(self, capsys: pytest.CaptureFixtur...
    method test_print_text_ignores_format (line 126) | def test_print_text_ignores_format(self, capsys: pytest.CaptureFixture...

FILE: cli/tests/test_resolve_id.py
  function _make_sandbox_info (line 28) | def _make_sandbox_info(sandbox_id: str) -> MagicMock:
  function _make_paged_result (line 35) | def _make_paged_result(
  function _make_client_context (line 46) | def _make_client_context(
  class TestResolveSandboxId (line 83) | class TestResolveSandboxId:
    method test_full_uuid_skips_listing (line 86) | def test_full_uuid_skips_listing(self) -> None:
    method test_unique_prefix_resolves (line 94) | def test_unique_prefix_resolves(self) -> None:
    method test_exact_match_among_multiple (line 103) | def test_exact_match_among_multiple(self) -> None:
    method test_ambiguous_prefix_raises (line 113) | def test_ambiguous_prefix_raises(self) -> None:
    method test_ambiguous_error_shows_ids (line 123) | def test_ambiguous_error_shows_ids(self) -> None:
    method test_no_match_raises (line 131) | def test_no_match_raises(self) -> None:
    method test_empty_sandbox_list_raises (line 137) | def test_empty_sandbox_list_raises(self) -> None:
    method test_single_char_prefix (line 143) | def test_single_char_prefix(self) -> None:
    method test_full_id_matches_exactly (line 152) | def test_full_id_matches_exactly(self) -> None:
    method test_more_than_five_ambiguous_shows_ellipsis (line 158) | def test_more_than_five_ambiguous_shows_ellipsis(self) -> None:
    method test_match_on_second_page (line 169) | def test_match_on_second_page(self) -> None:
    method test_collision_across_pages (line 181) | def test_collision_across_pages(self) -> None:
    method test_no_match_across_all_pages (line 193) | def test_no_match_across_all_pages(self) -> None:

FILE: cli/tests/test_utils.py
  class TestParseDuration (line 32) | class TestParseDuration:
    method test_valid_durations (line 46) | def test_valid_durations(self, input_str: str, expected: timedelta) ->...
    method test_invalid_durations (line 59) | def test_invalid_durations(self, input_str: str) -> None:
    method test_strips_whitespace (line 63) | def test_strips_whitespace(self) -> None:
  class TestDurationType (line 72) | class TestDurationType:
    method test_converts_string (line 73) | def test_converts_string(self) -> None:
    method test_passes_through_timedelta (line 77) | def test_passes_through_timedelta(self) -> None:
    method test_invalid_raises_bad_parameter (line 82) | def test_invalid_raises_bad_parameter(self) -> None:
  class TestKeyValueType (line 92) | class TestKeyValueType:
    method test_parses_simple_kv (line 93) | def test_parses_simple_kv(self) -> None:
    method test_value_can_contain_equals (line 96) | def test_value_can_contain_equals(self) -> None:
    method test_empty_value (line 99) | def test_empty_value(self) -> None:
    method test_missing_equals_fails (line 102) | def test_missing_equals_fails(self) -> None:
    method test_passes_through_tuple (line 106) | def test_passes_through_tuple(self) -> None:

FILE: components/egress/main.go
  function main (line 34) | func main() {
  function withLogger (line 99) | func withLogger(ctx context.Context) context.Context {
  function envOrDefault (line 105) | func envOrDefault(key, defaultVal string) string {
  function isTruthy (line 112) | func isTruthy(v string) bool {
  function containsAddr (line 121) | func containsAddr(addrs []netip.Addr, a netip.Addr) bool {
  function parseMode (line 130) | func parseMode() string {

FILE: components/egress/nameserver.go
  function AllowIPsForNft (line 31) | func AllowIPsForNft(resolvPath string) []netip.Addr {
  function maxNameserversFromEnv (line 59) | func maxNameserversFromEnv() int {
  function isValidNameserverIP (line 75) | func isValidNameserverIP(ip netip.Addr) bool {
  function formatIPs (line 85) | func formatIPs(ips []netip.Addr) []string {

FILE: components/egress/nameserver_test.go
  function TestAllowIPsForNft_EmptyResolv (line 27) | func TestAllowIPsForNft_EmptyResolv(t *testing.T) {
  function TestAllowIPsForNft_ValidNameservers (line 36) | func TestAllowIPsForNft_ValidNameservers(t *testing.T) {
  function TestAllowIPsForNft_FiltersInvalid (line 49) | func TestAllowIPsForNft_FiltersInvalid(t *testing.T) {
  function TestAllowIPsForNft_Cap (line 61) | func TestAllowIPsForNft_Cap(t *testing.T) {
  function TestIsValidNameserverIP (line 77) | func TestIsValidNameserverIP(t *testing.T) {
  function TestMaxNameserversFromEnv (line 100) | func TestMaxNameserversFromEnv(t *testing.T) {

FILE: components/egress/nft.go
  function createNftManager (line 31) | func createNftManager(mode string) nftApplier {
  function setupNft (line 40) | func setupNft(ctx context.Context, nftMgr nftApplier, initialPolicy *pol...
  function parseNftOptions (line 58) | func parseNftOptions() nftables.Options {

FILE: components/egress/pkg/constants/configuration.go
  constant EnvBlockDoH443 (line 18) | EnvBlockDoH443    = "OPENSANDBOX_EGRESS_BLOCK_DOH_443"
  constant EnvDoHBlocklist (line 19) | EnvDoHBlocklist   = "OPENSANDBOX_EGRESS_DOH_BLOCKLIST"
  constant EnvEgressMode (line 20) | EnvEgressMode     = "OPENSANDBOX_EGRESS_MODE"
  constant EnvEgressHTTPAddr (line 21) | EnvEgressHTTPAddr = "OPENSANDBOX_EGRESS_HTTP_ADDR"
  constant EnvEgressToken (line 22) | EnvEgressToken    = "OPENSANDBOX_EGRESS_TOKEN"
  constant EnvEgressRules (line 23) | EnvEgressRules    = "OPENSANDBOX_EGRESS_RULES"
  constant EnvEgressLogLevel (line 24) | EnvEgressLogLevel = "OPENSANDBOX_EGRESS_LOG_LEVEL"
  constant EnvMaxNameservers (line 25) | EnvMaxNameservers = "OPENSANDBOX_EGRESS_MAX_NS"
  constant EnvBlockedWebhook (line 26) | EnvBlockedWebhook = "OPENSANDBOX_EGRESS_DENY_WEBHOOK"
  constant ENVSandboxID (line 27) | ENVSandboxID      = "OPENSANDBOX_EGRESS_SANDBOX_ID"
  constant EnvNameserverExempt (line 30) | EnvNameserverExempt = "OPENSANDBOX_EGRESS_NAMESERVER_EXEMPT"
  constant PolicyDnsOnly (line 34) | PolicyDnsOnly = "dns"
  constant PolicyDnsNft (line 35) | PolicyDnsNft  = "dns+nft"
  constant DefaultEgressServerAddr (line 39) | DefaultEgressServerAddr = ":18080"
  constant DefaultMaxNameservers (line 40) | DefaultMaxNameservers   = 3

FILE: components/egress/pkg/constants/constants.go
  constant MarkValue (line 18) | MarkValue = 0x1
  constant MarkHex (line 19) | MarkHex   = "0x1"
  constant EgressAuthTokenHeader (line 23) | EgressAuthTokenHeader = "OPENSANDBOX-EGRESS-AUTH"

FILE: components/egress/pkg/dnsproxy/exempt.go
  function ParseNameserverExemptList (line 34) | func ParseNameserverExemptList() []netip.Addr {
  function parseNameserverExemptListUncached (line 39) | func parseNameserverExemptListUncached() {
  function UpstreamInExemptList (line 67) | func UpstreamInExemptList(upstreamHost string) bool {

FILE: components/egress/pkg/dnsproxy/exempt_test.go
  function resetNameserverExemptCache (line 26) | func resetNameserverExemptCache(t *testing.T) {
  function TestParseNameserverExemptList_IPOnly (line 33) | func TestParseNameserverExemptList_IPOnly(t *testing.T) {
  function TestUpstreamInExemptList_IPOnly (line 45) | func TestUpstreamInExemptList_IPOnly(t *testing.T) {
  function TestUpstreamInExemptList_CIDRIgnored (line 55) | func TestUpstreamInExemptList_CIDRIgnored(t *testing.T) {

FILE: components/egress/pkg/dnsproxy/proxy.go
  constant defaultListenAddr (line 35) | defaultListenAddr = "127.0.0.1:15353"
  type Proxy (line 37) | type Proxy struct
    method Start (line 71) | func (p *Proxy) Start(ctx context.Context) error {
    method serveDNS (line 105) | func (p *Proxy) serveDNS(w dns.ResponseWriter, r *dns.Msg) {
    method maybeNotifyResolved (line 138) | func (p *Proxy) maybeNotifyResolved(domain string, resp *dns.Msg) {
    method forward (line 149) | func (p *Proxy) forward(r *dns.Msg) (*dns.Msg, error) {
    method UpstreamHost (line 159) | func (p *Proxy) UpstreamHost() string {
    method UpdatePolicy (line 169) | func (p *Proxy) UpdatePolicy(newPolicy *policy.NetworkPolicy) {
    method CurrentPolicy (line 176) | func (p *Proxy) CurrentPolicy() *policy.NetworkPolicy {
    method SetOnResolved (line 184) | func (p *Proxy) SetOnResolved(fn func(domain string, ips []nftables.Re...
    method SetBlockedBroadcaster (line 189) | func (p *Proxy) SetBlockedBroadcaster(b *events.Broadcaster) {
    method publishBlocked (line 193) | func (p *Proxy) publishBlocked(domain string) {
  function New (line 52) | func New(p *policy.NetworkPolicy, listenAddr string) (*Proxy, error) {
  function extractResolvedIPs (line 212) | func extractResolvedIPs(resp *dns.Msg) []nftables.ResolvedIP {
  constant fallbackUpstream (line 243) | fallbackUpstream = "8.8.8.8:53"
  function discoverUpstream (line 245) | func discoverUpstream() (string, error) {
  function ResolvNameserverIPs (line 275) | func ResolvNameserverIPs(resolvPath string) ([]netip.Addr, error) {
  function LoadPolicyFromEnvVar (line 292) | func LoadPolicyFromEnvVar(envName string) (*policy.NetworkPolicy, error) {
  function ensurePolicyDefaults (line 300) | func ensurePolicyDefaults(p *policy.NetworkPolicy) *policy.NetworkPolicy {

FILE: components/egress/pkg/dnsproxy/proxy_linux.go
  method dialerWithMark (line 37) | func (p *Proxy) dialerWithMark() *net.Dialer {

FILE: components/egress/pkg/dnsproxy/proxy_other.go
  method dialerWithMark (line 25) | func (p *Proxy) dialerWithMark() *net.Dialer {

FILE: components/egress/pkg/dnsproxy/proxy_test.go
  function TestProxyUpdatePolicy (line 29) | func TestProxyUpdatePolicy(t *testing.T) {
  function TestLoadPolicyFromEnvVar (line 48) | func TestLoadPolicyFromEnvVar(t *testing.T) {
  function TestExtractResolvedIPs (line 64) | func TestExtractResolvedIPs(t *testing.T) {
  function TestExtractResolvedIPs_EmptyOrNil (line 82) | func TestExtractResolvedIPs_EmptyOrNil(t *testing.T) {
  function TestSetOnResolved (line 90) | func TestSetOnResolved(t *testing.T) {
  function TestMaybeNotifyResolved_CallsCallbackWhenAOrAAAA (line 109) | func TestMaybeNotifyResolved_CallsCallbackWhenAOrAAAA(t *testing.T) {
  function TestMaybeNotifyResolved_NoCallWhenOnResolvedNil (line 139) | func TestMaybeNotifyResolved_NoCallWhenOnResolvedNil(t *testing.T) {
  function TestMaybeNotifyResolved_NoCallWhenNoAOrAAAA (line 148) | func TestMaybeNotifyResolved_NoCallWhenNoAOrAAAA(t *testing.T) {

FILE: components/egress/pkg/events/broadcaster.go
  constant defaultQueueSize (line 26) | defaultQueueSize = 128
  type BlockedEvent (line 29) | type BlockedEvent struct
  type Subscriber (line 35) | type Subscriber interface
  type BroadcasterConfig (line 40) | type BroadcasterConfig struct
  type Broadcaster (line 45) | type Broadcaster struct
    method AddSubscriber (line 69) | func (b *Broadcaster) AddSubscriber(sub Subscriber) {
    method Publish (line 95) | func (b *Broadcaster) Publish(event BlockedEvent) {
    method Close (line 113) | func (b *Broadcaster) Close() {
  function NewBroadcaster (line 56) | func NewBroadcaster(ctx context.Context, cfg BroadcasterConfig) *Broadca...

FILE: components/egress/pkg/events/events_test.go
  type captureSubscriber (line 30) | type captureSubscriber struct
    method HandleBlocked (line 34) | func (c *captureSubscriber) HandleBlocked(_ context.Context, ev Blocke...
  type blockingSubscriber (line 38) | type blockingSubscriber struct
    method HandleBlocked (line 42) | func (b *blockingSubscriber) HandleBlocked(_ context.Context, ev Block...
  function TestBroadcasterFanout (line 48) | func TestBroadcasterFanout(t *testing.T) {
  function TestBroadcasterDropsWhenSubscriberBackedUp (line 79) | func TestBroadcasterDropsWhenSubscriberBackedUp(t *testing.T) {
  function TestWebhookSubscriberSendsPayload (line 102) | func TestWebhookSubscriberSendsPayload(t *testing.T) {

FILE: components/egress/pkg/events/webhook.go
  constant webhookSource (line 32) | webhookSource         = "opensandbox-egress"
  constant defaultWebhookTimeout (line 33) | defaultWebhookTimeout = 5 * time.Second
  constant defaultWebhookRetries (line 34) | defaultWebhookRetries = 3
  constant defaultWebhookBackoff (line 35) | defaultWebhookBackoff = 1 * time.Second
  type WebhookSubscriber (line 39) | type WebhookSubscriber struct
    method HandleBlocked (line 71) | func (w *WebhookSubscriber) HandleBlocked(ctx context.Context, ev Bloc...
  type webhookPayload (line 48) | type webhookPayload struct
  function NewWebhookSubscriber (line 56) | func NewWebhookSubscriber(url string) *WebhookSubscriber {

FILE: components/egress/pkg/iptables/redirect.go
  function SetupRedirect (line 30) | func SetupRedirect(port int, exemptDst []netip.Addr) error {

FILE: components/egress/pkg/log/logger.go
  function WithLogger (line 28) | func WithLogger(ctx context.Context, logger slogger.Logger) context.Cont...
  function Debugf (line 35) | func Debugf(template string, args ...any) {
  function Infof (line 39) | func Infof(template string, args ...any) {
  function Warnf (line 43) | func Warnf(template string, args ...any) {
  function Errorf (line 47) | func Errorf(template string, args ...any) {
  function Fatalf (line 51) | func Fatalf(template string, args ...any) {

FILE: components/egress/pkg/nftables/dynamic.go
  constant dynAllowV4Set (line 25) | dynAllowV4Set  = "dyn_allow_v4"
  constant dynAllowV6Set (line 26) | dynAllowV6Set  = "dyn_allow_v6"
  constant dynSetTimeoutS (line 27) | dynSetTimeoutS = 300
  constant minTTLSec (line 28) | minTTLSec      = 60
  constant maxTTLSec (line 29) | maxTTLSec      = 300
  type ResolvedIP (line 33) | type ResolvedIP struct
  function buildAddResolvedIPsScript (line 40) | func buildAddResolvedIPsScript(table string, ips []ResolvedIP) string {
  function clampTTL (line 60) | func clampTTL(d time.Duration) int {

FILE: components/egress/pkg/nftables/manager.go
  constant tableName (line 30) | tableName     = "opensandbox"
  constant chainName (line 31) | chainName     = "egress"
  constant allowV4Set (line 32) | allowV4Set    = "allow_v4"
  constant allowV6Set (line 33) | allowV6Set    = "allow_v6"
  constant denyV4Set (line 34) | denyV4Set     = "deny_v4"
  constant denyV6Set (line 35) | denyV6Set     = "deny_v6"
  constant dohBlockV4Set (line 36) | dohBlockV4Set = "doh_block_v4"
  constant dohBlockV6Set (line 37) | dohBlockV6Set = "doh_block_v6"
  type runner (line 40) | type runner
  type Options (line 43) | type Options struct
  type Manager (line 53) | type Manager struct
    method ApplyStatic (line 85) | func (m *Manager) ApplyStatic(ctx context.Context, p *policy.NetworkPo...
    method AddResolvedIPs (line 113) | func (m *Manager) AddResolvedIPs(ctx context.Context, ips []ResolvedIP...
  function NewManager (line 60) | func NewManager() *Manager {
  function NewManagerWithRunner (line 65) | func NewManagerWithRunner(r runner) *Manager {
  function NewManagerWithRunnerAndOptions (line 70) | func NewManagerWithRunnerAndOptions(r runner, opts Options) *Manager {
  function NewManagerWithOptions (line 75) | func NewManagerWithOptions(opts Options) *Manager {
  function buildRuleset (line 129) | func buildRuleset(p *policy.NetworkPolicy, opts Options) string {
  function writeElements (line 196) | func writeElements(b *strings.Builder, setName string, elems []string) {
  function defaultRunner (line 203) | func defaultRunner(ctx context.Context, script string) ([]byte, error) {
  function isMissingTableError (line 213) | func isMissingTableError(err error) bool {
  function removeDeleteTableLine (line 221) | func removeDeleteTableLine(script string) string {

FILE: components/egress/pkg/nftables/manager_test.go
  function TestApplyStatic_BuildsRuleset_DefaultDeny (line 28) | func TestApplyStatic_BuildsRuleset_DefaultDeny(t *testing.T) {
  function TestApplyStatic_DefaultAllowUsesAcceptPolicy (line 62) | func TestApplyStatic_DefaultAllowUsesAcceptPolicy(t *testing.T) {
  function expectContains (line 83) | func expectContains(t *testing.T, s, substr string) {
  function TestApplyStatic_RetryWhenTableMissing (line 88) | func TestApplyStatic_RetryWhenTableMissing(t *testing.T) {
  function TestApplyStatic_DoHBlocklist (line 107) | func TestApplyStatic_DoHBlocklist(t *testing.T) {
  function TestAddResolvedIPs_BuildsDynamicElements (line 129) | func TestAddResolvedIPs_BuildsDynamicElements(t *testing.T) {
  function TestAddResolvedIPs_ClampsTTL (line 144) | func TestAddResolvedIPs_ClampsTTL(t *testing.T) {
  function TestAddResolvedIPs_EmptyNoOp (line 159) | func TestAddResolvedIPs_EmptyNoOp(t *testing.T) {

FILE: components/egress/pkg/policy/policy.go
  constant ActionAllow (line 25) | ActionAllow = "allow"
  constant ActionDeny (line 26) | ActionDeny  = "deny"
  type targetKind (line 29) | type targetKind
  constant targetUnknown (line 32) | targetUnknown targetKind = iota
  constant targetDomain (line 33) | targetDomain
  constant targetIP (line 34) | targetIP
  constant targetCIDR (line 35) | targetCIDR
  function DefaultDenyPolicy (line 39) | func DefaultDenyPolicy() *NetworkPolicy {
  type NetworkPolicy (line 45) | type NetworkPolicy struct
    method Evaluate (line 78) | func (p *NetworkPolicy) Evaluate(domain string) string {
    method WithExtraAllowIPs (line 148) | func (p *NetworkPolicy) WithExtraAllowIPs(ips []netip.Addr) *NetworkPo...
    method StaticIPSets (line 168) | func (p *NetworkPolicy) StaticIPSets() (allowV4, allowV6, denyV4, deny...
  type EgressRule (line 50) | type EgressRule struct
    method matchesDomain (line 213) | func (r *EgressRule) matchesDomain(domain string) bool {
  function ParsePolicy (line 61) | func ParsePolicy(raw string) (*NetworkPolicy, error) {
  function ensureDefaults (line 101) | func ensureDefaults(p *NetworkPolicy) *NetworkPolicy {
  function normalizePolicy (line 111) | func normalizePolicy(p *NetworkPolicy) error {

FILE: components/egress/pkg/policy/policy_test.go
  function TestParsePolicy_EmptyOrNullDefaultsDeny (line 24) | func TestParsePolicy_EmptyOrNullDefaultsDeny(t *testing.T) {
  function TestParsePolicy_DefaultActionFallback (line 40) | func TestParsePolicy_DefaultActionFallback(t *testing.T) {
  function TestParsePolicy_EmptyEgressDefaultsDeny (line 47) | func TestParsePolicy_EmptyEgressDefaultsDeny(t *testing.T) {
  function TestParsePolicy_IPAndCIDRSupported (line 54) | func TestParsePolicy_IPAndCIDRSupported(t *testing.T) {
  function TestParsePolicy_InvalidAction (line 75) | func TestParsePolicy_InvalidAction(t *testing.T) {
  function TestParsePolicy_EmptyTargetError (line 80) | func TestParsePolicy_EmptyTargetError(t *testing.T) {
  function TestWithExtraAllowIPs (line 85) | func TestWithExtraAllowIPs(t *testing.T) {

FILE: components/egress/policy_server.go
  type policyUpdater (line 36) | type policyUpdater interface
  type enforcementReporter (line 42) | type enforcementReporter interface
  type nftApplier (line 47) | type nftApplier interface
  function startPolicyServer (line 58) | func startPolicyServer(ctx context.Context, proxy policyUpdater, nft nft...
  type policyServer (line 101) | type policyServer struct
    method handlePolicy (line 119) | func (s *policyServer) handlePolicy(w http.ResponseWriter, r *http.Req...
    method handleGet (line 137) | func (s *policyServer) handleGet(w http.ResponseWriter) {
    method handlePost (line 148) | func (s *policyServer) handlePost(w http.ResponseWriter, r *http.Reque...
    method handlePatch (line 207) | func (s *policyServer) handlePatch(w http.ResponseWriter, r *http.Requ...
    method authorize (line 272) | func (s *policyServer) authorize(r *http.Request) bool {
  type policyStatusResponse (line 111) | type policyStatusResponse struct
  function writeJSON (line 286) | func writeJSON(w http.ResponseWriter, status int, payload any) {
  function modeFromPolicy (line 292) | func modeFromPolicy(p *policy.NetworkPolicy) string {
  function mergeEgressRules (line 306) | func mergeEgressRules(base, additions []policy.EgressRule) []policy.Egre...
  function mergeKey (line 335) | func mergeKey(r policy.EgressRule) string {

FILE: components/egress/policy_server_test.go
  type stubProxy (line 31) | type stubProxy struct
    method CurrentPolicy (line 35) | func (s *stubProxy) CurrentPolicy() *policy.NetworkPolicy {
    method UpdatePolicy (line 39) | func (s *stubProxy) UpdatePolicy(p *policy.NetworkPolicy) {
  type stubNft (line 43) | type stubNft struct
    method ApplyStatic (line 49) | func (s *stubNft) ApplyStatic(_ context.Context, p *policy.NetworkPoli...
    method AddResolvedIPs (line 55) | func (s *stubNft) AddResolvedIPs(_ context.Context, _ []nftables.Resol...
  function TestHandlePolicy_AppliesNftAndUpdatesProxy (line 59) | func TestHandlePolicy_AppliesNftAndUpdatesProxy(t *testing.T) {
  function TestHandlePolicy_NftFailureReturns500 (line 78) | func TestHandlePolicy_NftFailureReturns500(t *testing.T) {
  function TestHandleGet_ReturnsEnforcementMode (line 95) | func TestHandleGet_ReturnsEnforcementMode(t *testing.T) {
  function TestHandlePatch_MergesAndApplies (line 111) | func TestHandlePatch_MergesAndApplies(t *testing.T) {
  function TestHandlePatch_DomainCaseOverride (line 143) | func TestHandlePatch_DomainCaseOverride(t *testing.T) {

FILE: components/egress/tests/webhook-server.py
  class WebhookHandler (line 41) | class WebhookHandler(http.server.BaseHTTPRequestHandler):
    method _send (line 42) | def _send(self, code: int = 200, body: str = "ok") -> None:
    method do_POST (line 48) | def do_POST(self) -> None:  # noqa: N802 (BaseHTTPRequestHandler API)
    method log_message (line 75) | def log_message(self, *args) -> None:
  function main (line 79) | def main() -> None:

FILE: components/execd/main.go
  function main (line 33) | func main() {

FILE: components/execd/pkg/flag/parser.go
  constant jupyterHostEnv (line 28) | jupyterHostEnv             = "JUPYTER_HOST"
  constant jupyterTokenEnv (line 29) | jupyterTokenEnv            = "JUPYTER_TOKEN"
  constant gracefulShutdownTimeoutEnv (line 30) | gracefulShutdownTimeoutEnv = "EXECD_API_GRACE_SHUTDOWN"
  function InitFlags (line 34) | func InitFlags() {

FILE: components/execd/pkg/jupyter/auth/auth.go
  type Auth (line 23) | type Auth struct
    method Validate (line 45) | func (a *Auth) Validate() string {
    method AddAuthToURL (line 56) | func (a *Auth) AddAuthToURL(baseURL string) (string, error) {
  function NewTokenAuth (line 30) | func NewTokenAuth(token string) *Auth {
  function NewBasicAuth (line 37) | func NewBasicAuth(username, password string) *Auth {

FILE: components/execd/pkg/jupyter/auth/auth_test.go
  function TestTokenAuthentication (line 23) | func TestTokenAuthentication(t *testing.T) {
  function TestBasicAuthentication (line 56) | func TestBasicAuthentication(t *testing.T) {
  function TestAuthValidation (line 89) | func TestAuthValidation(t *testing.T) {

FILE: components/execd/pkg/jupyter/auth/client.go
  type Client (line 24) | type Client struct
    method Do (line 38) | func (c *Client) Do(req *http.Request) (*http.Response, error) {
    method Get (line 53) | func (c *Client) Get(url string) (*http.Response, error) {
    method Post (line 62) | func (c *Client) Post(url, contentType string, body io.Reader) (*http....
    method Put (line 72) | func (c *Client) Put(url, contentType string, body io.Reader) (*http.R...
    method Delete (line 82) | func (c *Client) Delete(url string) (*http.Response, error) {
  function NewClient (line 30) | func NewClient(httpClient *http.Client, auth *Auth) *Client {

FILE: components/execd/pkg/jupyter/auth/types.go
  constant AuthTypeNone (line 18) | AuthTypeNone          = "none"
  constant AuthTypeToken (line 19) | AuthTypeToken         = "token"
  constant AuthTypeBasic (line 20) | AuthTypeBasic         = "basic"
  constant AuthHeaderKey (line 21) | AuthHeaderKey         = "Authorization"
  constant AuthHeaderValuePrefix (line 22) | AuthHeaderValuePrefix = "token "
  constant AuthURLParamKey (line 23) | AuthURLParamKey       = "token"
  function NewAuth (line 27) | func NewAuth() *Auth {
  method IsValid (line 32) | func (a *Auth) IsValid() bool {
  method GetAuthType (line 37) | func (a *Auth) GetAuthType() string {

FILE: components/execd/pkg/jupyter/client.go
  type Client (line 30) | type Client struct
    method SetToken (line 86) | func (c *Client) SetToken(token string) {
    method SetBasicAuth (line 91) | func (c *Client) SetBasicAuth(username, password string) {
    method ValidateAuth (line 97) | func (c *Client) ValidateAuth() (string, error) {
    method GetKernelSpecs (line 106) | func (c *Client) GetKernelSpecs() (*kernel.KernelSpecs, error) {
    method ListKernels (line 111) | func (c *Client) ListKernels() ([]*kernel.Kernel, error) {
    method GetKernel (line 116) | func (c *Client) GetKernel(kernelId string) (*kernel.Kernel, error) {
    method StartKernel (line 121) | func (c *Client) StartKernel(name string) (*kernel.Kernel, error) {
    method RestartKernel (line 126) | func (c *Client) RestartKernel(kernelId string) (bool, error) {
    method InterruptKernel (line 131) | func (c *Client) InterruptKernel(kernelId string) error {
    method ShutdownKernel (line 136) | func (c *Client) ShutdownKernel(kernelId string, restart bool) error {
    method ListSessions (line 141) | func (c *Client) ListSessions() ([]*session.Session, error) {
    method GetSession (line 146) | func (c *Client) GetSession(sessionId string) (*session.Session, error) {
    method CreateSession (line 151) | func (c *Client) CreateSession(name, ipynb, kernel string) (*session.S...
    method ModifySession (line 156) | func (c *Client) ModifySession(sessionId, name, path, kernel string) (...
    method DeleteSession (line 161) | func (c *Client) DeleteSession(sessionId string) error {
    method ConnectToKernel (line 166) | func (c *Client) ConnectToKernel(kernelId string) error {
    method DisconnectFromKernel (line 187) | func (c *Client) DisconnectFromKernel(kernelId string) {
    method ExecuteCodeStream (line 192) | func (c *Client) ExecuteCodeStream(kernelId, code string, resultChan c...
    method ExecuteCodeWithCallback (line 197) | func (c *Client) ExecuteCodeWithCallback(code string, handler execute....
  type ClientOption (line 40) | type ClientOption
  function WithHTTPClient (line 43) | func WithHTTPClient(client *http.Client) ClientOption {
  function WithToken (line 50) | func WithToken(token string) ClientOption {
  function WithBasicAuth (line 57) | func WithBasicAuth(username, password string) ClientOption {
  function NewClient (line 65) | func NewClient(baseURL string, options ...ClientOption) *Client {

FILE: components/execd/pkg/jupyter/debug_integration_test.go
  function TestDebugServerIntegration (line 25) | func TestDebugServerIntegration(t *testing.T) {
  type debugTransport (line 140) | type debugTransport struct
    method RoundTrip (line 144) | func (d *debugTransport) RoundTrip(req *http.Request) (*http.Response,...

FILE: components/execd/pkg/jupyter/execute/execute.go
  type HTTPClient (line 31) | type HTTPClient interface
  type Client (line 36) | type Client struct
    method Connect (line 70) | func (c *Client) Connect(wsURL string) error {
    method Disconnect (line 97) | func (c *Client) Disconnect() {
    method IsConnected (line 108) | func (c *Client) IsConnected() bool {
    method ExecuteCodeStream (line 115) | func (c *Client) ExecuteCodeStream(code string, resultChan chan *Execu...
    method ExecuteCodeWithCallback (line 295) | func (c *Client) ExecuteCodeWithCallback(code string, handler Callback...
    method registerDefaultHandlers (line 410) | func (c *Client) registerDefaultHandlers() {
    method registerHandler (line 415) | func (c *Client) registerHandler(msgType MessageType, handler func(*Me...
    method clearTemporaryHandlers (line 422) | func (c *Client) clearTemporaryHandlers() {
    method receiveMessages (line 430) | func (c *Client) receiveMessages() {
    method handleMessage (line 454) | func (c *Client) handleMessage(msg *Message) {
    method nextMessageID (line 469) | func (c *Client) nextMessageID() string {
  function NewClient (line 60) | func NewClient(baseURL string, httpClient HTTPClient) *Client {

FILE: components/execd/pkg/jupyter/execute/execute_test.go
  function createTestServer (line 29) | func createTestServer(t *testing.T, handleFunc func(conn *websocket.Conn...
  function TestExecuteCodeStream (line 57) | func TestExecuteCodeStream(t *testing.T) {

FILE: components/execd/pkg/jupyter/execute/executor.go
  type Executor (line 18) | type Executor struct
    method Connect (line 35) | func (e *Executor) Connect() error {
    method Disconnect (line 40) | func (e *Executor) Disconnect() {
    method ExecuteCodeStream (line 45) | func (e *Executor) ExecuteCodeStream(code string, resultChan chan *Exe...
    method ExecuteCodeWithCallback (line 50) | func (e *Executor) ExecuteCodeWithCallback(code string, handler Callba...
  function NewExecutor (line 26) | func NewExecutor(wsURL string, httpClient HTTPClient) *Executor {

FILE: components/execd/pkg/jupyter/execute/types.go
  type MessageType (line 26) | type MessageType
  constant MsgExecuteRequest (line 30) | MsgExecuteRequest MessageType = "execute_request"
  constant MsgExecuteInput (line 33) | MsgExecuteInput MessageType = "execute_input"
  constant MsgExecuteResult (line 36) | MsgExecuteResult MessageType = "execute_result"
  constant MsgDisplayData (line 39) | MsgDisplayData MessageType = "display_data"
  constant MsgStream (line 42) | MsgStream MessageType = "stream"
  constant MsgError (line 45) | MsgError MessageType = "error"
  constant MsgStatus (line 48) | MsgStatus MessageType = "status"
  constant MsgClearOutput (line 51) | MsgClearOutput MessageType = "clear_output"
  constant MsgComm (line 54) | MsgComm MessageType = "comm"
  constant MsgCommOpen (line 57) | MsgCommOpen MessageType = "comm_open"
  constant MsgCommClose (line 60) | MsgCommClose MessageType = "comm_close"
  constant MsgCommMsg (line 63) | MsgCommMsg MessageType = "comm_msg"
  constant MsgKernelInfo (line 66) | MsgKernelInfo MessageType = "kernel_info_request"
  constant MsgKernelInfoReply (line 69) | MsgKernelInfoReply MessageType = "kernel_info_reply"
  constant MsgExecuteReply (line 71) | MsgExecuteReply MessageType = "execute_reply"
  type StreamType (line 75) | type StreamType
  constant StreamStdout (line 79) | StreamStdout StreamType = "stdout"
  constant StreamStderr (line 82) | StreamStderr StreamType = "stderr"
  type ExecutionState (line 86) | type ExecutionState
  constant StateIdle (line 90) | StateIdle ExecutionState = "idle"
  constant StateBusy (line 93) | StateBusy ExecutionState = "busy"
  constant StateStarting (line 96) | StateStarting ExecutionState = "starting"
  type Header (line 100) | type Header struct
  type Message (line 121) | type Message struct
  type ExecuteRequest (line 142) | type ExecuteRequest struct
  type StreamOutput (line 163) | type StreamOutput struct
  type ExecuteResult (line 172) | type ExecuteResult struct
  type ExecuteReply (line 183) | type ExecuteReply struct
  type DisplayData (line 193) | type DisplayData struct
  type ErrorOutput (line 202) | type ErrorOutput struct
    method String (line 213) | func (e *ErrorOutput) String() string {
  type StatusUpdate (line 222) | type StatusUpdate struct
  type ExecutionResult (line 228) | type ExecutionResult struct
  type CallbackHandler (line 249) | type CallbackHandler struct

FILE: components/execd/pkg/jupyter/execute/zz_generated.deepcopy.go
  method DeepCopyInto (line 24) | func (in *ErrorOutput) DeepCopyInto(out *ErrorOutput) {
  method DeepCopy (line 34) | func (in *ErrorOutput) DeepCopy() *ErrorOutput {
  method DeepCopyInto (line 44) | func (in *ExecutionResult) DeepCopyInto(out *ExecutionResult) {
  method DeepCopy (line 65) | func (in *ExecutionResult) DeepCopy() *ExecutionResult {
  method DeepCopyInto (line 75) | func (in *StreamOutput) DeepCopyInto(out *StreamOutput) {
  method DeepCopy (line 80) | func (in *StreamOutput) DeepCopy() *StreamOutput {

FILE: components/execd/pkg/jupyter/integration_test.go
  function TestIntegrationFlow (line 29) | func TestIntegrationFlow(t *testing.T) {

FILE: components/execd/pkg/jupyter/kernel/kernel.go
  type Client (line 27) | type Client struct
    method GetKernelSpecs (line 44) | func (c *Client) GetKernelSpecs() (*KernelSpecs, error) {
    method ListKernels (line 76) | func (c *Client) ListKernels() ([]*Kernel, error) {
    method GetKernel (line 108) | func (c *Client) GetKernel(kernelId string) (*Kernel, error) {
    method StartKernel (line 140) | func (c *Client) StartKernel(name string) (*Kernel, error) {
    method RestartKernel (line 190) | func (c *Client) RestartKernel(kernelId string) (bool, error) {
    method InterruptKernel (line 229) | func (c *Client) InterruptKernel(kernelId string) error {
    method ShutdownKernel (line 256) | func (c *Client) ShutdownKernel(kernelId string, restart bool) error {
  function NewClient (line 36) | func NewClient(baseURL string, httpClient *http.Client) *Client {

FILE: components/execd/pkg/jupyter/kernel/types.go
  type KernelSpecs (line 23) | type KernelSpecs struct
  type KernelSpecInfo (line 32) | type KernelSpecInfo struct
  type KernelSpecDetail (line 42) | type KernelSpecDetail struct
  type Kernel (line 56) | type Kernel struct
  type KernelStartRequest (line 74) | type KernelStartRequest struct
  type KernelRestartResponse (line 83) | type KernelRestartResponse struct
  type KernelInterruptRequest (line 98) | type KernelInterruptRequest struct
  type KernelShutdownRequest (line 104) | type KernelShutdownRequest struct
  type KernelStatus (line 110) | type KernelStatus
  constant KernelStatusIdle (line 114) | KernelStatusIdle KernelStatus = "idle"
  constant KernelStatusBusy (line 117) | KernelStatusBusy KernelStatus = "busy"
  constant KernelStatusStarting (line 120) | KernelStatusStarting KernelStatus = "starting"
  constant KernelStatusRestarting (line 123) | KernelStatusRestarting KernelStatus = "restarting"
  constant KernelStatusDead (line 126) | KernelStatusDead KernelStatus = "dead"

FILE: components/execd/pkg/jupyter/live_integration_test.go
  type authTransport (line 28) | type authTransport struct
    method RoundTrip (line 34) | func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, ...
  function TestLiveServerIntegration (line 44) | func TestLiveServerIntegration(t *testing.T) {
  function getEnv (line 337) | func getEnv(key, defaultValue string) string {
  function truncateString (line 346) | func truncateString(s string, maxLen int) string {
  function getKeys (line 354) | func getKeys(m map[string]interface{}) []string {

FILE: components/execd/pkg/jupyter/session/session.go
  type Client (line 27) | type Client struct
    method ListSessions (line 44) | func (c *Client) ListSessions() ([]*Session, error) {
    method GetSession (line 76) | func (c *Client) GetSession(sessionId string) (*Session, error) {
    method CreateSession (line 108) | func (c *Client) CreateSession(name, ipynb, kernel string) (*Session, ...
    method ModifySession (line 163) | func (c *Client) ModifySession(sessionId, name, path, kernel string) (...
    method DeleteSession (line 222) | func (c *Client) DeleteSession(sessionId string) error {
    method CreateSessionWithOptions (line 248) | func (c *Client) CreateSessionWithOptions(options *SessionOptions) (*S...
  function NewClient (line 36) | func NewClient(baseURL string, httpClient *http.Client) *Client {

FILE: components/execd/pkg/jupyter/session/session_test.go
  function TestListSessions (line 25) | func TestListSessions(t *testing.T) {
  function TestCreateSession (line 110) | func TestCreateSession(t *testing.T) {
  function TestGetSession (line 188) | func TestGetSession(t *testing.T) {

FILE: components/execd/pkg/jupyter/session/types.go
  type Session (line 23) | type Session struct
  type KernelInfo (line 47) | type KernelInfo struct
  type SessionCreateRequest (line 65) | type SessionCreateRequest struct
  type KernelSpec (line 80) | type KernelSpec struct
  type SessionUpdateRequest (line 89) | type SessionUpdateRequest struct
  type SessionListResponse (line 104) | type SessionListResponse
  type SessionOptions (line 107) | type SessionOptions struct
  constant DefaultSessionType (line 125) | DefaultSessionType = "notebook"

FILE: components/execd/pkg/jupyter/transport.go
  type AuthTransport (line 19) | type AuthTransport struct
    method RoundTrip (line 24) | func (t *AuthTransport) RoundTrip(req *http.Request) (*http.Response, ...

FILE: components/execd/pkg/log/log.go
  constant logFileEnvKey (line 23) | logFileEnvKey = "EXECD_LOG_FILE"
  function Init (line 29) | func Init(level int) {
  function mapLevel (line 33) | func mapLevel(level int) string {
  function newLogger (line 48) | func newLogger(level string) slogger.Logger {
  function getLogger (line 59) | func getLogger() slogger.Logger {
  function Debug (line 68) | func Debug(format string, args ...any) {
  function Info (line 72) | func Info(format string, args ...any) {
  function Warn (line 76) | func Warn(format string, args ...any) {
  function Warning (line 81) | func Warning(format string, args ...any) {
  function Error (line 85) | func Error(format string, args ...any) {

FILE: components/execd/pkg/runtime/bash_session.go
  constant envDumpStartMarker (line 40) | envDumpStartMarker = "__ENV_DUMP_START__"
  constant envDumpEndMarker (line 41) | envDumpEndMarker   = "__ENV_DUMP_END__"
  constant exitMarkerPrefix (line 42) | exitMarkerPrefix   = "__EXIT_CODE__:"
  constant pwdMarkerPrefix (line 43) | pwdMarkerPrefix    = "__PWD__:"
  method createBashSession (line 46) | func (c *Controller) createBashSession(req *CreateContextRequest) (strin...
  method runBashSession (line 57) | func (c *Controller) runBashSession(ctx context.Context, request *Execut...
  method getBashSession (line 66) | func (c *Controller) getBashSession(sessionId string) *bashSession {
  method closeBashSession (line 75) | func (c *Controller) closeBashSession(sessionId string) error {
  method CreateBashSession (line 90) | func (c *Controller) CreateBashSession(req *CreateContextRequest) (strin...
  method RunInBashSession (line 94) | func (c *Controller) RunInBashSession(ctx context.Context, req *ExecuteC...
  method DeleteBashSession (line 98) | func (c *Controller) DeleteBashSession(sessionID string) error {
  function newBashSession (line 103) | func newBashSession(cwd string) *bashSession {
  method start (line 123) | func (s *bashSession) start() error {
  method trackCurrentProcess (line 135) | func (s *bashSession) trackCurrentProcess(pid int) {
  method untrackCurrentProcess (line 141) | func (s *bashSession) untrackCurrentProcess() {
  method run (line 148) | func (s *bashSession) run(ctx context.Context, request *ExecuteCodeReque...
  function buildWrappedScript (line 306) | func buildWrappedScript(command string, env map[string]string, cwd strin...
  constant maxPersistedEnvValueSize (line 354) | maxPersistedEnvValueSize = 8 * 1024
  function parseExportDump (line 356) | func parseExportDump(lines []string) map[string]string {
  function parseExportLine (line 371) | func parseExportLine(line string) (string, string, bool) {
  function shellEscape (line 396) | func shellEscape(value string) string {
  function isValidEnvKey (line 400) | func isValidEnvKey(key string) bool {
  function copyEnvMap (line 420) | func copyEnvMap(src map[string]string) map[string]string {
  function splitEnvPair (line 432) | func splitEnvPair(kv string) (string, string, bool) {
  method close (line 443) | func (s *bashSession) close() error {
  function uuidString (line 461) | func uuidString() string {

FILE: components/execd/pkg/runtime/bash_session_test.go
  function TestBashSession_NonZeroExitEmitsError (line 34) | func TestBashSession_NonZeroExitEmitsError(t *testing.T) {
  function TestBashSession_envAndExitCode (line 90) | func TestBashSession_envAndExitCode(t *testing.T) {
  function TestBashSession_envLargeOutputChained (line 163) | func TestBashSession_envLargeOutputChained(t *testing.T) {
  function TestBashSession_cwdPersistsWithoutOverride (line 216) | func TestBashSession_cwdPersistsWithoutOverride(t *testing.T) {
  function TestBashSession_requestCwdOverridesAfterCd (line 256) | func TestBashSession_requestCwdOverridesAfterCd(t *testing.T) {
  function TestBashSession_envDumpNotLeakedWhenNoTrailingNewline (line 301) | func TestBashSession_envDumpNotLeakedWhenNoTrailingNewline(t *testing.T) {
  function TestBashSession_envDumpNotLeakedWhenNoOutput (line 329) | func TestBashSession_envDumpNotLeakedWhenNoOutput(t *testing.T) {
  function TestBashSession_heredoc (line 359) | func TestBashSession_heredoc(t *testing.T) {
  function TestBashSession_execReplacesShell (line 413) | func TestBashSession_execReplacesShell(t *testing.T) {
  function TestBashSession_complexExec (line 453) | func TestBashSession_complexExec(t *testing.T) {
  function containsLine (line 497) | func containsLine(lines []string, target string) bool {
  function TestBashSession_CloseKillsRunningProcess (line 508) | func TestBashSession_CloseKillsRunningProcess(t *testing.T) {
  function TestBashSession_DeleteBashSessionKillsRunningProcess (line 543) | func TestBashSession_DeleteBashSessionKillsRunningProcess(t *testing.T) {
  function TestBashSession_CloseWithNoActiveRun (line 583) | func TestBashSession_CloseWithNoActiveRun(t *testing.T) {

FILE: components/execd/pkg/runtime/bash_session_windows.go
  method CreateBashSession (line 28) | func (c *Controller) CreateBashSession(_ *CreateContextRequest) (string,...
  method RunInBashSession (line 33) | func (c *Controller) RunInBashSession(_ context.Context, _ *ExecuteCodeR...
  method DeleteBashSession (line 38) | func (c *Controller) DeleteBashSession(_ string) error { //nolint:revive

FILE: components/execd/pkg/runtime/command.go
  function getShell (line 40) | func getShell() string {
  function buildCredential (line 47) | func buildCredential(uid, gid *uint32) (*syscall.Credential, error) {
  method runCommand (line 88) | func (c *Controller) runCommand(ctx context.Context, request *ExecuteCod...
  method runBackgroundCommand (line 215) | func (c *Controller) runBackgroundCommand(ctx context.Context, cancel co...

FILE: components/execd/pkg/runtime/command_common.go
  method tailStdPipe (line 29) | func (c *Controller) tailStdPipe(file string, onExecute func(text string...
  method getCommandKernel (line 48) | func (c *Controller) getCommandKernel(sessionID string) *commandKernel {
  method storeCommandKernel (line 58) | func (c *Controller) storeCommandKernel(sessionID string, kernel *comman...
  method stdLogDescriptor (line 65) | func (c *Controller) stdLogDescriptor(session string) (io.WriteCloser, i...
  method combinedOutputDescriptor (line 84) | func (c *Controller) combinedOutputDescriptor(session string) (io.WriteC...
  method stdoutFileName (line 93) | func (c *Controller) stdoutFileName(session string) string {
  method stderrFileName (line 98) | func (c *Controller) stderrFileName(session string) string {
  method combinedOutputFileName (line 102) | func (c *Controller) combinedOutputFileName(session string) string {
  method readFromPos (line 107) | func (c *Controller) readFromPos(mutex *sync.Mutex, filepath string, sta...

FILE: components/execd/pkg/runtime/command_status.go
  type CommandStatus (line 25) | type CommandStatus struct
  type CommandOutput (line 36) | type CommandOutput struct
  method commandSnapshot (line 42) | func (c *Controller) commandSnapshot(session string) *commandKernel {
  method GetCommandStatus (line 56) | func (c *Controller) GetCommandStatus(session string) (*CommandStatus, e...
  method SeekBackgroundCommandOutput (line 75) | func (c *Controller) SeekBackgroundCommandOutput(session string, cursor ...
  method markCommandFinished (line 113) | func (c *Controller) markCommandFinished(session string, exitCode int, e...

FILE: components/execd/pkg/runtime/command_status_test.go
  function TestGetCommandStatus_NotFound (line 28) | func TestGetCommandStatus_NotFound(t *testing.T) {
  function TestGetCommandStatus_Running (line 35) | func TestGetCommandStatus_Running(t *testing.T) {
  function TestSeekBackgroundCommandOutput_Completed (line 79) | func TestSeekBackgroundCommandOutput_Completed(t *testing.T) {
  function TestSeekBackgroundCommandOutput_WithRunBackgroundCommand (line 111) | func TestSeekBackgroundCommandOutput_WithRunBackgroundCommand(t *testing...

FILE: components/execd/pkg/runtime/command_test.go
  function TestReadFromPos_SplitsOnCRAndLF (line 34) | func TestReadFromPos_SplitsOnCRAndLF(t *testing.T) {
  function TestReadFromPos_LongLine (line 70) | func TestReadFromPos_LongLine(t *testing.T) {
  function TestReadFromPos_FlushesTrailingLine (line 86) | func TestReadFromPos_FlushesTrailingLine(t *testing.T) {
  function TestRunCommand_Echo (line 110) | func TestRunCommand_Echo(t *testing.T) {
  function TestRunCommand_Error (line 164) | func TestRunCommand_Error(t *testing.T) {
  function TestStdLogDescriptor_AutoCreatesTempDir (line 222) | func TestStdLogDescriptor_AutoCreatesTempDir(t *testing.T) {
  function TestCombinedOutputDescriptor_AutoCreatesTempDir (line 246) | func TestCombinedOutputDescriptor_AutoCreatesTempDir(t *testing.T) {

FILE: components/execd/pkg/runtime/command_windows.go
  method runCommand (line 35) | func (c *Controller) runCommand(ctx context.Context, request *ExecuteCod...
  method runBackgroundCommand (line 107) | func (c *Controller) runBackgroundCommand(ctx context.Context, cancel co...

FILE: components/execd/pkg/runtime/context.go
  method CreateContext (line 35) | func (c *Controller) CreateContext(req *CreateContextRequest) (string, e...
  method DeleteContext (line 69) | func (c *Controller) DeleteContext(session string) error {
  method GetContext (line 73) | func (c *Controller) GetContext(session string) (CodeContext, error) {
  method ListContext (line 84) | func (c *Controller) ListContext(language string) ([]CodeContext, error) {
  method DeleteLanguageContext (line 95) | func (c *Controller) DeleteLanguageContext(language Language) error {
  method deleteSessionAndCleanup (line 115) | func (c *Controller) deleteSessionAndCleanup(session string) error {
  method newContextID (line 127) | func (c *Controller) newContextID() string {
  method newIpynbPath (line 131) | func (c *Controller) newIpynbPath(sessionID, cwd string) (string, error) {
  method createDefaultLanguageJupyterContext (line 143) | func (c *Controller) createDefaultLanguageJupyterContext(language Langua...
  method createJupyterContext (line 177) | func (c *Controller) createJupyterContext(request CreateContextRequest) ...
  method storeJupyterKernel (line 216) | func (c *Controller) storeJupyterKernel(sessionID string, kernel *jupyte...
  method jupyterClient (line 220) | func (c *Controller) jupyterClient() *jupyter.Client {
  method getDefaultLanguageSession (line 233) | func (c *Controller) getDefaultLanguageSession(language Language) string {
  method setDefaultLanguageSession (line 242) | func (c *Controller) setDefaultLanguageSession(language Language, sessio...
  method deleteDefaultSessionByID (line 246) | func (c *Controller) deleteDefaultSessionByID(sessionID string) {
  method listAllContexts (line 255) | func (c *Controller) listAllContexts() ([]CodeContext, error) {
  method listLanguageContexts (line 278) | func (c *Controller) listLanguageContexts(language Language) ([]CodeCont...

FILE: components/execd/pkg/runtime/context_test.go
  function TestListContextsAndNewIpynbPath (line 28) | func TestListContextsAndNewIpynbPath(t *testing.T) {
  function TestNewContextID_UniqueAndLength (line 52) | func TestNewContextID_UniqueAndLength(t *testing.T) {
  function TestNewIpynbPath_ErrorWhenCwdIsFile (line 64) | func TestNewIpynbPath_ErrorWhenCwdIsFile(t *testing.T) {
  function TestListContextUnsupportedLanguage (line 73) | func TestListContextUnsupportedLanguage(t *testing.T) {
  function TestDeleteContext_NotFound (line 83) | func TestDeleteContext_NotFound(t *testing.T) {
  function TestGetContext_NotFound (line 90) | func TestGetContext_NotFound(t *testing.T) {
  function TestDeleteContext_RemovesCacheOnSuccess (line 98) | func TestDeleteContext_RemovesCacheOnSuccess(t *testing.T) {
  function TestDeleteLanguageContext_RemovesCacheOnSuccess (line 120) | func TestDeleteLanguageContext_RemovesCacheOnSuccess(t *testing.T) {

FILE: components/execd/pkg/runtime/ctrl.go
  type Controller (line 37) | type Controller struct
    method Execute (line 78) | func (c *Controller) Execute(request *ExecuteCodeRequest) error {
  type jupyterKernel (line 49) | type jupyterKernel struct
  type commandKernel (line 56) | type commandKernel struct
  function NewController (line 70) | func NewController(baseURL, token string) *Controller {

FILE: components/execd/pkg/runtime/env.go
  function loadExtraEnvFromFile (line 27) | func loadExtraEnvFromFile() map[string]string {
  function mergeEnvs (line 58) | func mergeEnvs(base []string, extra map[string]string) []string {
  function mergeExtraEnvs (line 84) | func mergeExtraEnvs(fromFile, fromRequest map[string]string) map[string]...

FILE: components/execd/pkg/runtime/env_test.go
  function TestLoadExtraEnvFromFileUnset (line 26) | func TestLoadExtraEnvFromFileUnset(t *testing.T) {
  function TestLoadExtraEnvFromFileParsesAndExpands (line 31) | func TestLoadExtraEnvFromFileParsesAndExpands(t *testing.T) {
  function TestLoadExtraEnvFromFileMissingFile (line 58) | func TestLoadExtraEnvFromFileMissingFile(t *testing.T) {
  function TestMergeEnvsOverlaysExtra (line 66) | func TestMergeEnvsOverlaysExtra(t *testing.T) {
  function TestMergeExtraEnvsMergesAndOverrides (line 85) | func TestMergeExtraEnvsMergesAndOverrides(t *testing.T) {
  function TestMergeExtraEnvsHandlesNilFromFile (line 97) | func TestMergeExtraEnvsHandlesNilFromFile(t *testing.T) {

FILE: components/execd/pkg/runtime/helpers_test.go
  type stubDriver (line 31) | type stubDriver struct
  type stubConn (line 42) | type stubConn struct
    method Prepare (line 46) | func (c *stubConn) Prepare(string) (driver.Stmt, error) { return nil, ...
    method Close (line 47) | func (c *stubConn) Close() error                        { return nil }
    method Begin (line 48) | func (c *stubConn) Begin() (driver.Tx, error)           { return nil, ...
    method Ping (line 50) | func (c *stubConn) Ping(context.Context) error {
    method ExecContext (line 54) | func (c *stubConn) ExecContext(_ context.Context, _ string, _ []driver...
    method QueryContext (line 62) | func (c *stubConn) QueryContext(_ context.Context, _ string, _ []drive...
  type stubRows (line 73) | type stubRows struct
    method Columns (line 79) | func (r *stubRows) Columns() []string { return r.columns }
    method Close (line 80) | func (r *stubRows) Close() error      { return nil }
    method Next (line 81) | func (r *stubRows) Next(dest []driver.Value) error {
  type stubConnector (line 93) | type stubConnector struct
    method Connect (line 97) | func (c *stubConnector) Connect(context.Context) (driver.Conn, error) {
    method Driver (line 101) | func (c *stubConnector) Driver() driver.Driver {
    method Open (line 105) | func (c *stubConnector) Open(string) (driver.Conn, error) {
  function newStubDB (line 109) | func newStubDB(t *testing.T, d *stubDriver) *sql.DB {

FILE: components/execd/pkg/runtime/interrupt.go
  method Interrupt (line 32) | func (c *Controller) Interrupt(sessionID string) error {
  method killPid (line 49) | func (c *Controller) killPid(pid int) error {

FILE: components/execd/pkg/runtime/interrupt_windows.go
  method Interrupt (line 30) | func (c *Controller) Interrupt(sessionID string) error {
  method killPid (line 45) | func (c *Controller) killPid(pid int) error {

FILE: components/execd/pkg/runtime/jupyter.go
  method runJupyter (line 27) | func (c *Controller) runJupyter(ctx context.Context, request *ExecuteCod...
  method runJupyterCode (line 60) | func (c *Controller) runJupyterCode(ctx context.Context, kernel *jupyter...
  method setWorkingDir (line 131) | func (c *Controller) setWorkingDir(_ *jupyterKernel, _ *CreateContextReq...
  method getJupyterKernel (line 136) | func (c *Controller) getJupyterKernel(sessionID string) *jupyterKernel {
  method searchKernel (line 146) | func (c *Controller) searchKernel(client *jupyter.Client, language Langu...

FILE: components/execd/pkg/runtime/language.go
  type Language (line 18) | type Language
    method String (line 33) | func (l Language) String() string {
  constant Command (line 21) | Command           Language = "command"
  constant Bash (line 22) | Bash              Language = "bash"
  constant Python (line 23) | Python            Language = "python"
  constant Java (line 24) | Java              Language = "java"
  constant JavaScript (line 25) | JavaScript        Language = "javascript"
  constant TypeScript (line 26) | TypeScript        Language = "typescript"
  constant Go (line 27) | Go                Language = "go"
  constant SQL (line 28) | SQL               Language = "sql"
  constant BackgroundCommand (line 29) | BackgroundCommand Language = "background-command"

FILE: components/execd/pkg/runtime/sql.go
  type QueryResult (line 35) | type QueryResult struct
  method runSQL (line 42) | func (c *Controller) runSQL(ctx context.Context, request *ExecuteCodeReq...
  method executeSelectSQLQuery (line 67) | func (c *Controller) executeSelectSQLQuery(ctx context.Context, request ...
  method executeUpdateSQLQuery (line 131) | func (c *Controller) executeUpdateSQLQuery(ctx context.Context, request ...
  method getQueryType (line 161) | func (c *Controller) getQueryType(query string) string {
  method initDB (line 170) | func (c *Controller) initDB() error {

FILE: components/execd/pkg/runtime/sql_test.go
  function TestExecuteSelectSQLQuery_Success (line 28) | func TestExecuteSelectSQLQuery_Success(t *testing.T) {
  function TestExecuteUpdateSQLQuery_Success (line 78) | func TestExecuteUpdateSQLQuery_Success(t *testing.T) {

FILE: components/execd/pkg/runtime/types.go
  type ExecuteResultHook (line 26) | type ExecuteResultHook struct
  type ExecuteCodeRequest (line 37) | type ExecuteCodeRequest struct
    method SetDefaultHooks (line 50) | func (req *ExecuteCodeRequest) SetDefaultHooks() {
  type CreateContextRequest (line 77) | type CreateContextRequest struct
  type CodeContext (line 82) | type CodeContext struct
  type bashSessionConfig (line 88) | type bashSessionConfig struct
  type bashSession (line 100) | type bashSession struct

FILE: components/execd/pkg/runtime/types_test.go
  function TestExecuteCodeRequest_SetDefaultHooks (line 24) | func TestExecuteCodeRequest_SetDefaultHooks(t *testing.T) {

FILE: components/execd/pkg/util/glob/index.go
  function findUnescapedByteIndex (line 17) | func findUnescapedByteIndex(s string, c byte, allowEscaping bool) int {
  function findMatchedClosingAltIndex (line 31) | func findMatchedClosingAltIndex(s string, allowEscaping bool) int {
  function findMatchedClosingBracketIndex (line 36) | func findMatchedClosingBracketIndex(s string, allowEscaping bool) int {
  function findNextCommaIndex (line 41) | func findNextCommaIndex(s string, allowEscaping bool) int {
  function findMatchedClosingSymbolsIndex (line 58) | func findMatchedClosingSymbolsIndex(s string, allowEscaping bool, left, ...

FILE: components/execd/pkg/util/glob/match.go
  function PathMatch (line 30) | func PathMatch(pattern, name string) (bool, error) {
  function matchWithSeparator (line 34) | func matchWithSeparator(pattern, name string, separator rune, validate b...
  function doMatchWithSeparator (line 39) | func doMatchWithSeparator(pattern, name string, separator rune, validate...
  function isZeroLengthPattern (line 280) | func isZeroLengthPattern(pattern string, separator rune) (ret bool, err ...

FILE: components/execd/pkg/util/glob/match_benchmark_test.go
  function BenchmarkPathMatch (line 22) | func BenchmarkPathMatch(b *testing.B) {

FILE: components/execd/pkg/util/glob/match_test.go
  type MatchTest (line 31) | type MatchTest struct
  function TestValidatePattern (line 224) | func TestValidatePattern(t *testing.T) {
  function testValidatePatternWith (line 230) | func testValidatePatternWith(t *testing.T, idx int, tt MatchTest) {
  function TestPathMatch (line 243) | func TestPathMatch(t *testing.T) {
  function testPathMatchWith (line 252) | func testPathMatchWith(t *testing.T, idx int, tt MatchTest) {
  function TestPathMatchFake (line 274) | func TestPathMatchFake(t *testing.T) {
  function testPathMatchFakeWith (line 288) | func testPathMatchFakeWith(t *testing.T, idx int, tt MatchTest) {
  function compareErrors (line 303) | func compareErrors(a, b error) bool {

FILE: components/execd/pkg/util/glob/pattern.go
  function isValidPattern (line 20) | func isValidPattern(s string, separator rune) bool {

FILE: components/execd/pkg/util/safego/safe.go
  function InitPanicLogger (line 26) | func InitPanicLogger(_ context.Context) {
  function init (line 45) | func init() {
  function Go (line 49) | func Go(f func()) {

FILE: components/execd/pkg/util/safego/safe_test.go
  function Test_Go (line 23) | func Test_Go(t *testing.T) {

FILE: components/execd/pkg/web/controller/basic.go
  type basicController (line 27) | type basicController struct
    method RespondError (line 35) | func (c *basicController) RespondError(status int, code model.ErrorCod...
    method RespondSuccess (line 46) | func (c *basicController) RespondSuccess(data any) {
    method QueryInt64 (line 54) | func (c *basicController) QueryInt64(query string, defaultValue int64)...
    method bindJSON (line 62) | func (c *basicController) bindJSON(target any) error {
  function newBasicController (line 31) | func newBasicController(ctx *gin.Context) *basicController {

FILE: components/execd/pkg/web/controller/basic_test.go
  function TestBasicControllerRespondSuccess (line 27) | func TestBasicControllerRespondSuccess(t *testing.T) {
  function TestBasicControllerRespondError (line 40) | func TestBasicControllerRespondError(t *testing.T) {
  function setupBasicController (line 53) | func setupBasicController(method string) (*basicController, *httptest.Re...
  function TestRespondSuccessWritesPayload (line 59) | func TestRespondSuccessWritesPayload(t *testing.T) {
  function TestRespondErrorAddsCodeAndMessage (line 71) | func TestRespondErrorAddsCodeAndMessage(t *testing.T) {
  function TestQueryInt64 (line 83) | func TestQueryInt64(t *testing.T) {

FILE: components/execd/pkg/web/controller/codeinterpreting.go
  function InitCodeRunner (line 35) | func InitCodeRunner() {
  type CodeInterpretingController (line 40) | type CodeInterpretingController struct
    method CreateContext (line 54) | func (c *CodeInterpretingController) CreateContext() {
    method InterruptCode (line 86) | func (c *CodeInterpretingController) InterruptCode() {
    method RunCode (line 91) | func (c *CodeInterpretingController) RunCode() {
    method GetContext (line 133) | func (c *CodeInterpretingController) GetContext() {
    method ListContexts (line 165) | func (c *CodeInterpretingController) ListContexts() {
    method DeleteContextsByLanguage (line 182) | func (c *CodeInterpretingController) DeleteContextsByLanguage() {
    method DeleteContext (line 207) | func (c *CodeInterpretingController) DeleteContext() {
    method CreateSession (line 242) | func (c *CodeInterpretingController) CreateSession() {
    method RunInSession (line 269) | func (c *CodeInterpretingController) RunInSession() {
    method DeleteSession (line 325) | func (c *CodeInterpretingController) DeleteSession() {
    method buildExecuteCodeRequest (line 358) | func (c *CodeInterpretingController) buildExecuteCodeRequest(request m...
    method interrupt (line 372) | func (c *CodeInterpretingController) interrupt() {
  function NewCodeInterpretingController (line 47) | func NewCodeInterpretingController(ctx *gin.Context) *CodeInterpretingCo...

FILE: components/execd/pkg/web/controller/codeinterpreting_test.go
  function TestBuildExecuteCodeRequestDefaultsToCommand (line 29) | func TestBuildExecuteCodeRequestDefaultsToCommand(t *testing.T) {
  function TestBuildExecuteCodeRequestRespectsLanguage (line 46) | func TestBuildExecuteCodeRequestRespectsLanguage(t *testing.T) {
  function TestGetContext_NotFoundReturns404 (line 63) | func TestGetContext_NotFoundReturns404(t *testing.T) {
  function TestGetContext_MissingIDReturns400 (line 82) | func TestGetContext_MissingIDReturns400(t *testing.T) {

FILE: components/execd/pkg/web/controller/command.go
  method RunCommand (line 30) | func (c *CodeInterpretingController) RunCommand() {
  method InterruptCommand (line 73) | func (c *CodeInterpretingController) InterruptCommand() {
  method GetCommandStatus (line 78) | func (c *CodeInterpretingController) GetCommandStatus() {
  method GetBackgroundCommandOutput (line 109) | func (c *CodeInterpretingController) GetBackgroundCommandOutput() {
  method buildExecuteCommandRequest (line 128) | func (c *CodeInterpretingController) buildExecuteCommandRequest(request ...

FILE: components/execd/pkg/web/controller/command_test.go
  function TestBuildExecuteCommandRequestForwardsEnvs (line 29) | func TestBuildExecuteCommandRequestForwardsEnvs(t *testing.T) {
  function TestBuildExecuteCommandRequestForwardsEnvsBackground (line 45) | func TestBuildExecuteCommandRequestForwardsEnvsBackground(t *testing.T) {
  function setupCommandController (line 60) | func setupCommandController(method, path string) (*CodeInterpretingContr...
  function TestGetCommandStatus_MissingID (line 66) | func TestGetCommandStatus_MissingID(t *testing.T) {
  function TestGetBackgroundCommandOutput_MissingID (line 79) | func TestGetBackgroundCommandOutput_MissingID(t *testing.T) {

FILE: components/execd/pkg/web/controller/filesystem.go
  type FilesystemController (line 37) | type FilesystemController struct
    method handleFileError (line 45) | func (c *FilesystemController) handleFileError(err error) {
    method GetFilesInfo (line 62) | func (c *FilesystemController) GetFilesInfo() {
    method RemoveFiles (line 83) | func (c *FilesystemController) RemoveFiles() {
    method ChmodFiles (line 100) | func (c *FilesystemController) ChmodFiles() {
    method RenameFiles (line 127) | func (c *FilesystemController) RenameFiles() {
    method MakeDirs (line 149) | func (c *FilesystemController) MakeDirs() {
    method RemoveDirs (line 171) | func (c *FilesystemController) RemoveDirs() {
    method SearchFiles (line 188) | func (c *FilesystemController) SearchFiles() {
    method ReplaceContent (line 283) | func (c *FilesystemController) ReplaceContent() {
  function NewFilesystemController (line 41) | func NewFilesystemController(ctx *gin.Context) *FilesystemController {

FILE: components/execd/pkg/web/controller/filesystem_download.go
  method DownloadFile (line 30) | func (c *FilesystemController) DownloadFile() {
  function formatContentDisposition (line 88) | func formatContentDisposition(filename string) string {

FILE: components/execd/pkg/web/controller/filesystem_test.go
  function newFilesystemController (line 31) | func newFilesystemController(t *testing.T, method, rawURL string, body [...
  function TestFilesystemControllerGetFilesInfo (line 38) | func TestFilesystemControllerGetFilesInfo(t *testing.T) {
  function TestFilesystemControllerSearchFiles (line 57) | func TestFilesystemControllerSearchFiles(t *testing.T) {
  function TestFilesystemControllerReplaceContent (line 76) | func TestFilesystemControllerReplaceContent(t *testing.T) {
  function TestFilesystemControllerSearchFilesHandlesAbsentDir (line 99) | func TestFilesystemControllerSearchFilesHandlesAbsentDir(t *testing.T) {
  function TestReplaceContentFailsUnknownFile (line 108) | func TestReplaceContentFailsUnknownFile(t *testing.T) {
  function TestFormatContentDisposition (line 122) | func TestFormatContentDisposition(t *testing.T) {

FILE: components/execd/pkg/web/controller/filesystem_upload.go
  method UploadFile (line 30) | func (c *FilesystemController) UploadFile() {

FILE: components/execd/pkg/web/controller/filesystem_windows.go
  type FilesystemController (line 35) | type FilesystemController struct
    method handleFileError (line 43) | func (c *FilesystemController) handleFileError(err error) {
    method GetFilesInfo (line 60) | func (c *FilesystemController) GetFilesInfo() {
    method RemoveFiles (line 81) | func (c *FilesystemController) RemoveFiles() {
    method ChmodFiles (line 98) | func (c *FilesystemController) ChmodFiles() {
    method RenameFiles (line 125) | func (c *FilesystemController) RenameFiles() {
    method MakeDirs (line 147) | func (c *FilesystemController) MakeDirs() {
    method RemoveDirs (line 169) | func (c *FilesystemController) RemoveDirs() {
    method SearchFiles (line 186) | func (c *FilesystemController) SearchFiles() {
    method ReplaceContent (line 269) | func (c *FilesystemController) ReplaceContent() {
  function NewFilesystemController (line 39) | func NewFilesystemController(ctx *gin.Context) *FilesystemController {

FILE: components/execd/pkg/web/controller/metric.go
  type MetricController (line 33) | type MetricController struct
    method GetMetrics (line 42) | func (c *MetricController) GetMetrics() {
    method WatchMetrics (line 57) | func (c *MetricController) WatchMetrics() {
    method readMetrics (line 91) | func (c *MetricController) readMetrics() (*model.Metrics, error) {
  function NewMetricController (line 37) | func NewMetricController(ctx *gin.Context) *MetricController {

FILE: components/execd/pkg/web/controller/metric_test.go
  function setupMetricController (line 29) | func setupMetricController(method, path string) (*MetricController, *htt...
  function TestReadMetrics (line 36) | func TestReadMetrics(t *testing.T) {
  function TestGetMetricsEndpoint (line 64) | func TestGetMetricsEndpoint(t *testing.T) {
  function TestWatchMetricsHeaders (line 83) | func TestWatchMetricsHeaders(t *testing.T) {
  function TestMetricSerialization (line 102) | func TestMetricSerialization(t *testing.T) {

FILE: components/execd/pkg/web/controller/mock_test.go
  type mockOutput (line 22) | type mockOutput struct
    method Header (line 28) | func (m *mockOutput) Header() http.Header {
    method Write (line 35) | func (m *mockOutput) Write(b []byte) (int, error) {
    method WriteHeader (line 39) | func (m *mockOutput) WriteHeader(code int) {
    method Status (line 43) | func (m *mockOutput) Status() int {
    method Body (line 47) | func (m *mockOutput) Body() []byte {

FILE: components/execd/pkg/web/controller/ping.go
  type MainController (line 20) | type MainController struct
    method Ping (line 29) | func (c *MainController) Ping() {
  function NewMainController (line 24) | func NewMainController(ctx *gin.Context) *MainController {
  function PingHandler (line 34) | func PingHandler(ctx *gin.Context) {

FILE: components/execd/pkg/web/controller/sse.go
  method setupSSEResponse (line 39) | func (c *basicController) setupSSEResponse() {
  method setServerEventsHandler (line 49) | func (c *CodeInterpretingController) setServerEventsHandler(ctx context....
  method writeSingleEvent (line 156) | func (c *CodeInterpretingController) writeSingleEvent(handler string, da...
  method ping (line 192) | func (c *CodeInterpretingController) ping(ctx context.Context) {

FILE: components/execd/pkg/web/controller/syscall_linux.go
  function getFileCreateTime (line 26) | func getFileCreateTime(fileInfo os.FileInfo) time.Time {

FILE: components/execd/pkg/web/controller/syscall_others.go
  function getFileCreateTime (line 25) | func getFileCreateTime(_ os.FileInfo) time.Time {

FILE: components/execd/pkg/web/controller/test_helpers.go
  function newTestContext (line 25) | func newTestContext(method, path string, body []byte) (*gin.Context, *ht...

FILE: components/execd/pkg/web/controller/utils.go
  function DeleteFile (line 34) | func DeleteFile(filePath string) error {
  function ChmodFile (line 59) | func ChmodFile(file string, perms model.Permission) error {
  function SetFileOwnership (line 78) | func SetFileOwnership(absPath string, owner string, group string) error {
  function RenameFile (line 119) | func RenameFile(item model.RenameFileItem) error {
  function MakeDir (line 151) | func MakeDir(dir string, perm model.Permission) error {
  function GetFileInfo (line 164) | func GetFileInfo(filePath string) (model.FileInfo, error) {
  function SearchFileMetadata (line 205) | func SearchFileMetadata(metadata map[string]model.FileMetadata, filePath...
  type httpRange (line 216) | type httpRange struct
  function ParseRange (line 220) | func ParseRange(s string, size int64) ([]httpRange, error) {

FILE: components/execd/pkg/web/controller/utils_test.go
  function TestDeleteFile (line 27) | func TestDeleteFile(t *testing.T) {
  function TestRenameFile (line 40) | func TestRenameFile(t *testing.T) {
  function TestSearchFileMetadata (line 58) | func TestSearchFileMetadata(t *testing.T) {
  function TestParseRange (line 73) | func TestParseRange(t *testing.T) {

FILE: components/execd/pkg/web/controller/utils_windows.go
  function DeleteFile (line 33) | func DeleteFile(filePath string) error {
  function ChmodFile (line 58) | func ChmodFile(file string, perms model.Permission) error {
  function SetFileOwnership (line 78) | func SetFileOwnership(_ string, _ string, _ string) error {
  function RenameFile (line 83) | func RenameFile(item model.RenameFileItem) error {
  function MakeDir (line 115) | func MakeDir(dir string, perm model.Permission) error {
  function GetFileInfo (line 128) | func GetFileInfo(filePath string) (model.FileInfo, error) {
  function SearchFileMetadata (line 165) | func SearchFileMetadata(metadata map[string]model.FileMetadata, filePath...
  type httpRange (line 176) | type httpRange struct
  function ParseRange (line 180) | func ParseRange(s string, size int64) ([]httpRange, error) {

FILE: components/execd/pkg/web/model/codeinterpreting.go
  type RunCodeRequest (line 29) | type RunCodeRequest struct
    method Validate (line 34) | func (r *RunCodeRequest) Validate() error {
  type CodeContext (line 40) | type CodeContext struct
  type CodeContextRequest (line 45) | type CodeContextRequest struct
  type RunCommandRequest (line 51) | type RunCommandRequest struct
    method Validate (line 63) | func (r *RunCommandRequest) Validate() error {
  type ServerStreamEventType (line 74) | type ServerStreamEventType
  constant StreamEventTypeInit (line 77) | StreamEventTypeInit     ServerStreamEventType = "init"
  constant StreamEventTypeStatus (line 78) | StreamEventTypeStatus   ServerStreamEventType = "status"
  constant StreamEventTypeError (line 79) | StreamEventTypeError    ServerStreamEventType = "error"
  constant StreamEventTypeStdout (line 80) | StreamEventTypeStdout   ServerStreamEventType = "stdout"
  constant StreamEventTypeStderr (line 81) | StreamEventTypeStderr   ServerStreamEventType = "stderr"
  constant StreamEventTypeResult (line 82) | StreamEventTypeResult   ServerStreamEventType = "result"
  constant StreamEventTypeComplete (line 83) | StreamEventTypeComplete ServerStreamEventType = "execution_complete"
  constant StreamEventTypeCount (line 84) | StreamEventTypeCount    ServerStreamEventType = "execution_count"
  constant StreamEventTypePing (line 85) | StreamEventTypePing     ServerStreamEventType = "ping"
  type ServerStreamEvent (line 89) | type ServerStreamEvent struct
    method ToJSON (line 100) | func (s ServerStreamEvent) ToJSON() []byte {
    method Summary (line 106) | func (s ServerStreamEvent) Summary() string {
  function truncateString (line 127) | func truncateString(value string, maxCount int) string {

FILE: components/execd/pkg/web/model/codeinterpreting_test.go
  function TestRunCodeRequestValidate (line 26) | func TestRunCodeRequestValidate(t *testing.T) {
  function TestRunCommandRequestValidate (line 36) | func TestRunCommandRequestValidate(t *testing.T) {
  function ptr32 (line 52) | func ptr32(v uint32) *uint32 { return &v }
  function TestRunCommandRequestValidateUidGid (line 54) | func TestRunCommandRequestValidateUidGid(t *testing.T) {
  function TestServerStreamEventToJSON (line 68) | func TestServerStreamEventToJSON(t *testing.T) {
  function TestServerStreamEventSummary (line 83) | func TestServerStreamEventSummary(t *testing.T) {

FILE: components/execd/pkg/web/model/command.go
  type CommandStatusResponse (line 20) | type CommandStatusResponse struct

FILE: components/execd/pkg/web/model/error.go
  type ErrorCode (line 17) | type ErrorCode
  constant ErrorCodeInvalidRequest (line 20) | ErrorCodeInvalidRequest      ErrorCode = "INVALID_REQUEST_BODY"
  constant ErrorCodeMissingQuery (line 21) | ErrorCodeMissingQuery        ErrorCode = "MISSING_QUERY"
  constant ErrorCodeRuntimeError (line 22) | ErrorCodeRuntimeError        ErrorCode = "RUNTIME_ERROR"
  constant ErrorCodeInvalidFile (line 23) | ErrorCodeInvalidFile         ErrorCode = "INVALID_FILE"
  constant ErrorCodeInvalidFileContent (line 24) | ErrorCodeInvalidFileContent  ErrorCode = "INVALID_FILE_CONTENT"
  constant ErrorCodeInvalidFileMetadata (line 25) | ErrorCodeInvalidFileMetadata ErrorCode = "INVALID_FILE_METADATA"
  constant ErrorCodeFileNotFound (line 26) | ErrorCodeFileNotFound        ErrorCode = "FILE_NOT_FOUND"
  constant ErrorCodeUnknown (line 27) | ErrorCodeUnknown             ErrorCode = "UNKNOWN"
  constant ErrorCodeContextNotFound (line 28) | ErrorCodeContextNotFound     ErrorCode = "CONTEXT_NOT_FOUND"
  type ErrorResponse (line 31) | type ErrorResponse struct

FILE: components/execd/pkg/web/model/filesystem.go
  type FileInfo (line 20) | type FileInfo struct
  type FileMetadata (line 28) | type FileMetadata struct
  type Permission (line 34) | type Permission struct
  type RenameFileItem (line 41) | type RenameFileItem struct
  type ReplaceFileContentItem (line 47) | type ReplaceFileContentItem struct

FILE: components/execd/pkg/web/model/header.go
  constant ApiAccessTokenHeader (line 19) | ApiAccessTokenHeader = "X-EXECD-ACCESS-TOKEN"

FILE: components/execd/pkg/web/model/metric.go
  type Metrics (line 20) | type Metrics struct
  function NewMetrics (line 28) | func NewMetrics() *Metrics {

FILE: components/execd/pkg/web/model/session.go
  type CreateSessionRequest (line 22) | type CreateSessionRequest struct
  type CreateSessionResponse (line 27) | type CreateSessionResponse struct
  type RunInSessionRequest (line 32) | type RunInSessionRequest struct
    method Validate (line 39) | func (r *RunInSessionRequest) Validate() error {

FILE: components/execd/pkg/web/proxy.go
  function ProxyMiddleware (line 30) | func ProxyMiddleware() gin.HandlerFunc {
  function getClientIP (line 110) | func getClientIP(r *http.Request) string {

FILE: components/execd/pkg/web/router.go
  function NewRouter (line 28) | func NewRouter(accessToken string) *gin.Engine {
  function withFilesystem (line 89) | func withFilesystem(fn func(*controller.FilesystemController)) gin.Handl...
  function withCode (line 95) | func withCode(fn func(*controller.CodeInterpretingController)) gin.Handl...
  function withMetric (line 101) | func withMetric(fn func(*controller.MetricController)) gin.HandlerFunc {
  function accessTokenMiddleware (line 107) | func accessTokenMiddleware(token string) gin.HandlerFunc {
  function logMiddleware (line 126) | func logMiddleware() gin.HandlerFunc {

FILE: components/execd/tests/smoke_api.py
  function expect (line 47) | def expect(cond: bool, msg: str):
  function sse_get_command_id (line 52) | def sse_get_command_id() -> str:
  function wait_status (line 73) | def wait_status(cmd_id: str, timeout: float = 15.0) -> dict:
  function fetch_logs (line 87) | def fetch_logs(cmd_id: str, cursor: int = 0):
  function sse_disconnect_should_stop_ping (line 94) | def sse_disconnect_should_stop_ping():
  function upload_and_download (line 130) | def upload_and_download():
  function filesystem_smoke (line 146) | def filesystem_smoke():
  function main (line 216) | def main():

FILE: components/ingress/main.go
  function main (line 36) | func main() {
  function withLogger (line 95) | func withLogger(ctx context.Context, logLevel string) context.Context {

FILE: components/ingress/pkg/flag/parser.go
  function InitFlags (line 21) | func InitFlags() {

FILE: components/ingress/pkg/proxy/healthz.go
  function Healthz (line 19) | func Healthz(w http.ResponseWriter, _ *http.Request) {

FILE: components/ingress/pkg/proxy/healthz_test.go
  function TestHealthz (line 25) | func TestHealthz(t *testing.T) {

FILE: components/ingress/pkg/proxy/host.go
  type Mode (line 25) | type Mode
  constant ModeHeader (line 30) | ModeHeader Mode = "header"
  constant ModeURI (line 36) | ModeURI Mode = "uri"
  method getSandboxHostDefinition (line 39) | func (p *Proxy) getSandboxHostDefinition(r *http.Request) (*sandboxHost,...
  method parseTargetHostByHeader (line 59) | func (p *Proxy) parseTargetHostByHeader(r *http.Request) string {
  type sandboxHost (line 72) | type sandboxHost struct
  method parseSandboxHost (line 78) | func (p *Proxy) parseSandboxHost(s string) (*sandboxHost, error) {
  method parseSandboxURI (line 97) | func (p *Proxy) parseSandboxURI(r *http.Request) (*sandboxHost, error) {

FILE: components/ingress/pkg/proxy/http.go
  type HTTPProxy (line 23) | type HTTPProxy struct
    method ServeHTTP (line 29) | func (hp *HTTPProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    method newReverseProxy (line 41) | func (hp *HTTPProxy) newReverseProxy(targetHost string) (*httputil.Rev...
  function NewHTTPProxy (line 25) | func NewHTTPProxy() *HTTPProxy {

FILE: components/ingress/pkg/proxy/http_test.go
  type mockProvider (line 33) | type mockProvider struct
    method GetEndpoint (line 38) | func (m *mockProvider) GetEndpoint(sandboxId string) (string, error) {
    method Start (line 48) | func (m *mockProvider) Start(_ context.Context) error {
  function Test_HTTPProxy (line 52) | func Test_HTTPProxy(t *testing.T) {
  function httpProxyWithHeaderMode (line 62) | func httpProxyWithHeaderMode(t *testing.T) {
  function httpProxyWithURIMode (line 136) | func httpProxyWithURIMode(t *testing.T) {
  function realBackendHTTPHandler (line 193) | func realBackendHTTPHandler(w http.ResponseWriter, r *http.Request) {

FILE: components/ingress/pkg/proxy/logger.go
  function WithLogger (line 25) | func WithLogger(ctx context.Context, logger slogger.Logger) context.Cont...

FILE: components/ingress/pkg/proxy/proxy.go
  type Proxy (line 30) | type Proxy struct
    method ServeHTTP (line 44) | func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    method serve (line 92) | func (p *Proxy) serve(w http.ResponseWriter, r *http.Request) {
    method isWebSocketRequest (line 119) | func (p *Proxy) isWebSocketRequest(r *http.Request) bool {
    method resolveRealHost (line 132) | func (p *Proxy) resolveRealHost(host *sandboxHost) (string, error, int) {
    method getClientIP (line 152) | func (p *Proxy) getClientIP(r *http.Request) string {
  function NewProxy (line 36) | func NewProxy(_ context.Context, sandboxProvider sandbox.Provider, mode ...

FILE: components/ingress/pkg/proxy/proxy_test.go
  function TestIsWebSocketRequest (line 28) | func TestIsWebSocketRequest(t *testing.T) {
  function TestParseSandboxHost (line 48) | func TestParseSandboxHost(t *testing.T) {
  function TestGetClientIP (line 68) | func TestGetClientIP(t *testing.T) {
  function findAvailablePort (line 86) | func findAvailablePort() (int, error) {

FILE: components/ingress/pkg/proxy/websocket.go
  type WebSocketProxy (line 43) | type WebSocketProxy struct
    method ServeHTTP (line 82) | func (w *WebSocketProxy) ServeHTTP(rw http.ResponseWriter, r *http.Req...
  function ProxyHandler (line 65) | func ProxyHandler(target *url.URL) http.Handler { return NewWebSocketPro...
  function NewWebSocketProxy (line 69) | func NewWebSocketProxy(target *url.URL) *WebSocketProxy {
  function copyResponse (line 224) | func copyResponse(rw http.ResponseWriter, resp *http.Response) error {
  function copyHeader (line 233) | func copyHeader(dst, src http.Header) {

FILE: components/ingress/pkg/proxy/websocket_test.go
  function Test_WebSocketProxy (line 32) | func Test_WebSocketProxy(t *testing.T) {
  function webSocketProxyWithHeaderMode (line 41) | func webSocketProxyWithHeaderMode(t *testing.T) {
  function webSocketProxyWithURIMode (line 133) | func webSocketProxyWithURIMode(t *testing.T) {

FILE: components/ingress/pkg/renewintent/intent.go
  type Intent (line 19) | type Intent struct
  function NewIntent (line 26) | func NewIntent(sandboxID string, port int, requestURI string) Intent {

FILE: components/ingress/pkg/renewintent/intent_test.go
  function TestNewIntent (line 24) | func TestNewIntent(t *testing.T) {
  function TestIntent_JSONRoundTrip (line 32) | func TestIntent_JSONRoundTrip(t *testing.T) {
  function TestIntent_JSONHasRequiredFields (line 44) | func TestIntent_JSONHasRequiredFields(t *testing.T) {

FILE: components/ingress/pkg/renewintent/publisher.go
  type Publisher (line 17) | type Publisher interface

FILE: components/ingress/pkg/renewintent/redis.go
  constant redisOpTimeout (line 31) | redisOpTimeout = 5 * time.Second
  constant publishWorkers (line 32) | publishWorkers = 4
  constant publishChanCap (line 33) | publishChanCap = 8192
  type RedisPublisherConfig (line 36) | type RedisPublisherConfig struct
  type intentReq (line 43) | type intentReq struct
  type RedisPublisher (line 49) | type RedisPublisher struct
    method shouldSendIntent (line 83) | func (p *RedisPublisher) shouldSendIntent(sandboxID string) bool {
    method PublishIntent (line 97) | func (p *RedisPublisher) PublishIntent(sandboxID string, port int, req...
    method doPublish (line 107) | func (p *RedisPublisher) doPublish(sandboxID string, port int, request...
    method runCleanupThrottle (line 152) | func (p *RedisPublisher) runCleanupThrottle(_ context.Context) {
  function NewRedisPublisher (line 57) | func NewRedisPublisher(ctx context.Context, client *redis.Client, cfg Re...
  function RedisClientFromDSN (line 141) | func RedisClientFromDSN(dsn string) (*redis.Client, error) {

FILE: components/ingress/pkg/renewintent/redis_bench_test.go
  type nopLogger (line 27) | type nopLogger struct
    method Debugf (line 29) | func (nopLogger) Debugf(string, ...any)                {}
    method Infof (line 30) | func (nopLogger) Infof(string, ...any)                 {}
    method Warnf (line 31) | func (nopLogger) Warnf(string, ...any)                 {}
    method Errorf (line 32) | func (nopLogger) Errorf(string, ...any)                {}
    method With (line 33) | func (n nopLogger) With(...logger.Field) logger.Logger { return n }
    method Named (line 34) | func (n nopLogger) Named(string) logger.Logger         { return n }
    method Sync (line 35) | func (nopLogger) Sync() error                          { return nil }
  function BenchmarkRedisPublisher_PublishIntent (line 39) | func BenchmarkRedisPublisher_PublishIntent(b *testing.B) {
  function BenchmarkRedisPublisher_PublishIntent_Throttled (line 70) | func BenchmarkRedisPublisher_PublishIntent_Throttled(b *testing.B) {
  function BenchmarkRedisPublisher_PublishIntent_ManySandboxes (line 100) | func BenchmarkRedisPublisher_PublishIntent_ManySandboxes(b *testing.B) {

FILE: components/ingress/pkg/sandbox/agent_sandbox_provider.go
  constant agentSandboxGroup (line 38) | agentSandboxGroup    = "agents.x-k8s.io"
  constant agentSandboxVersion (line 39) | agentSandboxVersion  = "v1alpha1"
  constant agentSandboxResource (line 40) | agentSandboxResource = "sandboxes"
  constant agentSandboxConditionReady (line 42) | agentSandboxConditionReady = "Ready"
  constant agentSandboxNamePrefix (line 43) | agentSandboxNamePrefix     = "sandbox"
  type AgentSandboxProvider (line 53) | type AgentSandboxProvider struct
    method GetEndpoint (line 160) | func (a *AgentSandboxProvider) GetEndpoint(sandboxId string) (string, ...
    method Start (line 205) | func (a *AgentSandboxProvider) Start(ctx context.Context) error {
    method checkSandboxReadyCondition (line 219) | func (a *AgentSandboxProvider) checkSandboxReadyCondition(status map[s...
  function NewAgentSandboxProvider (line 61) | func NewAgentSandboxProvider(config *rest.Config, namespace string, resy...
  function newAgentSandboxProviderWithClient (line 71) | func newAgentSandboxProviderWithClient(dyn dynamic.Interface, namespace ...
  function agentSandboxResourceName (line 95) | func agentSandboxResourceName(sandboxId string) string {
  function toDNS1035Label (line 99) | func toDNS1035Label(value, prefix string) string {
  function startsWithLetter (line 130) | func startsWithLetter(value string) bool {
  function legacyAgentSandboxName (line 138) | func legacyAgentSandboxName(sandboxId string) string {
  function resourceNameCandidates (line 146) | func resourceNameCandidates(sandboxId string) []string {

FILE: components/ingress/pkg/sandbox/agent_sandbox_provider_test.go
  function buildUnstructuredSandbox (line 32) | func buildUnstructuredSandbox(name, namespace string) *unstructured.Unst...
  function TestAgentSandboxProvider_Start_Success (line 53) | func TestAgentSandboxProvider_Start_Success(t *testing.T) {
  function TestAgentSandboxProvider_Start_ContextCancelled (line 88) | func TestAgentSandboxProvider_Start_ContextCancelled(t *testing.T) {
  function TestAgentSandboxProvider_GetEndpoint_ServiceFQDN (line 113) | func TestAgentSandboxProvider_GetEndpoint_ServiceFQDN(t *testing.T) {
  function TestAgentSandboxProvider_GetEndpoint_NotFound (line 155) | func TestAgentSandboxProvider_GetEndpoint_NotFound(t *testing.T) {
  function TestAgentSandboxProvider_GetEndpoint_NoServiceFQDN (line 183) | func TestAgentSandboxProvider_GetEndpoint_NoServiceFQDN(t *testing.T) {
  function TestAgentSandboxProvider_GetEndpoint_NotReadyCondition (line 217) | func TestAgentSandboxProvider_GetEndpoint_NotReadyCondition(t *testing.T) {
  function TestToDNS1035Label_HashOnSymbolOnlyIDs (line 261) | func TestToDNS1035Label_HashOnSymbolOnlyIDs(t *testing.T) {
  function TestToDNS1035Label_PrefixesDigitStart (line 270) | func TestToDNS1035Label_PrefixesDigitStart(t *testing.T) {
  function TestToDNS1035Label_TruncatesWithHashSuffix (line 275) | func TestToDNS1035Label_TruncatesWithHashSuffix(t *testing.T) {

FILE: components/ingress/pkg/sandbox/batchsandbox_provider.go
  type BatchSandboxProvider (line 34) | type BatchSandboxProvider struct
    method Start (line 69) | func (p *BatchSandboxProvider) Start(ctx context.Context) error {
    method GetEndpoint (line 81) | func (p *BatchSandboxProvider) GetEndpoint(sandboxId string) (string, ...
  function NewBatchSandboxProvider (line 42) | func NewBatchSandboxProvider(

FILE: components/ingress/pkg/sandbox/batchsandbox_provider_test.go
  function TestBatchSandboxProvider_WithFakeInformer (line 36) | func TestBatchSandboxProvider_WithFakeInformer(t *testing.T) {
  function TestBatchSandboxProvider_MissingAnnotation (line 130) | func TestBatchSandboxProvider_MissingAnnotation(t *testing.T) {
  function TestBatchSandboxProvider_InvalidAnnotation (line 181) | func TestBatchSandboxProvider_InvalidAnnotation(t *testing.T) {
  function TestBatchSandboxProvider_DynamicUpdate (line 234) | func TestBatchSandboxProvider_DynamicUpdate(t *testing.T) {
  function TestBatchSandboxProvider_StartCacheSyncFailure (line 295) | func TestBatchSandboxProvider_StartCacheSyncFailure(t *testing.T) {
  function TestBatchSandboxProvider_GetEndpointNonNotFoundError (line 327) | func TestBatchSandboxProvider_GetEndpointNonNotFoundError(t *testing.T) {
  function ptr (line 381) | func ptr(i int32) *int32 {

FILE: components/ingress/pkg/sandbox/errors_test.go
  function TestErrSandboxNotReadyWrapping (line 24) | func TestErrSandboxNotReadyWrapping(t *testing.T) {

FILE: components/ingress/pkg/sandbox/factory.go
  type DefaultProviderFactory (line 25) | type DefaultProviderFactory struct
    method CreateProvider (line 41) | func (f *DefaultProviderFactory) CreateProvider(providerType ProviderT...
  function NewProviderFactory (line 32) | func NewProviderFactory(config *rest.Config, namespace string, resyncPer...

FILE: components/ingress/pkg/sandbox/provider.go
  type ProviderType (line 22) | type ProviderType
    method String (line 29) | func (tpy ProviderType) String() string { return string(tpy) }
  constant ProviderTypeBatchSandbox (line 25) | ProviderTypeBatchSandbox ProviderType = "batchsandbox"
  constant ProviderTypeAgentSandbox (line 26) | ProviderTypeAgentSandbox ProviderType = "agent-sandbox"
  type Provider (line 43) | type Provider interface
  type ProviderFactory (line 58) | type ProviderFactory interface

FILE: components/internal/logger/logger.go
  type Field (line 18) | type Field struct
  type Logger (line 28) | type Logger interface

FILE: components/internal/logger/zap.go
  constant envLogOutput (line 25) | envLogOutput = "OPENSANDBOX_LOG_OUTPUT"
  type Config (line 32) | type Config struct
  function New (line 39) | func New(cfg Config) (Logger, error) {
  function MustNew (line 61) | func MustNew(cfg Config) Logger {
  function AsZapSugared (line 70) | func AsZapSugared(l Logger) (*zap.SugaredLogger, bool) {
  type zapLogger (line 78) | type zapLogger struct
    method Debugf (line 83) | func (l *zapLogger) Debugf(template string, args ...any) {
    method Infof (line 87) | func (l *zapLogger) Infof(template string, args ...any) {
    method Warnf (line 91) | func (l *zapLogger) Warnf(template string, args ...any) {
    method Errorf (line 95) | func (l *zapLogger) Errorf(template string, args ...any) {
    method With (line 99) | func (l *zapLogger) With(fields ...Field) Logger {
    method Named (line 111) | func (l *zapLogger) Named(name string) Logger {
    method Sync (line 116) | func (l *zapLogger) Sync() error {
  function parseLevel (line 120) | func parseLevel(level string) zapcore.Level {
  function applyEnvOutputs (line 135) | func applyEnvOutputs(cfg Config) Config {
  function splitAndTrim (line 151) | func splitAndTrim(s string) []string {

FILE: components/internal/version/version.go
  function EchoVersion (line 34) | func EchoVersion(componentName string) {

FILE: docs/.vitepress/scripts/docs-manifest.mjs
  function ensureDir (line 220) | function ensureDir(dirPath) {
  function rmIfExists (line 224) | function rmIfExists(targetPath) {
  function walkMarkdownFiles (line 230) | function walkMarkdownFiles(absDirPath, acc = []) {
  function shouldIgnoreRepoPath (line 251) | function shouldIgnoreRepoPath(repoRelPath) {
  function toRepoRelative (line 269) | function toRepoRelative(absPath) {
  function readHeadingTitle (line 273) | function readHeadingTitle(absPath, fallbackTitle) {
  function normalizeTitleWhitespace (line 297) | function normalizeTitleWhitespace(title) {
  function shortenOsepTitle (line 301) | function shortenOsepTitle(repoRelPath, title, locale = "en") {
  function shortenTitleByRule (line 335) | function shortenTitleByRule(title) {
  function shortenTitleByRuleZh (line 346) | function shortenTitleByRuleZh(title) {
  function getShortTitle (line 357) | function getShortTitle(repoRelPath, currentTitle, locale = "en") {
  function toYamlString (line 373) | function toYamlString(value) {
  function normalizeSlugFromPath (line 377) | function normalizeSlugFromPath(relPath) {
  function resolveZhCandidate (line 392) | function resolveZhCandidate(repoRelPath, readmeCandidatesByDir) {
  function buildGeneratedAssetPath (line 403) | function buildGeneratedAssetPath(locale, routeSlug, resolvedRepoPath) {
  function normalizeLinkTarget (line 420) | function normalizeLinkTarget(target, sourceDirRel, isImage, routeSlug, l...
  function rewriteRelativeLinks (line 455) | function rewriteRelativeLinks(markdown, sourceRelPath, routeSlug, locale) {
  function renderPageSource (line 482) | function renderPageSource({ locale, title, sourceRelPath, routeSlug, pas...
  function prettifyPathTitle (line 502) | function prettifyPathTitle(repoRelPath) {
  function collectAutoEntries (line 518) | function collectAutoEntries() {
  function buildEntries (line 603) | function buildEntries() {
  function toSidebarItems (line 617) | function toSidebarItems(entries, locale) {
  function buildOverviewSidebar (line 626) | function buildOverviewSidebar(entries, locale) {
  function buildModulesSidebar (line 648) | function buildModulesSidebar(entries, locale) {
  function buildExamplesSidebar (line 673) | function buildExamplesSidebar(entries, locale) {
  function buildCommunitySidebar (line 681) | function buildCommunitySidebar(entries, locale) {
  function buildSidebarByPath (line 709) | function buildSidebarByPath(entries, locale) {
  function writeGeneratedPages (line 730) | function writeGeneratedPages(entries) {
  function buildManifest (line 786) | function buildManifest() {
  function loadManifest (line 818) | function loadManifest() {

FILE: examples/agent-sandbox/main.py
  function main (line 23) | async def main() -> None:

FILE: examples/aio-sandbox/main.py
  function check_aio_process (line 34) | def check_aio_process(sbx: SandboxSync) -> bool:
  function main (line 63) | def main() -> None:

FILE: examples/chrome/main.go
  function main (line 30) | func main() {
  function run (line 38) | func run(ctx context.Context) error {
  type Chrome (line 80) | type Chrome struct
    method Run (line 83) | func (c *Chrome) Run(ctx context.Context) error {
    method WaitForReady (line 101) | func (c *Chrome) WaitForReady(ctx context.Context) error {
  type VNCServer (line 146) | type VNCServer struct
    method Run (line 149) | func (v *VNCServer) Run(ctx context.Context) error {
    method WaitForReady (line 173) | func (v *VNCServer) WaitForReady(ctx context.Context) error {

FILE: examples/chrome/main.py
  function main (line 22) | async def main():

FILE: examples/claude-code/main.py
  function _required_env (line 23) | def _required_env(name: str) -> str:
  function _print_execution_logs (line 30) | async def _print_execution_logs(execution) -> None:
  function main (line 39) | async def main() -> None:

FILE: examples/code-interpreter/main.py
  function main (line 24) | async def main() -> None:

FILE: examples/code-interpreter/main_use_pool.py
  function main (line 24) | async def main() -> None:

FILE: examples/codex-cli/main.py
  function _required_env (line 23) | def _required_env(name: str) -> str:
  function _print_execution_logs (line 30) | async def _print_execution_logs(execution) -> None:
  function main (line 39) | async def main() -> None:

FILE: examples/desktop/main.py
  function _required_env (line 24) | def _required_env(name: str) -> str:
  function _print_logs (line 31) | async def _print_logs(label: str, execution) -> None:
  function main (line 40) | async def main() -> None:

FILE: examples/docker-ossfs-volume-mount/main.py
  function _required_env (line 48) | def _required_env(name: str) -> str:
  function build_ossfs (line 55) | def build_ossfs() -> OSSFS:
  function print_exec (line 64) | async def print_exec(sandbox: Sandbox, command: str) -> str:
  function demo_basic_mount (line 77) | async def demo_basic_mount(config: ConnectionConfig, image: str, run_id:...
  function demo_cross_sandbox_sharing (line 107) | async def demo_cross_sandbox_sharing(config: ConnectionConfig, image: st...
  function demo_subpath_mounts (line 153) | async def demo_subpath_mounts(config: ConnectionConfig, image: str, run_...
  function main (line 209) | async def main() -> None:

FILE: examples/docker-pvc-volume-mount/main.py
  function print_exec (line 64) | async def print_exec(sandbox: Sandbox, command: str) -> str | None:
  function ensure_named_volume (line 76) | def ensure_named_volume() -> None:
  function demo_readwrite_mount (line 107) | async def demo_readwrite_mount(config: ConnectionConfig, image: str) -> ...
  function demo_readonly_mount (line 162) | async def demo_readonly_mount(config: ConnectionConfig, image: str) -> N...
  function demo_cross_sandbox_sharing (line 211) | async def demo_cross_sandbox_sharing(config: ConnectionConfig, image: st...
  function demo_subpath_mount (line 269) | async def demo_subpath_mount(config: ConnectionConfig, image: str) -> None:
  function main (line 324) | async def main() -> None:

FILE: examples/gemini-cli/main.py
  function _required_env (line 23) | def _required_env(name: str) -> str:
  function _print_execution_logs (line 30) | async def _print_execution_logs(execution) -> None:
  function main (line 39) | async def main() -> None:

FILE: examples/google-adk/main.py
  function _required_env (line 29) | def _required_env(name: str) -> str:
  function main (line 36) | async def main() -> None:

FILE: examples/host-volume-mount/main.py
  function print_exec (line 60) | async def print_exec(sandbox: Sandbox, command: str) -> str | None:
  function demo_readwrite_mount (line 72) | async def demo_readwrite_mount(config: ConnectionConfig, image: str, hos...
  function demo_readonly_mount (line 131) | async def demo_readonly_mount(config: ConnectionConfig, image: str, host...
  function demo_subpath_mount (line 184) | async def demo_subpath_mount(config: ConnectionConfig, image: str, host_...
  function main (line 236) | async def main() -> None:

FILE: examples/kimi-cli/main.py
  function _required_env (line 23) | def _required_env(name: str) -> str:
  function _print_execution_logs (line 30) | async def _print_execution_logs(execution) -> None:
  function main (line 39) | async def main() -> None:

FILE: examples/kubernetes-pvc-volume-mount/main.py
  function basic_pvc_mount (line 60) | async def basic_pvc_mount():
  function main (line 120) | async def main():

FILE: examples/langgraph/main.py
  class WorkflowState (line 25) | class WorkflowState(TypedDict):
  function _configure_anthropic_env (line 37) | def _configure_anthropic_env() -> None:
  function _build_llm (line 54) | def _build_llm() -> ChatAnthropic:
  function _format_execution (line 65) | def _format_execution(execution) -> str:
  function create_sandbox (line 83) | async def create_sandbox(state: WorkflowState) -> WorkflowState:
  function prepare_workspace (line 108) | async def prepare_workspace(state: WorkflowState) -> WorkflowState:
  function run_job (line 128) | async def run_job(state: WorkflowState) -> WorkflowState:
  function decide_next (line 159) | def decide_next(state: WorkflowState) -> str:
  function inspect_results (line 168) | async def inspect_results(state: WorkflowState) -> WorkflowState:
  function cleanup_sandbox (line 188) | async def cleanup_sandbox(state: WorkflowState) -> WorkflowState:
  function main (line 200) | async def main() -> None:

FILE: examples/nullclaw/main.py
  function check_nullclaw (line 24) | def check_nullclaw(sbx: SandboxSync) -> bool:
  function main (line 52) | def main() -> None:

FILE: examples/openclaw/main.py
  function check_openclaw (line 25) | def check_openclaw(sbx: SandboxSync) -> bool:
  function main (line 53) | def main() -> None:

FILE: examples/playwright/main.py
  function _required_env (line 24) | def _required_env(name: str) -> str:
  function _print_logs (line 31) | async def _print_logs(label: str, execution) -> None:
  function main (line 40) | async def main() -> None:

FILE: examples/rl-training/main.py
  function _load_requirements (line 25) | def _load_requirements() -> str:
  function _training_script (line 30) | def _training_script() -> str:
  function _print_execution_logs (line 79) | async def _print_execution_logs(execution) -> None:
  function _execution_failed (line 88) | def _execution_failed(execution) -> bool:
  function _run_command (line 92) | async def _run_command(sandbox: Sandbox, command: str) -> bool:
  function _with_python_env (line 98) | def _with_python_env(command: str) -> str:
  function _ensure_pip (line 109) | async def _ensure_pip(sandbox: Sandbox) -> bool:
  function _install_requirements (line 122) | async def _install_requirements(sandbox: Sandbox) -> bool:
  function main (line 136) | async def main() -> None:

FILE: examples/vscode/main.py
  function _required_env (line 24) | def _required_env(name: str) -> str:
  function _print_logs (line 31) | async def _print_logs(label: str, execution) -> None:
  function main (line 40) | async def main() -> None:

FILE: kubernetes/apis/sandbox/v1alpha1/batchsandbox_types.go
  type BatchSandboxSpec (line 24) | type BatchSandboxSpec struct
  type TaskResourcePolicy (line 75) | type TaskResourcePolicy
  constant TaskResourcePolicyRetain (line 78) | TaskResourcePolicyRetain  TaskResourcePolicy = "Retain"
  constant TaskResourcePolicyRelease (line 79) | TaskResourcePolicyRelease TaskResourcePolicy = "Release"
  type BatchSandboxStatus (line 83) | type BatchSandboxStatus struct
  type BatchSandbox (line 121) | type BatchSandbox struct
  type BatchSandboxList (line 132) | type BatchSandboxList struct
  function init (line 138) | func init() {
  type TaskTemplateSpec (line 143) | type TaskTemplateSpec struct
  type TaskSpec (line 148) | type TaskSpec struct
  type ProcessTask (line 157) | type ProcessTask struct
  type TaskStatus (line 175) | type TaskStatus struct
  type TaskState (line 187) | type TaskState struct
  type TaskStateWaiting (line 200) | type TaskStateWaiting struct
  type TaskStateRunning (line 210) | type TaskStateRunning struct
  type TaskStateTerminated (line 217) | type TaskStateTerminated struct

FILE: kubernetes/apis/sandbox/v1alpha1/groupversion_info.go
  function Resource (line 40) | func Resource(resource string) schema.GroupResource {

FILE: kubernetes/apis/sandbox/v1alpha1/pool_types.go
  type PoolSpec (line 26) | type PoolSpec struct
  type CapacitySpec (line 37) | type CapacitySpec struct
  type PoolStatus (line 57) | type PoolStatus struct
  type Pool (line 79) | type Pool struct
  type PoolList (line 90) | type PoolList struct
  function init (line 96) | func init() {

FILE: kubernetes/apis/sandbox/v1alpha1/zz_generated.deepcopy.go
  method DeepCopyInto (line 27) | func (in *BatchSandbox) DeepCopyInto(out *BatchSandbox) {
  method DeepCopy (line 36) | func (in *BatchSandbox) DeepCopy() *BatchSandbox {
  method DeepCopyObject (line 46) | func (in *BatchSandbox) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 54) | func (in *BatchSandboxList) DeepCopyInto(out *BatchSandboxList) {
  method DeepCopy (line 68) | func (in *BatchSandboxList) DeepCopy() *BatchSandboxList {
  method DeepCopyObject (line 78) | func (in *BatchSandboxList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 86) | func (in *BatchSandboxSpec) DeepCopyInto(out *BatchSandboxSpec) {
  method DeepCopy (line 129) | func (in *BatchSandboxSpec) DeepCopy() *BatchSandboxSpec {
  method DeepCopyInto (line 139) | func (in *BatchSandboxStatus) DeepCopyInto(out *BatchSandboxStatus) {
  method DeepCopy (line 144) | func (in *BatchSandboxStatus) DeepCopy() *BatchSandboxStatus {
  method DeepCopyInto (line 154) | func (in *CapacitySpec) DeepCopyInto(out *CapacitySpec) {
  method DeepCopy (line 159) | func (in *CapacitySpec) DeepCopy() *CapacitySpec {
  method DeepCopyInto (line 169) | func (in *Pool) DeepCopyInto(out *Pool) {
  method DeepCopy (line 178) | func (in *Pool) DeepCopy() *Pool {
  method DeepCopyObject (line 188) | func (in *Pool) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 196) | func (in *PoolList) DeepCopyInto(out *PoolList) {
  method DeepCopy (line 210) | func (in *PoolList) DeepCopy() *PoolList {
  method DeepCopyObject (line 220) | func (in *PoolList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 228) | func (in *PoolSpec) DeepCopyInto(out *PoolSpec) {
  method DeepCopy (line 239) | func (in *PoolSpec) DeepCopy() *PoolSpec {
  method DeepCopyInto (line 249) | func (in *PoolStatus) DeepCopyInto(out *PoolStatus) {
  method DeepCopy (line 254) | func (in *PoolStatus) DeepCopy() *PoolStatus {
  method DeepCopyInto (line 264) | func (in *ProcessTask) DeepCopyInto(out *ProcessTask) {
  method DeepCopy (line 286) | func (in *ProcessTask) DeepCopy() *ProcessTask {
  method DeepCopyInto (line 296) | func (in *TaskSpec) DeepCopyInto(out *TaskSpec) {
  method DeepCopy (line 311) | func (in *TaskSpec) DeepCopy() *TaskSpec {
  method DeepCopyInto (line 321) | func (in *TaskState) DeepCopyInto(out *TaskState) {
  method DeepCopy (line 341) | func (in *TaskState) DeepCopy() *TaskState {
  method DeepCopyInto (line 351) | func (in *TaskStateRunning) DeepCopyInto(out *TaskStateRunning) {
  method DeepCopy (line 357) | func (in *TaskStateRunning) DeepCopy() *TaskStateRunning {
  method DeepCopyInto (line 367) | func (in *TaskStateTerminated) DeepCopyInto(out *TaskStateTerminated) {
  method DeepCopy (line 374) | func (in *TaskStateTerminated) DeepCopy() *TaskStateTerminated {
  method DeepCopyInto (line 384) | func (in *TaskStateWaiting) DeepCopyInto(out *TaskStateWaiting) {
  method DeepCopy (line 389) | func (in *TaskStateWaiting) DeepCopy() *TaskStateWaiting {
  method DeepCopyInto (line 399) | func (in *TaskStatus) DeepCopyInto(out *TaskStatus) {
  method DeepCopy (line 406) | func (in *TaskStatus) DeepCopy() *TaskStatus {
  method DeepCopyInto (line 416) | func (in *TaskTemplateSpec) DeepCopyInto(out *TaskTemplateSpec) {
  method DeepCopy (line 422) | func (in *TaskTemplateSpec) DeepCopy() *TaskTemplateSpec {

FILE: kubernetes/cmd/controller/main.go
  function init (line 50) | func init() {
  function main (line 58) | func main() {

FILE: kubernetes/cmd/task-executor/main.go
  function main (line 35) | func main() {

FILE: kubernetes/examples/controller/main.go
  type Controller (line 40) | type Controller struct
    method Run (line 107) | func (c *Controller) Run(ctx context.Context, workers int) error {
    method runWorker (line 127) | func (c *Controller) runWorker(ctx context.Context) {
    method processNextWorkItem (line 132) | func (c *Controller) processNextWorkItem(ctx context.Context) bool {
  function NewController (line 56) | func NewController(
  function DemonstrateClientsetUsage (line 144) | func DemonstrateClientsetUsage(ctx context.Context, client clientset.Int...
  function DemonstrateListerUsage (line 309) | func DemonstrateListerUsage(
  function main (line 370) | func main() {

FILE: kubernetes/examples/task-executor/main.go
  function main (line 26) | func main() {
  function getTaskState (line 85) | func getTaskState(task *taskexecutor.Task) string {

FILE: kubernetes/hack/pool-perf.py
  class PoolPerformanceTester (line 30) | class PoolPerformanceTester:
    method __init__ (line 31) | def __init__(self, pool_name, pool_size, replicas_per_bsb, total_bsb_c...
    method create_pool_manifest (line 47) | def create_pool_manifest(self, size):
    method create_bsb_manifest (line 67) | def create_bsb_manifest(self, name):
    method setup_pool (line 78) | async def setup_pool(self):
    method create_bsb (line 106) | async def create_bsb(self, index):
    method wait_for_allocation (line 119) | async def wait_for_allocation(self, name):
    method run (line 140) | async def run(self):
    method print_report (line 155) | def print_report(self, total_duration):
    method cleanup (line 177) | def cleanup(self):

FILE: kubernetes/internal/controller/allocator.go
  type AllocationStore (line 37) | type AllocationStore interface
  type annoAllocationStore (line 42) | type annoAllocationStore struct
    method GetAllocation (line 52) | func (store *annoAllocationStore) GetAllocation(ctx context.Context, p...
    method SetAllocation (line 72) | func (store *annoAllocationStore) SetAllocation(ctx context.Context, p...
  function NewAnnoAllocationStore (line 46) | func NewAnnoAllocationStore(client client.Client) AllocationStore {
  type AllocationSyncer (line 105) | type AllocationSyncer interface
  type annoAllocationSyncer (line 110) | type annoAllocationSyncer struct
    method SetAllocation (line 120) | func (syncer *annoAllocationSyncer) SetAllocation(ctx context.Context,...
    method GetAllocation (line 139) | func (syncer *annoAllocationSyncer) GetAllocation(ctx context.Context,...
    method GetRelease (line 156) | func (syncer *annoAllocationSyncer) GetRelease(ctx context.Context, sa...
  function NewAnnoAllocationSyncer (line 114) | func NewAnnoAllocationSyncer(client client.Client) AllocationSyncer {
  type AllocSpec (line 173) | type AllocSpec struct
  type AllocStatus (line 182) | type AllocStatus struct
  type Allocator (line 191) | type Allocator interface
  type defaultAllocator (line 205) | type defaultAllocator struct
    method Schedule (line 217) | func (allocator *defaultAllocator) Schedule(ctx context.Context, spec ...
    method initAllocation (line 254) | func (allocator *defaultAllocator) initAllocation(ctx context.Context,...
    method allocate (line 266) | func (allocator *defaultAllocator) allocate(ctx context.Context, statu...
    method doAllocate (line 289) | func (allocator *defaultAllocator) doAllocate(ctx context.Context, sta...
    method deallocate (line 334) | func (allocator *defaultAllocator) deallocate(ctx context.Context, sta...
    method doDeallocate (line 367) | func (allocator *defaultAllocator) doDeallocate(ctx context.Context, s...
    method getPodAllocation (line 393) | func (allocator *defaultAllocator) getPodAllocation(ctx context.Contex...
    method PersistPoolAllocation (line 404) | func (allocator *defaultAllocator) PersistPoolAllocation(ctx context.C...
    method syncAllocResult (line 410) | func (allocator *defaultAllocator) syncAllocResult(ctx context.Context...
    method doSyncAllocResult (line 428) | func (allocator *defaultAllocator) doSyncAllocResult(ctx context.Conte...
  function NewDefaultAllocator (line 210) | func NewDefaultAllocator(client client.Client) Allocator {

FILE: kubernetes/internal/controller/allocator_mock.go
  type MockAllocationStore (line 17) | type MockAllocationStore struct
    method EXPECT (line 35) | func (m *MockAllocationStore) EXPECT() *MockAllocationStoreMockRecorder {
    method GetAllocation (line 40) | func (m *MockAllocationStore) GetAllocation(ctx context.Context, pool ...
    method SetAllocation (line 55) | func (m *MockAllocationStore) SetAllocation(ctx context.Context, pool ...
  type MockAllocationStoreMockRecorder (line 23) | type MockAllocationStoreMockRecorder struct
    method GetAllocation (line 49) | func (mr *MockAllocationStoreMockRecorder) GetAllocation(ctx, pool int...
    method SetAllocation (line 63) | func (mr *MockAllocationStoreMockRecorder) SetAllocation(ctx, pool, al...
  function NewMockAllocationStore (line 28) | func NewMockAllocationStore(ctrl *gomock.Controller) *MockAllocationStore {
  type MockAllocationSyncer (line 69) | type MockAllocationSyncer struct
    method EXPECT (line 87) | func (m *MockAllocationSyncer) EXPECT() *MockAllocationSyncerMockRecor...
    method GetAllocation (line 92) | func (m *MockAllocationSyncer) GetAllocation(ctx context.Context, sand...
    method GetRelease (line 107) | func (m *MockAllocationSyncer) GetRelease(ctx context.Context, sandbox...
    method SetAllocation (line 122) | func (m *MockAllocationSyncer) SetAllocation(ctx context.Context, sand...
  type MockAllocationSyncerMockRecorder (line 75) | type MockAllocationSyncerMockRecorder struct
    method GetAllocation (line 101) | func (mr *MockAllocationSyncerMockRecorder) GetAllocation(ctx, sandbox...
    method GetRelease (line 116) | func (mr *MockAllocationSyncerMockRecorder) GetRelease(ctx, sandbox in...
    method SetAllocation (line 130) | func (mr *MockAllocationSyncerMockRecorder) SetAllocation(ctx, sandbox...
  function NewMockAllocationSyncer (line 80) | func NewMockAllocationSyncer(ctrl *gomock.Controller) *MockAllocationSyn...
  type MockAllocator (line 136) | type MockAllocator struct
    method EXPECT (line 154) | func (m *MockAllocator) EXPECT() *MockAllocatorMockRecorder {
    method Schedule (line 159) | func (m *MockAllocator) Schedule(ctx context.Context, spec *AllocSpec)...
  type MockAllocatorMockRecorder (line 142) | type MockAllocatorMockRecorder struct
    method Schedule (line 168) | func (mr *MockAllocatorMockRecorder) Schedule(ctx, spec interface{}) *...
  function NewMockAllocator (line 147) | func NewMockAllocator(ctrl *gomock.Controller) *MockAllocator {

FILE: kubernetes/internal/controller/allocator_test.go
  function TestAllocatorSchedule (line 30) | func TestAllocatorSchedule(t *testing.T) {

FILE: kubernetes/internal/controller/apis.go
  constant AnnoAllocStatusKey (line 27) | AnnoAllocStatusKey           = "sandbox.opensandbox.io/alloc-status"
  constant AnnoAllocReleaseKey (line 28) | AnnoAllocReleaseKey          = "sandbox.opensandbox.io/alloc-release"
  constant LabelBatchSandboxPodIndexKey (line 29) | LabelBatchSandboxPodIndexKey = "batch-sandbox.sandbox.opensandbox.io/pod...
  constant AnnoPoolAllocStatusKey (line 31) | AnnoPoolAllocStatusKey     = "pool.opensandbox.io/alloc-status"
  constant AnnoPoolAllocGenerationKey (line 32) | AnnoPoolAllocGenerationKey = "pool.opensandbox.io/alloc-generation"
  constant FinalizerTaskCleanup (line 34) | FinalizerTaskCleanup = "batch-sandbox.sandbox.opensandbox.io/task-cleanup"
  type SandboxAllocation (line 40) | type SandboxAllocation struct
  type AllocationRelease (line 44) | type AllocationRelease struct
  type PoolAllocation (line 48) | type PoolAllocation struct
  function parseSandboxAllocation (line 52) | func parseSandboxAllocation(obj metav1.Object) (SandboxAllocation, error) {
  function setSandboxAllocation (line 62) | func setSandboxAllocation(obj metav1.Object, alloc SandboxAllocation) {
  function parseSandboxReleased (line 69) | func parseSandboxReleased(obj metav1.Object) (AllocationRelease, error) {

FILE: kubernetes/internal/controller/batchsandbox_controller.go
  type BatchSandboxReconciler (line 62) | type BatchSandboxReconciler struct
    method Reconcile (line 84) | func (r *BatchSandboxReconciler) Reconcile(ctx context.Context, req ct...
    method listPods (line 274) | func (r *BatchSandboxReconciler) listPods(ctx context.Context, poolStr...
    method getTaskScheduler (line 320) | func (r *BatchSandboxReconciler) getTaskScheduler(ctx context.Context,...
    method deleteTaskScheduler (line 354) | func (r *BatchSandboxReconciler) deleteTaskScheduler(ctx context.Conte...
    method scheduleTasks (line 361) | func (r *BatchSandboxReconciler) scheduleTasks(ctx context.Context, tS...
    method getTasksCleanupUnfinished (line 417) | func (r *BatchSandboxReconciler) getTasksCleanupUnfinished(batchSbx *s...
    method releasePods (line 427) | func (r *BatchSandboxReconciler) releasePods(ctx context.Context, batc...
    method scaleBatchSandbox (line 461) | func (r *BatchSandboxReconciler) scaleBatchSandbox(ctx context.Context...
    method updateStatus (line 540) | func (r *BatchSandboxReconciler) updateStatus(batchSandbox *sandboxv1a...
    method SetupWithManager (line 552) | func (r *BatchSandboxReconciler) SetupWithManager(mgr ctrl.Manager) er...
  function calPodIndex (line 250) | func calPodIndex(poolStrategy strategy.PoolStrategy, batchSbx *sandboxv1...
  function parseIndex (line 529) | func parseIndex(pod *corev1.Pod) (int, error) {

FILE: kubernetes/internal/controller/batchsandbox_controller_test.go
  function init (line 57) | func init() {
  function randomIPv4 (line 470) | func randomIPv4() net.IP {
  function TestBatchSandboxReconciler_scheduleTasks (line 593) | func TestBatchSandboxReconciler_scheduleTasks(t *testing.T) {
  function Test_parseIndex (line 699) | func Test_parseIndex(t *testing.T) {
  function Test_calPodIndex (line 747) | func Test_calPodIndex(t *testing.T) {

FILE: kubernetes/internal/controller/pool_controller.go
  constant defaultRetryTime (line 53) | defaultRetryTime = 5 * time.Second
  constant LabelPoolName (line 57) | LabelPoolName     = "sandbox.opensandbox.io/pool-name"
  constant LabelPoolRevision (line 58) | LabelPoolRevision = "sandbox.opensandbox.io/pool-revision"
  type PoolReconciler (line 66) | type PoolReconciler struct
    method Reconcile (line 81) | func (r *PoolReconciler) Reconcile(ctx context.Context, req ctrl.Reque...
    method reconcilePool (line 143) | func (r *PoolReconciler) reconcilePool(ctx context.Context, pool *sand...
    method calculateRevision (line 214) | func (r *PoolReconciler) calculateRevision(pool *sandboxv1alpha1.Pool)...
    method SetupWithManager (line 225) | func (r *PoolReconciler) SetupWithManager(mgr ctrl.Manager) error {
    method scheduleSandbox (line 298) | func (r *PoolReconciler) scheduleSandbox(ctx context.Context, pool *sa...
    method updatePool (line 317) | func (r *PoolReconciler) updatePool(latestRevision string, pods []*cor...
    method scalePool (line 353) | func (r *PoolReconciler) scalePool(ctx context.Context, args *scaleArg...
    method updatePoolStatus (line 406) | func (r *PoolReconciler) updatePoolStatus(ctx context.Context, latestR...
    method pickPodsToDelete (line 432) | func (r *PoolReconciler) pickPodsToDelete(pods []*corev1.Pod, idlePodN...
    method createPoolPod (line 469) | func (r *PoolReconciler) createPoolPod(ctx context.Context, pool *sand...
  type scaleArgs (line 343) | type scaleArgs struct

FILE: kubernetes/internal/controller/pool_controller_test.go
  function getSandboxAllocation (line 491) | func getSandboxAllocation(obj kclient.Object) (*SandboxAllocation, error) {
  function getPoolAllocation (line 508) | func getPoolAllocation(pool *sandboxv1alpha1.Pool) (*PoolAllocation, err...

FILE: kubernetes/internal/controller/strategy/pool_strategy.go
  type PoolStrategy (line 17) | type PoolStrategy interface

FILE: kubernetes/internal/controller/strategy/pool_strategy_default.go
  type DefaultPoolStrategy (line 21) | type DefaultPoolStrategy struct
    method IsPooledMode (line 31) | func (s *DefaultPoolStrategy) IsPooledMode() bool {
  function NewDefaultPoolStrategy (line 25) | func NewDefaultPoolStrategy(batchSandbox *sandboxv1alpha1.BatchSandbox) ...

FILE: kubernetes/internal/controller/strategy/pool_strategy_factory.go
  function NewPoolStrategy (line 21) | func NewPoolStrategy(batchSbx *sandboxv1alpha1.BatchSandbox) PoolStrategy {

FILE: kubernetes/internal/controller/strategy/pool_strategy_test.go
  function TestDefaultPoolStrategy_IsPooledMode (line 27) | func TestDefaultPoolStrategy_IsPooledMode(t *testing.T) {
  function TestNewPoolStrategy (line 72) | func TestNewPoolStrategy(t *testing.T) {
  function getTypeName (line 102) | func getTypeName(i interface{}) string {

FILE: kubernetes/internal/controller/strategy/task_scheduling_strategy.go
  type TaskSchedulingStrategy (line 24) | type TaskSchedulingStrategy interface

FILE: kubernetes/internal/controller/strategy/task_scheduling_strategy_default.go
  type DefaultTaskSchedulingStrategy (line 28) | type DefaultTaskSchedulingStrategy struct
    method NeedTaskScheduling (line 40) | func (s *DefaultTaskSchedulingStrategy) NeedTaskScheduling() bool {
    method GenerateTaskSpecs (line 45) | func (s *DefaultTaskSchedulingStrategy) GenerateTaskSpecs() ([]*api.Ta...
    method getTaskSpec (line 59) | func (s *DefaultTaskSchedulingStrategy) getTaskSpec(idx int) (*api.Tas...
  function NewDefaultTaskSchedulingStrategy (line 33) | func NewDefaultTaskSchedulingStrategy(batchSbx *sandboxv1alpha1.BatchSan...

FILE: kubernetes/internal/controller/strategy/task_scheduling_strategy_default_test.go
  function TestDefaultTaskSchedulingStrategy_NeedTaskScheduling (line 28) | func TestDefaultTaskSchedulingStrategy_NeedTaskScheduling(t *testing.T) {
  function TestDefaultTaskSchedulingStrategy_getTaskSpec (line 63) | func TestDefaultTaskSchedulingStrategy_getTaskSpec(t *testing.T) {

FILE: kubernetes/internal/controller/strategy/task_scheduling_strategy_factory.go
  function NewTaskSchedulingStrategy (line 23) | func NewTaskSchedulingStrategy(batchSbx *sandboxv1alpha1.BatchSandbox) T...

FILE: kubernetes/internal/controller/suite_test.go
  function TestControllers (line 54) | func TestControllers(t *testing.T) {
  function startTestManager (line 118) | func startTestManager(ctx context.Context, mgr manager.Manager) *sync.Wa...
  function getFirstFoundEnvTestBinaryDir (line 147) | func getFirstFoundEnvTestBinaryDir() string {

FILE: kubernetes/internal/scheduler/default_scheduler.go
  type taskSpec (line 41) | type taskSpec struct
  type taskNode (line 46) | type taskNode struct
    method GetPodName (line 64) | func (t *taskNode) GetPodName() string {
    method GetState (line 68) | func (t *taskNode) GetState() TaskState {
    method IsResourceReleased (line 72) | func (t *taskNode) IsResourceReleased() bool {
    method isTaskCompleted (line 76) | func (t *taskNode) isTaskCompleted() bool {
    method isTaskDeleted (line 80) | func (t *taskNode) isTaskDeleted() bool {
    method transSchState (line 84) | func (t *taskNode) transSchState(to string, log logr.Logger) {
    method transTaskState (line 99) | func (t *taskNode) transTaskState(to TaskState, log logr.Logger) {
  constant stateReleasing (line 133) | stateReleasing = "releasing"
  constant stateReleased (line 134) | stateReleased  = "released"
  constant stateUnknown (line 135) | stateUnknown   = "unknown"
  type taskClient (line 138) | type taskClient interface
  constant defaultTimeout (line 144) | defaultTimeout        time.Duration = 3 * time.Second
  constant defaultTaskPort (line 145) | defaultTaskPort                     = "5758"
  constant defaultSchConcurrency (line 146) | defaultSchConcurrency int           = 10
  function newTaskClient (line 149) | func newTaskClient(ip string) taskClient {
  function fmtEndpoint (line 153) | func fmtEndpoint(podIP string) string {
  type defaultTaskScheduler (line 157) | type defaultTaskScheduler struct
    method Schedule (line 208) | func (sch *defaultTaskScheduler) Schedule() error {
    method UpdatePods (line 214) | func (sch *defaultTaskScheduler) UpdatePods(pods []*corev1.Pod) {
    method ListTask (line 218) | func (sch *defaultTaskScheduler) ListTask() []Task {
    method StopTask (line 226) | func (sch *defaultTaskScheduler) StopTask() []Task {
    method collectTaskStatus (line 258) | func (sch *defaultTaskScheduler) collectTaskStatus(taskNodes []*taskNo...
    method scheduleTaskNodes (line 317) | func (sch *defaultTaskScheduler) scheduleTaskNodes() error {
    method refreshFreePods (line 340) | func (sch *defaultTaskScheduler) refreshFreePods() {
  function newTaskScheduler (line 174) | func newTaskScheduler(name string, tasks []*api.Task, pods []*corev1.Pod...
  function indexByName (line 200) | func indexByName(taskNodes []*taskNode) map[string]*taskNode {
  function initTaskNodes (line 238) | func initTaskNodes(tasks []*api.Task) ([]*taskNode, error) {
  function parseTaskState (line 280) | func parseTaskState(task *api.Task) TaskState {
  function parseProcessTaskState (line 290) | func parseProcessTaskState(status *api.ProcessStatus) TaskState {
  function parsePodTaskState (line 303) | func parsePodTaskState(status *corev1.PodStatus) TaskState {
  function assignTaskNodes (line 359) | func assignTaskNodes(taskNodes []*taskNode, freePods []*corev1.Pod, log ...
  function needRelease (line 376) | func needRelease(tNode *taskNode, policy sandboxv1alpha1.TaskResourcePol...
  function scheduleSingleTaskNode (line 387) | func scheduleSingleTaskNode(tNode *taskNode, taskClientCreator func(endp...
  function setTask (line 426) | func setTask(client taskClient, task *api.Task, log logr.Logger) (*api.T...

FILE: kubernetes/internal/scheduler/default_scheduler_mock.go
  type MocktaskClient (line 18) | type MocktaskClient struct
    method EXPECT (line 36) | func (m *MocktaskClient) EXPECT() *MocktaskClientMockRecorder {
    method Get (line 41) | func (m *MocktaskClient) Get(ctx context.Context) (*api.Task, error) {
    method Set (line 56) | func (m *MocktaskClient) Set(ctx context.Context, task *api.Task) (*ap...
  type MocktaskClientMockRecorder (line 24) | type MocktaskClientMockRecorder struct
    method Get (line 50) | func (mr *MocktaskClientMockRecorder) Get(ctx interface{}) *gomock.Call {
    method Set (line 65) | func (mr *MocktaskClientMockRecorder) Set(ctx, task interface{}) *gomo...
  function NewMocktaskClient (line 29) | func NewMocktaskClient(ctrl *gomock.Controller) *MocktaskClient {

FILE: kubernetes/internal/scheduler/default_scheduler_test.go
  type mockLogger (line 33) | type mockLogger struct
    method Init (line 35) | func (m mockLogger) Init(info logr.RuntimeInfo)                       ...
    method Info (line 36) | func (m mockLogger) Info(level int, msg string, keysAndValues ...inter...
    method Error (line 37) | func (m mockLogger) Error(err error, msg string, keysAndValues ...inte...
    method Enabled (line 38) | func (m mockLogger) Enabled(level int) bool                           ...
    method WithValues (line 39) | func (m mockLogger) WithValues(keysAndValues ...interface{}) logr.LogS...
    method WithName (line 40) | func (m mockLogger) WithName(name string) logr.LogSink                ...
  function Test_scheduleSingleTaskNode (line 44) | func Test_scheduleSingleTaskNode(t *testing.T) {
  function Test_assignTaskNodes (line 223) | func Test_assignTaskNodes(t *testing.T) {
  function Test_refreshFreePods (line 317) | func Test_refreshFreePods(t *testing.T) {
  function Test_collectTaskStatus (line 453) | func Test_collectTaskStatus(t *testing.T) {
  function Test_indexByName (line 696) | func Test_indexByName(t *testing.T) {
  function Test_scheduleTaskNodes (line 786) | func Test_scheduleTaskNodes(t *testing.T) {
  function Test_parseTaskState (line 1136) | func Test_parseTaskState(t *testing.T) {
  function Test_initTaskNodes (line 1198) | func Test_initTaskNodes(t *testing.T) {

FILE: kubernetes/internal/scheduler/interface.go
  type TaskScheduler (line 25) | type TaskScheduler interface
  function NewTaskScheduler (line 32) | func NewTaskScheduler(name string, tasks []*apis.Task, pods []*corev1.Po...

FILE: kubernetes/internal/scheduler/mock/interface.go
  type MockTaskScheduler (line 17) | type MockTaskScheduler struct
    method EXPECT (line 35) | func (m *MockTaskScheduler) EXPECT() *MockTaskSchedulerMockRecorder {
    method ListTask (line 40) | func (m *MockTaskScheduler) ListTask() []scheduler.Task {
    method Schedule (line 54) | func (m *MockTaskScheduler) Schedule() error {
    method StopTask (line 68) | func (m *MockTaskScheduler) StopTask() []scheduler.Task {
    method UpdatePods (line 82) | func (m *MockTaskScheduler) UpdatePods(pod []*v1.Pod) {
  type MockTaskSchedulerMockRecorder (line 23) | type MockTaskSchedulerMockRecorder struct
    method ListTask (line 48) | func (mr *MockTaskSchedulerMockRecorder) ListTask() *gomock.Call {
    method Schedule (line 62) | func (mr *MockTaskSchedulerMockRecorder) Schedule() *gomock.Call {
    method StopTask (line 76) | func (mr *MockTaskSchedulerMockRecorder) StopTask() *gomock.Call {
    method UpdatePods (line 88) | func (mr *MockTaskSchedulerMockRecorder) UpdatePods(pod interface{}) *...
  function NewMockTaskScheduler (line 28) | func NewMockTaskScheduler(ctrl *gomock.Controller) *MockTaskScheduler {

FILE: kubernetes/internal/scheduler/mock/types.go
  type MockTask (line 16) | type MockTask struct
    method EXPECT (line 34) | func (m *MockTask) EXPECT() *MockTaskMockRecorder {
    method GetName (line 39) | func (m *MockTask) GetName() string {
    method GetPodName (line 53) | func (m *MockTask) GetPodName() string {
    method GetState (line 67) | func (m *MockTask) GetState() scheduler.TaskState {
    method IsResourceReleased (line 81) | func (m *MockTask) IsResourceReleased() bool {
  type MockTaskMockRecorder (line 22) | type MockTaskMockRecorder struct
    method GetName (line 47) | func (mr *MockTaskMockRecorder) GetName() *gomock.Call {
    method GetPodName (line 61) | func (mr *MockTaskMockRecorder) GetPodName() *gomock.Call {
    method GetState (line 75) | func (mr *MockTaskMockRecorder) GetState() *gomock.Call {
    method IsResourceReleased (line 89) | func (mr *MockTaskMockRecorder) IsResourceReleased() *gomock.Call {
  function NewMockTask (line 27) | func NewMockTask(ctrl *gomock.Controller) *MockTask {

FILE: kubernetes/internal/scheduler/recovery.go
  method recover (line 28) | func (sch *defaultTaskScheduler) recover() error {
  method recoverTaskNodesStatus (line 37) | func (sch *defaultTaskScheduler) recoverTaskNodesStatus() error {
  function recoverOneTaskNode (line 72) | func recoverOneTaskNode(tNode *taskNode, currentTask *api.Task, ip strin...

FILE: kubernetes/internal/scheduler/recovery_test.go
  function Test_recoverOneTaskNode (line 32) | func Test_recoverOneTaskNode(t *testing.T) {
  function Test_defaultTaskScheduler_recoverTaskNodesStatus (line 123) | func Test_defaultTaskScheduler_recoverTaskNodesStatus(t *testing.T) {

FILE: kubernetes/internal/scheduler/status_collector.go
  type taskClientCreator (line 27) | type taskClientCreator
  function newTaskStatusCollector (line 29) | func newTaskStatusCollector(creator taskClientCreator, logger logr.Logge...
  type taskStatusCollector (line 34) | type taskStatusCollector interface
  type defaultTaskStatusCollector (line 39) | type defaultTaskStatusCollector struct
    method Collect (line 44) | func (s *defaultTaskStatusCollector) Collect(ctx context.Context, ipLi...

FILE: kubernetes/internal/scheduler/status_collector_mock.go
  type MocktaskStatusCollector (line 17) | type MocktaskStatusCollector struct
    method EXPECT (line 35) | func (m *MocktaskStatusCollector) EXPECT() *MocktaskStatusCollectorMoc...
    method Collect (line 40) | func (m *MocktaskStatusCollector) Collect(ctx context.Context, ipList ...
  type MocktaskStatusCollectorMockRecorder (line 23) | type MocktaskStatusCollectorMockRecorder struct
    method Collect (line 48) | func (mr *MocktaskStatusCollectorMockRecorder) Collect(ctx, ipList int...
  function NewMocktaskStatusCollector (line 28) | func NewMocktaskStatusCollector(ctrl *gomock.Controller) *MocktaskStatus...

FILE: kubernetes/internal/scheduler/types.go
  type Task (line 17) | type Task interface
  type TaskState (line 26) | type TaskState
  constant RunningTaskState (line 29) | RunningTaskState TaskState = "RUNNING"
  constant FailedTaskState (line 30) | FailedTaskState  TaskState = "FAILED"
  constant SucceedTaskState (line 31) | SucceedTaskState TaskState = "SUCCEED"
  constant UnknownTaskState (line 32) | UnknownTaskState TaskState = "UNKNOWN"

FILE: kubernetes/internal/task-executor/config/config.go
  type Config (line 27) | type Config struct
    method LoadFromEnv (line 59) | func (c *Config) LoadFromEnv() {
    method LoadFromFlags (line 77) | func (c *Config) LoadFromFlags() {
    method InitKlog (line 91) | func (c *Config) InitKlog() error {
  function NewConfig (line 42) | func NewConfig() *Config {

FILE: kubernetes/internal/task-executor/manager/interface.go
  type TaskManager (line 24) | type TaskManager interface

FILE: kubernetes/internal/task-executor/manager/task_manager.go
  constant maxConcurrentTasks (line 34) | maxConcurrentTasks = 1
  type taskManager (line 37) | type taskManager struct
    method isTaskActive (line 75) | func (m *taskManager) isTaskActive(task *types.Task) bool {
    method countActiveTasks (line 87) | func (m *taskManager) countActiveTasks() int {
    method Create (line 97) | func (m *taskManager) Create(ctx context.Context, task *types.Task) (*...
    method Sync (line 148) | func (m *taskManager) Sync(ctx context.Context, desired []*types.Task)...
    method Get (line 189) | func (m *taskManager) Get(ctx context.Context, name string) (*types.Ta...
    method List (line 205) | func (m *taskManager) List(ctx context.Context) ([]*types.Task, error) {
    method Delete (line 213) | func (m *taskManager) Delete(ctx context.Context, name string) error {
    method softDeleteLocked (line 230) | func (m *taskManager) softDeleteLocked(ctx context.Context, task *type...
    method Start (line 247) | func (m *taskManager) Start(ctx context.Context) {
    method Stop (line 259) | func (m *taskManager) Stop() {
    method createTaskLocked (line 267) | func (m *taskManager) createTaskLocked(ctx context.Context, task *type...
    method listTasksLocked (line 304) | func (m *taskManager) listTasksLocked() []*types.Task {
    method recoverTasks (line 314) | func (m *taskManager) recoverTasks(ctx context.Context) error {
    method reconcileLoop (line 347) | func (m *taskManager) reconcileLoop(ctx context.Context) {
    method reconcileTasks (line 366) | func (m *taskManager) reconcileTasks(ctx context.Context) {
  function NewTaskManager (line 52) | func NewTaskManager(cfg *config.Config, taskStore store.TaskStore, exec ...
  function isTerminalState (line 452) | func isTerminalState(state types.TaskState) bool {

FILE: kubernetes/internal/task-executor/manager/task_manager_test.go
  function setupTestManager (line 32) | func setupTestManager(t *testing.T) (TaskManager, *config.Config) {
  function cleanupTask (line 57) | func cleanupTask(t *testing.T, mgr TaskManager, name string) {
  function TestNewTaskManager (line 71) | func TestNewTaskManager(t *testing.T) {
  function TestTaskManager_Create (line 129) | func TestTaskManager_Create(t *testing.T) {
  function TestTaskManager_CreateDuplicate (line 192) | func TestTaskManager_CreateDuplicate(t *testing.T) {
  function TestTaskManager_CreateMaxConcurrentTasks (line 220) | func TestTaskManager_CreateMaxConcurrentTasks(t *testing.T) {
  function TestTaskManager_Get (line 256) | func TestTaskManager_Get(t *testing.T) {
  function TestTaskManager_GetNotFound (line 288) | func TestTaskManager_GetNotFound(t *testing.T) {
  function TestTaskManager_GetEmptyName (line 298) | func TestTaskManager_GetEmptyName(t *testing.T) {
  function TestTaskManager_List (line 308) | func TestTaskManager_List(t *testing.T) {
  function TestTaskManager_Delete (line 348) | func TestTaskManager_Delete(t *testing.T) {
  function TestTaskManager_DeleteNonExistent (line 398) | func TestTaskManager_DeleteNonExistent(t *testing.T) {
  function TestTaskManager_Sync (line 409) | func TestTaskManager_Sync(t *testing.T) {
  function TestTaskManager_SyncNil (line 485) | func TestTaskManager_SyncNil(t *testing.T) {
  function TestTaskManager_AsyncStopOnDelete (line 495) | func TestTaskManager_AsyncStopOnDelete(t *testing.T) {
  function TestTaskManager_TimeoutHandling (line 558) | func TestTaskManager_TimeoutHandling(t *testing.T) {
  function TestTaskManager_CountActiveTasks (line 621) | func TestTaskManager_CountActiveTasks(t *testing.T) {
  function TestIsTerminalState (line 675) | func TestIsTerminalState(t *testing.T) {

FILE: kubernetes/internal/task-executor/runtime/composite.go
  function NewExecutor (line 27) | func NewExecutor(cfg *config.Config) (Executor, error) {
  type compositeExecutor (line 50) | type compositeExecutor struct
    method getDelegate (line 55) | func (e *compositeExecutor) getDelegate(task *types.Task) (Executor, e...
    method Start (line 69) | func (e *compositeExecutor) Start(ctx context.Context, task *types.Tas...
    method Inspect (line 77) | func (e *compositeExecutor) Inspect(ctx context.Context, task *types.T...
    method Stop (line 85) | func (e *compositeExecutor) Stop(ctx context.Context, task *types.Task...

FILE: kubernetes/internal/task-executor/runtime/container.go
  type containerExecutor (line 26) | type containerExecutor struct
    method Start (line 43) | func (e *containerExecutor) Start(ctx context.Context, task *types.Tas...
    method Inspect (line 48) | func (e *containerExecutor) Inspect(ctx context.Context, task *types.T...
    method Stop (line 53) | func (e *containerExecutor) Stop(ctx context.Context, task *types.Task...
  function newContainerExecutor (line 32) | func newContainerExecutor(cfg *config.Config) (Executor, error) {

FILE: kubernetes/internal/task-executor/runtime/interface.go
  type Executor (line 24) | type Executor interface

FILE: kubernetes/internal/task-executor/runtime/process.go
  constant ExitFile (line 36) | ExitFile   = "exit"
  constant PidFile (line 37) | PidFile    = "pid"
  constant StdoutFile (line 38) | StdoutFile = "stdout.log"
  constant StderrFile (line 39) | StderrFile = "stderr.log"
  type processExecutor (line 44) | type processExecutor struct
    method Start (line 53) | func (e *processExecutor) Start(ctx context.Context, task *types.Task)...
    method executeCommand (line 116) | func (e *processExecutor) executeCommand(task *types.Task, cmd *exec.C...
    method buildShimScript (line 189) | func (e *processExecutor) buildShimScript(exitPath, cmdStr string) str...
    method Inspect (line 215) | func (e *processExecutor) Inspect(ctx context.Context, task *types.Tas...
    method Stop (line 288) | func (e *processExecutor) Stop(ctx context.Context, task *types.Task) ...
    method findPidByEnvVar (line 393) | func (e *processExecutor) findPidByEnvVar(envName, expectedValue strin...
  function NewProcessExecutor (line 49) | func NewProcessExecutor(config *config.Config) (Executor, error) {
  function getChildrenPIDs (line 352) | func getChildrenPIDs(pid int) ([]int, error) {
  function isProcessRunning (line 368) | func isProcessRunning(pid int) bool {
  function shellEscape (line 377) | func shellEscape(args []string) string {
  function shellEscapePath (line 388) | func shellEscapePath(s string) string {
  function getProcEnviron (line 438) | func getProcEnviron(pid int) ([]string, error) {

FILE: kubernetes/internal/task-executor/runtime/process_test.go
  function setupTestExecutor (line 34) | func setupTestExecutor(t *testing.T) (Executor, string) {
  function TestProcessExecutor_Lifecycle (line 47) | func TestProcessExecutor_Lifecycle(t *testing.T) {
  function TestProcessExecutor_ShortLived (line 103) | func TestProcessExecutor_ShortLived(t *testing.T) {
  function TestProcessExecutor_Failure (line 142) | func TestProcessExecutor_Failure(t *testing.T) {
  function TestProcessExecutor_InvalidArgs (line 180) | func TestProcessExecutor_InvalidArgs(t *testing.T) {
  function TestShellEscape (line 199) | func TestShellEscape(t *testing.T) {
  function TestNewExecutor (line 217) | func TestNewExecutor(t *testing.T) {
  function TestProcessExecutor_EnvInheritance (line 246) | func TestProcessExecutor_EnvInheritance(t *testing.T) {
  function TestProcessExecutor_TimeoutDetection (line 298) | func TestProcessExecutor_TimeoutDetection(t *testing.T) {
  function TestProcessExecutor_TimeoutNotExceeded (line 341) | func TestProcessExecutor_TimeoutNotExceeded(t *testing.T) {
  function TestProcessExecutor_NoTimeout (line 377) | func TestProcessExecutor_NoTimeout(t *testing.T) {

FILE: kubernetes/internal/task-executor/server/handler.go
  type ErrorResponse (line 34) | type ErrorResponse struct
  type Handler (line 39) | type Handler struct
    method CreateTask (line 57) | func (h *Handler) CreateTask(w http.ResponseWriter, r *http.Request) {
    method SyncTasks (line 96) | func (h *Handler) SyncTasks(w http.ResponseWriter, r *http.Request) {
    method GetTask (line 139) | func (h *Handler) GetTask(w http.ResponseWriter, r *http.Request) {
    method ListTasks (line 165) | func (h *Handler) ListTasks(w http.ResponseWriter, r *http.Request) {
    method Health (line 189) | func (h *Handler) Health(w http.ResponseWriter, r *http.Request) {
    method DeleteTask (line 197) | func (h *Handler) DeleteTask(w http.ResponseWriter, r *http.Request) {
    method convertAPIToInternalTask (line 230) | func (h *Handler) convertAPIToInternalTask(apiTask *api.Task) *types.T...
  function NewHandler (line 44) | func NewHandler(mgr manager.TaskManager, cfg *config.Config) *Handler {
  function writeError (line 221) | func writeError(w http.ResponseWriter, code int, message string) {
  function convertInternalToAPITask (line 246) | func convertInternalToAPITask(task *types.Task) *api.Task {

FILE: kubernetes/internal/task-executor/server/handler_test.go
  type MockTaskManager (line 38) | type MockTaskManager struct
    method Create (line 49) | func (m *MockTaskManager) Create(ctx context.Context, task *types.Task...
    method Sync (line 57) | func (m *MockTaskManager) Sync(ctx context.Context, desired []*types.T...
    method Get (line 70) | func (m *MockTaskManager) Get(ctx context.Context, id string) (*types....
    method List (line 80) | func (m *MockTaskManager) List(ctx context.Context) ([]*types.Task, er...
    method Delete (line 91) | func (m *MockTaskManager) Delete(ctx context.Context, id string) error {
    method Start (line 99) | func (m *MockTaskManager) Start(ctx context.Context) {}
    method Stop (line 100) | func (m *MockTaskManager) Stop()                     {}
  function NewMockTaskManager (line 43) | func NewMockTaskManager() *MockTaskManager {
  function TestHandler_Health (line 102) | func TestHandler_Health(t *testing.T) {
  function TestHandler_CreateTask (line 115) | func TestHandler_CreateTask(t *testing.T) {
  function TestHandler_GetTask (line 142) | func TestHandler_GetTask(t *testing.T) {
  function TestHandler_DeleteTask (line 165) | func TestHandler_DeleteTask(t *testing.T) {
  function TestHandler_ListTasks (line 186) | func TestHandler_ListTasks(t *testing.T) {
  function TestHandler_SyncTasks (line 209) | func TestHandler_SyncTasks(t *testing.T) {
  function TestHandler_Errors (line 233) | func TestHandler_Errors(t *testing.T) {
  function TestConvertInternalToAPITask (line 250) | func TestConvertInternalToAPITask(t *testing.T) {
  function TestConvertInternalToAPITask_Timeout (line 363) | func TestConvertInternalToAPITask_Timeout(t *testing.T) {

FILE: kubernetes/internal/task-executor/server/router.go
  function NewRouter (line 21) | func NewRouter(h *Handler) http.Handler {

FILE: kubernetes/internal/task-executor/storage/file_store.go
  type fileStore (line 31) | type fileStore struct
    method getTaskLock (line 58) | func (s *fileStore) getTaskLock(name string) *sync.RWMutex {
    method Create (line 63) | func (s *fileStore) Create(ctx context.Context, task *types.Task) error {
    method Update (line 97) | func (s *fileStore) Update(ctx context.Context, task *types.Task) error {
    method Get (line 127) | func (s *fileStore) Get(ctx context.Context, name string) (*types.Task...
    method List (line 149) | func (s *fileStore) List(ctx context.Context) ([]*types.Task, error) {
    method Delete (line 184) | func (s *fileStore) Delete(ctx context.Context, name string) error {
    method getTaskFilePath (line 212) | func (s *fileStore) getTaskFilePath(taskDir string) string {
    method writeTaskFile (line 217) | func (s *fileStore) writeTaskFile(taskDir string, task *types.Task) er...
    method readTaskFile (line 250) | func (s *fileStore) readTaskFile(taskDir, taskName string) (*types.Tas...
  function NewFileStore (line 36) | func NewFileStore(dataDir string) (TaskStore, error) {

FILE: kubernetes/internal/task-executor/storage/file_store_test.go
  function TestNewFileStore (line 28) | func TestNewFileStore(t *testing.T) {
  function TestFileStore_CRUD (line 46) | func TestFileStore_CRUD(t *testing.T) {
  function TestFileStore_EdgeCases (line 133) | func TestFileStore_EdgeCases(t *testing.T) {
  function TestFileStore_CorruptedData (line 171) | func TestFileStore_CorruptedData(t *testing.T) {
  function TestFileStore_Concurrency (line 197) | func TestFileStore_Concurrency(t *testing.T) {

FILE: kubernetes/internal/task-executor/storage/interface.go
  type TaskStore (line 24) | type TaskStore interface

FILE: kubernetes/internal/task-executor/types/task.go
  type TaskState (line 26) | type TaskState
  constant TaskStatePending (line 29) | TaskStatePending   TaskState = "Pending"
  constant TaskStateRunning (line 30) | TaskStateRunning   TaskState = "Running"
  constant TaskStateSucceeded (line 31) | TaskStateSucceeded TaskState = "Succeeded"
  constant TaskStateFailed (line 32) | TaskStateFailed    TaskState = "Failed"
  constant TaskStateUnknown (line 33) | TaskStateUnknown   TaskState = "Unknown"
  constant TaskStateNotFound (line 34) | TaskStateNotFound  TaskState = "NotFound"
  constant TaskStateTimeout (line 35) | TaskStateTimeout   TaskState = "Timeout"
  type Status (line 40) | type Status struct
  type SubStatus (line 45) | type SubStatus struct
  type Task (line 54) | type Task struct

FILE: kubernetes/internal/task-executor/utils/pathutil.go
  function SafeJoin (line 23) | func SafeJoin(baseDir, userPath string) (string, error) {
  function isSubPath (line 42) | func isSubPath(parent, child string) bool {

FILE: kubernetes/internal/task-executor/utils/pathutil_test.go
  function TestSafeJoin (line 23) | func TestSafeJoin(t *testing.T) {

FILE: kubernetes/internal/utils/controller/util.go
  function GetControllerKey (line 23) | func GetControllerKey(obj metav1.Object) string {

FILE: kubernetes/internal/utils/expectations/init.go
  function init (line 22) | func init() {

FILE: kubernetes/internal/utils/expectations/resource_version_expectation.go
  type ResourceVersionExpectation (line 26) | type ResourceVersionExpectation interface
  function NewResourceVersionExpectation (line 33) | func NewResourceVersionExpectation() ResourceVersionExpectation {
  type realResourceVersionExpectation (line 37) | type realResourceVersionExpectation struct
    method Expect (line 47) | func (r *realResourceVersionExpectation) Expect(obj metav1.Object) {
    method Observe (line 60) | func (r *realResourceVersionExpectation) Observe(obj metav1.Object) {
    method IsSatisfied (line 73) | func (r *realResourceVersionExpectation) IsSatisfied(obj metav1.Object...
    method Delete (line 97) | func (r *realResourceVersionExpectation) Delete(obj metav1.Object) {
  type objectCacheVersions (line 42) | type objectCacheVersions struct
  function isResourceVersionNewer (line 103) | func isResourceVersionNewer(old, new string) bool {

FILE: kubernetes/internal/utils/expectations/resource_version_expectation_test.go
  function TestResourceVersionExpectation (line 24) | func TestResourceVersionExpectation(t *testing.T) {

FILE: kubernetes/internal/utils/expectations/scale_expectations.go
  type ScaleAction (line 25) | type ScaleAction
  constant Create (line 29) | Create ScaleAction = "create"
  constant Delete (line 31) | Delete ScaleAction = "delete"
  type ScaleExpectations (line 35) | type ScaleExpectations interface
  function NewScaleExpectations (line 44) | func NewScaleExpectations() ScaleExpectations {
  type realScaleExpectations (line 50) | type realScaleExpectations struct
    method GetExpectations (line 62) | func (r *realScaleExpectations) GetExpectations(controllerKey string) ...
    method ExpectScale (line 79) | func (r *realScaleExpectations) ExpectScale(controllerKey string, acti...
    method ObserveScale (line 98) | func (r *realScaleExpectations) ObserveScale(controllerKey string, act...
    method SatisfiedExpectations (line 121) | func (r *realScaleExpectations) SatisfiedExpectations(controllerKey st...
    method DeleteExpectations (line 143) | func (r *realScaleExpectations) DeleteExpectations(controllerKey strin...
  type realControllerScaleExpectations (line 56) | type realControllerScaleExpectations struct

FILE: kubernetes/internal/utils/expectations/scale_expectations_test.go
  function TestScale (line 21) | func TestScale(t *testing.T) {

FILE: kubernetes/internal/utils/fieldindex/register.go
  constant IndexNameForOwnerRefUID (line 29) | IndexNameForOwnerRefUID = "ownerRefUID"
  constant IndexNameForPoolRef (line 30) | IndexNameForPoolRef     = "poolRef"
  function RegisterFieldIndexes (line 53) | func RegisterFieldIndexes(c cache.Cache) error {

FILE: kubernetes/internal/utils/finalizer.go
  type FinalizerOpType (line 27) | type FinalizerOpType
  constant AddFinalizerOpType (line 30) | AddFinalizerOpType    FinalizerOpType = "Add"
  constant RemoveFinalizerOpType (line 31) | RemoveFinalizerOpType FinalizerOpType = "Remove"
  function UpdateFinalizer (line 34) | func UpdateFinalizer(c client.Client, object client.Object, op Finalizer...

FILE: kubernetes/internal/utils/helper.go
  function GetAnnotation (line 22) | func GetAnnotation(obj metav1.Object, key string) string {

FILE: kubernetes/internal/utils/json.go
  function DumpJSON (line 23) | func DumpJSON(o interface{}) string {
  function IsJSONObjectEqual (line 29) | func IsJSONObjectEqual(o1, o2 interface{}) bool {

FILE: kubernetes/internal/utils/logging/logger.go
  type Options (line 28) | type Options struct
  function DefaultOptions (line 48) | func DefaultOptions() Options {
  function NewLoggerWithZapOptions (line 65) | func NewLoggerWithZapOptions(opts Options) logr.Logger {

FILE: kubernetes/internal/utils/pod.go
  function IsPodAvailable (line 34) | func IsPodAvailable(pod *v1.Pod, minReadySeconds int32, now metav1.Time)...
  function IsPodReady (line 48) | func IsPodReady(pod *v1.Pod) bool {
  function IsPodTerminal (line 53) | func IsPodTerminal(pod *v1.Pod) bool {
  function IsPodPhaseTerminal (line 58) | func IsPodPhaseTerminal(phase v1.PodPhase) bool {
  function IsPodReadyConditionTrue (line 63) | func IsPodReadyConditionTrue(status v1.PodStatus) bool {
  function IsContainersReadyConditionTrue (line 69) | func IsContainersReadyConditionTrue(status v1.PodStatus) bool {
  function GetPodReadyCondition (line 76) | func GetPodReadyCondition(status v1.PodStatus) *v1.PodCondition {
  function GetContainersReadyCondition (line 83) | func GetContainersReadyCondition(status v1.PodStatus) *v1.PodCondition {
  function GetPodCondition (line 90) | func GetPodCondition(status *v1.PodStatus, conditionType v1.PodCondition...
  function GetPodConditionFromList (line 99) | func GetPodConditionFromList(conditions []v1.PodCondition, conditionType...
  function GetPodFromTemplate (line 111) | func GetPodFromTemplate(
  function getPodsLabelSet (line 140) | func getPodsLabelSet(template *v1.PodTemplateSpec) labels.Set {
  function getPodsFinalizers (line 148) | func getPodsFinalizers(template *v1.PodTemplateSpec) []string {
  function getPodsAnnotationSet (line 154) | func getPodsAnnotationSet(template *v1.PodTemplateSpec) labels.Set {
  function getPodsPrefix (line 162) | func getPodsPrefix(controllerName string) string {
  function IsAssigned (line 171) | func IsAssigned(pod *v1.Pod) bool {
  function PodNameSorter (line 175) | func PodNameSorter(a, b *v1.Pod) int {
  function WithPodIndexSorter (line 184) | func WithPodIndexSorter(podIndex map[string]int) func(*v1.Pod, *v1.Pod) ...
  type MultiPodSorter (line 206) | type MultiPodSorter
    method Sort (line 208) | func (m MultiPodSorter) Sort(a, b *v1.Pod) int {

FILE: kubernetes/internal/utils/pod_test.go
  function TestWithPodIndexSorter (line 25) | func TestWithPodIndexSorter(t *testing.T) {
  function TestMultiPodSorter (line 110) | func TestMultiPodSorter(t *testing.T) {
  function TestMultiPodSorter_Integration (line 215) | func TestMultiPodSorter_Integration(t *testing.T) {

FILE: kubernetes/internal/utils/requeueduration/duration.go
  type DurationStore (line 24) | type DurationStore struct
    method Push (line 28) | func (dm *DurationStore) Push(key string, newDuration time.Duration) {
    method Pop (line 38) | func (dm *DurationStore) Pop(key string) time.Duration {
  type Duration (line 52) | type Duration struct
    method Update (line 58) | func (rd *Duration) Update(newDuration time.Duration) {
    method UpdateWithMsg (line 68) | func (rd *Duration) UpdateWithMsg(newDuration time.Duration, format st...
    method Merge (line 79) | func (rd *Duration) Merge(rd2 *Duration) {
    method Get (line 85) | func (rd *Duration) Get() time.Duration {
    method GetWithMsg (line 91) | func (rd *Duration) GetWithMsg() (time.Duration, string) {

FILE: kubernetes/pkg/client/clientset/versioned/clientset.go
  type Interface (line 28) | type Interface interface
  type Clientset (line 34) | type Clientset struct
    method SandboxV1alpha1 (line 40) | func (c *Clientset) SandboxV1alpha1() sandboxv1alpha1.SandboxV1alpha1I...
    method Discovery (line 45) | func (c *Clientset) Discovery() discovery.DiscoveryInterface {
  function NewForConfig (line 57) | func NewForConfig(c *rest.Config) (*Clientset, error) {
  function NewForConfigAndClient (line 77) | func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Cl...
  function NewForConfigOrDie (line 102) | func NewForConfigOrDie(c *rest.Config) *Clientset {
  function New (line 111) | func New(c rest.Interface) *Clientset {

FILE: kubernetes/pkg/client/clientset/versioned/fake/clientset_generated.go
  function NewSimpleClientset (line 38) | func NewSimpleClientset(objects ...runtime.Object) *Clientset {
  type Clientset (line 69) | type Clientset struct
    method Discovery (line 75) | func (c *Clientset) Discovery() discovery.DiscoveryInterface {
    method Tracker (line 79) | func (c *Clientset) Tracker() testing.ObjectTracker {
    method SandboxV1alpha1 (line 89) | func (c *Clientset) SandboxV1alpha1() sandboxv1alpha1.SandboxV1alpha1I...

FILE: kubernetes/pkg/client/clientset/versioned/fake/register.go
  function init (line 50) | func init() {

FILE: kubernetes/pkg/client/clientset/versioned/scheme/register.go
  function init (line 50) | func init() {

FILE: kubernetes/pkg/client/clientset/versioned/typed/sandbox/v1alpha1/batchsandbox.go
  type BatchSandboxesGetter (line 31) | type BatchSandboxesGetter interface
  type BatchSandboxInterface (line 36) | type BatchSandboxInterface interface
  type batchSandboxes (line 51) | type batchSandboxes struct
  function newBatchSandboxes (line 56) | func newBatchSandboxes(c *SandboxV1alpha1Client, namespace string) *batc...

FILE: kubernetes/pkg/client/clientset/versioned/typed/sandbox/v1alpha1/fake/fake_batchsandbox.go
  type fakeBatchSandboxes (line 25) | type fakeBatchSandboxes struct
  function newFakeBatchSandboxes (line 30) | func newFakeBatchSandboxes(fake *FakeSandboxV1alpha1, namespace string) ...

FILE: kubernetes/pkg/client/clientset/versioned/typed/sandbox/v1alpha1/fake/fake_pool.go
  type fakePools (line 25) | type fakePools struct
  function newFakePools (line 30) | func newFakePools(fake *FakeSandboxV1alpha1, namespace string) sandboxv1...

FILE: kubernetes/pkg/client/clientset/versioned/typed/sandbox/v1alpha1/fake/fake_sandbox_client.go
  type FakeSandboxV1alpha1 (line 24) | type FakeSandboxV1alpha1 struct
    method BatchSandboxes (line 28) | func (c *FakeSandboxV1alpha1) BatchSandboxes(namespace string) v1alpha...
    method Pools (line 32) | func (c *FakeSandboxV1alpha1) Pools(namespace string) v1alpha1.PoolInt...
    method RESTClient (line 38) | func (c *FakeSandboxV1alpha1) RESTClient() rest.Interface {

FILE: kubernetes/pkg/client/clientset/versioned/typed/sandbox/v1alpha1/generated_expansion.go
  type BatchSandboxExpansion (line 18) | type BatchSandboxExpansion interface
  type PoolExpansion (line 20) | type PoolExpansion interface

FILE: kubernetes/pkg/client/clientset/versioned/typed/sandbox/v1alpha1/pool.go
  type PoolsGetter (line 31) | type PoolsGetter interface
  type PoolInterface (line 36) | type PoolInterface interface
  type pools (line 51) | type pools struct
  function newPools (line 56) | func newPools(c *SandboxV1alpha1Client, namespace string) *pools {

FILE: kubernetes/pkg/client/clientset/versioned/typed/sandbox/v1alpha1/sandbox_client.go
  type SandboxV1alpha1Interface (line 26) | type SandboxV1alpha1Interface interface
  type SandboxV1alpha1Client (line 33) | type SandboxV1alpha1Client struct
    method BatchSandboxes (line 37) | func (c *SandboxV1alpha1Client) BatchSandboxes(namespace string) Batch...
    method Pools (line 41) | func (c *SandboxV1alpha1Client) Pools(namespace string) PoolInterface {
    method RESTClient (line 98) | func (c *SandboxV1alpha1Client) RESTClient() rest.Interface {
  function NewForConfig (line 48) | func NewForConfig(c *rest.Config) (*SandboxV1alpha1Client, error) {
  function NewForConfigAndClient (line 60) | func NewForConfigAndClient(c *rest.Config, h *http.Client) (*SandboxV1al...
  function NewForConfigOrDie (line 72) | func NewForConfigOrDie(c *rest.Config) *SandboxV1alpha1Client {
  function New (line 81) | func New(c rest.Interface) *SandboxV1alpha1Client {
  function setConfigDefaults (line 85) | func setConfigDefaults(config *rest.Config) {

FILE: kubernetes/pkg/client/informers/externalversions/factory.go
  type SharedInformerOption (line 33) | type SharedInformerOption
  type sharedInformerFactory (line 35) | type sharedInformerFactory struct
    method Start (line 121) | func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
    method Shutdown (line 145) | func (f *sharedInformerFactory) Shutdown() {
    method WaitForCacheSync (line 154) | func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{...
    method InformerFor (line 177) | func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFun...
    method Sandbox (line 257) | func (f *sharedInformerFactory) Sandbox() sandbox.Interface {
  function WithCustomResyncConfig (line 56) | func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) Sh...
  function WithTweakListOptions (line 66) | func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListO...
  function WithNamespace (line 74) | func WithNamespace(namespace string) SharedInformerOption {
  function WithTransform (line 82) | func WithTransform(transform cache.TransformFunc) SharedInformerOption {
  function NewSharedInformerFactory (line 90) | func NewSharedInformerFactory(client versioned.Interface, defaultResync ...
  function NewFilteredSharedInformerFactory (line 98) | func NewFilteredSharedInformerFactory(client versioned.Interface, defaul...
  function NewSharedInformerFactoryWithOptions (line 103) | func NewSharedInformerFactoryWithOptions(client versioned.Interface, def...
  type SharedInformerFactory (line 223) | type SharedInformerFactory interface

FILE: kubernetes/pkg/client/informers/externalversions/generic.go
  type GenericInformer (line 28) | type GenericInformer interface
  type genericInformer (line 33) | type genericInformer struct
    method Informer (line 39) | func (f *genericInformer) Informer() cache.SharedIndexInformer {
    method Lister (line 44) | func (f *genericInformer) Lister() cache.GenericLister {
  method ForResource (line 50) | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersion...

FILE: kubernetes/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
  type NewInformerFunc (line 28) | type NewInformerFunc
  type SharedInformerFactory (line 31) | type SharedInformerFactory interface
  type TweakListOptionsFunc (line 37) | type TweakListOptionsFunc

FILE: kubernetes/pkg/client/informers/externalversions/sandbox/interface.go
  type Interface (line 24) | type Interface interface
  type group (line 29) | type group struct
    method V1alpha1 (line 41) | func (g *group) V1alpha1() v1alpha1.Interface {
  function New (line 36) | func New(f internalinterfaces.SharedInformerFactory, namespace string, t...

FILE: kubernetes/pkg/client/informers/externalversions/sandbox/v1alpha1/batchsandbox.go
  type BatchSandboxInformer (line 34) | type BatchSandboxInformer interface
  type batchSandboxInformer (line 39) | type batchSandboxInformer struct
    method defaultInformer (line 89) | func (f *batchSandboxInformer) defaultInformer(client versioned.Interf...
    method Informer (line 93) | func (f *batchSandboxInformer) Informer() cache.SharedIndexInformer {
    method Lister (line 97) | func (f *batchSandboxInformer) Lister() sandboxv1alpha1.BatchSandboxLi...
  function NewBatchSandboxInformer (line 48) | func NewBatchSandboxInformer(client versioned.Interface, namespace strin...
  function NewFilteredBatchSandboxInformer (line 55) | func NewFilteredBatchSandboxInformer(client versioned.Interface, namespa...

FILE: kubernetes/pkg/client/informers/externalversions/sandbox/v1alpha1/interface.go
  type Interface (line 23) | type Interface interface
  type version (line 30) | type version struct
    method BatchSandboxes (line 42) | func (v *version) BatchSandboxes() BatchSandboxInformer {
    method Pools (line 47) | func (v *version) Pools() PoolInformer {
  function New (line 37) | func New(f internalinterfaces.SharedInformerFactory, namespace string, t...

FILE: kubernetes/pkg/client/informers/externalversions/sandbox/v1alpha1/pool.go
  type PoolInformer (line 34) | type PoolInformer interface
  type poolInformer (line 39) | type poolInformer struct
    method defaultInformer (line 89) | func (f *poolInformer) defaultInformer(client versioned.Interface, res...
    method Informer (line 93) | func (f *poolInformer) Informer() cache.SharedIndexInformer {
    method Lister (line 97) | func (f *poolInformer) Lister() sandboxv1alpha1.PoolLister {
  function NewPoolInformer (line 48) | func NewPoolInformer(client versioned.Interface, namespace string, resyn...
  function NewFilteredPoolInformer (line 55) | func NewFilteredPoolInformer(client versioned.Interface, namespace strin...

FILE: kubernetes/pkg/client/listers/sandbox/v1alpha1/batchsandbox.go
  type BatchSandboxLister (line 27) | type BatchSandboxLister interface
  type batchSandboxLister (line 37) | type batchSandboxLister struct
    method BatchSandboxes (line 47) | func (s *batchSandboxLister) BatchSandboxes(namespace string) BatchSan...
  function NewBatchSandboxLister (line 42) | func NewBatchSandboxLister(indexer cache.Indexer) BatchSandboxLister {
  type BatchSandboxNamespaceLister (line 53) | type BatchSandboxNamespaceLister interface
  type batchSandboxNamespaceLister (line 65) | type batchSandboxNamespaceLister struct

FILE: kubernetes/pkg/client/listers/sandbox/v1alpha1/expansion_generated.go
  type BatchSandboxListerExpansion (line 20) | type BatchSandboxListerExpansion interface
  type BatchSandboxNamespaceListerExpansion (line 24) | type BatchSandboxNamespaceListerExpansion interface
  type PoolListerExpansion (line 28) | type PoolListerExpansion interface
  type PoolNamespaceListerExpansion (line 32) | type PoolNamespaceListerExpansion interface

FILE: kubernetes/pkg/client/listers/sandbox/v1alpha1/pool.go
  type PoolLister (line 27) | type PoolLister interface
  type poolLister (line 37) | type poolLister struct
    method Pools (line 47) | func (s *poolLister) Pools(namespace string) PoolNamespaceLister {
  function NewPoolLister (line 42) | func NewPoolLister(indexer cache.Indexer) PoolLister {
  type PoolNamespaceLister (line 53) | type PoolNamespaceLister interface
  type poolNamespaceLister (line 65) | type poolNamespaceLister struct

FILE: kubernetes/pkg/task-executor/client.go
  type Client (line 29) | type Client struct
    method Set (line 48) | func (c *Client) Set(ctx context.Context, task *Task) (*Task, error) {
    method Get (line 113) | func (c *Client) Get(ctx context.Context) (*Task, error) {
  function NewClient (line 34) | func NewClient(baseURL string) *Client {

FILE: kubernetes/pkg/task-executor/types.go
  type Task (line 24) | type Task struct
  type Process (line 35) | type Process struct
  type ProcessStatus (line 51) | type ProcessStatus struct
  type Waiting (line 64) | type Waiting struct
  type Running (line 74) | type Running struct
  type Terminated (line 81) | type Terminated struct

FILE: kubernetes/pkg/utils/endpoints.go
  constant AnnotationEndpoints (line 26) | AnnotationEndpoints = "sandbox.opensandbox.io/endpoints"
  function GetEndpoints (line 32) | func GetEndpoints(bs *sandboxv1alpha1.BatchSandbox) ([]string, error) {

FILE: kubernetes/pkg/utils/endpoints_test.go
  function TestGetEndpoints (line 24) | func TestGetEndpoints(t *testing.T) {
  function contains (line 154) | func contains(s, substr string) bool {
  function findSubstr (line 160) | func findSubstr(s, substr string) bool {

FILE: kubernetes/test/e2e/e2e_suite_test.go
  function TestE2E (line 32) | func TestE2E(t *testing.T) {

FILE: kubernetes/test/e2e/e2e_test.go
  constant namespace (line 35) | namespace = "opensandbox-system"
  function renderTemplate (line 1299) | func renderTemplate(templateFile string, data map[string]interface{}) (s...

FILE: kubernetes/test/e2e_runtime/gvisor/gvisor_test.go
  function runKubectl (line 31) | func runKubectl(args ...string) (string, error) {

FILE: kubernetes/test/e2e_runtime/gvisor/suite_test.go
  constant RuntimeClassName (line 30) | RuntimeClassName = "gvisor"
  function getKindCluster (line 37) | func getKindCluster() string {
  function TestGVisorRuntimeClass (line 47) | func TestGVisorRuntimeClass(t *testing.T) {

FILE: kubernetes/test/e2e_task/suite_test.go
  function TestE2E (line 24) | func TestE2E(t *testing.T) {

FILE: kubernetes/test/e2e_task/task_e2e_test.go
  constant ImageName (line 31) | ImageName         = "task-executor-e2e"
  constant TargetContainer (line 32) | TargetContainer   = "task-e2e-target"
  constant ExecutorContainer (line 33) | ExecutorContainer = "task-e2e-executor"
  constant VolumeName (line 34) | VolumeName        = "task-e2e-vol"
  constant HostPort (line 35) | HostPort          = "5758"

FILE: kubernetes/test/utils/image.go
  function getEnv (line 33) | func getEnv(key, defaultValue string) string {

FILE: kubernetes/test/utils/utils.go
  constant prometheusOperatorVersion (line 29) | prometheusOperatorVersion = "v0.77.1"
  constant prometheusOperatorURL (line 30) | prometheusOperatorURL     = "https://github.com/prometheus-operator/prom...
  constant certmanagerVersion (line 33) | certmanagerVersion = "v1.16.3"
  constant certmanagerURLTmpl (line 34) | certmanagerURLTmpl = "https://github.com/cert-manager/cert-manager/relea...
  function warnError (line 37) | func warnError(err error) {
  function Run (line 42) | func Run(cmd *exec.Cmd) (string, error) {
  function InstallPrometheusOperator (line 62) | func InstallPrometheusOperator() error {
  function UninstallPrometheusOperator (line 70) | func UninstallPrometheusOperator() {
  function IsPrometheusCRDsInstalled (line 80) | func IsPrometheusCRDsInstalled() bool {
  function UninstallCertManager (line 106) | func UninstallCertManager() {
  function InstallCertManager (line 115) | func InstallCertManager() error {
  function IsCertManagerCRDsInstalled (line 135) | func IsCertManagerCRDsInstalled() bool {
  function LoadImageToKindClusterWithName (line 167) | func LoadImageToKindClusterWithName(name string) error {
  function GetNonEmptyLines (line 180) | func GetNonEmptyLines(output string) []string {
  function GetProjectDir (line 193) | func GetProjectDir() (string, error) {
  function UncommentCode (line 204) | func UncommentCode(filename, target, prefix string) error {

FILE: scripts/spec-doc/generate-spec.js
  function findProjectRoot (line 37) | function findProjectRoot() {
  function parseOutputPathArg (line 48) | function parseOutputPathArg(projectRoot) {
  function main (line 63) | function main() {

FILE: sdks/code-interpreter/csharp/src/OpenSandbox.CodeInterpreter/Adapters/CodesAdapter.cs
  class CodesAdapter (line 31) | internal sealed class CodesAdapter : ICodes
    method CodesAdapter (line 46) | public CodesAdapter(
    method CreateContextAsync (line 60) | public async Task<CodeContext> CreateContextAsync(string language, Can...
    method GetContextAsync (line 81) | public async Task<CodeContext> GetContextAsync(string contextId, Cance...
    method ListContextsAsync (line 101) | public async Task<IReadOnlyList<CodeContext>> ListContextsAsync(string...
    method DeleteContextAsync (line 123) | public async Task DeleteContextAsync(string contextId, CancellationTok...
    method DeleteContextsAsync (line 134) | public async Task DeleteContextsAsync(string language, CancellationTok...
    method InterruptAsync (line 146) | public async Task InterruptAsync(string contextId, CancellationToken c...
    method RunStreamAsync (line 158) | public async IAsyncEnumerable<ServerStreamEvent> RunStreamAsync(
    method RunAsync (line 196) | public async Task<Execution> RunAsync(string code, RunCodeOptions? opt...

FILE: sdks/code-interpreter/csharp/src/OpenSandbox.CodeInterpreter/CodeInterpreter.cs
  class CodeInterpreterCreateOptions (line 28) | public class CodeInterpreterCreateOptions
  class CodeInterpreter (line 52) | public sealed class CodeInterpreter
    method CodeInterpreter (line 86) | private CodeInterpreter(Sandbox sandbox, ICodes codes, ILogger logger)
    method CreateAsync (line 103) | public static async Task<CodeInterpreter> CreateAsync(
    method MergeHeaders (line 134) | private static IReadOnlyDictionary<string, string> MergeHeaders(

FILE: sdks/code-interpreter/csharp/src/OpenSandbox.CodeInterpreter/Factory/DefaultCodeInterpreterAdapterFactory.cs
  class DefaultCodeInterpreterAdapterFactory (line 26) | public class DefaultCodeInterpreterAdapterFactory : ICodeInterpreterAdap...
    method Create (line 32) | public static DefaultCodeInterpreterAdapterFactory Create() => new();
    method CreateCodes (line 35) | public ICodes CreateCodes(CreateCodesStackOptions options)

FILE: sdks/code-interpreter/csharp/src/OpenSandbox.CodeInterpreter/Factory/ICodeInterpreterAdapterFactory.cs
  class CreateCodesStackOptions (line 25) | public class CreateCodesStackOptions
  type ICodeInterpreterAdapterFactory (line 56) | public interface ICodeInterpreterAdapterFactory
    method CreateCodes (line 63) | ICodes CreateCodes(CreateCodesStackOptions options);

FILE: sdks/code-interpreter/csharp/src/OpenSandbox.CodeInterpreter/Models/CodeModels.cs
  class SupportedLanguage (line 22) | public static class SupportedLanguage
  class CodeContext (line 58) | public class CodeContext
  class RunCodeRequest (line 76) | public class RunCodeRequest
  class RunCodeOptions (line 94) | public class RunCodeOptions
  class CreateContextRequest (line 120) | internal class CreateContextRequest

FILE: sdks/code-interpreter/csharp/src/OpenSandbox.CodeInterpreter/Services/ICodes.cs
  type ICodes (line 24) | public interface ICodes
    method CreateContextAsync (line 34) | Task<CodeContext> CreateContextAsync(string language, CancellationToke...
    method GetContextAsync (line 44) | Task<CodeContext> GetContextAsync(string contextId, CancellationToken ...
    method ListContextsAsync (line 54) | Task<IReadOnlyList<CodeContext>> ListContextsAsync(string language, Ca...
    method DeleteContextAsync (line 63) | Task DeleteContextAsync(string contextId, CancellationToken cancellati...
    method DeleteContextsAsync (line 72) | Task DeleteContextsAsync(string language, CancellationToken cancellati...
    method RunAsync (line 83) | Task<Execution> RunAsync(string code, RunCodeOptions? options = null, ...
    method RunStreamAsync (line 93) | IAsyncEnumerable<ServerStreamEvent> RunStreamAsync(RunCodeRequest requ...
    method InterruptAsync (line 102) | Task InterruptAsync(string contextId, CancellationToken cancellationTo...

FILE: sdks/code-interpreter/csharp/tests/OpenSandbox.CodeInterpreter.Tests/CodeInterpreterTests.cs
  class CodeInterpreterTests (line 21) | public class CodeInterpreterTests
    method CreateAsync_ThrowsOnNullSandbox (line 23) | [Fact]
    method CodeInterpreterCreateOptions_DefaultsAreNull (line 30) | [Fact]
    method CodeInterpreterCreateOptions_CanSetAdapterFactory (line 38) | [Fact]
    class TestAdapterFactory (line 50) | private class TestAdapterFactory : Factory.ICodeInterpreterAdapterFactory
      method CreateCodes (line 52) | public Services.ICodes CreateCodes(Factory.CreateCodesStackOptions o...

FILE: sdks/code-interpreter/csharp/tests/OpenSandbox.CodeInterpreter.Tests/CodesAdapterTests.cs
  class CodesAdapterTests (line 29) | public class CodesAdapterTests
    method ListContextsAsync_ThrowsOnEmptyLanguage (line 31) | [Fact]
    method ListContextsAsync_SendsLanguageQuery (line 41) | [Fact]
    method RunStreamAsync_ThrowsOnEmptyCode (line 65) | [Fact]
    method RunStreamAsync_ParsesSseEvent (line 81) | [Fact]
    method DrainAsync (line 118) | private static async Task DrainAsync<T>(IAsyncEnumerable<T> source)
    method CreateAdapter (line 125) | private static CodesAdapter CreateAdapter(HttpMessageHandler httpHandl...
    class StubHttpMessageHandler (line 135) | private sealed class StubHttpMessageHandler : HttpMessageHandler
      method StubHttpMessageHandler (line 139) | public StubHttpMessageHandler(Func<HttpRequestMessage, CancellationT...
      method SendAsync (line 147) | protected override async Task<HttpResponseMessage> SendAsync(HttpReq...
      method MediaTypeToString (line 154) | private static string MediaTypeToString(MediaTypeWithQualityHeaderVa...

FILE: sdks/code-interpreter/csharp/tests/OpenSandbox.CodeInterpreter.Tests/FactoryTests.cs
  class FactoryTests (line 23) | public class FactoryTests
    method DefaultCodeInterpreterAdapterFactory_Create_ReturnsInstance (line 25) | [Fact]
    method DefaultCodeInterpreterAdapterFactory_CreateCodes_ThrowsOnNullOptions (line 34) | [Fact]
    method DefaultCodeInterpreterAdapterFactory_CreateCodes_ThrowsOnNullConnectionConfig (line 42) | [Fact]
    method DefaultCodeInterpreterAdapterFactory_CreateCodes_ThrowsOnEmptyBaseUrl (line 58) | [Fact]
    method CreateCodesStackOptions_RequiredProperties (line 75) | [Fact]

FILE: sdks/code-interpreter/csharp/tests/OpenSandbox.CodeInterpreter.Tests/ModelsTests.cs
  class ModelsTests (line 21) | public class ModelsTests
    method SupportedLanguage_HasCorrectValues (line 23) | [Fact]
    method CodeContext_SerializesToJson (line 34) | [Fact]
    method CodeContext_DeserializesFromJson (line 48) | [Fact]
    method CodeContext_DeserializesWithNullId (line 59) | [Fact]
    method RunCodeRequest_SerializesToJson (line 70) | [Fact]
    method RunCodeRequest_DeserializesFromJson (line 91) | [Fact]
    method RunCodeOptions_DefaultsAreNull (line 104) | [Fact]
    method RunCodeOptions_CanSetProperties (line 114) | [Fact]
    method RunCodeOptions_CanSetLanguageOnly (line 130) | [Fact]

FILE: sdks/code-interpreter/javascript/src/adapters/codesAdapter.ts
  type ApiCreateContextRequest (line 28) | type ApiCreateContextRequest =
  type ApiCreateContextOk (line 30) | type ApiCreateContextOk =
  type ApiGetContextOk (line 32) | type ApiGetContextOk =
  type ApiListContextsOk (line 34) | type ApiListContextsOk =
  type ApiRunCodeRequest (line 36) | type ApiRunCodeRequest =
  function joinUrl (line 45) | function joinUrl(baseUrl: string, pathname: string): string {
  class CodesAdapter (line 51) | class CodesAdapter implements Codes {
    method constructor (line 54) | constructor(
    method createContext (line 61) | async createContext(language: SupportedLanguage): Promise<CodeContext> {
    method getContext (line 77) | async getContext(contextId: string): Promise<CodeContext> {
    method listContexts (line 95) | async listContexts(language?: SupportedLanguage): Promise<CodeContext[...
    method deleteContext (line 109) | async deleteContext(contextId: string): Promise<void> {
    method deleteContexts (line 119) | async deleteContexts(language: SupportedLanguage): Promise<void> {
    method interrupt (line 126) | async interrupt(contextId: string): Promise<void> {
    method runStream (line 133) | async *runStream(req: ApiRunCodeRequest, signal?: AbortSignal): AsyncI...
    method run (line 152) | async run(

FILE: sdks/code-interpreter/javascript/src/adapters/openapiError.ts
  function throwOnOpenApiFetchError (line 17) | function throwOnOpenApiFetchError(

FILE: sdks/code-interpreter/javascript/src/adapters/sse.ts
  function tryParseJson (line 17) | function tryParseJson(line: string): unknown | undefined {

FILE: sdks/code-interpreter/javascript/src/factory/adapterFactory.ts
  type CreateCodesStackOptions (line 18) | interface CreateCodesStackOptions {
  type AdapterFactory (line 27) | interface AdapterFactory {

FILE: sdks/code-interpreter/javascript/src/factory/defaultAdapterFactory.ts
  class DefaultAdapterFactory (line 20) | class DefaultAdapterFactory implements AdapterFactory {
    method createCodes (line 21) | createCodes(opts: CreateCodesStackOptions): Codes {
  function createDefaultAdapterFactory (line 41) | function createDefaultAdapterFactory(): AdapterFactory {

FILE: sdks/code-interpreter/javascript/src/interpreter.ts
  type CodeInterpreterCreateOptions (line 22) | interface CodeInterpreterCreateOptions {
  class CodeInterpreter (line 35) | class CodeInterpreter {
    method constructor (line 36) | private constructor(
    method create (line 41) | static async create(sandbox: Sandbox, opts: CodeInterpreterCreateOptio...
    method id (line 54) | get id() {
    method files (line 58) | get files() {
    method commands (line 62) | get commands() {
    method metrics (line 66) | get metrics() {

FILE: sdks/code-interpreter/javascript/src/models.ts
  type SupportedLanguage (line 24) | type SupportedLanguage =
  type CodeContext (line 27) | interface CodeContext {
  type RunCodeRequest (line 32) | interface RunCodeRequest {

FILE: sdks/code-interpreter/javascript/src/services/codes.ts
  type Codes (line 19) | interface Codes {

FILE: sdks/code-interpreter/javascript/tests/interpreter.headers.test.mjs
  method getEndpoint (line 14) | async getEndpoint(port) {
  method createCodes (line 24) | createCodes(opts) {

FILE: sdks/code-interpreter/python/src/code_interpreter/adapters/code_adapter.py
  function _normalize_sse_event (line 54) | def _normalize_sse_event(event_dict: dict) -> dict:
  class CodesAdapter (line 70) | class CodesAdapter(Codes):
    method __init__ (line 87) | def __init__(
    method _get_client (line 144) | async def _get_client(self):
    method _get_execd_url (line 148) | def _get_execd_url(self, path: str) -> str:
    method _get_sse_client (line 153) | async def _get_sse_client(self) -> httpx.AsyncClient:
    method create_context (line 157) | async def create_context(self, language: str) -> CodeContext:
    method get_context (line 189) | async def get_context(self, context_id: str) -> CodeContext:
    method list_contexts (line 208) | async def list_contexts(self, language: str) -> list[CodeContext]:
    method delete_context (line 224) | async def delete_context(self, context_id: str) -> None:
    method delete_contexts (line 238) | async def delete_contexts(self, language: str) -> None:
    method run (line 254) | async def run(
    method interrupt (line 342) | async def interrupt(self, execution_id: str) -> None:

FILE: sdks/code-interpreter/python/src/code_interpreter/adapters/converter/code_execution_converter.py
  class CodeExecutionConverter (line 30) | class CodeExecutionConverter:
    method to_api_run_code_request (line 36) | def to_api_run_code_request(code: str, context: CodeContext | None) ->...
    method to_api_code_context (line 55) | def to_api_code_context(context: CodeContext) -> dict[str, Any]:
    method from_api_code_context (line 75) | def from_api_code_context(api_context: ApiCodeContext) -> CodeContext:
    method from_api_code_context_dict (line 95) | def from_api_code_context_dict(api_context: dict[str, Any]) -> CodeCon...

FILE: sdks/code-interpreter/python/src/code_interpreter/adapters/factory.py
  class AdapterFactory (line 30) | class AdapterFactory:
    method __init__ (line 39) | def __init__(self, connection_config: ConnectionConfig) -> None:
    method create_code_execution_service (line 48) | def create_code_execution_service(self, endpoint: SandboxEndpoint) -> ...

FILE: sdks/code-interpreter/python/src/code_interpreter/code_interpreter.py
  class CodeInterpreter (line 39) | class CodeInterpreter:
    method __init__ (line 88) | def __init__(self, sandbox: Sandbox, code_service: Codes) -> None:
    method sandbox (line 102) | def sandbox(self) -> Sandbox:
    method id (line 112) | def id(self) -> str:
    method files (line 122) | def files(self):
    method commands (line 134) | def commands(self):
    method metrics (line 146) | def metrics(self):
    method codes (line 158) | def codes(self) -> Codes:
    method create (line 173) | async def create(cls, sandbox: Sandbox) -> "CodeInterpreter":

FILE: sdks/code-interpreter/python/src/code_interpreter/models/code.py
  class SupportedLanguage (line 26) | class SupportedLanguage:
  class CodeContext (line 41) | class CodeContext(BaseModel):
    method language_must_not_be_empty (line 62) | def language_must_not_be_empty(cls, v: str) -> str:

FILE: sdks/code-interpreter/python/src/code_interpreter/models/code_sync.py
  class SupportedLanguageSync (line 23) | class SupportedLanguageSync:
  class CodeContextSync (line 32) | class CodeContextSync(BaseModel):
    method language_must_not_be_empty (line 38) | def language_must_not_be_empty(cls, v: str) -> str:

FILE: sdks/code-interpreter/python/src/code_interpreter/services/code.py
  class Codes (line 30) | class Codes(Protocol):
    method create_context (line 74) | async def create_context(self, language: str) -> CodeContext:
    method get_context (line 94) | async def get_context(self, context_id: str) -> CodeContext:
    method list_contexts (line 106) | async def list_contexts(self, language: str) -> list[CodeContext]:
    method delete_context (line 118) | async def delete_context(self, context_id: str) -> None:
    method delete_contexts (line 127) | async def delete_contexts(self, language: str) -> None:
    method run (line 137) | async def run(
    method run (line 146) | async def run(
    method run (line 154) | async def run(
    method interrupt (line 194) | async def interrupt(self, execution_id: str) -> None:

FILE: sdks/code-interpreter/python/src/code_interpreter/sync/adapters/code_adapter.py
  function _normalize_sse_event (line 49) | def _normalize_sse_event(event_dict: dict) -> dict:
  class CodesAdapterSync (line 65) | class CodesAdapterSync(CodesSync):
    method __init__ (line 84) | def __init__(self, execd_endpoint: SandboxEndpoint, connection_config:...
    method _get_execd_url (line 117) | def _get_execd_url(self, path: str) -> str:
    method create_context (line 121) | def create_context(self, language: str) -> CodeContextSync:
    method get_context (line 149) | def get_context(self, context_id: str) -> CodeContextSync:
    method list_contexts (line 169) | def list_contexts(self, language: str) -> list[CodeContextSync]:
    method delete_context (line 190) | def delete_context(self, context_id: str) -> None:
    method delete_contexts (line 203) | def delete_contexts(self, language: str) -> None:
    method run (line 218) | def run(
    method interrupt (line 298) | def interrupt(self, execution_id: str) -> None:

FILE: sdks/code-interpreter/python/src/code_interpreter/sync/adapters/factory.py
  class AdapterFactorySync (line 27) | class AdapterFactorySync:
    method __init__ (line 35) | def __init__(self, connection_config: ConnectionConfigSync) -> None:
    method create_code_execution_service (line 44) | def create_code_execution_service(self, endpoint: SandboxEndpoint) -> ...

FILE: sdks/code-interpreter/python/src/code_interpreter/sync/code_interpreter.py
  class CodeInterpreterSync (line 36) | class CodeInterpreterSync:
    method __init__ (line 71) | def __init__(self, sandbox: SandboxSync, code_service: CodesSync) -> N...
    method sandbox (line 85) | def sandbox(self) -> SandboxSync:
    method id (line 95) | def id(self) -> str:
    method files (line 105) | def files(self):
    method commands (line 115) | def commands(self):
    method metrics (line 125) | def metrics(self):
    method codes (line 135) | def codes(self) -> CodesSync:
    method create (line 150) | def create(cls, sandbox: SandboxSync) -> "CodeInterpreterSync":

FILE: sdks/code-interpreter/python/src/code_interpreter/sync/services/code.py
  class CodesSync (line 33) | clas
Condensed preview — 1108 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,466K chars).
[
  {
    "path": ".github/CODEOWNERS",
    "chars": 928,
    "preview": "# CODEOWNERS for OpenSandbox\n# Rules are evaluated top-to-bottom; the last matching pattern wins.\n\n# Default owners (fal"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/FEATURE_REQUEST.md",
    "chars": 451,
    "preview": "---\nname: Feature Request\nabout: Suggest an idea for OpenSandbox\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n## Why do you "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 187,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Any Questions or Suggestions?\n    url: https://github.com/alibaba/O"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 440,
    "preview": "# Summary\n- What is changing and why?\n\n# Testing\n- [ ] Not run (explain why)\n- [ ] Unit tests\n- [ ] Integration tests\n- "
  },
  {
    "path": ".github/workflows/deploy-docs-pages.yml",
    "chars": 1971,
    "preview": "name: Deploy Docs Pages\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - \"docs/**\"\n      - \"specs/**\"\n      - "
  },
  {
    "path": ".github/workflows/egress-test.yaml.yml",
    "chars": 1886,
    "preview": "name: Egress Tests\n\non:\n  pull_request:\n    branches: [ main ]\n    paths:\n      - 'components/egress/**'\n      - 'compon"
  },
  {
    "path": ".github/workflows/execd-test.yml",
    "chars": 2887,
    "preview": "name: Execd Tests\n\non:\n  pull_request:\n    branches: [ main ]\n    paths:\n      - 'components/execd/**'\n      - 'componen"
  },
  {
    "path": ".github/workflows/ingress-test.yaml",
    "chars": 846,
    "preview": "name: Ingress Tests\n\non:\n  pull_request:\n    branches: [ main ]\n    paths:\n      - 'components/ingress/**'\n      - 'comp"
  },
  {
    "path": ".github/workflows/publish-components.yml",
    "chars": 4773,
    "preview": "name: Publish Components Image\n\npermissions:\n  # required for bump step to push branch and create PR\n  contents: write\n "
  },
  {
    "path": ".github/workflows/publish-csharp-sdks.yml",
    "chars": 3143,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": ".github/workflows/publish-helm-chart.yml",
    "chars": 6314,
    "preview": "name: Publish Helm Chart\n\non:\n  workflow_dispatch:\n    inputs:\n      component:\n        description: 'Component to relea"
  },
  {
    "path": ".github/workflows/publish-java-sdks.yml",
    "chars": 1521,
    "preview": "name: Publish Java SDKs\n\non:\n  push:\n    tags:\n      - \"java/sandbox/v*\"\n      - \"java/code-interpreter/v*\"\n\npermissions"
  },
  {
    "path": ".github/workflows/publish-js-sdks.yml",
    "chars": 2056,
    "preview": "name: Publish JavaScript SDKs\n\non:\n  push:\n    tags:\n      - \"js/sandbox/v*\"\n      - \"js/code-interpreter/v*\"\n\npermissio"
  },
  {
    "path": ".github/workflows/publish-python-sdks.yml",
    "chars": 3046,
    "preview": "# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": ".github/workflows/publish-server.yml",
    "chars": 2880,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": ".github/workflows/real-e2e.yml",
    "chars": 10543,
    "preview": "name: Real E2E Tests\n\npermissions:\n  contents: read\n\non:\n  pull_request:\n    branches: [ main ]\n    paths:\n      - 'serv"
  },
  {
    "path": ".github/workflows/sandbox-k8s-e2e.yml",
    "chars": 864,
    "preview": "name: Sandbox K8S E2E Tests\n\non:\n  pull_request:\n    branches: [ main ]\n    paths:\n      - 'kubernetes/**'\n\npermissions:"
  },
  {
    "path": ".github/workflows/sandbox-k8s-test.yml",
    "chars": 772,
    "preview": "name: Sandbox K8S Tests\n\non:\n  pull_request:\n    branches: [ main ]\n    paths:\n      - 'kubernetes/**'\n\npermissions:\n  c"
  },
  {
    "path": ".github/workflows/sdk-tests.yml",
    "chars": 4009,
    "preview": "# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": ".github/workflows/server-test.yml",
    "chars": 2245,
    "preview": "name: Server Tests\n\non:\n  pull_request:\n    branches: [ main ]\n    paths:\n      - 'server/src/**'\n      - 'server/tests/"
  },
  {
    "path": ".github/workflows/verify-license.yml",
    "chars": 500,
    "preview": "name: Verify License Headers\n\non:\n  pull_request:\n    branches: [ main ]\n\nconcurrency:\n  group: ${{ github.workflow }}-$"
  },
  {
    "path": ".gitignore",
    "chars": 3210,
    "preview": "# IDE and Editor files\n.vscode/\n.idea/\n*.swp\n*.swo\n*~\n.DS_Store\nThumbs.db\n\n# Go\n# Binaries for programs and plugins\n*.ex"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 762,
    "preview": "# Minimal cross-language pre-commit hooks\n# Install: pip install pre-commit && pre-commit install\n# Run once on all file"
  },
  {
    "path": "AGENTS.md",
    "chars": 3148,
    "preview": "# Repository Guidelines\n\n## Project Structure & Module Organization\n- `server/`: Python FastAPI service, configs, and te"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 920,
    "preview": "# Code of Conduct\n\nWe are committed to a welcoming, safe, and respectful community.\n\n## Expected Behavior\n- Be respectfu"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 14862,
    "preview": "# Contributing to OpenSandbox\n\nThank you for your interest in contributing to OpenSandbox! This guide will help you get "
  },
  {
    "path": "LICENSE",
    "chars": 11324,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "README.md",
    "chars": 12361,
    "preview": "<div align=\"center\">\n  <img src=\"docs/assets/logo.svg\" alt=\"OpenSandbox logo\" width=\"150\" />\n\n  <h1>OpenSandbox</h1>\n\n  "
  },
  {
    "path": "SECURITY.md",
    "chars": 958,
    "preview": "# Security Policy\n\n## Reporting Security Issues\n\nThe OpenSandbox team takes security seriously. If you discover a securi"
  },
  {
    "path": "cli/README.md",
    "chars": 7277,
    "preview": "# OpenSandbox CLI\n\nA command-line interface for managing OpenSandbox environments from your terminal. Built on top of th"
  },
  {
    "path": "cli/pyproject.toml",
    "chars": 3737,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/__init__.py",
    "chars": 733,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/__main__.py",
    "chars": 721,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/client.py",
    "chars": 4707,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/commands/__init__.py",
    "chars": 590,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/commands/code.py",
    "chars": 6496,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/commands/command.py",
    "chars": 6669,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/commands/config_cmd.py",
    "chars": 5376,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/commands/file.py",
    "chars": 11048,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/commands/sandbox.py",
    "chars": 11604,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/config.py",
    "chars": 4147,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/main.py",
    "chars": 4367,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/output.py",
    "chars": 11616,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/src/opensandbox_cli/utils.py",
    "chars": 4783,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "cli/tests/conftest.py",
    "chars": 1729,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/tests/test_cli_help.py",
    "chars": 6098,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/tests/test_commands.py",
    "chars": 11012,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/tests/test_config.py",
    "chars": 6985,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/tests/test_output.py",
    "chars": 4821,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/tests/test_resolve_id.py",
    "chars": 7301,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "cli/tests/test_utils.py",
    "chars": 3724,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "components/egress/Dockerfile",
    "chars": 2220,
    "preview": "# Copyright 2026 Alibaba Group Holding Ltd.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you m"
  },
  {
    "path": "components/egress/README.md",
    "chars": 9578,
    "preview": "# OpenSandbox Egress Sidecar\n\nThe **Egress Sidecar** is a core component of OpenSandbox that provides **FQDN-based egres"
  },
  {
    "path": "components/egress/TODO.md",
    "chars": 2145,
    "preview": "# Egress Sidecar TODO (Linux MVP → Full OSEP-0001)\n\n- Layer 2 still partial: static IP/CIDR now pushed to nftables, DoH/"
  },
  {
    "path": "components/egress/build.sh",
    "chars": 1650,
    "preview": "#!/bin/bash\n# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "components/egress/docs/benchmark.md",
    "chars": 4851,
    "preview": "# Egress Benchmark\n\nThis document describes the **Egress Sidecar** end-to-end benchmark: it compares **dns** and **dns+n"
  },
  {
    "path": "components/egress/go.mod",
    "chars": 654,
    "preview": "module github.com/alibaba/opensandbox/egress\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/alibaba/opensandbox/internal v0.0.0\n\tgith"
  },
  {
    "path": "components/egress/go.sum",
    "chars": 2280,
    "preview": "github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.m"
  },
  {
    "path": "components/egress/main.go",
    "chars": 4532,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/nameserver.go",
    "chars": 2600,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/nameserver_test.go",
    "chars": 4496,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/nft.go",
    "chars": 3289,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/constants/configuration.go",
    "chars": 1517,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/constants/constants.go",
    "chars": 731,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/dnsproxy/exempt.go",
    "chars": 2211,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/dnsproxy/exempt_test.go",
    "chars": 2278,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/dnsproxy/proxy.go",
    "chars": 8300,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/dnsproxy/proxy_linux.go",
    "chars": 1799,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/dnsproxy/proxy_other.go",
    "chars": 810,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/dnsproxy/proxy_test.go",
    "chars": 6322,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/events/broadcaster.go",
    "chars": 2916,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/events/events_test.go",
    "chars": 3967,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/events/webhook.go",
    "chars": 3334,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/iptables/redirect.go",
    "chars": 3400,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/log/logger.go",
    "chars": 1494,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/nftables/dynamic.go",
    "chars": 1864,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/nftables/manager.go",
    "chars": 8821,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/nftables/manager_test.go",
    "chars": 7081,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/policy/policy.go",
    "chars": 5728,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/pkg/policy/policy_test.go",
    "chars": 4021,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/policy_server.go",
    "chars": 10458,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/policy_server_test.go",
    "chars": 6101,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/egress/tests/bench-dns-nft.sh",
    "chars": 13130,
    "preview": "#!/bin/bash\n\n# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Licens"
  },
  {
    "path": "components/egress/tests/egress-in-webhook.sh",
    "chars": 1198,
    "preview": "#!/bin/bash\n\n# Copyright 2026 Alibaba Group Holding Ltd.\n# \n# Licensed under the Apache License, Version 2.0 (the \"Licen"
  },
  {
    "path": "components/egress/tests/hostname.txt",
    "chars": 1192,
    "preview": "example.com\nexample.org\nexample.net\nexample.edu\nexample.io\ngithub.com\ngithub.io\ngoogle.com\ncloudflare.com\namazon.com\nwik"
  },
  {
    "path": "components/egress/tests/smoke-dns.sh",
    "chars": 2483,
    "preview": "#!/bin/bash\n\n# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Licens"
  },
  {
    "path": "components/egress/tests/smoke-dynamic-ip.sh",
    "chars": 2853,
    "preview": "#!/bin/bash\n\n# Copyright 2026 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Licens"
  },
  {
    "path": "components/egress/tests/smoke-nft.sh",
    "chars": 4906,
    "preview": "#!/bin/bash\n\n# Copyright 2026 Alibaba Group Holding Ltd.\n# \n# Licensed under the Apache License, Version 2.0 (the \"Licen"
  },
  {
    "path": "components/egress/tests/webhook-server.py",
    "chars": 2687,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2026 Alibaba Group Holding Ltd.\n# \n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "components/execd/.golangci.yml",
    "chars": 9470,
    "preview": "run:\n  skip-dirs:\n    - vendor\n    - tests\n    - scripts\n  skip-files:\n    - .*/zz_generated.deepcopy.go\n    - .*/mock/*"
  },
  {
    "path": "components/execd/DEVELOPMENT.md",
    "chars": 12762,
    "preview": "# Development Guide - execd\n\nThis comprehensive guide explains how to work on `execd` as a contributor or maintainer. It"
  },
  {
    "path": "components/execd/Dockerfile",
    "chars": 1660,
    "preview": "# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "components/execd/Makefile",
    "chars": 1602,
    "preview": ".PHONY: fmt\nfmt: ## Run go fmt against code.\n\tgo fmt ./...\n\n.PHONY: vet\nvet: ## Run go vet against code.\n\tgo mod tidy &&"
  },
  {
    "path": "components/execd/README.md",
    "chars": 9138,
    "preview": "# execd - OpenSandbox Execution Daemon\n\nEnglish | [中文](README_zh.md)\n\n`execd` is the execution daemon for OpenSandbox. B"
  },
  {
    "path": "components/execd/README_zh.md",
    "chars": 6493,
    "preview": "# execd - OpenSandbox 执行守护进程\n\n中文 | [English](README.md)\n\n`execd` 是 OpenSandbox 的执行守护进程,基于 Beego 框架提供全面的 HTTP API。它将外部请求转"
  },
  {
    "path": "components/execd/bootstrap.sh",
    "chars": 1782,
    "preview": "#!/bin/sh\n\n# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\""
  },
  {
    "path": "components/execd/build.sh",
    "chars": 1647,
    "preview": "#!/bin/bash\n# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "components/execd/go.mod",
    "chars": 2926,
    "preview": "module github.com/alibaba/opensandbox/execd\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/alibaba/opensandbox/internal v0.0.0\n\tgithu"
  },
  {
    "path": "components/execd/go.sum",
    "chars": 17315,
    "preview": "filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw=\nfilippo.io/edwards25519 v1.1.1/go.mod h1:"
  },
  {
    "path": "components/execd/main.go",
    "chars": 1432,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/flag/flags.go",
    "chars": 1160,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/flag/parser.go",
    "chars": 3018,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/auth/auth.go",
    "chars": 1631,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/auth/auth_test.go",
    "chars": 3342,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/auth/client.go",
    "chars": 2343,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/auth/types.go",
    "chars": 1203,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/client.go",
    "chars": 6090,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/debug_integration_test.go",
    "chars": 4735,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/execute/events.json",
    "chars": 6458,
    "preview": "[\n  {\n    \"header\": {\n      \"msg_id\": \"e5e24851-db96ed91126b13f9b603136f_123284_6\",\n      \"username\": \"username\",\n      "
  },
  {
    "path": "components/execd/pkg/jupyter/execute/execute.go",
    "chars": 10901,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/execute/execute_test.go",
    "chars": 4392,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/execute/executor.go",
    "chars": 1634,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/execute/types.go",
    "chars": 7533,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/execute/zz_generated.deepcopy.go",
    "chars": 2449,
    "preview": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2022.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyo"
  },
  {
    "path": "components/execd/pkg/jupyter/integration_test.go",
    "chars": 9218,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/kernel/kernel.go",
    "chars": 7925,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/kernel/kernelspecs.json",
    "chars": 640,
    "preview": "{\n  \"default\" : \"python3\",\n  \"kernelspecs\" : {\n    \"python3\" : {\n      \"name\" : \"python3\",\n      \"spec\" : {\n        \"arg"
  },
  {
    "path": "components/execd/pkg/jupyter/kernel/types.go",
    "chars": 3982,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/live_integration_test.go",
    "chars": 9819,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/session/session.go",
    "chars": 8377,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/session/session_test.go",
    "chars": 7069,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/session/sessions.json",
    "chars": 2611,
    "preview": "[ {\n  \"id\" : \"cb1baca9-a60e-4937-a1d0-18bc1fc45e60\",\n  \"path\" : \"my_notebook.ipynb\",\n  \"name\" : \"my_session\",\n  \"type\" :"
  },
  {
    "path": "components/execd/pkg/jupyter/session/types.go",
    "chars": 3951,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/jupyter/transport.go",
    "chars": 920,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/log/log.go",
    "chars": 2013,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/bash_session.go",
    "chars": 11230,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/bash_session_test.go",
    "chars": 17986,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/bash_session_windows.go",
    "chars": 1322,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/command.go",
    "chars": 7915,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/command_common.go",
    "chars": 4631,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/command_status.go",
    "chars": 3613,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/command_status_test.go",
    "chars": 4696,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/command_test.go",
    "chars": 7947,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/command_windows.go",
    "chars": 4830,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/context.go",
    "chars": 7768,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/context_test.go",
    "chars": 5274,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/ctrl.go",
    "chars": 2711,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/env.go",
    "chars": 2402,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/env_test.go",
    "chars": 2753,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/errors.go",
    "chars": 695,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/helpers_test.go",
    "chars": 2876,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/interrupt.go",
    "chars": 2716,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/interrupt_windows.go",
    "chars": 1885,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/jupyter.go",
    "chars": 4620,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/language.go",
    "chars": 1197,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/sql.go",
    "chars": 5248,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/sql_test.go",
    "chars": 3283,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/types.go",
    "chars": 3853,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/runtime/types_test.go",
    "chars": 1319,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/util/glob/index.go",
    "chars": 1952,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/util/glob/match.go",
    "chars": 9360,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/util/glob/match_benchmark_test.go",
    "chars": 958,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/util/glob/match_test.go",
    "chars": 16588,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/util/glob/pattern.go",
    "chars": 1400,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/util/safego/safe.go",
    "chars": 1372,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/util/safego/safe_test.go",
    "chars": 898,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/basic.go",
    "chars": 1618,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/basic_test.go",
    "chars": 3278,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/codeinterpreting.go",
    "chars": 9885,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/codeinterpreting_test.go",
    "chars": 2863,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/command.go",
    "chars": 4302,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/command_test.go",
    "chars": 2866,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/filesystem.go",
    "chars": 7609,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/filesystem_download.go",
    "chars": 3062,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/filesystem_test.go",
    "chars": 4896,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/filesystem_upload.go",
    "chars": 4264,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/filesystem_windows.go",
    "chars": 7177,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/metric.go",
    "chars": 2999,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/metric_test.go",
    "chars": 4116,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/mock_test.go",
    "chars": 1145,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/ping.go",
    "chars": 1092,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/sse.go",
    "chars": 5728,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/syscall_linux.go",
    "chars": 906,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/syscall_others.go",
    "chars": 757,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/test_helpers.go",
    "chars": 1004,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/utils.go",
    "chars": 6462,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/utils_test.go",
    "chars": 3183,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/controller/utils_windows.go",
    "chars": 5546,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/codeinterpreting.go",
    "chars": 4246,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/codeinterpreting_test.go",
    "chars": 3523,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/command.go",
    "chars": 1070,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/error.go",
    "chars": 1314,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/filesystem.go",
    "chars": 1545,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/header.go",
    "chars": 725,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/metric.go",
    "chars": 1084,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/model/session.go",
    "chars": 1396,
    "preview": "// Copyright 2026 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/proxy.go",
    "chars": 3133,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/pkg/web/router.go",
    "chars": 5175,
    "preview": "// Copyright 2025 Alibaba Group Holding Ltd.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
  },
  {
    "path": "components/execd/tests/jupyter.sh",
    "chars": 994,
    "preview": "#!/bin/bash\n# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "components/execd/tests/smoke.sh",
    "chars": 861,
    "preview": "#!/bin/bash\n# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "components/execd/tests/smoke_api.py",
    "chars": 8800,
    "preview": "#!/usr/bin/env python3\n\n# Copyright 2025 Alibaba Group Holding Ltd.\n# \n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "components/ingress/.golangci.yml",
    "chars": 9489,
    "preview": "run:\n  skip-dirs:\n    - vendor\n    - tests\n    - scripts\n  skip-files:\n    - .*/zz_generated.deepcopy.go\n    - .*/mock/*"
  },
  {
    "path": "components/ingress/DEVELOPMENT.md",
    "chars": 1345,
    "preview": "# Development Guide (Quick)\n\n## Prerequisites\n- Go 1.24+\n- Docker (optional, for image build)\n- Access to a Kubernetes c"
  },
  {
    "path": "components/ingress/Dockerfile",
    "chars": 1621,
    "preview": "# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
  },
  {
    "path": "components/ingress/Makefile",
    "chars": 1225,
    "preview": ".PHONY: fmt\nfmt: ## Run go fmt against code.\n\tgo fmt ./...\n\n.PHONY: vet\nvet: ## Run go vet against code.\n\tgo mod tidy &&"
  },
  {
    "path": "components/ingress/README.md",
    "chars": 6195,
    "preview": "# OpenSandbox Ingress\n\n## Overview\n- HTTP/WebSocket reverse proxy that routes to sandbox instances.\n- Watches sandbox CR"
  },
  {
    "path": "components/ingress/build.sh",
    "chars": 1661,
    "preview": "#!/bin/bash\n# Copyright 2025 Alibaba Group Holding Ltd.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "components/ingress/go.mod",
    "chars": 3515,
    "preview": "module github.com/alibaba/opensandbox/ingress\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/alibaba/OpenSandbox/sandbox-k8s v0.0.0\n\t"
  },
  {
    "path": "components/ingress/go.sum",
    "chars": 19096,
    "preview": "github.com/alicebob/miniredis/v2 v2.37.0 h1:RheObYW32G1aiJIj81XVt78ZHJpHonHLHW7OLIshq68=\ngithub.com/alicebob/miniredis/v"
  }
]

// ... and 908 more files (download for full content)

About this extraction

This page contains the full source code of the alibaba/OpenSandbox GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1108 files (5.8 MB), approximately 1.6M tokens, and a symbol index with 5263 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!