superwait 0.2.0__tar.gz → 0.3.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.
- superwait-0.3.0/PKG-INFO +118 -0
- superwait-0.3.0/README.md +104 -0
- superwait-0.3.0/docs/assets/superwait-banner.png +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/docs/hosts.md +51 -1
- superwait-0.3.0/docs/reference.md +39 -0
- superwait-0.3.0/docs/savings.md +46 -0
- {superwait-0.2.0 → superwait-0.3.0}/pyproject.toml +1 -1
- superwait-0.3.0/src/superwait/SKILL.md +26 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/cli.py +2 -2
- superwait-0.3.0/src/superwait/references/api.md +223 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/setup.py +26 -11
- superwait-0.3.0/tests/test_hooks_setup.py +230 -0
- {superwait-0.2.0 → superwait-0.3.0}/uv.lock +1 -1
- superwait-0.2.0/PKG-INFO +0 -146
- superwait-0.2.0/README.md +0 -132
- superwait-0.2.0/src/superwait/SKILL.md +0 -95
- superwait-0.2.0/tests/test_hooks_setup.py +0 -91
- {superwait-0.2.0 → superwait-0.3.0}/.gitignore +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/CONTRIBUTING.md +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/LICENSE +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/__init__.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/__main__.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/engine.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/hooks.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/models.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/server.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/src/superwait/store.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/tests/test_ergonomics.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/tests/test_transport.py +0 -0
- {superwait-0.2.0 → superwait-0.3.0}/tests/test_wait.py +0 -0
superwait-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: superwait
|
|
3
|
+
Version: 0.3.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
|
+
<img src="https://raw.githubusercontent.com/ctxrs/superwait/main/docs/assets/superwait-banner.png" alt="20% of your tokens are spent on the wait tool call. superwait cuts that in half, so you save 10% of total spend." width="100%">
|
|
16
|
+
|
|
17
|
+
**superwait gives coding agents one place to wait for the outcome they need.** It works with Codex, Claude Code, and Cursor, runs locally, and makes no model calls while checking conditions.
|
|
18
|
+
|
|
19
|
+
[Install](#install) · [How it works](#how-it-works) · [Host setup](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md) · [Reference](https://github.com/ctxrs/superwait/blob/main/docs/reference.md) · [About the numbers](https://github.com/ctxrs/superwait/blob/main/docs/savings.md)
|
|
20
|
+
|
|
21
|
+
## Why use superwait?
|
|
22
|
+
|
|
23
|
+
A build is still running. A reviewer hasn't finished. A service isn't ready yet. Your agent checks, reads “still running,” and calls another wait.
|
|
24
|
+
|
|
25
|
+
Each trip back to the model can process the conversation again just to decide to keep waiting. With several workers, it also has to track which results arrived, which ones matter, and how much time is left.
|
|
26
|
+
|
|
27
|
+
superwait lets the agent describe that outcome once:
|
|
28
|
+
|
|
29
|
+
> Wait for two of the three reviewers. Wake early if the test worker reports a blocker. Stop after 30 minutes.
|
|
30
|
+
|
|
31
|
+
Local code checks the conditions. The agent gets the completed results and remaining work when there is something to act on. If a blocker interrupts the wait, it can resume with the original deadline intact.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
Install [uv](https://docs.astral.sh/uv/getting-started/installation/) if you don't have it. uv manages Python for you, so there is no separate Python installation step.
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
uv tool install --python 3.12 superwait
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Set up your host once (recommended)
|
|
42
|
+
|
|
43
|
+
Run **one** command for your coding agent. It applies across your projects for your user account:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
superwait setup codex
|
|
47
|
+
# Or, for your host:
|
|
48
|
+
superwait setup claude
|
|
49
|
+
superwait setup cursor
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Restart your coding agent and review its normal MCP and hook trust prompts. Set up before spawning workers so their lifecycle events can be recorded.
|
|
53
|
+
|
|
54
|
+
Then ask your agent:
|
|
55
|
+
|
|
56
|
+
> Use superwait to wait for both reviewers, but return early if either reports a blocker. Stop after 30 minutes.
|
|
57
|
+
|
|
58
|
+
Setup adds the tool, lifecycle hooks, and instructions to your host's user configuration. It preserves unrelated settings, backs up files it changes, and doesn't add files to your repositories. There is no superwait account, API key, or hosted service to configure.
|
|
59
|
+
|
|
60
|
+
### Only need it in one repository?
|
|
61
|
+
|
|
62
|
+
Use project-only setup instead:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
superwait setup codex --project .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use `claude` or `cursor` for those hosts. Choose one scope for each project to avoid duplicate hooks. See [setup locations and existing installations](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md#installation-scope) for details.
|
|
69
|
+
|
|
70
|
+
## How it works
|
|
71
|
+
|
|
72
|
+
1. **Describe the result.** Wait for any, all, or a chosen number of workers and conditions. Add a deadline and anything that should wake the agent early.
|
|
73
|
+
2. **Let local code watch.** The wait engine checks conditions concurrently. Hooks record worker events; file, HTTP, and command checks run locally as requested.
|
|
74
|
+
3. **Continue with useful results.** The response explains why the wait ended, includes completed reports, and lists what remains pending. A ready-to-use continuation preserves the deadline and remaining count.
|
|
75
|
+
|
|
76
|
+
The same engine is available as an MCP tool and a CLI. For a long wait that exceeds your host's tool timeout, the agent can use its background terminal.
|
|
77
|
+
|
|
78
|
+
### What can you wait for?
|
|
79
|
+
|
|
80
|
+
| You need… | superwait watches… |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| Enough reviews to proceed | Any, all, or a quorum of subagents |
|
|
83
|
+
| A checkpoint or blocker | An explicit signal from a worker or script |
|
|
84
|
+
| An artifact to be ready | A file appearing, changing, disappearing, or containing text |
|
|
85
|
+
| A service to come online | An HTTP response with the requested status |
|
|
86
|
+
| A custom readiness check | A command returning the requested exit code |
|
|
87
|
+
|
|
88
|
+
Early-wake conditions can be combined with any of these. A timeout returns the partial results; it does not cancel the workers.
|
|
89
|
+
|
|
90
|
+
See the [request and result reference](https://github.com/ctxrs/superwait/blob/main/docs/reference.md) for examples, continuation behavior, and CLI usage.
|
|
91
|
+
|
|
92
|
+
## When does it help most?
|
|
93
|
+
|
|
94
|
+
Use superwait when an agent keeps checking unchanged state, or when several workers and external conditions need to be coordinated together. A single native wait is often enough for one worker. superwait adds the compound conditions, early wakeups, and shared deadline.
|
|
95
|
+
|
|
96
|
+
It does not replace your host's built-in wait tools automatically. Your agent needs to use it, and the condition must be observable through a supported hook or check.
|
|
97
|
+
|
|
98
|
+
## Works with ctx
|
|
99
|
+
|
|
100
|
+
superwait is made by **ctx engineering**, the team behind [ctx](https://github.com/ctxrs/ctx).
|
|
101
|
+
|
|
102
|
+
We recommend installing ctx alongside superwait. ctx gives your coding agents fast, local search across their past sessions, so they can recover earlier decisions, reuse investigations, and find solutions they've already worked out. Results link back to the original messages and tool calls.
|
|
103
|
+
|
|
104
|
+
[Install ctx and get started →](https://github.com/ctxrs/ctx#install-and-set-up-ctx)
|
|
105
|
+
|
|
106
|
+
## About the numbers
|
|
107
|
+
|
|
108
|
+
Our corpus study found that wait-only model responses accounted for about **20% of input tokens**. Auditing repeated waits identified roughly half of that input as a consolidation opportunity—about **9–10% of total input**, before replacement overhead.
|
|
109
|
+
|
|
110
|
+
Actual token and spend savings depend on your corpus, model pricing, caching, and host integration; input-token savings are not the same as measured bill savings. [See the study and how to evaluate your own workload](https://github.com/ctxrs/superwait/blob/main/docs/savings.md).
|
|
111
|
+
|
|
112
|
+
## Host support and details
|
|
113
|
+
|
|
114
|
+
Linux and Codex have live integration coverage. Claude Code and Cursor have adapter tests; full live workflows in those hosts, other operating systems, and multi-hour host waits still need qualification.
|
|
115
|
+
|
|
116
|
+
- [Host setup, permissions, and compatibility](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md)
|
|
117
|
+
- [API, CLI, long waits, and local data](https://github.com/ctxrs/superwait/blob/main/docs/reference.md)
|
|
118
|
+
- [Contributing](https://github.com/ctxrs/superwait/blob/main/CONTRIBUTING.md) · [PyPI](https://pypi.org/project/superwait/) · [MIT license](https://github.com/ctxrs/superwait/blob/main/LICENSE)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<img src="https://raw.githubusercontent.com/ctxrs/superwait/main/docs/assets/superwait-banner.png" alt="20% of your tokens are spent on the wait tool call. superwait cuts that in half, so you save 10% of total spend." width="100%">
|
|
2
|
+
|
|
3
|
+
**superwait gives coding agents one place to wait for the outcome they need.** It works with Codex, Claude Code, and Cursor, runs locally, and makes no model calls while checking conditions.
|
|
4
|
+
|
|
5
|
+
[Install](#install) · [How it works](#how-it-works) · [Host setup](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md) · [Reference](https://github.com/ctxrs/superwait/blob/main/docs/reference.md) · [About the numbers](https://github.com/ctxrs/superwait/blob/main/docs/savings.md)
|
|
6
|
+
|
|
7
|
+
## Why use superwait?
|
|
8
|
+
|
|
9
|
+
A build is still running. A reviewer hasn't finished. A service isn't ready yet. Your agent checks, reads “still running,” and calls another wait.
|
|
10
|
+
|
|
11
|
+
Each trip back to the model can process the conversation again just to decide to keep waiting. With several workers, it also has to track which results arrived, which ones matter, and how much time is left.
|
|
12
|
+
|
|
13
|
+
superwait lets the agent describe that outcome once:
|
|
14
|
+
|
|
15
|
+
> Wait for two of the three reviewers. Wake early if the test worker reports a blocker. Stop after 30 minutes.
|
|
16
|
+
|
|
17
|
+
Local code checks the conditions. The agent gets the completed results and remaining work when there is something to act on. If a blocker interrupts the wait, it can resume with the original deadline intact.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
Install [uv](https://docs.astral.sh/uv/getting-started/installation/) if you don't have it. uv manages Python for you, so there is no separate Python installation step.
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
uv tool install --python 3.12 superwait
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Set up your host once (recommended)
|
|
28
|
+
|
|
29
|
+
Run **one** command for your coding agent. It applies across your projects for your user account:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
superwait setup codex
|
|
33
|
+
# Or, for your host:
|
|
34
|
+
superwait setup claude
|
|
35
|
+
superwait setup cursor
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Restart your coding agent and review its normal MCP and hook trust prompts. Set up before spawning workers so their lifecycle events can be recorded.
|
|
39
|
+
|
|
40
|
+
Then ask your agent:
|
|
41
|
+
|
|
42
|
+
> Use superwait to wait for both reviewers, but return early if either reports a blocker. Stop after 30 minutes.
|
|
43
|
+
|
|
44
|
+
Setup adds the tool, lifecycle hooks, and instructions to your host's user configuration. It preserves unrelated settings, backs up files it changes, and doesn't add files to your repositories. There is no superwait account, API key, or hosted service to configure.
|
|
45
|
+
|
|
46
|
+
### Only need it in one repository?
|
|
47
|
+
|
|
48
|
+
Use project-only setup instead:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
superwait setup codex --project .
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Use `claude` or `cursor` for those hosts. Choose one scope for each project to avoid duplicate hooks. See [setup locations and existing installations](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md#installation-scope) for details.
|
|
55
|
+
|
|
56
|
+
## How it works
|
|
57
|
+
|
|
58
|
+
1. **Describe the result.** Wait for any, all, or a chosen number of workers and conditions. Add a deadline and anything that should wake the agent early.
|
|
59
|
+
2. **Let local code watch.** The wait engine checks conditions concurrently. Hooks record worker events; file, HTTP, and command checks run locally as requested.
|
|
60
|
+
3. **Continue with useful results.** The response explains why the wait ended, includes completed reports, and lists what remains pending. A ready-to-use continuation preserves the deadline and remaining count.
|
|
61
|
+
|
|
62
|
+
The same engine is available as an MCP tool and a CLI. For a long wait that exceeds your host's tool timeout, the agent can use its background terminal.
|
|
63
|
+
|
|
64
|
+
### What can you wait for?
|
|
65
|
+
|
|
66
|
+
| You need… | superwait watches… |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| Enough reviews to proceed | Any, all, or a quorum of subagents |
|
|
69
|
+
| A checkpoint or blocker | An explicit signal from a worker or script |
|
|
70
|
+
| An artifact to be ready | A file appearing, changing, disappearing, or containing text |
|
|
71
|
+
| A service to come online | An HTTP response with the requested status |
|
|
72
|
+
| A custom readiness check | A command returning the requested exit code |
|
|
73
|
+
|
|
74
|
+
Early-wake conditions can be combined with any of these. A timeout returns the partial results; it does not cancel the workers.
|
|
75
|
+
|
|
76
|
+
See the [request and result reference](https://github.com/ctxrs/superwait/blob/main/docs/reference.md) for examples, continuation behavior, and CLI usage.
|
|
77
|
+
|
|
78
|
+
## When does it help most?
|
|
79
|
+
|
|
80
|
+
Use superwait when an agent keeps checking unchanged state, or when several workers and external conditions need to be coordinated together. A single native wait is often enough for one worker. superwait adds the compound conditions, early wakeups, and shared deadline.
|
|
81
|
+
|
|
82
|
+
It does not replace your host's built-in wait tools automatically. Your agent needs to use it, and the condition must be observable through a supported hook or check.
|
|
83
|
+
|
|
84
|
+
## Works with ctx
|
|
85
|
+
|
|
86
|
+
superwait is made by **ctx engineering**, the team behind [ctx](https://github.com/ctxrs/ctx).
|
|
87
|
+
|
|
88
|
+
We recommend installing ctx alongside superwait. ctx gives your coding agents fast, local search across their past sessions, so they can recover earlier decisions, reuse investigations, and find solutions they've already worked out. Results link back to the original messages and tool calls.
|
|
89
|
+
|
|
90
|
+
[Install ctx and get started →](https://github.com/ctxrs/ctx#install-and-set-up-ctx)
|
|
91
|
+
|
|
92
|
+
## About the numbers
|
|
93
|
+
|
|
94
|
+
Our corpus study found that wait-only model responses accounted for about **20% of input tokens**. Auditing repeated waits identified roughly half of that input as a consolidation opportunity—about **9–10% of total input**, before replacement overhead.
|
|
95
|
+
|
|
96
|
+
Actual token and spend savings depend on your corpus, model pricing, caching, and host integration; input-token savings are not the same as measured bill savings. [See the study and how to evaluate your own workload](https://github.com/ctxrs/superwait/blob/main/docs/savings.md).
|
|
97
|
+
|
|
98
|
+
## Host support and details
|
|
99
|
+
|
|
100
|
+
Linux and Codex have live integration coverage. Claude Code and Cursor have adapter tests; full live workflows in those hosts, other operating systems, and multi-hour host waits still need qualification.
|
|
101
|
+
|
|
102
|
+
- [Host setup, permissions, and compatibility](https://github.com/ctxrs/superwait/blob/main/docs/hosts.md)
|
|
103
|
+
- [API, CLI, long waits, and local data](https://github.com/ctxrs/superwait/blob/main/docs/reference.md)
|
|
104
|
+
- [Contributing](https://github.com/ctxrs/superwait/blob/main/CONTRIBUTING.md) · [PyPI](https://pypi.org/project/superwait/) · [MIT license](https://github.com/ctxrs/superwait/blob/main/LICENSE)
|
|
Binary file
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
# Host integration
|
|
2
2
|
|
|
3
3
|
All three hosts use the same `wait_for`, `list_agents`, and `signal` MCP API.
|
|
4
|
-
The CLI runs the same wait engine.
|
|
4
|
+
The CLI runs the same wait engine.
|
|
5
|
+
|
|
6
|
+
## Installation scope
|
|
7
|
+
|
|
8
|
+
**Host-wide setup is recommended:** run `superwait setup codex`, `superwait setup
|
|
9
|
+
claude`, or `superwait setup cursor` once. This installs into the selected host's
|
|
10
|
+
user configuration and applies across projects for that OS user. It does not
|
|
11
|
+
configure other users, remote machines, or cloud agent VMs.
|
|
12
|
+
|
|
13
|
+
Host-wide setup requires superwait 0.3.0 or newer. If you installed 0.2.0, run
|
|
14
|
+
`uv tool upgrade superwait` before following the [README](../README.md#install).
|
|
15
|
+
|
|
16
|
+
| Host | User MCP configuration | User lifecycle hooks | User skill |
|
|
17
|
+
| --- | --- | --- | --- |
|
|
18
|
+
| Codex | `~/.codex/config.toml` | `~/.codex/hooks.json` | `~/.agents/skills/superwait/SKILL.md` |
|
|
19
|
+
| Claude Code | `~/.claude.json` | `~/.claude/settings.json` | `~/.claude/skills/superwait/SKILL.md` |
|
|
20
|
+
| Cursor | `~/.cursor/mcp.json` | `~/.cursor/hooks.json` | `~/.cursor/skills/superwait/SKILL.md` |
|
|
21
|
+
|
|
22
|
+
Codex honors `CODEX_HOME` for its config and hooks; its user skill stays in
|
|
23
|
+
`~/.agents/skills`. Claude Code honors `CLAUDE_CONFIG_DIR`: when set, the MCP
|
|
24
|
+
entry goes into `.claude.json` inside that directory, with settings and skills
|
|
25
|
+
alongside it. Cursor uses its standard `~/.cursor` directory.
|
|
26
|
+
|
|
27
|
+
### Project-only setup
|
|
28
|
+
|
|
29
|
+
Add `--project /path/to/repo` to limit setup to one repository. This explicitly
|
|
30
|
+
uses the repository paths below, even if a user configuration directory is set
|
|
31
|
+
in your environment.
|
|
5
32
|
|
|
6
33
|
| Host | MCP configuration | Lifecycle hook configuration | Skill |
|
|
7
34
|
| --- | --- | --- | --- |
|
|
@@ -9,6 +36,29 @@ The CLI runs the same wait engine. Setup writes only to the project you name.
|
|
|
9
36
|
| Claude Code | `.mcp.json` | `.claude/settings.json` | `.claude/skills/superwait/SKILL.md` |
|
|
10
37
|
| Cursor | `.cursor/mcp.json` | `.cursor/hooks.json` | `.cursor/skills/superwait/SKILL.md` |
|
|
11
38
|
|
|
39
|
+
Setup preserves unrelated settings, creates owner-only `.superwait-backup`
|
|
40
|
+
copies of existing files before changing them, and can be run again without
|
|
41
|
+
duplicating its hook entries in the same scope. It does not change host trust
|
|
42
|
+
or approval settings.
|
|
43
|
+
|
|
44
|
+
### Moving an existing project installation to host-wide setup
|
|
45
|
+
|
|
46
|
+
Setup does not remove existing project installations. Hosts can load hooks from
|
|
47
|
+
both scopes, which would record events twice. Remove only the old superwait MCP
|
|
48
|
+
entry, its hook entries, and its installed skill from the project before using
|
|
49
|
+
the host-wide installation there. Keep unrelated settings and hooks. For Codex,
|
|
50
|
+
the managed MCP entry is between `# BEGIN superwait` and `# END superwait`.
|
|
51
|
+
Then restart the host and review its normal trust prompts.
|
|
52
|
+
|
|
53
|
+
Sources: [Codex config](https://learn.chatgpt.com/docs/config-file/config-reference),
|
|
54
|
+
[Codex hooks](https://developers.openai.com/codex/hooks),
|
|
55
|
+
[Codex skills](https://learn.chatgpt.com/docs/build-skills),
|
|
56
|
+
[Claude Code MCP scopes](https://code.claude.com/docs/en/mcp#user-scope),
|
|
57
|
+
[Claude Code settings](https://code.claude.com/docs/en/settings),
|
|
58
|
+
[Cursor MCP](https://cursor.com/docs/context/mcp),
|
|
59
|
+
[Cursor hooks](https://cursor.com/docs/hooks),
|
|
60
|
+
[Cursor skills](https://cursor.com/docs/context/skills).
|
|
61
|
+
|
|
12
62
|
## Codex
|
|
13
63
|
|
|
14
64
|
`SubagentStart` and `SubagentStop` supply the agent ID and parent session ID.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Superwait reference
|
|
2
|
+
|
|
3
|
+
The [full API and CLI reference](../src/superwait/references/api.md) is also
|
|
4
|
+
installed beside the skill as `references/api.md`, so agents can read it locally
|
|
5
|
+
only when needed.
|
|
6
|
+
|
|
7
|
+
## Install from source
|
|
8
|
+
|
|
9
|
+
To install the current source instead of the PyPI release:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
uv tool install 'git+https://github.com/ctxrs/superwait'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Python and package installation
|
|
16
|
+
|
|
17
|
+
[uv](https://docs.astral.sh/uv/getting-started/installation/) is the recommended
|
|
18
|
+
installer. It creates a persistent, isolated tool environment and can download
|
|
19
|
+
Python automatically. You do not need to set up Python or a virtual environment
|
|
20
|
+
yourself. To explicitly select a runtime for the published package:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
uv tool install --python 3.12 superwait
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The [README](../README.md#install) covers host-wide setup, available in 0.3.0
|
|
27
|
+
and newer. Upgrade an existing uv installation with `uv tool upgrade superwait`.
|
|
28
|
+
|
|
29
|
+
If you already manage Python 3.11+ with pipx, `pipx install superwait` is another
|
|
30
|
+
option. Keep whichever tool environment you install: the generated MCP and hook
|
|
31
|
+
commands point at its Python executable. A temporary `uvx` run is not the
|
|
32
|
+
recommended setup path because its cached environment can be removed.
|
|
33
|
+
|
|
34
|
+
If `superwait` is not found after installation, follow uv's printed PATH
|
|
35
|
+
instructions or run `uv tool update-shell` and open a new terminal. Setup itself
|
|
36
|
+
does not edit shell profiles.
|
|
37
|
+
|
|
38
|
+
Sources: [uv tool environments](https://docs.astral.sh/uv/guides/tools/),
|
|
39
|
+
[automatic Python downloads](https://docs.astral.sh/uv/guides/install-python/#automatic-python-downloads).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Where the numbers come from
|
|
2
|
+
|
|
3
|
+
[Back to the README](../README.md)
|
|
4
|
+
|
|
5
|
+
The banner is a rounded savings pitch based on a retrospective study of coding-agent history. The study measured how many tokens accompanied waiting responses and estimated which repeated responses could be consolidated. It did not measure a 10% reduction in bills from installing superwait.
|
|
6
|
+
|
|
7
|
+
## What we measured
|
|
8
|
+
|
|
9
|
+
We froze a sample of 200 Codex sessions before analyzing their waiting behavior. After excluding one session with ambiguous turn and token attribution, the analysis retained 199 sessions and 24,897 attributed model responses.
|
|
10
|
+
|
|
11
|
+
A **wait-only response** calls only recognized waiting tools. Input counts include cached input; cached tokens are a subset, not an additional total.
|
|
12
|
+
|
|
13
|
+
| Finding | Result |
|
|
14
|
+
| --- | ---: |
|
|
15
|
+
| Input processed across the retained sample | 3.112 billion tokens |
|
|
16
|
+
| Input associated with wait-only responses | About 20% |
|
|
17
|
+
| Repeated-wait follow-ups eligible for investigation | 2,436 across 43 tasks |
|
|
18
|
+
| Probability-sampled transitions retained in the manual audit | 187 |
|
|
19
|
+
| Estimated input associated with skippable deterministic repeats | 281.6 million tokens, or 9.05% of total input |
|
|
20
|
+
| Including conditional cases that require preserving additional behavior | 317.9 million tokens, or 10.22% of total input |
|
|
21
|
+
|
|
22
|
+
The main estimate is about 46% of wait-only input; including the conditional cases reaches about 52%. That is the basis for the headline's “20%” and “half.”
|
|
23
|
+
|
|
24
|
+
The manual audit also included 20 supplemental cases for coverage. These did not enter the numerical projection. Separate reviewers checked overlapping cases and the accounting.
|
|
25
|
+
|
|
26
|
+
## What that means for savings
|
|
27
|
+
|
|
28
|
+
Waiting time itself does not consume model tokens. The opportunity is avoiding another model response whose only useful action is to keep waiting.
|
|
29
|
+
|
|
30
|
+
The estimate is gross input-token opportunity, before the cost of instructions, monitor setup, result delivery, and changes to later context or cache use. Approximately 99.3% of the main projected input was cached. Cached input, fresh input, and output can have different prices, so a raw input percentage does not establish the same percentage reduction in spending.
|
|
31
|
+
|
|
32
|
+
The current package also cannot consume a host's opaque execution-cell or terminal-session handles directly. About 91.6% of the main input projection involved that integration requirement. The retrospective therefore does not establish that installing superwait delivers the full projected saving. Longer native waits can also eliminate some repeated checks.
|
|
33
|
+
|
|
34
|
+
The corpus deliberately oversampled parent tasks and covered Codex sessions from one workflow. It is not a representative benchmark for every developer, model, or supported host.
|
|
35
|
+
|
|
36
|
+
## Evaluate your own workload
|
|
37
|
+
|
|
38
|
+
Use the same tasks, model, host configuration, and completion criteria for a baseline and a superwait run.
|
|
39
|
+
|
|
40
|
+
1. **Start with a good baseline.** Use the host's supported native wait and timeout settings. Keep required progress updates and result delivery.
|
|
41
|
+
2. **Use observable conditions.** Give superwait the worker, signal, file, HTTP, or command conditions that actually describe readiness.
|
|
42
|
+
3. **Compare whole runs.** Record input, cached input, and output separately, including instructions and setup overhead. Also compare task completion, useful updates, failures, and elapsed time.
|
|
43
|
+
4. **Apply your prices.** Compute each run's bill using its cached-input, uncached-input, and output rates. Divide the cost difference by the baseline cost to get spend savings.
|
|
44
|
+
5. **Repeat across tasks.** Report how you selected the workload and which host integrations were available.
|
|
45
|
+
|
|
46
|
+
No corpus upload is required for this comparison. Use the usage records your host or provider makes available. superwait does not currently ship an automatic token-savings evaluator.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: superwait
|
|
3
|
+
description: Prefer superwait for waiting on agents, files, services, or signals.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# superwait
|
|
7
|
+
|
|
8
|
+
Prefer superwait over native wait tools or polling loops. Use native tools to
|
|
9
|
+
spawn or steer agents.
|
|
10
|
+
|
|
11
|
+
Call the `wait_for` MCP tool:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{"request":{"agents":["worker-a-id","worker-b-id"],"timeout":"10m"}}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Use handles returned by the host. For Codex `/root/...` paths, add `session`
|
|
18
|
+
from startup context. The default waits for all agents. Read the `ready`
|
|
19
|
+
reports; use `continue_wait` as the next `request` for remaining work.
|
|
20
|
+
|
|
21
|
+
In Codex code mode, start `functions.exec` with
|
|
22
|
+
`// @exec: {"yield_time_ms":60000}`. If it yields, resume that cell with
|
|
23
|
+
`functions.wait` and `yield_time_ms: 60000`.
|
|
24
|
+
|
|
25
|
+
For other conditions, quorum, early wakeups, continuation details, or CLI usage,
|
|
26
|
+
read the [local API reference](references/api.md) only when needed.
|
|
@@ -31,9 +31,9 @@ def parser():
|
|
|
31
31
|
hook = commands.add_parser("hook", help="Host lifecycle adapter; reads JSON on stdin.")
|
|
32
32
|
hook.add_argument("provider", choices=["codex", "claude", "cursor"])
|
|
33
33
|
commands.add_parser("serve", help="Serve the MCP API over stdio.")
|
|
34
|
-
setup = commands.add_parser("setup", help="Configure hooks, MCP, and the skill
|
|
34
|
+
setup = commands.add_parser("setup", help="Configure hooks, MCP, and the skill for your host.")
|
|
35
35
|
setup.add_argument("provider", choices=["codex", "claude", "cursor"])
|
|
36
|
-
setup.add_argument("--project",
|
|
36
|
+
setup.add_argument("--project", type=Path, help="Only configure this project; default: all projects for your user.")
|
|
37
37
|
setup.add_argument("--max-wait", default="24h", help="Host tool timeout, where supported.")
|
|
38
38
|
prune = commands.add_parser("prune", help="Delete old local observations.")
|
|
39
39
|
prune.add_argument("--days", type=float, default=30)
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Superwait API reference
|
|
2
|
+
|
|
3
|
+
Superwait exposes the same wait engine through an MCP tool and a CLI. The MCP
|
|
4
|
+
server provides `wait_for`, `list_agents`, and `signal`.
|
|
5
|
+
|
|
6
|
+
## Wait requests
|
|
7
|
+
|
|
8
|
+
Call `wait_for` with a `request`:
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"request": {
|
|
13
|
+
"agents": ["reviewer-a-id", "reviewer-b-id", "reviewer-c-id"],
|
|
14
|
+
"mode": "quorum",
|
|
15
|
+
"quorum": 2,
|
|
16
|
+
"wake_on": [
|
|
17
|
+
{"kind": "signal", "key": "review-42/blocker", "state": "blocked"}
|
|
18
|
+
],
|
|
19
|
+
"timeout": "2h"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Use native worker IDs from the selected host. Codex task paths such as
|
|
25
|
+
`/root/reviewer_a` also work when accompanied by the parent `session` supplied
|
|
26
|
+
in its startup context. `list_agents` is available for discovery and
|
|
27
|
+
troubleshooting.
|
|
28
|
+
|
|
29
|
+
`mode` is `all` by default, or `any`, or `quorum` with a count. Conditions in
|
|
30
|
+
`targets` count toward the same threshold as `agents`. Conditions in `wake_on`
|
|
31
|
+
return early independently of that threshold.
|
|
32
|
+
|
|
33
|
+
### Request fields
|
|
34
|
+
|
|
35
|
+
| Field | Meaning / default |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `agents` | Worker handles; shorthand for agent conditions; default `[]` |
|
|
38
|
+
| `provider` | `codex`, `claude`, or `cursor`; defaults to the configured host (standalone: `codex`) |
|
|
39
|
+
| `session` | Parent session for unscoped agent conditions in the selected provider; required for Codex task paths |
|
|
40
|
+
| `targets` | Explicit conditions; default `[]`; at least one agent or target is required |
|
|
41
|
+
| `mode` | `all` (default), `any`, or `quorum` |
|
|
42
|
+
| `quorum` | Required positive count for `quorum` mode only; no greater than the number of agents and targets |
|
|
43
|
+
| `wake_on` | Conditions that interrupt the wait; default `[]` |
|
|
44
|
+
| `timeout` | String containing positive seconds or a duration such as `30s`, `10m`, `2h`, `1d`; default `10m`; `ms` also supported |
|
|
45
|
+
| `deadline` | Timezone-qualified timestamp overriding `timeout`; continuation preserves it |
|
|
46
|
+
| `interval` | Seconds between probes; default `1`, minimum `0.05`; increase for remote checks |
|
|
47
|
+
| `details` | Include raw observations; default `false` |
|
|
48
|
+
|
|
49
|
+
Unknown fields and duplicate main targets are rejected. Every condition accepts
|
|
50
|
+
an optional `label` for readable results. The same condition types work in
|
|
51
|
+
`targets` and `wake_on`.
|
|
52
|
+
|
|
53
|
+
### Conditions
|
|
54
|
+
|
|
55
|
+
| Condition | Matches when |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `agent` | A lifecycle hook observes a requested worker state |
|
|
58
|
+
| `signal` | A task-specific event is published |
|
|
59
|
+
| `file` | A path exists, is missing, changes, or contains literal text |
|
|
60
|
+
| `http` | A GET returns the requested status code |
|
|
61
|
+
| `command` | An observational command returns the requested exit code |
|
|
62
|
+
|
|
63
|
+
| Kind | Required fields | Optional fields |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `agent` | `provider`, `id` | `session`; `states` defaults to `["stopped", "error", "aborted"]` (`running` also supported); `after` defaults to `0` |
|
|
66
|
+
| `signal` | `key` | `state` (any if omitted); `after` defaults to `0` |
|
|
67
|
+
| `file` | `path` | `event`: `exists` (default), `missing`, `changed`, or `contains`; `text` required for `contains`; `since` is a continuation baseline, not needed for new waits |
|
|
68
|
+
| `http` | `url` (`http://` or `https://`) | `status` defaults to `200`; redirects are not followed |
|
|
69
|
+
| `command` | Nonempty `argv` array | `cwd`; `exit_code` defaults to `0`; positive `probe_timeout` defaults to `10` seconds |
|
|
70
|
+
|
|
71
|
+
`after` is a nonnegative event cursor: only later observations match. File
|
|
72
|
+
`contains` uses literal UTF-8 text; `changed` compares file metadata against the
|
|
73
|
+
initial observation or preserved `since` baseline.
|
|
74
|
+
|
|
75
|
+
For example, wait for a healthy service and a ready log, but wake on a blocker:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"request": {
|
|
80
|
+
"targets": [
|
|
81
|
+
{"kind": "http", "url": "http://localhost:8080/health", "status": 200},
|
|
82
|
+
{"kind": "file", "path": "/workspace/server.log", "event": "contains", "text": "Ready"}
|
|
83
|
+
],
|
|
84
|
+
"wake_on": [{"kind": "file", "path": "/workspace/blocker.json"}],
|
|
85
|
+
"timeout": "10m"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Checks run concurrently. Command probes take an argument array and run without
|
|
91
|
+
a shell. They repeat, so use them only for observational checks. `interval`
|
|
92
|
+
controls polling and defaults to one second. Prefer absolute paths when the MCP
|
|
93
|
+
server's working directory may differ from the caller's.
|
|
94
|
+
|
|
95
|
+
### Agent handles and hooks
|
|
96
|
+
|
|
97
|
+
Install hooks before spawning workers. Codex task paths become resolvable
|
|
98
|
+
when a stop hook supplies worker metadata; native UUIDs need no extra session
|
|
99
|
+
scope. The Codex CLI fills the session from `CODEX_THREAD_ID` when available.
|
|
100
|
+
Cursor stop hooks sometimes lack enough identity: use a unique outcome signal
|
|
101
|
+
for indistinguishable concurrent assignments.
|
|
102
|
+
|
|
103
|
+
### Other MCP tools
|
|
104
|
+
|
|
105
|
+
`list_agents(provider, session?)` returns `agents` and `limit` (50) for recent
|
|
106
|
+
hook-observed workers. Use it for discovery or troubleshooting, not before every
|
|
107
|
+
wait. `provider` is required: `codex`, `claude`, or `cursor`.
|
|
108
|
+
|
|
109
|
+
`signal(key, state="ready", data=null)` publishes an event and returns its `seq`
|
|
110
|
+
cursor. The key and state must be nonempty strings; optional data is a JSON object.
|
|
111
|
+
Use task-specific keys: existing matching signals count unless `after` excludes
|
|
112
|
+
them.
|
|
113
|
+
|
|
114
|
+
Publish an explicit checkpoint or blocker through the `signal` MCP tool or CLI:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
superwait signal review-42/blocker \
|
|
118
|
+
--state blocked \
|
|
119
|
+
--data '{"reason":"missing fixture"}'
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Results and continuation
|
|
123
|
+
|
|
124
|
+
The result includes:
|
|
125
|
+
|
|
126
|
+
- `status`: `matched`, `interrupted`, `timed_out`, or `error`
|
|
127
|
+
- `reason`: why the wait ended
|
|
128
|
+
- `ready`: completed reports
|
|
129
|
+
- `pending`: remaining work or condition errors
|
|
130
|
+
- `triggered`: early wake conditions that fired
|
|
131
|
+
- `progress`: counts of `ready`, `required`, and `total` conditions
|
|
132
|
+
- `deadline`: the absolute deadline; `elapsed_seconds`: time spent waiting
|
|
133
|
+
- `continue_wait`: a ready-to-use request for remaining work, or `null`
|
|
134
|
+
|
|
135
|
+
Reports include the observed state, available worker result, and event cursor
|
|
136
|
+
where applicable. `details: true` adds `checks` and raw `targets` / `wake_on`
|
|
137
|
+
observations. An early wake condition wins if it and the main threshold match
|
|
138
|
+
in the same check.
|
|
139
|
+
|
|
140
|
+
Pass `continue_wait` back as the next request to resume. It preserves the
|
|
141
|
+
deadline, remaining count, and file-change baselines, and advances past
|
|
142
|
+
delivered event signals. Persistent conditions such as an existing blocker
|
|
143
|
+
file must clear or be removed before continuing. After a quorum is reached,
|
|
144
|
+
continuation waits for all remaining work.
|
|
145
|
+
|
|
146
|
+
A stopped worker response does not prove its assignment succeeded. Read its
|
|
147
|
+
report; another host hook may continue that worker. For a resumed worker, use
|
|
148
|
+
an `agent` target with `after` set to its last returned cursor. Unknown workers
|
|
149
|
+
stay pending.
|
|
150
|
+
|
|
151
|
+
For a new response from a resumed worker:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"request": {
|
|
156
|
+
"session": "parent-session-from-startup-context",
|
|
157
|
+
"targets": [{"kind": "agent", "provider": "codex", "id": "/root/reviewer_a", "after": 42}],
|
|
158
|
+
"timeout": "2h"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Long waits and the CLI
|
|
164
|
+
|
|
165
|
+
Setup configures a per-server MCP timeout of 24 hours plus 30 seconds for Codex
|
|
166
|
+
and Claude Code. Change the ceiling with `setup --max-wait 3d`. Each request
|
|
167
|
+
still has its own `timeout` or timezone-qualified `deadline`. An absolute
|
|
168
|
+
deadline survives continuation; a timed-out continuation remains expired.
|
|
169
|
+
|
|
170
|
+
In Codex code mode, start `functions.exec` with
|
|
171
|
+
`// @exec: {"yield_time_ms":60000}`. If it yields, resume that cell with
|
|
172
|
+
`functions.wait` and `yield_time_ms: 60000`. This avoids unnecessary model
|
|
173
|
+
turns collecting an unfinished tool call.
|
|
174
|
+
|
|
175
|
+
For long Cursor waits, or waits beyond a host's configured MCP timeout, run the
|
|
176
|
+
same request through the host's background terminal:
|
|
177
|
+
|
|
178
|
+
```sh
|
|
179
|
+
superwait wait --request wait.json --output result.json
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`wait.json` contains the request itself without the MCP `request` wrapper. The
|
|
183
|
+
CLI prints one final JSON result and atomically saves the optional output. It
|
|
184
|
+
exits 0 for matched or interrupted, 124 for timeout, 130 for Ctrl-C, and 2 for
|
|
185
|
+
an invalid request or target ambiguity. The CLI does not background itself.
|
|
186
|
+
|
|
187
|
+
Cancellation stops the wait and probes it launched. It does not cancel the
|
|
188
|
+
workers being observed. The process and machine must remain alive.
|
|
189
|
+
|
|
190
|
+
### CLI commands
|
|
191
|
+
|
|
192
|
+
Global options go before the command: `--db PATH` selects the shared store;
|
|
193
|
+
`--provider codex|claude|cursor` selects the default host for agent shorthand.
|
|
194
|
+
|
|
195
|
+
| Command | Options / behavior |
|
|
196
|
+
| --- | --- |
|
|
197
|
+
| `wait` | `--request FILE` (default `-` reads stdin); `--timeout DURATION` overrides duration and clears a supplied deadline; `--output FILE` saves the result |
|
|
198
|
+
| `signal KEY` | `--state STATE` (default `ready`); `--data JSON` (default `{}`) |
|
|
199
|
+
| `agents PROVIDER` | Optional `--session SESSION`; lists up to 50 recent workers |
|
|
200
|
+
| `setup PROVIDER` | Host-wide by default; `--project PATH` installs for one repository; `--max-wait DURATION` defaults to `24h` |
|
|
201
|
+
| `serve` | Runs the MCP server over stdio |
|
|
202
|
+
| `hook PROVIDER` | Lifecycle recorder used by setup; reads the host's JSON event from stdin |
|
|
203
|
+
| `prune` | `--days NUMBER` deletes older observations; positive number, default `30` |
|
|
204
|
+
|
|
205
|
+
Setup installs `SKILL.md` and this reference together, preserving unrelated
|
|
206
|
+
host settings and saving originals of changed files as `.superwait-backup`.
|
|
207
|
+
Restart the host and review its MCP/hooks trust prompts after setup.
|
|
208
|
+
|
|
209
|
+
## Local state
|
|
210
|
+
|
|
211
|
+
Hooks and waiters share a local SQLite database, defaulting to
|
|
212
|
+
`$XDG_STATE_HOME/superwait/events.sqlite3` or
|
|
213
|
+
`~/.local/state/superwait/events.sqlite3`. Set `SUPERWAIT_DB` or pass `--db` to
|
|
214
|
+
use another store. Stored observations include worker IDs, report excerpts,
|
|
215
|
+
and available transcript paths.
|
|
216
|
+
|
|
217
|
+
```sh
|
|
218
|
+
superwait prune --days 30
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The Codex task-name adapter reads only the metadata header of the exact worker
|
|
222
|
+
transcript supplied by its hook. It does not scan conversation history. Network
|
|
223
|
+
requests occur only for explicitly requested HTTP or command checks.
|