dispatchbox 0.1.0__tar.gz → 0.1.1__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. {dispatchbox-0.1.0/dispatchbox.egg-info → dispatchbox-0.1.1}/PKG-INFO +2 -2
  2. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/README.md +1 -1
  3. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/__init__.py +1 -1
  4. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/worker.py +19 -0
  5. {dispatchbox-0.1.0 → dispatchbox-0.1.1/dispatchbox.egg-info}/PKG-INFO +2 -2
  6. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox.egg-info/SOURCES.txt +1 -0
  7. dispatchbox-0.1.1/examples/hello-codex.json +26 -0
  8. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/pyproject.toml +1 -1
  9. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/test_step0.py +16 -2
  10. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/LICENSE +0 -0
  11. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/MANIFEST.in +0 -0
  12. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/__main__.py +0 -0
  13. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/chat.py +0 -0
  14. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/cron.py +0 -0
  15. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/feishu.py +0 -0
  16. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/hub.py +0 -0
  17. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/net.py +0 -0
  18. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/rules.py +0 -0
  19. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/server.py +0 -0
  20. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/slack.py +0 -0
  21. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox/store.py +0 -0
  22. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox.egg-info/dependency_links.txt +0 -0
  23. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox.egg-info/entry_points.txt +0 -0
  24. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox.egg-info/requires.txt +0 -0
  25. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/dispatchbox.egg-info/top_level.txt +0 -0
  26. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/examples/hello.json +0 -0
  27. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/rules.example.json +0 -0
  28. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/setup.cfg +0 -0
  29. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/__init__.py +0 -0
  30. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/helpers.py +0 -0
  31. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/test_chat.py +0 -0
  32. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/test_cron_rules.py +0 -0
  33. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/test_e2e.py +0 -0
  34. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/test_hub.py +0 -0
  35. {dispatchbox-0.1.0 → dispatchbox-0.1.1}/tests/test_net.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dispatchbox
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Route events to Claude Code and Codex running on your own machines, and ask you only when it matters.
5
5
  Author: Xixian Yang
6
6
  License-Expression: MIT
@@ -93,7 +93,7 @@ Most developers already have `claude` or `codex` signed in on their workstation
93
93
 
94
94
  **Prerequisites:**
95
95
  - Python **3.10+** (uses the Python standard library only; no `pip install` required).
