opencode-a2a-server 0.2.1__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.secrets.baseline +2 -12
  2. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/PKG-INFO +91 -54
  3. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/README.md +90 -53
  4. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/SECURITY.md +4 -4
  5. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/docs/guide.md +31 -3
  6. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/pyproject.toml +1 -1
  7. opencode_a2a_server-0.2.2/scripts/README.md +22 -0
  8. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/app.py +2 -2
  9. opencode_a2a_server-0.2.2/src/opencode_a2a_server/cli.py +53 -0
  10. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/config.py +1 -1
  11. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/opencode_client.py +1 -1
  12. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/PKG-INFO +91 -54
  13. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/SOURCES.txt +2 -24
  14. opencode_a2a_server-0.2.2/src/opencode_a2a_server.egg-info/entry_points.txt +2 -0
  15. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/helpers.py +1 -1
  16. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_agent_card.py +1 -1
  17. opencode_a2a_server-0.2.2/tests/test_cli.py +58 -0
  18. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_directory_validation.py +1 -1
  19. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_opencode_client_params.py +7 -7
  20. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_opencode_session_extension.py +26 -26
  21. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_settings.py +13 -0
  22. opencode_a2a_server-0.2.1/docs/agent_deploy_sop.md +0 -292
  23. opencode_a2a_server-0.2.1/docs/release_deploy_smoke_test.md +0 -188
  24. opencode_a2a_server-0.2.1/scripts/README.md +0 -34
  25. opencode_a2a_server-0.2.1/scripts/deploy/enable_instance.sh +0 -175
  26. opencode_a2a_server-0.2.1/scripts/deploy/install_release_runtime.sh +0 -52
  27. opencode_a2a_server-0.2.1/scripts/deploy/install_units.sh +0 -110
  28. opencode_a2a_server-0.2.1/scripts/deploy/provider_secret_env_keys.sh +0 -69
  29. opencode_a2a_server-0.2.1/scripts/deploy/run_a2a.sh +0 -18
  30. opencode_a2a_server-0.2.1/scripts/deploy/run_opencode.sh +0 -80
  31. opencode_a2a_server-0.2.1/scripts/deploy/setup_instance.sh +0 -483
  32. opencode_a2a_server-0.2.1/scripts/deploy/update_a2a.sh +0 -27
  33. opencode_a2a_server-0.2.1/scripts/deploy.sh +0 -344
  34. opencode_a2a_server-0.2.1/scripts/deploy_readme.md +0 -333
  35. opencode_a2a_server-0.2.1/scripts/deploy_release.sh +0 -8
  36. opencode_a2a_server-0.2.1/scripts/deploy_release_readme.md +0 -72
  37. opencode_a2a_server-0.2.1/scripts/init_release_system.sh +0 -15
  38. opencode_a2a_server-0.2.1/scripts/init_release_system_readme.md +0 -41
  39. opencode_a2a_server-0.2.1/scripts/init_system.sh +0 -852
  40. opencode_a2a_server-0.2.1/scripts/init_system_readme.md +0 -69
  41. opencode_a2a_server-0.2.1/scripts/init_system_uv_release_manifest.sh +0 -17
  42. opencode_a2a_server-0.2.1/scripts/shell_helpers.sh +0 -34
  43. opencode_a2a_server-0.2.1/scripts/uninstall.sh +0 -383
  44. opencode_a2a_server-0.2.1/scripts/uninstall_readme.md +0 -39
  45. opencode_a2a_server-0.2.1/src/opencode_a2a_server.egg-info/entry_points.txt +0 -2
  46. opencode_a2a_server-0.2.1/tests/test_deploy_security_contract.py +0 -164
  47. opencode_a2a_server-0.2.1/tests/test_init_system_security.py +0 -101
  48. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.github/workflows/ci.yml +0 -0
  49. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.github/workflows/dependency-health.yml +0 -0
  50. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.github/workflows/publish.yml +0 -0
  51. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.gitignore +0 -0
  52. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.pre-commit-config.yaml +0 -0
  53. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/AGENTS.md +0 -0
  54. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/CONTRIBUTING.md +0 -0
  55. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/LICENSE +0 -0
  56. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/dependency_health.sh +0 -0
  57. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/doctor.sh +0 -0
  58. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/health_common.sh +0 -0
  59. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/lint.sh +0 -0
  60. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/smoke_test_built_cli.sh +0 -0
  61. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/setup.cfg +0 -0
  62. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/__init__.py +0 -0
  63. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/agent.py +0 -0
  64. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/extension_contracts.py +0 -0
  65. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/jsonrpc_ext.py +0 -0
  66. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/jsonrpc_models.py +0 -0
  67. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/parts_mapper.py +0 -0
  68. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/text_parts.py +0 -0
  69. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/dependency_links.txt +0 -0
  70. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/requires.txt +0 -0
  71. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/top_level.txt +0 -0
  72. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/__init__.py +0 -0
  73. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_agent_errors.py +0 -0
  74. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_call_context_builder.py +0 -0
  75. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_cancel_contract.py +0 -0
  76. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_cancellation.py +0 -0
  77. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_extension_contract_consistency.py +0 -0
  78. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_jsonrpc_models.py +0 -0
  79. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_jsonrpc_unsupported_method.py +0 -0
  80. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_metrics.py +0 -0
  81. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_multipart_input.py +0 -0
  82. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_opencode_agent_session_binding.py +0 -0
  83. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_script_health_contract.py +0 -0
  84. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_session_ownership.py +0 -0
  85. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_streaming_output_contract.py +0 -0
  86. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_transport_contract.py +0 -0
  87. {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/uv.lock +0 -0
@@ -126,16 +126,6 @@
126
126
  "path": "detect_secrets.filters.heuristic.is_templated_secret"
127
127
  }
