optio-opencode 0.1.7__tar.gz → 0.1.8__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 (35) hide show
  1. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/PKG-INFO +1 -1
  2. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/pyproject.toml +1 -1
  3. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode/host_actions.py +4 -1
  4. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode/session.py +1 -0
  5. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode/types.py +4 -0
  6. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode.egg-info/PKG-INFO +1 -1
  7. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_host_actions.py +1 -0
  8. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_host_local.py +2 -2
  9. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_seed_config.py +5 -0
  10. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_session_hooks.py +1 -1
  11. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_session_local.py +1 -1
  12. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_session_resume.py +1 -1
  13. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_session_seed.py +1 -1
  14. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/README.md +0 -0
  15. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/setup.cfg +0 -0
  16. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode/__init__.py +0 -0
  17. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode/prompt.py +0 -0
  18. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode/seed_manifest.py +0 -0
  19. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode/snapshots.py +0 -0
  20. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode.egg-info/SOURCES.txt +0 -0
  21. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode.egg-info/dependency_links.txt +0 -0
  22. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode.egg-info/requires.txt +0 -0
  23. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/src/optio_opencode.egg-info/top_level.txt +0 -0
  24. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_host_primitives_local.py +0 -0
  25. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_host_primitives_remote.py +0 -0
  26. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_host_remote_resume.py +0 -0
  27. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_host_resume.py +0 -0
  28. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_prompt.py +0 -0
  29. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_purge_seed.py +0 -0
  30. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_sanity.py +0 -0
  31. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_session_blob_hooks.py +0 -0
  32. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_session_remote.py +0 -0
  33. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_smart_install.py +0 -0
  34. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_snapshots.py +0 -0
  35. {optio_opencode-0.1.7 → optio_opencode-0.1.8}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: optio-opencode
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Run opencode web as an optio task; local subprocess or remote via SSH.
5
5
  Author-email: Kristof Csillag <kristof.csillag@deai-labs.com>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "optio-opencode"
7
- version = "0.1.7"
7
+ version = "0.1.8"
8
8
  description = "Run opencode web as an optio task; local subprocess or remote via SSH."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -366,6 +366,7 @@ async def launch_opencode(
366
366
  opencode_executable: str = "opencode",
367
367
  hostname: str = "127.0.0.1",
368
368
  extra_env: dict[str, str] | None = None,
369
+ env_remove: list[str] | None = None,
369
370
  ) -> tuple[ProcessHandle, int]:
370
371
  """Launch ``opencode web`` on ``host``; wait for the listening URL.
371
372
 
@@ -425,7 +426,9 @@ async def launch_opencode(
425
426
  **(extra_env or {}),
426
427
  }
427
428
 
428
- handle = await host.launch_subprocess(cmd, env=env, cwd=host.workdir)
429
+ handle = await host.launch_subprocess(
430
+ cmd, env=env, cwd=host.workdir, env_remove=env_remove,
431
+ )
429
432
 
430
433
  async def _read_url() -> int:
431
434
  async for raw in handle.stdout:
@@ -268,6 +268,7 @@ async def run_opencode_session(ctx: ProcessContext, config: OpencodeTaskConfig)
268
268
  opencode_executable=opencode_exec,
269
269
  hostname=opencode_hostname,
270
270
  extra_env=hook_ctx.browser_launch_env,
271
+ env_remove=config.scrub_env,
271
272
  )
272
273
  launched_handle = handle
273
274
 
@@ -64,6 +64,10 @@ class OpencodeTaskConfig:
64
64
  # (POST /api/session/<id>/prompt "Read AGENTS.md and execute the task it
65
65
  # describes"); suppressed on resume.
66
66
  auto_start: bool = False
67
+ # Glob patterns (fnmatch) of env var NAMES to strip from the opencode
68
+ # subprocess, so inherited provider creds don't override the seed. e.g.
69
+ # ["*_API_KEY", "*_TOKEN"].
70
+ scrub_env: list[str] | None = None
67
71
 
68
72
  def __post_init__(self) -> None:
69
73
  e = self.session_blob_encrypt is not None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: optio-opencode
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Run opencode web as an optio task; local subprocess or remote via SSH.
5
5
  Author-email: Kristof Csillag <kristof.csillag@deai-labs.com>
6
6
  License-Expression: Apache-2.0
@@ -128,6 +128,7 @@ class _RecordingLaunchHost:
128
128
 
129
129
  async def launch_subprocess(
130
130
  self, command, *, env=None, cwd=None, merge_stderr=True, stdin=False,
131
+ env_remove=None,
131
132
  ) -> ProcessHandle:
132
133
  self.launch_cmd = command
133
134
  self.launch_env = env
@@ -71,7 +71,7 @@ async def test_launch_opencode_passes_hostname_into_cmd(local_host, monkeypatch)
71
71
  --hostname=`` argument."""
