superwait 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ .venv/
2
+ __pycache__/
3
+ .pytest_cache/
4
+ dist/
5
+ *.egg-info/
6
+ .superwait/
@@ -0,0 +1,21 @@
1
+ # Contributing
2
+
3
+ Use Python 3.11+ and uv. From a checkout:
4
+
5
+ ```sh
6
+ uv sync --locked
7
+ uv run --locked pytest
8
+ uv build
9
+ ```
10
+
11
+ The tests use temporary databases, synthetic lifecycle events, local HTTP
12
+ endpoints, subprocesses, and a real stdio MCP client. Keep them independent of
13
+ personal agent accounts, configuration, and conversation history.
14
+
15
+ For integration changes, include a focused regression and state which host
16
+ versions were actually exercised. Keep timeout, cancellation, and partial-result
17
+ behavior explicit. Adapter tests alone do not establish live host compatibility.
18
+
19
+ Submit changes through pull requests. Describe the observable behavior and how
20
+ you checked it. Avoid adding a service or framework when the existing wait
21
+ engine, host feature, or standard library is sufficient.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Superwait contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.5
2
+ Name: superwait
3
+ Version: 0.2.0
4
+ Summary: Conditional waiting for coding agents
5
+ Project-URL: Repository, https://github.com/ctxrs/superwait
6
+ Project-URL: Issues, https://github.com/ctxrs/superwait/issues
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.11
10
+ Requires-Dist: httpx2<3,>=2.13
11
+ Requires-Dist: mcp<3,>=2.2
12
+ Requires-Dist: pydantic<3,>=2.12
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Superwait
16
+
17
+ Conditional waiting for coding agents. Wait for any, all, or a count of workers
18
+ and other conditions, wake early on a blocker, and keep one deadline across
19
+ interruptions.
20
+
21
+ Superwait provides an MCP tool and CLI, with setup for Codex, Claude Code, and
22
+ Cursor. The agent chooses the workflow; local code checks the conditions.
23
+ There are no model calls inside the wait.
24
+
25
+ ## Install
26
+
27
+ Requires Python 3.11+ and [uv](https://docs.astral.sh/uv/).
28
+
29
+ ```sh
30
+ uv tool install superwait
31
+ superwait setup codex --project /path/to/project
32
+ # Other hosts:
33
+ superwait setup claude --project /path/to/project
34
+ superwait setup cursor --project /path/to/project
35
+ ```
36
+
37
+ Setup installs project-local MCP settings, lifecycle hooks, and agent
38
+ instructions. It preserves unrelated settings and backs up changed files as
39
+ `.superwait-backup`. Restart the host and accept its normal trust prompts.
40
+ Install hooks before spawning workers, and keep the Python tool environment
41
+ installed. See [host integration](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md) for details.
42
+
43
+ To install the current source instead, use
44
+ `uv tool install 'git+https://github.com/ctxrs/superwait'`.
45
+
46
+ Linux is tested. Codex has live integration coverage; Claude Code and Cursor
47
+ have adapter tests and still need full live workflow qualification. Other
48
+ operating systems and multi-hour host waits remain unqualified.
49
+
50
+ ## Express the wait
51
+
52
+ Call the MCP tool `wait_for` with a `request`. For example, wait for two of three
53
+ reviewers, or return early when an explicit blocker signal arrives:
54
+
55
+ ```json
56
+ {
57
+ "request": {
58
+ "agents": ["reviewer-a-id", "reviewer-b-id", "reviewer-c-id"],
59
+ "mode": "quorum",
60
+ "quorum": 2,
61
+ "wake_on": [{"kind": "signal", "key": "review-42/blocker", "state": "blocked"}],
62
+ "timeout": "2h"
63
+ }
64
+ }
65
+ ```
66
+
67
+ Use the native worker IDs from your host. The provider defaults to the host
68
+ selected during setup. Codex task paths such as `/root/reviewer_a` also work
69
+ when accompanied by the parent `session` supplied in its startup context.
70
+ `list_agents` is available for discovery and troubleshooting.
71
+
72
+ `mode` is `all` by default, or `any`, or `quorum` with a count. Add `targets` for
73
+ other conditions; they count toward the same threshold as `agents`.
74
+
75
+ | Condition | Matches when |
76
+ | --- | --- |
77
+ | `agent` | A lifecycle hook observes a requested worker state |
78
+ | `signal` | A task-specific event is published |
79
+ | `file` | A path exists, is missing, changes, or contains literal text |
80
+ | `http` | A GET returns the requested status code |
81
+ | `command` | An observational command returns the requested exit code |
82
+
83
+ Checks run concurrently. Command probes take an argument array and run without
84
+ a shell; use an observational check because it repeats. `interval` controls
85
+ polling, with a default of one second. Use absolute paths when the MCP server's
86
+ working directory may differ from yours.
87
+
88
+ Publish an explicit checkpoint or blocker through the `signal` MCP tool or CLI:
89
+
90
+ ```sh
91
+ superwait signal review-42/blocker --state blocked --data '{"reason":"missing fixture"}'
92
+ ```
93
+
94
+ ## Act on the result
95
+
96
+ The result includes `status`, `reason`, completed reports in `ready`, remaining
97
+ work in `pending`, and early wake conditions in `triggered`.
98
+
99
+ Pass the returned `continue_wait` object back as the next request to continue.
100
+ It preserves the deadline, remaining count, and file-change baselines, and
101
+ advances past delivered event signals. Persistent conditions such as an existing
102
+ blocker file must clear or be removed before continuing. After a quorum has
103
+ already been reached, continuation waits for all remaining work.
104
+
105
+ A stopped response does not prove an assignment succeeded. Read its report;
106
+ another host hook may continue that worker. For a resumed worker, use an `agent`
107
+ target with `after` set to its last returned `cursor`. Unknown workers stay
108
+ pending. `details: true` adds raw observations for troubleshooting.
109
+
110
+ ## Long waits and the CLI
111
+
112
+ Setup configures a per-server MCP timeout of 24 hours plus 30 seconds for Codex
113
+ and Claude Code. `setup --max-wait 3d` changes that ceiling. Each request still
114
+ has its own timeout or timezone-qualified `deadline`. An absolute deadline
115
+ survives continuation; a timed-out continuation remains expired.
116
+
117
+ For long Cursor waits, or waits beyond the host's configured MCP timeout, run
118
+ the same engine through the host's background terminal:
119
+
120
+ ```sh
121
+ superwait wait --request wait.json --output result.json
122
+ ```
123
+
124
+ `wait.json` contains the request itself, without the MCP `request` wrapper.
125
+ The CLI prints one final JSON result and atomically saves the optional output.
126
+ It exits 0 for matched/early wake, 124 for timeout, 130 for Ctrl-C, and 2 for an
127
+ invalid request or target ambiguity. Native completion notifications or terminal
128
+ collection retrieve the result; the CLI does not background itself.
129
+
130
+ Cancellation stops the wait and any probes it launched. It never cancels the
131
+ workers being observed. The machine and process must remain alive.
132
+
133
+ ## Local state
134
+
135
+ Hooks and waiters share a local SQLite database, defaulting to
136
+ `$XDG_STATE_HOME/superwait/events.sqlite3` or
137
+ `~/.local/state/superwait/events.sqlite3`. Set `SUPERWAIT_DB` or `--db` to use
138
+ another store. Stored observations include worker IDs, report excerpts, and
139
+ available transcript paths. `superwait prune --days 30` removes old observations.
140
+
141
+ The Codex task-name adapter reads only the metadata header of the exact worker
142
+ transcript supplied by its hook. It does not scan conversation history.
143
+ Network requests occur only for requested HTTP or command checks.
144
+
145
+ See [contributing](https://github.com/ctxrs/superwait/blob/main/CONTRIBUTING.md)
146
+ for local development. Licensed under [MIT](https://github.com/ctxrs/superwait/blob/main/LICENSE).
@@ -0,0 +1,132 @@
1
+ # Superwait
2
+
3
+ Conditional waiting for coding agents. Wait for any, all, or a count of workers
4
+ and other conditions, wake early on a blocker, and keep one deadline across
5
+ interruptions.
6
+
7
+ Superwait provides an MCP tool and CLI, with setup for Codex, Claude Code, and
8
+ Cursor. The agent chooses the workflow; local code checks the conditions.
9
+ There are no model calls inside the wait.
10
+
11
+ ## Install
12
+
13
+ Requires Python 3.11+ and [uv](https://docs.astral.sh/uv/).
14
+
15
+ ```sh
16
+ uv tool install superwait
17
+ superwait setup codex --project /path/to/project
18
+ # Other hosts:
19
+ superwait setup claude --project /path/to/project
20
+ superwait setup cursor --project /path/to/project
21
+ ```
22
+
23
+ Setup installs project-local MCP settings, lifecycle hooks, and agent
24
+ instructions. It preserves unrelated settings and backs up changed files as
25
+ `.superwait-backup`. Restart the host and accept its normal trust prompts.
26
+ Install hooks before spawning workers, and keep the Python tool environment
27
+ installed. See [host integration](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md) for details.
28
+
29
+ To install the current source instead, use
30
+ `uv tool install 'git+https://github.com/ctxrs/superwait'`.
31
+
32
+ Linux is tested. Codex has live integration coverage; Claude Code and Cursor
33
+ have adapter tests and still need full live workflow qualification. Other
34
+ operating systems and multi-hour host waits remain unqualified.
35
+
36
+ ## Express the wait
37
+
38
+ Call the MCP tool `wait_for` with a `request`. For example, wait for two of three
39
+ reviewers, or return early when an explicit blocker signal arrives:
40
+
41
+ ```json
42
+ {
43
+ "request": {
44
+ "agents": ["reviewer-a-id", "reviewer-b-id", "reviewer-c-id"],
45
+ "mode": "quorum",
46
+ "quorum": 2,
47
+ "wake_on": [{"kind": "signal", "key": "review-42/blocker", "state": "blocked"}],
48
+ "timeout": "2h"
49
+ }
50
+ }
51
+ ```
52
+
53
+ Use the native worker IDs from your host. The provider defaults to the host
54
+ selected during setup. Codex task paths such as `/root/reviewer_a` also work
55
+ when accompanied by the parent `session` supplied in its startup context.
56
+ `list_agents` is available for discovery and troubleshooting.
57
+
58
+ `mode` is `all` by default, or `any`, or `quorum` with a count. Add `targets` for
59
+ other conditions; they count toward the same threshold as `agents`.
60
+
61
+ | Condition | Matches when |
62
+ | --- | --- |
63
+ | `agent` | A lifecycle hook observes a requested worker state |
64
+ | `signal` | A task-specific event is published |
65
+ | `file` | A path exists, is missing, changes, or contains literal text |
66
+ | `http` | A GET returns the requested status code |
67
+ | `command` | An observational command returns the requested exit code |
68
+
69
+ Checks run concurrently. Command probes take an argument array and run without
70
+ a shell; use an observational check because it repeats. `interval` controls
71
+ polling, with a default of one second. Use absolute paths when the MCP server's
72
+ working directory may differ from yours.
73
+
74
+ Publish an explicit checkpoint or blocker through the `signal` MCP tool or CLI:
75
+
76
+ ```sh
77
+ superwait signal review-42/blocker --state blocked --data '{"reason":"missing fixture"}'
78
+ ```
79
+
80
+ ## Act on the result
81
+
82
+ The result includes `status`, `reason`, completed reports in `ready`, remaining
83
+ work in `pending`, and early wake conditions in `triggered`.
84
+
85
+ Pass the returned `continue_wait` object back as the next request to continue.
86
+ It preserves the deadline, remaining count, and file-change baselines, and
87
+ advances past delivered event signals. Persistent conditions such as an existing
88
+ blocker file must clear or be removed before continuing. After a quorum has
89
+ already been reached, continuation waits for all remaining work.
90
+
91
+ A stopped response does not prove an assignment succeeded. Read its report;
92
+ another host hook may continue that worker. For a resumed worker, use an `agent`
93
+ target with `after` set to its last returned `cursor`. Unknown workers stay
94
+ pending. `details: true` adds raw observations for troubleshooting.
95
+
96
+ ## Long waits and the CLI
97
+
98
+ Setup configures a per-server MCP timeout of 24 hours plus 30 seconds for Codex
99
+ and Claude Code. `setup --max-wait 3d` changes that ceiling. Each request still
100
+ has its own timeout or timezone-qualified `deadline`. An absolute deadline
101
+ survives continuation; a timed-out continuation remains expired.
102
+
103
+ For long Cursor waits, or waits beyond the host's configured MCP timeout, run
104
+ the same engine through the host's background terminal:
105
+
106
+ ```sh
107
+ superwait wait --request wait.json --output result.json
108
+ ```
109
+
110
+ `wait.json` contains the request itself, without the MCP `request` wrapper.
111
+ The CLI prints one final JSON result and atomically saves the optional output.
112
+ It exits 0 for matched/early wake, 124 for timeout, 130 for Ctrl-C, and 2 for an
113
+ invalid request or target ambiguity. Native completion notifications or terminal
114
+ collection retrieve the result; the CLI does not background itself.
115
+
116
+ Cancellation stops the wait and any probes it launched. It never cancels the
117
+ workers being observed. The machine and process must remain alive.
118
+
119
+ ## Local state
120
+
121
+ Hooks and waiters share a local SQLite database, defaulting to
122
+ `$XDG_STATE_HOME/superwait/events.sqlite3` or
123
+ `~/.local/state/superwait/events.sqlite3`. Set `SUPERWAIT_DB` or `--db` to use
124
+ another store. Stored observations include worker IDs, report excerpts, and
125
+ available transcript paths. `superwait prune --days 30` removes old observations.
126
+
127
+ The Codex task-name adapter reads only the metadata header of the exact worker
128
+ transcript supplied by its hook. It does not scan conversation history.
129
+ Network requests occur only for requested HTTP or command checks.
130
+
131
+ See [contributing](https://github.com/ctxrs/superwait/blob/main/CONTRIBUTING.md)
132
+ for local development. Licensed under [MIT](https://github.com/ctxrs/superwait/blob/main/LICENSE).
@@ -0,0 +1,104 @@
1
+ # Host integration
2
+
3
+ All three hosts use the same `wait_for`, `list_agents`, and `signal` MCP API.
4
+ The CLI runs the same wait engine. Setup writes only to the project you name.
5
+
6
+ | Host | MCP configuration | Lifecycle hook configuration | Skill |
7
+ | --- | --- | --- | --- |
8
+ | Codex | `.codex/config.toml` | `.codex/hooks.json` | `.agents/skills/superwait/SKILL.md` |
9
+ | Claude Code | `.mcp.json` | `.claude/settings.json` | `.claude/skills/superwait/SKILL.md` |
10
+ | Cursor | `.cursor/mcp.json` | `.cursor/hooks.json` | `.cursor/skills/superwait/SKILL.md` |
11
+
12
+ ## Codex
13
+
14
+ `SubagentStart` and `SubagentStop` supply the agent ID and parent session ID.
15
+ Superwait records the last assistant message when present. A stop hook observes
16
+ a response ending before other stop hooks necessarily finish deciding whether
17
+ to continue it. It is not a durable promise that the agent will never run again.
18
+
19
+ Some Codex runtimes return a task path such as `/root/reviewer` from spawning,
20
+ but lifecycle hooks report a UUID. Both can now be passed directly to `agents`.
21
+ At the stop hook, Superwait reads only the first metadata record of the
22
+ exact worker transcript Codex supplies. It validates both worker and parent IDs
23
+ before recording the task path. This metadata adapter supports the Codex 0.153.1
24
+ header format. It reads no conversation body and scans
25
+ no history. It is version-dependent; absent or unsupported metadata leaves
26
+ UUID-based waiting and explicit signals available.
27
+
28
+ A previously unknown task path remains pending until that mapping arrives.
29
+ Task paths require `session` even if only one old mapping exists: an unscoped
30
+ name could otherwise match a previous conversation before the new worker stops.
31
+ Setup installs a SessionStart hook that supplies this context to Codex; it
32
+ makes no permission decisions. The CLI fills missing scope from CODEX_THREAD_ID
33
+ only for task paths. Explicit session values and ordinary UUIDs are preserved.
34
+ Duplicate or ambiguous references return an actionable error. `list_agents`
35
+ remains available for discovery and diagnosis, with UUIDs in `key` and observed
36
+ task paths in `data.aliases`.
37
+
38
+ Setup sets `tool_timeout_sec` to the desired maximum wait plus 30 seconds.
39
+ The server sends MCP progress keepalives during normal polling; these do not
40
+ override the client's hard timeout. The tool remains cancellable.
41
+
42
+ For noninteractive `codex exec`, first review and trust the hooks with `/hooks`
43
+ in the same project and Codex home. A `never` approval policy cannot approve
44
+ MCP calls that still require a prompt. After reviewing this server's access,
45
+ configure `tools.wait_for.approval_mode = "approve"` and the other needed tools
46
+ under `[mcp_servers.superwait]`, or use that server's
47
+ `default_tools_approval_mode = "approve"`. Setup leaves that decision to the
48
+ host's normal approval flow. This approval includes repeated command and HTTP
49
+ probes with the server process's access.
50
+
51
+ Sources: [hooks](https://developers.openai.com/codex/hooks),
52
+ [MCP settings](https://learn.chatgpt.com/docs/extend/mcp),
53
+ [skill discovery](https://learn.chatgpt.com/docs/build-skills).
54
+
55
+ ## Claude Code
56
+
57
+ The same lifecycle event names provide `agent_id` and `session_id`. Setup also
58
+ observes `PostToolUse` for `SubagentHandback` because newer versions can deliver
59
+ the actual report there; the final assistant text may only be a closing note.
60
+ The report does not itself mark the agent as stopped.
61
+
62
+ The per-server `timeout` is in milliseconds. Current Claude Code can background
63
+ long MCP calls and notify on completion; its wall-clock limit still applies.
64
+ The CLI can also run under Bash or Monitor. Monitor receives its final JSON line
65
+ when the wait returns. A killed subagent may never emit a stop event, so retain
66
+ the wait's deadline and check native status if needed.
67
+
68
+ Sources: [hook payloads](https://code.claude.com/docs/en/hooks#subagentstop),
69
+ [MCP timeouts/backgrounding](https://code.claude.com/docs/en/mcp),
70
+ [Monitor](https://code.claude.com/docs/en/tools-reference#monitor-tool).
71
+
72
+ ## Cursor
73
+
74
+ `subagentStart` includes `subagent_id` and `parent_conversation_id`.
75
+ The documented `subagentStop` payload can omit both. Superwait uses the common
76
+ conversation ID and matches the exact task/type fingerprint only when there is
77
+ one running candidate in that parent. Concurrent identical tasks remain
78
+ unmatched. No timing heuristic guesses which agent finished.
79
+
80
+ For these cases, assign unique outcome signal keys in worker instructions.
81
+ Signals also work for checkpoints and blockers in every host. Cursor's explicit
82
+ `error` and `aborted` stop states are preserved when correlated.
83
+
84
+ The public MCP documentation does not specify a supported long-call timeout
85
+ setting. Setup does not invent one. Prefer the CLI through the background
86
+ terminal for hours-long waits. A live Cursor build is needed to qualify its
87
+ background completion delivery and exact hook payloads.
88
+
89
+ Sources: [hooks](https://cursor.com/docs/hooks),
90
+ [MCP](https://cursor.com/docs/mcp),
91
+ [subagents](https://cursor.com/docs/subagents).
92
+
93
+ ## Permissions and lifecycle
94
+
95
+ The tool does not bypass host permissions. MCP/terminal/hook trust is still
96
+ owned by the host. A predicate is an operation: HTTP requests and command probes
97
+ use the access of the local server process, so authorize it as you would other
98
+ local MCP tools. Use observational probes because they run repeatedly.
99
+
100
+ Signals are local observations, not messages to other tasks. No hosted service,
101
+ cloud account, or model endpoint is involved. Hooks and CLI use one shared
102
+ SQLite store. No provider database is accessed. The Codex task-name adapter
103
+ reads the metadata header described above; Claude and Cursor use their
104
+ documented hook fields.
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "superwait"
7
+ version = "0.2.0"
8
+ description = "Conditional waiting for coding agents"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.11"
12
+ dependencies = ["mcp>=2.2,<3", "httpx2>=2.13,<3", "pydantic>=2.12,<3"]
13
+
14
+ [project.urls]
15
+ Repository = "https://github.com/ctxrs/superwait"
16
+ Issues = "https://github.com/ctxrs/superwait/issues"
17
+
18
+ [project.scripts]
19
+ superwait = "superwait.cli:main"
20
+
21
+ [dependency-groups]
22
+ dev = ["pytest>=8", "pytest-asyncio>=1"]
23
+
24
+ [tool.pytest.ini_options]
25
+ asyncio_mode = "auto"
26
+ testpaths = ["tests"]
27
+
28
+ [tool.hatch.build.targets.wheel]
29
+ packages = ["src/superwait"]
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: superwait
3
+ description: Wait for agents and external conditions together, with any/all/quorum, early wake conditions, long deadlines, and useful partial results.
4
+ ---
5
+
6
+ # Superwait
7
+
8
+ Express when you want to wake. You choose the workflow; native tools remain
9
+ available for spawning, steering, or collecting additional results.
10
+
11
+ ## One request
12
+
13
+ Call wait_for with a request. For example, wait for two reviewers, wake early
14
+ on a blocker, and stop after two hours:
15
+
16
+ ~~~json
17
+ {
18
+ "agents": ["/root/reviewer_a", "/root/reviewer_b", "/root/reviewer_c"],
19
+ "session": "parent-session-from-startup-context",
20
+ "mode": "quorum",
21
+ "quorum": 2,
22
+ "wake_on": [{"kind": "signal", "key": "review-42/blocker", "state": "blocked", "label": "Review blocked"}],
23
+ "timeout": "2h"
24
+ }
25
+ ~~~
26
+
27
+ agents accepts native IDs and Codex task paths directly. The installed host
28
+ is the default provider; set provider for a different host. Hooks must be
29
+ installed before spawning. Codex paths become resolvable when its stop hook
30
+ supplies the worker metadata. Codex task paths require the parent session from
31
+ the SessionStart context supplied by setup; this prevents matching an old
32
+ conversation with the same names. The Codex CLI fallback fills it from the
33
+ calling thread's environment. Native UUIDs need no extra scope.
34
+ list_agents is available for discovery or troubleshooting, not a prerequisite.
35
+
36
+ mode is all by default, or any, or quorum with a count. Add targets
37
+ for other conditions; they and agents count toward the same threshold.
38
+ wake_on returns early independently of that threshold. Add label to any
39
+ condition to make its meaning explicit in the result.
40
+
41
+ ~~~json
42
+ {"kind":"file","path":"/workspace/ci-failed.json","label":"CI failed"}
43
+ {"kind":"http","url":"http://localhost:8080/health","status":200}
44
+ {"kind":"signal","key":"build-42","state":"ready"}
45
+ {"kind":"file","path":"/workspace/server.log","event":"contains","text":"Ready"}
46
+ {"kind":"command","argv":["python3","/workspace/check_ci.py"],"exit_code":0}
47
+ ~~~
48
+
49
+ Files support exists (default), missing, changed, and literal contains.
50
+ HTTP matches the status code. Command probes run repeatedly without a shell;
51
+ use an observational check, not the build/deploy itself. Prefer absolute paths.
52
+ interval controls polling, default 1 second; increase it for remote services.
53
+
54
+ ## Use the result
55
+
56
+ - status: matched, interrupted, timed_out, or error.
57
+ - reason and triggered: why the wait ended and which early condition fired.
58
+ - ready: observed results and event cursors; pending: remaining work/errors.
59
+ - continue_wait: a ready-to-use request for the remaining work, or null.
60
+
61
+ After handling an interruption, pass continue_wait back as the next request
62
+ if you want to continue. It retains the absolute deadline and file-change
63
+ baselines, carries the remaining quorum, and consumes delivered event signals.
64
+ Persistent conditions such as an existing blocker file must clear or be removed
65
+ from wake_on before proceeding. After reaching a quorum, continuation waits
66
+ for all remaining work. It does not repeat reports you already received.
67
+
68
+ timeout accepts 30s, 10m, 2h, or 1d. A timezone-qualified deadline
69
+ overrides it. A timed-out continuation remains expired; choose a new deadline
70
+ explicitly if you want more time. For a resumed worker, use an agent target
71
+ with after set to its last returned cursor to await a new response:
72
+
73
+ ~~~json
74
+ {"session":"parent-session","targets":[{"kind":"agent","provider":"codex","id":"/root/reviewer_a","after":42}],"timeout":"2h"}
75
+ ~~~
76
+
77
+ A stopped response is not proof the assignment passed; read its result. Another
78
+ stop hook can continue a worker. Unknown workers stay pending. Cursor stop
79
+ hooks sometimes lack enough identity: use an explicit unique outcome signal
80
+ for indistinguishable concurrent assignments. Signal keys should identify the
81
+ particular task; existing matching signals count unless after excludes them.
82
+ Use signal(key, state, data) for explicit checkpoints and outcomes.
83
+
84
+ ## Long waits and cancellation
85
+
86
+ Setup configures Codex/Claude's MCP timeout for 24 hours by default. For waits
87
+ beyond the configured host limit, or long Cursor waits, use the same request
88
+ with superwait wait --request wait.json --output result.json in the host's
89
+ background terminal. The CLI emits one final result; normal host notifications
90
+ or native collection retrieve it. It does not wake a closed conversation.
91
+
92
+ Cancel the MCP call or send Ctrl-C to the CLI to stop waiting. The observed
93
+ workers continue; only the wait's own probes are cleaned up. The process and
94
+ machine must stay alive. CLI exits: 0 matched/interrupted, 124 timeout,
95
+ 130 cancelled, 2 error. details: true adds raw observations for diagnosis.
@@ -0,0 +1 @@
1
+ """Conditional waits with no model calls between observations."""
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()