128
128
  ],
129
- "results": {
130
- "scripts/init_system.sh": [
131
- {
132
- "type": "Hex High Entropy String",
133
- "filename": "scripts/init_system.sh",
134
- "hashed_secret": "96183ea4ff07d786ed3233777364ddbf14eb74cc",
135
- "is_verified": false,
136
- "line_number": 25
137
- }
138
- ]
139
- },
140
- "generated_at": "2026-03-17T13:35:29Z"
129
+ "results": {},
130
+ "generated_at": "2026-03-19T03:57:43Z"
141
131
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencode-a2a-server
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A2A wrapper service for opencode
5
5
  Author: liujuanjuan1984@Intelligent-Internet
6
6
  License-Expression: Apache-2.0
@@ -38,12 +38,12 @@ Dynamic: license-file
38
38
 
39
39
  # opencode-a2a-server
40
40
 
41
- > Turn OpenCode into a stateful A2A service with a clear runtime boundary and production-friendly deployment workflow.
41
+ > Turn OpenCode into a stateful A2A service with a clear runtime boundary.
42
42
 
43
43
  `opencode-a2a-server` exposes OpenCode through standard A2A interfaces and adds
44
- the operational pieces that raw agent runtimes usually do not provide by
45
- default: authentication, session continuity, streaming contracts, interrupt
46
- handling, deployment tooling, and explicit security guidance.
44
+ the runtime pieces that raw agent runtimes usually do not provide by default:
45
+ authentication, session continuity, streaming contracts, interrupt handling,
46
+ and explicit security guidance.
47
47
 
48
48
  ## Why This Project Exists
49
49
 
@@ -52,7 +52,8 @@ need a stable service layer around it. This repository provides that layer by:
52
52
 
53
53
  - bridging A2A transport contracts to OpenCode session/message/event APIs
54
54
  - making session and interrupt behavior explicit and auditable
55
- - packaging release-first deployment scripts and operational guidance for long-running use
55
+ - keeping the server/runtime contract explicit while leaving deployment
56
+ supervision to the operator
56
57
 
57
58
  ## What It Already Provides
58
59
 
@@ -64,7 +65,7 @@ need a stable service layer around it. This repository provides that layer by:
64
65
  - session continuation via `metadata.shared.session.id`
65
66
  - request-scoped model selection via `metadata.shared.model`
66
67
  - OpenCode session query/control extensions and provider/model discovery
67
- - released CLI install/upgrade flow and release-based systemd deployment
68
+ - released CLI install/upgrade flow and a foreground runtime entrypoint
68
69
 
69
70
  ## Extension Capability Overview
70
71
 
@@ -96,7 +97,9 @@ Detailed consumption guidance:
96
97
  One `OpenCode + opencode-a2a-server` instance pair is treated as a
97
98
  single-tenant trust boundary.
98
99
 
99
- This repository's intended scaling model is parameterized self-deployment: consumers should launch their own isolated instance pairs through the provided deployment scripts instead of sharing one runtime across mutually untrusted tenants.
100
+ This repository's intended scaling model is parameterized self-deployment:
101
+ consumers should launch their own isolated instance pairs instead of sharing
102
+ one runtime across mutually untrusted tenants.
100
103
 
101
104
  - OpenCode may manage multiple projects/directories, but one deployed instance
102
105
  is not a secure multi-tenant runtime.
@@ -115,7 +118,6 @@ flowchart TD
115
118
  Mapping --> Runtime["OpenCode HTTP runtime"]
116
119
 
117
120
  Api --> Auth["Bearer auth + request logging controls"]
118
- Api --> Deploy["release-based deployment tooling"]
119
121
  Runtime --> Workspace["Shared workspace / environment boundary"]