96
- - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`) or [Codex CLI](https://github.com/openai/codex) (`codex`) installed and signed in (`examples/hello.json` uses `claude`).
96
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`) or [Codex CLI](https://github.com/openai/codex) (`codex`) installed and signed in. `examples/hello.json` uses `claude`; for Codex, use [`examples/hello-codex.json`](https://github.com/XixianWasTaken/dispatchbox/blob/main/examples/hello-codex.json) in the commands below.
97
97
 
98
98
  ### 1. Create a scratch workspace and shared token
99
99
 
@@ -63,7 +63,7 @@ Most developers already have `claude` or `codex` signed in on their workstation
63
63
 
64
64
  **Prerequisites:**
65
65
  - Python **3.10+** (uses the Python standard library only; no `pip install` required).
66
- - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`) or [Codex CLI](https://github.com/openai/codex) (`codex`) installed and signed in (`examples/hello.json` uses `claude`).
66
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`) or [Codex CLI](https://github.com/openai/codex) (`codex`) installed and signed in. `examples/hello.json` uses `claude`; for Codex, use [`examples/hello-codex.json`](https://github.com/XixianWasTaken/dispatchbox/blob/main/examples/hello-codex.json) in the commands below.
67
67
 
68
68
  ### 1. Create a scratch workspace and shared token
69
69
 
@@ -1,3 +1,3 @@
1
1
  """dispatchbox: a thin event router that hands work to coding agents on your own machines."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.1"
@@ -132,6 +132,7 @@ def build_command(task: dict[str, Any], cfg: WorkerConfig, tmpdir: str) -> tuple
132
132
  cmd = [cfg.codex_bin, "exec"]
133
133
  if resume:
134
134
  cmd += ["resume", resume]
135
+ extra = _sandbox_as_config(extra)
135
136
  cmd += ["--json", "-o", last]
136
137
  if model:
137
138
  cmd += ["-m", model]
@@ -141,6 +142,24 @@ def build_command(task: dict[str, Any], cfg: WorkerConfig, tmpdir: str) -> tuple
141
142
  raise ValueError(f"unknown runner {runner!r}")
142
143
 
143
144
 
145
+ def _sandbox_as_config(args: list[str]) -> list[str]:
146
+ """`codex exec resume` rejects -s/--sandbox, so pass the same choice as a config override."""
147
+ out: list[str] = []
148
+ i = 0
149
+ while i < len(args):
150
+ a = args[i]
151
+ if a in {"-s", "--sandbox"} and i + 1 < len(args):
152
+ out += ["-c", f'sandbox_mode="{args[i + 1]}"']
153
+ i += 2
154
+ continue
155
+ if a.startswith("--sandbox="):
156
+ out += ["-c", f'sandbox_mode="{a.split("=", 1)[1]}"']
157
+ else:
158
+ out.append(a)
159
+ i += 1
160
+ return out
161
+
162
+
144
163
  def parse_output(runner: str, stdout: str, stderr: str, tmpdir: str) -> dict[str, Any]:
145
164
  """Pull the agent's final message and session id out of the raw process output."""
146
165
  if runner == "claude":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dispatchbox
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Route events to Claude Code and Codex running on your own machines, and ask you only when it matters.
5
5
  Author: Xixian Yang
6
6
  License-Expression: MIT
@@ -93,7 +93,7 @@ Most developers already have `claude` or `codex` signed in on their workstation
93
93
 
94
94
  **Prerequisites:**
95
95
  - Python **3.10+** (uses the Python standard library only; no `pip install` required).
96
- - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`) or [Codex CLI](https://github.com/openai/codex) (`codex`) installed and signed in (`examples/hello.json` uses `claude`).
96
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`) or [Codex CLI](https://github.com/openai/codex) (`codex`) installed and signed in. `examples/hello.json` uses `claude`; for Codex, use [`examples/hello-codex.json`](https://github.com/XixianWasTaken/dispatchbox/blob/main/examples/hello-codex.json) in the commands below.
97
97
 
98
98
  ### 1. Create a scratch workspace and shared token
99
99
 
@@ -21,6 +21,7 @@ dispatchbox.egg-info/dependency_links.txt
21
21
  dispatchbox.egg-info/entry_points.txt
22
22
  dispatchbox.egg-info/requires.txt
23
23
  dispatchbox.egg-info/top_level.txt
24
+ examples/hello-codex.json
24
25
  examples/hello.json
25
26
  tests/__init__.py
26
27
  tests/helpers.py
@@ -0,0 +1,26 @@
1
+ {
2
+ "require_decision_for": ["delete_data"],
3
+ "defaults": { "runner": "codex", "cwd": "./demo", "timeout": "5m" },
4
+ "rules": [
5
+ {
6
+ "name": "ask",
7
+ "when": { "source": "manual", "type": "ask" },
8
+ "prompt": "Answer briefly, about the files in the current directory: {summary}",
9
+ "args": ["-s", "read-only", "--skip-git-repo-check"],
10
+ "notify": "always"
11
+ },
12
+ {
13
+ "name": "tidy",
14
+ "when": { "source": "manual", "type": "tidy" },
15
+ "prompt": "Do this in the current directory: {summary}. Deleting any file counts as delete_data.",
16
+ "args": ["-s", "read-only", "--skip-git-repo-check"]
17
+ },
18
+ {
19
+ "name": "after-decision",
20
+ "when": { "source": "dispatchbox", "type": "decision.made" },
21
+ "prompt": "The owner chose: {payload.choice}. Carry on from where you stopped.",
22
+ "args": ["-s", "workspace-write", "--skip-git-repo-check"],
23
+ "notify": "always"
24
+ }
25
+ ]
26
+ }
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dispatchbox"
7
- version = "0.1.0"
7
+ version = "0.1.1"
8
8
  description = "Route events to Claude Code and Codex running on your own machines, and ask you only when it matters."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -9,7 +9,7 @@ from pathlib import Path
9
9
  from dispatchbox import store
10
10
  from dispatchbox.hub import Hub, extract_status
11
11
  from dispatchbox.rules import load_config
12
- from dispatchbox.worker import parse_output
12
+ from dispatchbox.worker import WorkerConfig, build_command, parse_output
13
13
  from tests.helpers import FakeClock, write_rules
14
14
 
15
15
  RULES = {
@@ -36,7 +36,7 @@ CODEX_FAILED = "\n".join([
36
36
  ])
37
37
 
38
38
 
39
- # Schema exactly as released in 0.1.0, before the usage and retry columns.
39
+ # Schema of the first pre-release version, before the usage and retry columns.
40
40
  V01_SCHEMA = """
41
41
  CREATE TABLE IF NOT EXISTS events (
42
42
  id INTEGER PRIMARY KEY,
@@ -190,6 +190,20 @@ class Step0Units(unittest.TestCase):
190
190
  self.assertTrue(bad["agent_error"])
191
191
  self.assertIn("The model is not supported", bad["output"])
192
192
 
193
+ def test_codex_resume_passes_the_sandbox_as_config(self):
194
+ cfg = WorkerConfig(hub="", name="w", token="t")
195
+ task = {"runner": "codex", "prompt": "p", "args": ["-s", "workspace-write", "--sandbox=read-only", "--skip-git-repo-check"]}
196
+ with tempfile.TemporaryDirectory() as d:
197
+ fresh, _ = build_command(task, cfg, d)
198
+ resumed, _ = build_command({**task, "resume_session": "t-1"}, cfg, d)
199
+ self.assertIn("-s", fresh) # a new session takes the flag as written
200
+ self.assertEqual(resumed[:4], ["codex", "exec", "resume", "t-1"])
201
+ self.assertNotIn("-s", resumed)
202
+ self.assertNotIn("--sandbox=read-only", resumed)
203
+ self.assertIn('sandbox_mode="workspace-write"', resumed)
204
+ self.assertIn('sandbox_mode="read-only"', resumed)
205
+ self.assertIn("--skip-git-repo-check", resumed)
206
+
193
207
  def test_migrates_old_database(self):
194
208
  with tempfile.TemporaryDirectory() as d:
195
209
  path = str(Path(d, "old.db"))
File without changes
File without changes
File without changes