72
72
  captured: dict[str, str] = {}
73
73
 
74
- async def fake_launch_subprocess(self, cmd, *, env=None, cwd=None):
74
+ async def fake_launch_subprocess(self, cmd, *, env=None, cwd=None, env_remove=None):
75
75
  captured["cmd"] = cmd
76
76
  raise RuntimeError("stop before waiting on stdout")
77
77
 
@@ -92,7 +92,7 @@ async def test_launch_opencode_default_hostname_is_loopback(local_host, monkeypa
92
92
  """Default keeps single-host / RemoteHost-over-SSH behaviour intact."""
93
93
  captured: dict[str, str] = {}
94
94
 
95
- async def fake_launch_subprocess(self, cmd, *, env=None, cwd=None):
95
+ async def fake_launch_subprocess(self, cmd, *, env=None, cwd=None, env_remove=None):
96
96
  captured["cmd"] = cmd
97
97
  raise RuntimeError("stop")
98
98
 
@@ -32,6 +32,11 @@ def test_seed_config_defaults_none():
32
32
  assert cfg.auto_start is False
33
33
 
34
34
 
35
+ def test_opencode_config_scrub_env_default_none():
36
+ from optio_opencode.types import OpencodeTaskConfig
37
+ assert OpencodeTaskConfig(consumer_instructions="hi").scrub_env is None
38
+
39
+
35
40
  def test_manifest_shape():
36
41
  assert OPENCODE_SEED_SUFFIX == "_opencode_seeds"
37
42
  assert OPENCODE_SEED_MANIFEST.home_subdir == "home"
@@ -118,7 +118,7 @@ def _patch_host_actions(monkeypatch, host):
118
118
  async def _version(_host, *, opencode_executable="opencode"):
119
119
  return None
120
120
 
121
- async def _launch(_host, _password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None):
121
+ async def _launch(_host, _password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None, env_remove=None):
122
122
  host.timeline.append("launch_opencode")
123
123
  raise RuntimeError("test never gets past launch")
124
124
 
@@ -105,7 +105,7 @@ def _supply_scenario(monkeypatch):
105
105
  orig_launch = host_actions.launch_opencode
106
106
  scenario_holder: dict = {"name": "happy"}
107
107
 
108
- async def _launch(host, password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None):
108
+ async def _launch(host, password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None, env_remove=None):
109
109
  del opencode_executable # we substitute fully
110
110
  return await orig_launch(
111
111
  host, password,
@@ -53,7 +53,7 @@ def _supply_scenario(monkeypatch):
53
53
  orig_launch = host_actions.launch_opencode
54
54
  holder = {"name": "happy"}
55
55
 
56
- async def _launch(host, password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None):
56
+ async def _launch(host, password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None, env_remove=None):
57
57
  del opencode_executable
58
58
  return await orig_launch(
59
59
  host, password,
@@ -71,7 +71,7 @@ def _supply_scenario(monkeypatch):
71
71
  orig_launch = host_actions.launch_opencode
72
72
  holder = {"name": "happy"}
73
73
 
74
- async def _launch(host, password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None):
74
+ async def _launch(host, password, *, ready_timeout_s=30.0, opencode_executable="opencode", hostname="127.0.0.1", extra_env=None, env_remove=None):
75
75
  del opencode_executable
76
76
  return await orig_launch(
77
77
  host, password,
File without changes
File without changes