120
122
  ```
121
123
 
@@ -141,13 +143,14 @@ hard multi-tenant isolation layer.
141
143
  isolation boundary inside one deployed instance.
142
144
  - LLM provider keys are consumed by the OpenCode process. Prompt injection or
143
145
  indirect exfiltration attempts may still expose sensitive values.
144
- - systemd deploy defaults use operator-provisioned root-only secret files
145
- unless `ENABLE_SECRET_PERSISTENCE=true` is explicitly enabled.
146
+ - Deployment supervision is intentionally BYO. If you wrap this runtime with
147
+ `systemd`, Docker, Kubernetes, or another supervisor, you own the service
148
+ user, secret storage, restart policy, and hardening choices.
146
149
 
147
150
  Read before deployment:
148
151
 
149
152
  - [SECURITY.md](SECURITY.md)
150
- - [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
153
+ - [docs/guide.md](docs/guide.md)
151
154
 
152
155
  ## User Paths
153
156
 
@@ -184,12 +187,36 @@ opencode serve
184
187
 
185
188
  A2A_BEARER_TOKEN=prod-token \
186
189
  A2A_PUBLIC_URL=http://127.0.0.1:8000 \
187
- OPENCODE_DIRECTORY=/abs/path/to/workspace \
188
- opencode-a2a-server
190
+ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
191
+ opencode-a2a-server serve
189
192
  ```
190
193
 
194
+ `OPENCODE_WORKSPACE_ROOT` is the default workspace root that this runtime
195
+ exposes to OpenCode.
196
+
191
197
  Default address: `http://127.0.0.1:8000`
192
198
 
199
+ Common runtime variables:
200
+
201
+ | Variable | Required | Default | Purpose |
202
+ | --- | --- | --- | --- |
203
+ | `A2A_BEARER_TOKEN` | Yes | None | Bearer token required for authenticated runtime requests. |
204
+ | `OPENCODE_BASE_URL` | No | `http://127.0.0.1:4096` | Upstream OpenCode HTTP endpoint. |
205
+ | `OPENCODE_WORKSPACE_ROOT` | No | None | Default workspace root exposed to OpenCode. |
206
+ | `OPENCODE_PROVIDER_ID` | No | None | Default provider for the upstream runtime. |
207
+ | `OPENCODE_MODEL_ID` | No | None | Default model for the upstream runtime. Set together with `OPENCODE_PROVIDER_ID`. |
208
+ | `A2A_HOST` | No | `127.0.0.1` | Bind host for the A2A server. |
209
+ | `A2A_PORT` | No | `8000` | Bind port for the A2A server. |
210
+ | `A2A_PUBLIC_URL` | No | `http://127.0.0.1:8000` | Public base URL advertised by the Agent Card. |
211
+ | `A2A_LOG_LEVEL` | No | `WARNING` | Server log level. |
212
+ | `A2A_LOG_PAYLOADS` | No | `false` | Enable request/response payload logging. |
213
+ | `A2A_LOG_BODY_LIMIT` | No | `0` | Payload preview size used when payload logging is enabled. |
214
+ | `A2A_MAX_REQUEST_BODY_BYTES` | No | `1048576` | Maximum accepted request size. |
215
+ | `A2A_ALLOW_DIRECTORY_OVERRIDE` | No | `true` | Allow request-level `metadata.opencode.directory` overrides. |
216
+ | `A2A_ENABLE_SESSION_SHELL` | No | `false` | Enable high-risk `opencode.sessions.shell`. |
217
+ | `OPENCODE_TIMEOUT` | No | `120` | Upstream OpenCode request timeout in seconds. |
218
+ | `OPENCODE_TIMEOUT_STREAM` | No | None | Upstream OpenCode stream timeout override in seconds. |
219
+
193
220
  If you omit `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`, `opencode serve`
194
221
  uses your local OpenCode defaults (for example `~/.config/opencode/opencode.json`).
195
222
 
@@ -201,36 +228,63 @@ official docs and CLI:
201
228
  - Local checks: `opencode auth list`, `opencode models`, `opencode models <provider>`
202
229
 
203
230
  This path is for users who already manage their own shell, workspace, and
204
- process lifecycle. No host bootstrap script is required.
231
+ process lifecycle.
232
+
233
+ Use any supervisor you prefer for long-running operation:
205
234
 
206
- ### Path 2: Formal systemd Deploy From a Released Version
235
+ - `systemd`
236
+ - Docker / container runtimes
237
+ - Kubernetes
238
+ - `supervisord`, `pm2`, or similar process managers
207
239
 
208
- For long-running systemd deployments, use the release-based scripts:
240
+ The project no longer ships built-in host bootstrap or process-manager
241
+ wrappers. The official product surface is the runtime entrypoint itself.
242
+
243
+ Minimal `systemd` example:
244
+
245
+ 1. Create an env file such as `/etc/opencode-a2a/alpha.env`:
209
246
 
210
247
  ```bash
211
- ./scripts/init_release_system.sh
212
- ./scripts/deploy_release.sh project=alpha a2a_port=8010 a2a_host=127.0.0.1
248
+ A2A_BEARER_TOKEN=replace-me
249
+ A2A_HOST=127.0.0.1
250
+ A2A_PORT=8000
251
+ A2A_PUBLIC_URL=https://a2a.example.com
252
+ OPENCODE_BASE_URL=http://127.0.0.1:4096
253
+ OPENCODE_WORKSPACE_ROOT=/srv/my-workspace
213
254
  ```
214
255
 
215
- This path is for users who want:
256
+ 2. Create a unit file such as `/etc/systemd/system/opencode-a2a-server.service`:
257
+
258
+ ```ini
259
+ [Unit]
260
+ Description=OpenCode A2A Server
261
+ After=network-online.target
262
+ Wants=network-online.target
216
263
 
217
- - isolated Linux users and per-project directories
218
- - systemd-managed restart behavior
219
- - root-only secret files
220
- - published package versions as the deployment boundary
264
+ [Service]
265
+ Type=simple
266
+ WorkingDirectory=/srv/my-workspace
267
+ EnvironmentFile=/etc/opencode-a2a/alpha.env
268
+ ExecStart=/home/dev/.local/bin/opencode-a2a-server serve
269
+ Restart=on-failure
270
+ RestartSec=2
221
271
 
222
- Primary operator docs:
272
+ [Install]
273
+ WantedBy=multi-user.target
274
+ ```
275
+
276
+ Replace `ExecStart` with the absolute path returned by `command -v opencode-a2a-server`.
223
277
 
224
- - [scripts/init_release_system.sh](scripts/init_release_system.sh)
225
- - [scripts/deploy_release.sh](scripts/deploy_release.sh)
226
- - [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
227
- - [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
278
+ Migration notes:
279
+
280
+ - `OPENCODE_DIRECTORY` has been removed. Use `OPENCODE_WORKSPACE_ROOT`.
281
+ - Built-in `init-release-system`, `deploy-release`, and `uninstall-instance` have been removed.
282
+ - Secret storage, service users, restart policy, and supervisor configuration are now operator-managed.
228
283
 
229
284
  ## Contributor Paths
230
285
 
231
286
  Use the repository checkout directly only for development, local debugging, or
232
- validation against unreleased changes. Source-based deploy/bootstrap docs are
233
- kept for contributors and internal debugging, not as the recommended user path.
287
+ validation against unreleased changes.
234
288
 
235
289
  Quick source run:
236
290
 
@@ -243,8 +297,8 @@ OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
243
297
  opencode serve
244
298
 
245
299
  A2A_BEARER_TOKEN=dev-token \
246
- OPENCODE_DIRECTORY=/abs/path/to/workspace \
247
- uv run opencode-a2a-server
300
+ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
301
+ uv run opencode-a2a-server serve
248
302
  ```
249
303
 
250
304
  Baseline validation:
@@ -256,34 +310,17 @@ uv run pytest
256
310
 
257
311
  ## Documentation Map
258
312
 
259
- ### User / Operator Docs
313
+ ### User Docs
260
314
 
261
315
  - [docs/guide.md](docs/guide.md)
262
316
  Product behavior, API contracts, and detailed streaming/session/interrupt
263
317
  consumption guidance.
318
+ - [SECURITY.md](SECURITY.md)
319
+ Threat model, deployment caveats, and vulnerability disclosure guidance.
264
320
  - [CONTRIBUTING.md](CONTRIBUTING.md)
265
321
  Contributor workflow, validation baseline, and documentation expectations.
266
- - [docs/agent_deploy_sop.md](docs/agent_deploy_sop.md)
267
- Operator-facing SOP for release-based deployment, verification, and uninstall.
268
- - [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
269
- Real-host smoke test checklist for release-based systemd deployment.
270
- - [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
271
- Release-based systemd deployment guide for published package versions.
272
- - [scripts/init_release_system_readme.md](scripts/init_release_system_readme.md)
273
- Release-based host bootstrap guide that avoids source checkout.
274
- - [scripts/uninstall_readme.md](scripts/uninstall_readme.md)
275
- Preview-first uninstall flow for deployed instances.
276
322
  - [scripts/README.md](scripts/README.md)
277
- Full script index, including contributor/internal paths.
278
-
279
- ### Contributor / Internal Docs
280
-
281
- - [scripts/deploy_readme.md](scripts/deploy_readme.md)
282
- Source-based systemd deployment for development/debugging only.
283
- - [scripts/init_system_readme.md](scripts/init_system_readme.md)
284
- Source-based host bootstrap for contributor/internal workflows.
285
- - [SECURITY.md](SECURITY.md)
286
- threat model, deployment caveats, and vulnerability disclosure guidance.
323
+ Contributor helper script index.
287
324
 
288
325
  ## License
289
326
 
@@ -1,11 +1,11 @@
1
1
  # opencode-a2a-server
2
2
 
3
- > Turn OpenCode into a stateful A2A service with a clear runtime boundary and production-friendly deployment workflow.
3
+ > Turn OpenCode into a stateful A2A service with a clear runtime boundary.
4
4
 
5
5
  `opencode-a2a-server` exposes OpenCode through standard A2A interfaces and adds
6
- the operational pieces that raw agent runtimes usually do not provide by
7
- default: authentication, session continuity, streaming contracts, interrupt
8
- handling, deployment tooling, and explicit security guidance.
6
+ the runtime pieces that raw agent runtimes usually do not provide by default:
7
+ authentication, session continuity, streaming contracts, interrupt handling,
8
+ and explicit security guidance.
9
9
 
10
10
  ## Why This Project Exists
11
11
 
@@ -14,7 +14,8 @@ need a stable service layer around it. This repository provides that layer by:
14
14
 
15
15
  - bridging A2A transport contracts to OpenCode session/message/event APIs
16
16
  - making session and interrupt behavior explicit and auditable
17
- - packaging release-first deployment scripts and operational guidance for long-running use
17
+ - keeping the server/runtime contract explicit while leaving deployment
18
+ supervision to the operator
18
19
 
19
20
  ## What It Already Provides
20
21
 
@@ -26,7 +27,7 @@ need a stable service layer around it. This repository provides that layer by:
26
27
  - session continuation via `metadata.shared.session.id`
27
28
  - request-scoped model selection via `metadata.shared.model`
28
29
  - OpenCode session query/control extensions and provider/model discovery
29
- - released CLI install/upgrade flow and release-based systemd deployment
30
+ - released CLI install/upgrade flow and a foreground runtime entrypoint
30
31
 
31
32
  ## Extension Capability Overview
32
33
 
@@ -58,7 +59,9 @@ Detailed consumption guidance:
58
59
  One `OpenCode + opencode-a2a-server` instance pair is treated as a
59
60
  single-tenant trust boundary.
60
61
 
61
- This repository's intended scaling model is parameterized self-deployment: consumers should launch their own isolated instance pairs through the provided deployment scripts instead of sharing one runtime across mutually untrusted tenants.
62
+ This repository's intended scaling model is parameterized self-deployment:
63
+ consumers should launch their own isolated instance pairs instead of sharing
64
+ one runtime across mutually untrusted tenants.
62
65
 
63
66
  - OpenCode may manage multiple projects/directories, but one deployed instance
64
67
  is not a secure multi-tenant runtime.
@@ -77,7 +80,6 @@ flowchart TD
77
80
  Mapping --> Runtime["OpenCode HTTP runtime"]
78
81
 
79
82
  Api --> Auth["Bearer auth + request logging controls"]
80
- Api --> Deploy["release-based deployment tooling"]
81
83
  Runtime --> Workspace["Shared workspace / environment boundary"]
82
84
  ```
83
85
 
@@ -103,13 +105,14 @@ hard multi-tenant isolation layer.
103
105
  isolation boundary inside one deployed instance.
104
106
  - LLM provider keys are consumed by the OpenCode process. Prompt injection or
105
107
  indirect exfiltration attempts may still expose sensitive values.
106
- - systemd deploy defaults use operator-provisioned root-only secret files
107
- unless `ENABLE_SECRET_PERSISTENCE=true` is explicitly enabled.
108
+ - Deployment supervision is intentionally BYO. If you wrap this runtime with
109
+ `systemd`, Docker, Kubernetes, or another supervisor, you own the service
110
+ user, secret storage, restart policy, and hardening choices.
108
111
 
109
112
  Read before deployment:
110
113
 
111
114
  - [SECURITY.md](SECURITY.md)
112
- - [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
115
+ - [docs/guide.md](docs/guide.md)
113
116
 
114
117
  ## User Paths
115
118
 
@@ -146,12 +149,36 @@ opencode serve
146
149
 
147
150
  A2A_BEARER_TOKEN=prod-token \
148
151
  A2A_PUBLIC_URL=http://127.0.0.1:8000 \
149
- OPENCODE_DIRECTORY=/abs/path/to/workspace \
150
- opencode-a2a-server
152
+ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
153
+ opencode-a2a-server serve
151
154
  ```
152
155
 
156
+ `OPENCODE_WORKSPACE_ROOT` is the default workspace root that this runtime
157
+ exposes to OpenCode.
158
+
153
159
  Default address: `http://127.0.0.1:8000`
154
160
 
161
+ Common runtime variables:
162
+
163
+ | Variable | Required | Default | Purpose |
164
+ | --- | --- | --- | --- |
165
+ | `A2A_BEARER_TOKEN` | Yes | None | Bearer token required for authenticated runtime requests. |
166
+ | `OPENCODE_BASE_URL` | No | `http://127.0.0.1:4096` | Upstream OpenCode HTTP endpoint. |
167
+ | `OPENCODE_WORKSPACE_ROOT` | No | None | Default workspace root exposed to OpenCode. |
168
+ | `OPENCODE_PROVIDER_ID` | No | None | Default provider for the upstream runtime. |
169
+ | `OPENCODE_MODEL_ID` | No | None | Default model for the upstream runtime. Set together with `OPENCODE_PROVIDER_ID`. |
170
+ | `A2A_HOST` | No | `127.0.0.1` | Bind host for the A2A server. |
171
+ | `A2A_PORT` | No | `8000` | Bind port for the A2A server. |
172
+ | `A2A_PUBLIC_URL` | No | `http://127.0.0.1:8000` | Public base URL advertised by the Agent Card. |
173
+ | `A2A_LOG_LEVEL` | No | `WARNING` | Server log level. |
174
+ | `A2A_LOG_PAYLOADS` | No | `false` | Enable request/response payload logging. |
175
+ | `A2A_LOG_BODY_LIMIT` | No | `0` | Payload preview size used when payload logging is enabled. |
176
+ | `A2A_MAX_REQUEST_BODY_BYTES` | No | `1048576` | Maximum accepted request size. |
177
+ | `A2A_ALLOW_DIRECTORY_OVERRIDE` | No | `true` | Allow request-level `metadata.opencode.directory` overrides. |
178
+ | `A2A_ENABLE_SESSION_SHELL` | No | `false` | Enable high-risk `opencode.sessions.shell`. |
179
+ | `OPENCODE_TIMEOUT` | No | `120` | Upstream OpenCode request timeout in seconds. |
180
+ | `OPENCODE_TIMEOUT_STREAM` | No | None | Upstream OpenCode stream timeout override in seconds. |
181
+
155
182
  If you omit `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`, `opencode serve`
156
183
  uses your local OpenCode defaults (for example `~/.config/opencode/opencode.json`).
157
184
 
@@ -163,36 +190,63 @@ official docs and CLI:
163
190
  - Local checks: `opencode auth list`, `opencode models`, `opencode models <provider>`
164
191
 
165
192
  This path is for users who already manage their own shell, workspace, and
166
- process lifecycle. No host bootstrap script is required.
193
+ process lifecycle.
194
+
195
+ Use any supervisor you prefer for long-running operation:
167
196
 
168
- ### Path 2: Formal systemd Deploy From a Released Version
197
+ - `systemd`
198
+ - Docker / container runtimes
199
+ - Kubernetes
200
+ - `supervisord`, `pm2`, or similar process managers
169
201
 
170
- For long-running systemd deployments, use the release-based scripts:
202
+ The project no longer ships built-in host bootstrap or process-manager
203
+ wrappers. The official product surface is the runtime entrypoint itself.
204
+
205
+ Minimal `systemd` example:
206
+
207
+ 1. Create an env file such as `/etc/opencode-a2a/alpha.env`:
171
208
 
172
209
  ```bash
173
- ./scripts/init_release_system.sh
174
- ./scripts/deploy_release.sh project=alpha a2a_port=8010 a2a_host=127.0.0.1
210
+ A2A_BEARER_TOKEN=replace-me
211
+ A2A_HOST=127.0.0.1
212
+ A2A_PORT=8000
213
+ A2A_PUBLIC_URL=https://a2a.example.com
214
+ OPENCODE_BASE_URL=http://127.0.0.1:4096
215
+ OPENCODE_WORKSPACE_ROOT=/srv/my-workspace
175
216
  ```
176
217
 
177
- This path is for users who want:
218
+ 2. Create a unit file such as `/etc/systemd/system/opencode-a2a-server.service`:
219
+
220
+ ```ini
221
+ [Unit]
222
+ Description=OpenCode A2A Server
223
+ After=network-online.target
224
+ Wants=network-online.target
178
225
 
179
- - isolated Linux users and per-project directories
180
- - systemd-managed restart behavior
181
- - root-only secret files
182
- - published package versions as the deployment boundary
226
+ [Service]
227
+ Type=simple
228
+ WorkingDirectory=/srv/my-workspace
229
+ EnvironmentFile=/etc/opencode-a2a/alpha.env
230
+ ExecStart=/home/dev/.local/bin/opencode-a2a-server serve
231
+ Restart=on-failure
232
+ RestartSec=2
183
233
 
184
- Primary operator docs:
234
+ [Install]
235
+ WantedBy=multi-user.target
236
+ ```
237
+
238
+ Replace `ExecStart` with the absolute path returned by `command -v opencode-a2a-server`.
185
239
 
186
- - [scripts/init_release_system.sh](scripts/init_release_system.sh)
187
- - [scripts/deploy_release.sh](scripts/deploy_release.sh)
188
- - [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
189
- - [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
240
+ Migration notes:
241
+
242
+ - `OPENCODE_DIRECTORY` has been removed. Use `OPENCODE_WORKSPACE_ROOT`.
243
+ - Built-in `init-release-system`, `deploy-release`, and `uninstall-instance` have been removed.
244
+ - Secret storage, service users, restart policy, and supervisor configuration are now operator-managed.
190
245
 
191
246
  ## Contributor Paths
192
247
 
193
248
  Use the repository checkout directly only for development, local debugging, or
194
- validation against unreleased changes. Source-based deploy/bootstrap docs are
195
- kept for contributors and internal debugging, not as the recommended user path.
249
+ validation against unreleased changes.
196
250
 
197
251
  Quick source run:
198
252
 
@@ -205,8 +259,8 @@ OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
205
259
  opencode serve
206
260
 
207
261
  A2A_BEARER_TOKEN=dev-token \
208
- OPENCODE_DIRECTORY=/abs/path/to/workspace \
209
- uv run opencode-a2a-server
262
+ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
263
+ uv run opencode-a2a-server serve
210
264
  ```
211
265
 
212
266
  Baseline validation:
@@ -218,34 +272,17 @@ uv run pytest
218
272
 
219
273
  ## Documentation Map
220
274
 
221
- ### User / Operator Docs
275
+ ### User Docs
222
276
 
223
277
  - [docs/guide.md](docs/guide.md)
224
278
  Product behavior, API contracts, and detailed streaming/session/interrupt
225
279
  consumption guidance.
280
+ - [SECURITY.md](SECURITY.md)
281
+ Threat model, deployment caveats, and vulnerability disclosure guidance.
226
282
  - [CONTRIBUTING.md](CONTRIBUTING.md)
227
283
  Contributor workflow, validation baseline, and documentation expectations.
228
- - [docs/agent_deploy_sop.md](docs/agent_deploy_sop.md)
229
- Operator-facing SOP for release-based deployment, verification, and uninstall.
230
- - [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
231
- Real-host smoke test checklist for release-based systemd deployment.
232
- - [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
233
- Release-based systemd deployment guide for published package versions.
234
- - [scripts/init_release_system_readme.md](scripts/init_release_system_readme.md)
235
- Release-based host bootstrap guide that avoids source checkout.
236
- - [scripts/uninstall_readme.md](scripts/uninstall_readme.md)
237
- Preview-first uninstall flow for deployed instances.
238
284
  - [scripts/README.md](scripts/README.md)
239
- Full script index, including contributor/internal paths.
240
-
241
- ### Contributor / Internal Docs
242
-
243
- - [scripts/deploy_readme.md](scripts/deploy_readme.md)
244
- Source-based systemd deployment for development/debugging only.
245
- - [scripts/init_system_readme.md](scripts/init_system_readme.md)
246
- Source-based host bootstrap for contributor/internal workflows.
247
- - [SECURITY.md](SECURITY.md)
248
- threat model, deployment caveats, and vulnerability disclosure guidance.
285
+ Contributor helper script index.
249
286
 
250
287
  ## License
251
288
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  This repository is an adapter layer that exposes OpenCode through A2A
6
6
  HTTP+JSON and JSON-RPC interfaces. It adds authentication, task/session
7
- contracts, streaming, interrupt handling, and deployment tooling, but it does
7
+ contracts, streaming, interrupt handling, and runtime guidance, but it does
8
8
  not fully isolate upstream model credentials from OpenCode runtime behavior.
9
9
 
10
10
  ## Security Boundary
@@ -20,9 +20,9 @@ not fully isolate upstream model credentials from OpenCode runtime behavior.
20
20
  indirect exfiltration attempts may still expose sensitive values.
21
21
  - Payload logging is opt-in. When `A2A_LOG_PAYLOADS=true`, operators should
22
22
  treat logs as potentially sensitive operational data.
23
- - In systemd deployment mode, secret persistence is opt-in. The deploy scripts
24
- should not write `GH_TOKEN`, `A2A_BEARER_TOKEN`, or provider keys to disk
25
- unless `ENABLE_SECRET_PERSISTENCE=true` is explicitly set.
23
+ - This project does not ship host bootstrap or process-manager wrappers as an
24
+ official product capability. Operators remain responsible for file
25
+ permissions, secret storage, service users, and supervisor-specific hardening.
26
26
 
27
27
  ## Threat Model
28
28
 
@@ -19,16 +19,28 @@ and JSON-RPC extension details (README stays at overview level).
19
19
  This section keeps only the protocol-relevant variables.
20
20
  For the full runtime variable catalog and defaults, see
21
21
  [`../src/opencode_a2a_server/config.py`](../src/opencode_a2a_server/config.py).
22
- For deploy-time inputs and systemd-oriented parameters, see
23
- [`../scripts/deploy_readme.md`](../scripts/deploy_readme.md).
22
+ Deployment supervision is intentionally out of scope for this project; use your
23
+ own process manager, container runtime, or host orchestration.
24
24
 
25
25
  Key variables to understand protocol behavior:
26
26
 
27
27
  - `A2A_BEARER_TOKEN`: required for all authenticated runtime requests.
28
+ - `OPENCODE_BASE_URL`: upstream OpenCode HTTP endpoint. Default:
29
+ `http://127.0.0.1:4096`.
30
+ - `OPENCODE_WORKSPACE_ROOT`: service-level default workspace root exposed to
31
+ OpenCode when clients do not request a narrower directory override.
32
+ - `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`: default upstream model
33
+ selection. Set them together when you want the service to pin a specific
34
+ provider/model instead of using OpenCode's local defaults.
28
35
  - `A2A_ALLOW_DIRECTORY_OVERRIDE`: controls whether clients may pass
29
36
  `metadata.opencode.directory`.
30
37
  - `A2A_ENABLE_SESSION_SHELL`: gates high-risk JSON-RPC method
31
38
  `opencode.sessions.shell`.
39
+ - `A2A_HOST` / `A2A_PORT`: runtime bind address. Defaults:
40
+ `127.0.0.1:8000`.
41
+ - `A2A_PUBLIC_URL`: public base URL advertised by the Agent Card. Default:
42
+ `http://127.0.0.1:8000`.
43
+ - `A2A_LOG_LEVEL`: runtime log level. Default: `WARNING`.
32
44
  - `A2A_LOG_PAYLOADS` / `A2A_LOG_BODY_LIMIT`: payload logging behavior and
33
45
  truncation. When `A2A_LOG_LEVEL=DEBUG`, upstream OpenCode stream events are
34
46
  also logged with preview truncation controlled by `A2A_LOG_BODY_LIMIT`.
@@ -38,8 +50,22 @@ Key variables to understand protocol behavior:
38
50
  behavior for `(identity, contextId) -> session_id`.
39
51
  - `A2A_CANCEL_ABORT_TIMEOUT_SECONDS`: best-effort timeout for upstream
40
52
  `session.abort` in cancel flow.
53
+ - `OPENCODE_TIMEOUT` / `OPENCODE_TIMEOUT_STREAM`: upstream request timeout and
54
+ optional stream timeout override.
41
55
  - Runtime authentication is bearer-token only via `A2A_BEARER_TOKEN`.
42
56
 
57
+ Minimal runtime example:
58
+
59
+ ```bash
60
+ A2A_BEARER_TOKEN=dev-token \
61
+ A2A_HOST=127.0.0.1 \
62
+ A2A_PORT=8000 \
63
+ A2A_PUBLIC_URL=http://127.0.0.1:8000 \
64
+ OPENCODE_BASE_URL=http://127.0.0.1:4096 \
65
+ OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
66
+ opencode-a2a-server serve
67
+ ```
68
+
43
69
  ## Service Behavior
44
70
 
45
71
  - The service forwards A2A `message:send` to OpenCode session/message calls.
@@ -106,7 +132,9 @@ Key variables to understand protocol behavior:
106
132
  - Failure events include concrete error details with `failed` state.
107
133
  - Directory validation and normalization:
108
134
  - Clients can pass `metadata.opencode.directory`, but it must stay inside
109
- `${OPENCODE_DIRECTORY}` (or service runtime root if not configured).
135
+ `${OPENCODE_WORKSPACE_ROOT}` (or service runtime root if not configured).
136
+ - `OPENCODE_WORKSPACE_ROOT` is the service-level default workspace root used
137
+ when clients do not request a narrower directory override.
110
138
  - All paths are normalized with `realpath` to prevent `..` or symlink
111
139
  boundary bypass.
112
140
  - If `A2A_ALLOW_DIRECTORY_OVERRIDE=false`, only the default directory is
@@ -45,7 +45,7 @@ dev = [
45
45
  ]
46
46
 
47
47
  [project.scripts]
48
- opencode-a2a-server = "opencode_a2a_server.app:main"
48
+ opencode-a2a-server = "opencode_a2a_server.cli:main"
49
49
 
50
50
  [project.urls]
51
51
  Homepage = "https://github.com/Intelligent-Internet/opencode-a2a-server"
@@ -0,0 +1,22 @@
1
+ # scripts
2
+
3
+ Executable scripts live in this directory. This file is the entry index for the
4
+ remaining repository-maintenance helpers.
5
+
6
+ ## Product Contract vs Script Docs
7
+
8
+ - Product/API behavior (transport, protocol contracts, extension semantics):
9
+ - [`../docs/guide.md`](../docs/guide.md)
10
+ - Security boundary and disclosure guidance:
11
+ - [`../SECURITY.md`](../SECURITY.md)
12
+
13
+ ## Other Scripts
14
+
15
+ - [`doctor.sh`](./doctor.sh): local development regression entrypoint (`sync`/`pip check` + lint + tests)
16
+ - [`dependency_health.sh`](./dependency_health.sh): dependency review entrypoint (`sync`/`pip check` + outdated + audit)
17
+ - [`lint.sh`](./lint.sh): lint helper
18
+ - [`smoke_test_built_cli.sh`](./smoke_test_built_cli.sh): wheel-install smoke test for the released CLI runtime
19
+
20
+ ## Notes
21
+
22
+ - `doctor.sh` and `dependency_health.sh` intentionally remain separate entrypoints and share common prerequisites through [`health_common.sh`](./health_common.sh).
@@ -276,8 +276,8 @@ def _build_deployment_context(settings: Settings) -> dict[str, str | bool]:
276
276
  }
277
277
  if settings.a2a_project:
278
278
  context["project"] = settings.a2a_project
279
- if settings.opencode_directory:
280
- context["workspace_root"] = settings.opencode_directory
279
+ if settings.opencode_workspace_root:
280
+ context["workspace_root"] = settings.opencode_workspace_root
281
281
  if settings.opencode_provider_id:
282
282
  context["provider_id"] = settings.opencode_provider_id
283
283
  if settings.opencode_model_id: