cuekit 0.0.12 → 0.0.14
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.
- package/README.md +363 -0
- package/bin/cuekit.js +38 -33
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# cuekit
|
|
2
|
+
|
|
3
|
+
A child-agent delegation substrate for coding agents.
|
|
4
|
+
|
|
5
|
+
cuekit gives a parent agent a stable way to spawn child coding agents, attach to them live via tmux, steer them, collect normalized results, and clean up. The same protocol surface is exposed as a grouped human CLI (`cuekit task ...`) and a grouped MCP tool surface for AI callers.
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
cuekit is **not a workflow engine**. The parent agent stays the decision-maker; cuekit is the substrate that makes delegation observable and steerable.
|
|
10
|
+
|
|
11
|
+
- **Teams** are a lightweight view over related child tasks, not a swarm OS.
|
|
12
|
+
- **Strategies** are development playbooks, not workflow control.
|
|
13
|
+
- No automatic scheduling, auto-wake, or auto-steer that replaces parent judgment.
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- [Bun](https://bun.sh) ≥ 1.2
|
|
18
|
+
- A terminal multiplexer on `PATH`. By default cuekit uses **tmux** (with `new-session -e` support); children run in tmux sessions you can `tmux attach` into. Alternatively, cuekit can use **[zellij](https://github.com/zellij-org/zellij)** ≥ 0.43 or **[herdr](https://herdr.dev)** ≥ 0.5 by setting `multiplexer.backend: zellij` or `multiplexer.backend: herdr` in `.cuekit.yaml` — see [Multiplexer](#multiplexer) below.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
Pinned to a specific release tag (recommended):
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
bun install -g github:takemo101/cuekit#v0.0.8
|
|
26
|
+
cuekit doctor
|
|
27
|
+
cuekit mcp config # prints the snippet to register cuekit with your MCP client
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or resolve the most recent release tag at install time (no need to look up the version):
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
# Option A — uses the GitHub CLI:
|
|
34
|
+
bun install -g github:takemo101/cuekit#$(gh release view --repo takemo101/cuekit --json tagName -q .tagName)
|
|
35
|
+
|
|
36
|
+
# Option B — curl-only:
|
|
37
|
+
bun install -g github:takemo101/cuekit#$(curl -s https://api.github.com/repos/takemo101/cuekit/releases/latest | jq -r .tag_name)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Bun has no `#latest` shorthand for GitHub installs, so the one-liners above resolve the tag at command-execution time and pin the install to that exact version. After install, `cuekit update` is the advisory-only command that prints the next install command when a newer release exists.
|
|
41
|
+
|
|
42
|
+
When upgrading an existing global GitHub install, remove first and then install the new tag:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
bun remove -g cuekit-workspace
|
|
46
|
+
bun install -g github:takemo101/cuekit#v0.0.8
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This avoids Bun global-install dependency-loop errors that can occur when installing a newer `github:takemo101/cuekit#...` tag over an older one.
|
|
50
|
+
|
|
51
|
+
Use an immutable release tag for normal installs. Avoid floating `#main` outside development — Bun's caching semantics for branches are less explicit. After installing a newer tag, restart MCP clients.
|
|
52
|
+
|
|
53
|
+
> **Naming gotcha**: the binary is named `cuekit` but the workspace `package.json#name` is `cuekit-workspace`. This matters when you uninstall (see below) and when you list installed packages (`bun pm ls -g | grep cuekit`).
|
|
54
|
+
|
|
55
|
+
### Uninstall
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
bun remove -g cuekit-workspace
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`bun remove -g cuekit` is a **silent no-op** because no package by that name exists — Bun returns success without removing anything. Always remove by the package name `cuekit-workspace`. Verify with `which cuekit` (should report nothing) or `bun pm ls -g | grep cuekit-workspace` (should be empty).
|
|
62
|
+
|
|
63
|
+
For a deeper cleanup including state, transcript, and tmux sessions, see the uninstall recipe at the bottom of this file.
|
|
64
|
+
|
|
65
|
+
### Local development
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
git clone https://github.com/takemo101/cuekit
|
|
69
|
+
cd cuekit
|
|
70
|
+
bun install
|
|
71
|
+
bun link # exposes `cuekit` from the workspace
|
|
72
|
+
# or run directly:
|
|
73
|
+
bun packages/cli/src/bin.ts <command>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Quick start
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
# Submit a child agent task in your repo:
|
|
80
|
+
cuekit task submit \
|
|
81
|
+
--objective "add retry logic to src/api/client.ts" \
|
|
82
|
+
--agent_kind claude-code \
|
|
83
|
+
--model sonnet \
|
|
84
|
+
--cwd /path/to/repo
|
|
85
|
+
# → { task_id: "t_abc...", attach_hint: "tmux attach-session -t cuekit-task-t_abc..." }
|
|
86
|
+
|
|
87
|
+
# Watch the child live in another terminal:
|
|
88
|
+
cuekit task status --task_id t_abc... --format json | jq -r '.attach_hint'
|
|
89
|
+
# → use the printed attach command (tmux/zellij/herdr attach)
|
|
90
|
+
|
|
91
|
+
# Steer it without attaching:
|
|
92
|
+
cuekit task steer --task_id t_abc... --message "also cover exponential backoff"
|
|
93
|
+
|
|
94
|
+
# Collect the normalized result:
|
|
95
|
+
cuekit task result --task_id t_abc...
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## CLI
|
|
99
|
+
|
|
100
|
+
Commands are grouped by resource. Option names are `snake_case`. Every command accepts `--help`, `--llms` / `--llms-full` (machine-readable manifest), `--schema`, and `--format` (`toon` / `json` / `yaml` / `md` / `jsonl`).
|
|
101
|
+
|
|
102
|
+
| Group | Examples |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `task` | `submit`, `status`, `steer`, `cancel`, `result`, `wait`, `list` |
|
|
105
|
+
| `team` | `create`, `submit`, `start`, `result`, `steer`, `delete` |
|
|
106
|
+
| `agent` | `list` (discover role profiles) |
|
|
107
|
+
| `adapter` | `list` (runtime capabilities) |
|
|
108
|
+
| `tui` | interactive task cockpit |
|
|
109
|
+
| `mcp` | `config` (print MCP client snippet) |
|
|
110
|
+
| top-level | `init`, `doctor`, `update` |
|
|
111
|
+
|
|
112
|
+
Flat aliases like `cuekit submit_task` are intentionally not supported — only MCP tool names use that flat form.
|
|
113
|
+
|
|
114
|
+
### Agent profiles
|
|
115
|
+
|
|
116
|
+
Use `--role` to submit with focused child-agent instructions. Profiles resolve in this order: project (`<repo>/.cuekit/agents/*.md`) → user (`~/.cuekit/agents/*.md`) → builtins. `--agent_kind` / `--model` override profile defaults.
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
cuekit agent list
|
|
120
|
+
cuekit task submit --objective "review this diff" --role reviewer --cwd /path/to/repo
|
|
121
|
+
cuekit task submit --objective "debug the failing auth tests" --role auto --cwd /path/to/repo
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`role: "auto"` uses deterministic keyword selection and records the chosen role and reason in task status. See [Agent Profiles guide](docs/guides/agent-profiles.md).
|
|
125
|
+
|
|
126
|
+
### Project config
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
cuekit init # writes a safe .cuekit.yaml and adds .cuekit/tasks/ to .gitignore
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`.cuekit.yaml` defines project identity, safe submit defaults, TUI scope, and Task Teams defaults. The generated file uses prompt-safe adapter permissions; pass `cuekit init --unsafe-bypass` only in trusted repos when you want project-local defaults to request bypass behavior. Project-derived role/agent defaults still force prompt-safe adapter options unless a caller explicitly supplies `adapter_options`. See [Project Config guide](docs/guides/project-config.md) and [`.cuekit.example.yaml`](.cuekit.example.yaml).
|
|
133
|
+
|
|
134
|
+
### TUI
|
|
135
|
+
|
|
136
|
+
`cuekit tui` opens an interactive task cockpit for humans. The flat CLI stays optimized for agents/scripts; the TUI is a separate surface for browsing and acting.
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
↑/↓ or j/k select task a attach to task pane/session (one-way; exits TUI)
|
|
140
|
+
t switch tasks/teams A attach selected team dashboard (teams mode)
|
|
141
|
+
r refresh s steer selected task
|
|
142
|
+
c cancel selected d delete terminal task / empty team
|
|
143
|
+
q / Esc quit
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The task detail panel's `LIVE OUTPUT` section sources from the running task's multiplexer pane (e.g. `tmux capture-pane`) so the rendered screen matches what `tmux attach` would show — useful for TUI children (Gemini CLI, opencode TUI) whose output gets buried by redraws in the persisted transcript. Terminal tasks fall back to the file-tail. The header indicates which source is active. See [`docs/designs/cuekit-tui-live-pane-transcript-design.md`](docs/designs/cuekit-tui-live-pane-transcript-design.md).
|
|
147
|
+
|
|
148
|
+
## MCP
|
|
149
|
+
|
|
150
|
+
Start the stdio server:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
cuekit --mcp
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Grouped tool surface: `submit_task`, `submit_team_tasks`, `start_team_strategy`, `create_team`, `get_status`, `get_task_result`, `get_team_result`, `wait`, `cancel_tasks`, `list`, `report_task_event`, `steer`, `steer_task`, `steer_team`, `cleanup`, `delete`.
|
|
157
|
+
|
|
158
|
+
- `list({ kind: "tasks" | "teams" | "events" | "adapters" | "agent_profiles" | "strategies" })` — pass `cwd` for project-local strategy discovery.
|
|
159
|
+
- `steer({ kind: "task" | "team", ... })` — preferred. `steer_task` / `steer_team` remain as compatibility aliases.
|
|
160
|
+
- `delete({ kind: "team", ... })` — for empty teams only.
|
|
161
|
+
- `cuekit mcp config` is CLI-only; no MCP setup helpers are exposed as tools.
|
|
162
|
+
|
|
163
|
+
### Waiting on child work
|
|
164
|
+
|
|
165
|
+
`wait` is the parent-side polling primitive. Prefer **short bounded waits** over one long request:
|
|
166
|
+
|
|
167
|
+
```jsonc
|
|
168
|
+
{ "kind": "tasks", "task_ids": ["t_..."], "timeout_ms": 30000, "poll_interval_ms": 5000 }
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
A wait timeout only stops waiting; child work keeps running. Team waits are snapshot-based by default — coordinator-led / strategy-backed teams that submit workers after waiting begins can pass `follow_new_tasks: true`.
|
|
172
|
+
|
|
173
|
+
When a bounded wait times out, call `get_status`. If a task includes `attention_hint` (e.g. `stop_hook_or_idle_prompt_suspected`), use `steer({ kind: "task", ... })` with a short instruction. Inspect durable child reports with `list({ kind: "events", task_id: "t_..." })`.
|
|
174
|
+
|
|
175
|
+
## Execution model
|
|
176
|
+
|
|
177
|
+
Pane adapters default to **interactive** mode: the child runs in a dedicated `cuekit-task-<id>` tmux session so cuekit can attach, steer, and capture transcripts while the runtime stays alive.
|
|
178
|
+
|
|
179
|
+
For single-shot jobs, opt into batch mode per task:
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
cuekit task submit --objective "review this diff once and exit" \
|
|
183
|
+
--agent_kind claude-code \
|
|
184
|
+
--adapter_options '{"mode":"batch"}'
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Batch tasks still run in a pane and are attachable, but `metadata.adapter_mode: "batch"` and `supports_steering: false`; `steer_task` rejects them with `steering_unsupported`. Adapter list reports default capabilities; task status reports the actual mode chosen.
|
|
188
|
+
|
|
189
|
+
### Adapter defaults
|
|
190
|
+
|
|
191
|
+
- `claude-code` defaults to runtime permission bypass so delegated panes don't stall.
|
|
192
|
+
- `opencode` defaults to its interactive TUI; permission bypass applies only to opt-in batch/run mode.
|
|
193
|
+
- `gemini` defaults to runtime permission bypass (`-y`) and always passes `--skip-trust` so unattended panes don't stall on the trusted-folder gate.
|
|
194
|
+
|
|
195
|
+
See [`docs/specs/2026-04-23-cuekit-adapter-spec.md`](docs/specs/2026-04-23-cuekit-adapter-spec.md) §3.7 for the full pane-backend contract.
|
|
196
|
+
|
|
197
|
+
### Multiplexer
|
|
198
|
+
|
|
199
|
+
cuekit defaults to **tmux** as the terminal multiplexer. Projects can opt into **zellij** ≥ 0.43 via `.cuekit.yaml`:
|
|
200
|
+
|
|
201
|
+
```yaml
|
|
202
|
+
multiplexer:
|
|
203
|
+
backend: zellij # default is "tmux"
|
|
204
|
+
strict: false # optional. true → hard-fail when zellij is missing instead of soft-falling-back to tmux
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Behavioural differences when `multiplexer.backend: zellij` is active:
|
|
208
|
+
|
|
209
|
+
- Solo tasks live in compact `ct-<task_id>` zellij sessions (mirrors the tmux model).
|
|
210
|
+
- Team tasks share one compact `ctm-<team_id_suffix>` zellij session. In the TUI, `A` on the team list attaches to this multi-pane dashboard; `a` on a member/task focuses that member pane before attaching to the same dashboard session.
|
|
211
|
+
- Attach uses `zellij attach <session-name>` instead of `tmux attach-session`.
|
|
212
|
+
- The TUI's transcript pane sources from `zellij action dump-screen` instead of `tmux capture-pane`. Output formatting differs subtly (escape-sequence canonicalisation).
|
|
213
|
+
- Zellij pane state queries are slower than tmux on some systems, especially for multi-pane team dashboards. The TUI keeps list navigation responsive by using cached/persisted list rows, debouncing zellij detail loads, and showing a `Loading detail…` spinner while the selected detail refreshes. A small detail-panel lag is expected when zellij is selected.
|
|
214
|
+
- When zellij is configured but its binary is missing, cuekit logs a warning and silently falls back to tmux. To turn this into a hard failure (e.g. CI configs that want to surface the missing dependency), set `multiplexer.strict: true`.
|
|
215
|
+
- Per-task multiplexer dispatch: a task spawned under one backend stays attachable via that backend even if `.cuekit.yaml` is later switched. The active backend is per-task, recorded at spawn time.
|
|
216
|
+
|
|
217
|
+
See [`docs/designs/cuekit-multiplexer-backend-design.md`](docs/designs/cuekit-multiplexer-backend-design.md) for the full design and the zellij team-dashboard work tracked under Phase 4.
|
|
218
|
+
|
|
219
|
+
#### Herdr backend
|
|
220
|
+
|
|
221
|
+
Projects can also opt into **[herdr](https://herdr.dev)** ≥ 0.5 as the multiplexer:
|
|
222
|
+
|
|
223
|
+
```yaml
|
|
224
|
+
multiplexer:
|
|
225
|
+
backend: herdr
|
|
226
|
+
strict: false
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Herdr uses **workspaces** instead of sessions. Solo tasks get one workspace each; team tasks share one workspace with **named tabs per position** (for example, coordinator, worker, reviewer). Attach uses `herdr --session <name>`.
|
|
230
|
+
|
|
231
|
+
Key differences:
|
|
232
|
+
- **Team model**: one workspace per team with position-named tabs; same position shares a tab, different positions get separate tabs.
|
|
233
|
+
- **Pane IDs**: compacted on close (IDs may shift), so cuekit uses transcript identity verification to avoid closing the wrong pane.
|
|
234
|
+
- **Cross-process persistence**: team workspace handles are persisted in `task_teams.metadata_json` so coordinator-spawned members reuse the same workspace even across process restarts.
|
|
235
|
+
- **Fallback**: when herdr is missing and `strict: false`, cuekit falls back to tmux with a logged warning.
|
|
236
|
+
|
|
237
|
+
See [`docs/designs/cuekit-herdr-multiplexer-backend-design.md`](docs/designs/cuekit-herdr-multiplexer-backend-design.md) for the full design.
|
|
238
|
+
|
|
239
|
+
## State
|
|
240
|
+
|
|
241
|
+
| Where | What |
|
|
242
|
+
|---|---|
|
|
243
|
+
| `~/.cuekit/state.db` | global SQLite index — `sessions`, `tasks`, `schema_migrations`. WAL mode, `foreign_keys = ON`, one connection per process. |
|
|
244
|
+
| `<worktree>/.cuekit/tasks/<task_id>/` | per-task artifacts: `transcript.txt`, runtime-emitted `result.json`, anything else the adapter drops. Stored as `transcript_ref` / `result_ref` on the task row. |
|
|
245
|
+
| `cuekit-task-<id>` | one multiplexer session/workspace per task. Killed on terminal transition or explicit cancel. |
|
|
246
|
+
|
|
247
|
+
## Packages
|
|
248
|
+
|
|
249
|
+
| Package | Purpose |
|
|
250
|
+
|---|---|
|
|
251
|
+
| `@cuekit/core` | Protocol types, Zod schemas, lifecycle helpers. No runtime deps. |
|
|
252
|
+
| `@cuekit/store` | SQLite persistence at `~/.cuekit/state.db` with migrations. |
|
|
253
|
+
| `@cuekit/adapters` | Runtime bindings. Ships tmux, zellij, and herdr pane backends with adapters for claude-code, pi, opencode (stub), `jcode repl`, and gemini. |
|
|
254
|
+
| `@cuekit/agent-profiles` | Role-based child-agent profiles. |
|
|
255
|
+
| `@cuekit/project-config` | `.cuekit.yaml` loading, validation, and defaults. |
|
|
256
|
+
| `@cuekit/mcp` | MCP server and protocol/control command projection. |
|
|
257
|
+
| `@cuekit/cli` | The `cuekit` binary, setup helpers, diagnostics. |
|
|
258
|
+
| `@cuekit/tui` | OpenTUI-based human task cockpit. |
|
|
259
|
+
|
|
260
|
+
## Documentation
|
|
261
|
+
|
|
262
|
+
The full documentation index is at [`docs/README.md`](docs/README.md).
|
|
263
|
+
|
|
264
|
+
| Area | When to read |
|
|
265
|
+
|---|---|
|
|
266
|
+
| [`docs/specs/`](docs/specs/README.md) | What cuekit is — protocol, state model, MCP API, adapter contract. |
|
|
267
|
+
| [`docs/architecture/`](docs/architecture/README.md) | How cuekit must be built — package boundaries, coding rules, error taxonomy. |
|
|
268
|
+
| [`docs/decisions/`](docs/decisions/) | ADRs and durable design decisions. |
|
|
269
|
+
| [`docs/designs/`](docs/designs/README.md) | Stable feature/subsystem designs (teams, strategies, profiles, TUI, ...). |
|
|
270
|
+
| [`docs/guides/`](docs/guides/README.md) | Operator/developer guides for implemented features. |
|
|
271
|
+
| [`docs/issues/`](docs/issues/README.md) | Active investigations and bug reports. |
|
|
272
|
+
| [`docs/plans/`](docs/plans/) | Implementation plans and execution notes. |
|
|
273
|
+
| [`docs/references/`](docs/references/README.md) | Local copies of third-party docs (e.g. OpenTUI). |
|
|
274
|
+
|
|
275
|
+
## Development
|
|
276
|
+
|
|
277
|
+
```sh
|
|
278
|
+
bun run typecheck # tsc --noEmit across all packages
|
|
279
|
+
bun run test # bun:test across all packages
|
|
280
|
+
bun run check # Biome lint + format check
|
|
281
|
+
bun run fix # Biome auto-fix
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Tests use `FakeTmuxRunner` and `FakeHerdrRunner` (exported from `@cuekit/adapters`) so the default run does not require `tmux` or `herdr`. A small integration suite in `@cuekit/adapters` exercises real tmux when available and skips otherwise.
|
|
285
|
+
|
|
286
|
+
### Manual smoke tests
|
|
287
|
+
|
|
288
|
+
Adapter end-to-end checks against real runtimes are documented per adapter:
|
|
289
|
+
|
|
290
|
+
- [jcode adapter smoke test](docs/guides/jcode-adapter.md)
|
|
291
|
+
- [gemini adapter smoke test](docs/guides/gemini-adapter.md)
|
|
292
|
+
- Real `claude` CLI: `just install`, then submit a task with `--agent_kind claude-code` and attach via the hint from `cuekit task status --task_id <id>`. The transcript persists at `<cwd>/.cuekit/tasks/<task_id>/transcript.txt` after the session is killed.
|
|
293
|
+
|
|
294
|
+
### Cutting a release
|
|
295
|
+
|
|
296
|
+
Releases are GitHub-tagged (`v0.0.x`) and consumed via `bun install -g github:takemo101/cuekit#vX.Y.Z`. The published binary is the pre-built bundle at `bin/cuekit.js` — `package.json#bin.cuekit` points at it directly, so Bun installs it verbatim.
|
|
297
|
+
|
|
298
|
+
```sh
|
|
299
|
+
# 1. Bump version in every workspace package's package.json (and the
|
|
300
|
+
# project root if it tracks one). Update CHANGELOG.md.
|
|
301
|
+
# 2. Verify the bundle is in sync with the new version:
|
|
302
|
+
bun run release:check
|
|
303
|
+
# 3. If `release:check` reports the bundle was stale, commit the
|
|
304
|
+
# regenerated bin/cuekit.js it produced, then re-run.
|
|
305
|
+
# 4. Open the release PR and merge. After merge, tag the merge commit
|
|
306
|
+
# with `vX.Y.Z` and push.
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
`release:check` rebuilds the bundle, fails if the committed `bin/cuekit.js` differs from the freshly-built output (= the bundle was stale), and double-checks that the bundle contains the expected version string. Without this gate v0.0.2 and v0.0.3 both shipped a stale bundle that reported `0.0.1` from its baked-in `package.json` copy — see [#388](https://github.com/takemo101/cuekit/issues/388).
|
|
310
|
+
|
|
311
|
+
## v0 scope
|
|
312
|
+
|
|
313
|
+
| Supported | Deferred |
|
|
314
|
+
|---|---|
|
|
315
|
+
| `submit_task` / `get_status` / `get_task_result` / `wait` / `cancel_tasks` | Workflow engine, kanban, swarm OS |
|
|
316
|
+
| Grouped `list` / `cleanup` / `delete` MCP tools | Distributed worker pools, DAG scheduling |
|
|
317
|
+
| `steer_task` (best-effort, adapter-dependent) | Remote tenancy / auth model |
|
|
318
|
+
| tmux / zellij / herdr attach for every running task | Cost accounting, long-term memory |
|
|
319
|
+
|
|
320
|
+
Full v0 protocol: [`docs/specs/README.md`](docs/specs/README.md).
|
|
321
|
+
|
|
322
|
+
## Full uninstall
|
|
323
|
+
|
|
324
|
+
The basic `bun remove -g cuekit-workspace` (see [Uninstall](#uninstall)) removes only the binary. To wipe state, transcripts, and project artifacts as well:
|
|
325
|
+
|
|
326
|
+
```sh
|
|
327
|
+
# 1. Binary + Bun cache
|
|
328
|
+
bun remove -g cuekit-workspace
|
|
329
|
+
rm -rf ~/.bun/install/cache/@GH@takemo101-cuekit-*
|
|
330
|
+
rm -rf ~/.bun/install/global/node_modules/cuekit-workspace
|
|
331
|
+
|
|
332
|
+
# 2. Global state DB (task history, sessions, events)
|
|
333
|
+
rm -rf ~/.cuekit
|
|
334
|
+
|
|
335
|
+
# 3. Per-project artifacts (run inside each repo that used cuekit)
|
|
336
|
+
find . -name '.cuekit' -type d -prune -exec rm -rf {} +
|
|
337
|
+
rm -f ./.cuekit.yaml # if `cuekit init` was run
|
|
338
|
+
|
|
339
|
+
# 4. Kill any remaining multiplexer sessions
|
|
340
|
+
# tmux:
|
|
341
|
+
tmux ls 2>/dev/null | grep cuekit-task | cut -d: -f1 | xargs -I {} tmux kill-session -t {}
|
|
342
|
+
# herdr:
|
|
343
|
+
herdr workspace list 2>/dev/null | jq -r '.result.workspaces[].workspace_id' | xargs -I {} herdr workspace close {}
|
|
344
|
+
|
|
345
|
+
# 5. Remove the cuekit entry from MCP client configs
|
|
346
|
+
# Claude Code: `~/.claude.json` → `mcpServers.cuekit`
|
|
347
|
+
# Project: `<repo>/.mcp.json` → `mcpServers.cuekit`
|
|
348
|
+
# Cursor / Claude Desktop: each client's MCP config
|
|
349
|
+
# Restart the client after editing.
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Verify the removal:
|
|
353
|
+
|
|
354
|
+
```sh
|
|
355
|
+
which cuekit # should report nothing
|
|
356
|
+
ls ~/.cuekit # should be "No such file"
|
|
357
|
+
tmux ls 2>/dev/null | grep cuekit- # should be empty
|
|
358
|
+
herdr workspace list 2>/dev/null | grep cuekit # should be empty
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Step 1 is enough for most cases. Steps 2 and 3 are destructive — back up `transcript.txt` files first if you need them for review or postmortem.
|
|
362
|
+
|
|
363
|
+
Note: `bun remove -g cuekit` (without `-workspace`) returns success but removes nothing — the workspace package is named `cuekit-workspace` even though its binary is `cuekit`.
|
package/bin/cuekit.js
CHANGED
|
@@ -108769,7 +108769,7 @@ function resolveDisplayName(name, aliases) {
|
|
|
108769
108769
|
// packages/mcp/package.json
|
|
108770
108770
|
var package_default = {
|
|
108771
108771
|
name: "@cuekit/mcp",
|
|
108772
|
-
version: "0.0.
|
|
108772
|
+
version: "0.0.11",
|
|
108773
108773
|
private: true,
|
|
108774
108774
|
type: "module",
|
|
108775
108775
|
exports: {
|
|
@@ -108780,23 +108780,12 @@ var package_default = {
|
|
|
108780
108780
|
test: "bun test"
|
|
108781
108781
|
},
|
|
108782
108782
|
dependencies: {
|
|
108783
|
-
"@cuekit/adapters": "
|
|
108784
|
-
"@cuekit/core": "
|
|
108785
|
-
"@cuekit/project-config": "
|
|
108786
|
-
"@cuekit/store": "
|
|
108783
|
+
"@cuekit/adapters": "workspace:*",
|
|
108784
|
+
"@cuekit/core": "workspace:*",
|
|
108785
|
+
"@cuekit/project-config": "workspace:*",
|
|
108786
|
+
"@cuekit/store": "workspace:*",
|
|
108787
108787
|
incur: "0.4.3",
|
|
108788
|
-
"@cuekit/agent-profiles": "
|
|
108789
|
-
},
|
|
108790
|
-
publishConfig: {
|
|
108791
|
-
access: "public"
|
|
108792
|
-
},
|
|
108793
|
-
engines: {
|
|
108794
|
-
bun: ">=1.2.0"
|
|
108795
|
-
},
|
|
108796
|
-
license: "MIT",
|
|
108797
|
-
repository: {
|
|
108798
|
-
type: "git",
|
|
108799
|
-
url: "git+https://github.com/takemo101/cuekit.git"
|
|
108788
|
+
"@cuekit/agent-profiles": "workspace:*"
|
|
108800
108789
|
}
|
|
108801
108790
|
};
|
|
108802
108791
|
|
|
@@ -110035,9 +110024,12 @@ function buildTeamAttentionItemsFromEvents(taskEvents, options = {}) {
|
|
|
110035
110024
|
return [];
|
|
110036
110025
|
const includeFullMessage = options.includeFullMessage ?? true;
|
|
110037
110026
|
const items = taskEvents.flatMap(({ task: task2, events }) => {
|
|
110038
|
-
|
|
110039
|
-
|
|
110040
|
-
|
|
110027
|
+
return events.filter((event) => ATTENTION_TYPES.has(event.type)).filter((event) => {
|
|
110028
|
+
if (task2.team_position === "coordinator" && event.type === "completed") {
|
|
110029
|
+
return false;
|
|
110030
|
+
}
|
|
110031
|
+
return true;
|
|
110032
|
+
}).map((event) => {
|
|
110041
110033
|
const type = event.type;
|
|
110042
110034
|
return {
|
|
110043
110035
|
sequence: event.sequence,
|
|
@@ -110855,6 +110847,17 @@ ${input.strategy.intent}` : undefined,
|
|
|
110855
110847
|
"Use cuekit tools to coordinate: inspect the strategy's recommended team skeleton when useful, review and adjust it before submit_team_tasks, wait with follow_new_tasks, steer when needed, get_team_result, and report a final completed event. Cuekit will not auto-submit worker/reviewer tasks from the skeleton.",
|
|
110856
110848
|
"Report progress after submitting tasks, bounded waits, and steering so the parent can see the current state and avoid appearing idle while work is still in progress.",
|
|
110857
110849
|
"When submitting team tasks, set a clear position whenever the lifecycle lane is known: worker for implementation/investigation, reviewer for review, finisher for PR/release/cleanup finishing, observer for monitoring, and coordinator only for orchestration. Unpositioned team tasks are allowed for ambiguous ad-hoc work, but they will not appear in worker/reviewer/finisher lanes.",
|
|
110850
|
+
`## Coordinator wait loop recipe
|
|
110851
|
+
|
|
110852
|
+
You must stay active until all non-coordinator tasks are terminal. Use this pattern:
|
|
110853
|
+
|
|
110854
|
+
1. submit_team_tasks for workers (position: worker)
|
|
110855
|
+
2. loop { wait_team(follow_new_tasks, timeout_ms: 60000) }
|
|
110856
|
+
- if all workers terminal \u2192 submit reviewer (position: reviewer) or finisher
|
|
110857
|
+
- if blocked/stalled \u2192 steer affected task or report blocked
|
|
110858
|
+
- if attention_items include coordinator blocked \u2192 report immediately
|
|
110859
|
+
3. After reviewer/finisher completes \u2192 get_team_result and emit final completed report
|
|
110860
|
+
4. Never exit while non-coordinator tasks are running without explicit parent direction`,
|
|
110858
110861
|
"When team status or result includes attention_items, inspect them before deciding whether to continue, submit more tasks, steer a task, or emit your final report.",
|
|
110859
110862
|
"Do not emit your final completed report while submitted worker, reviewer, or finisher tasks are still non-terminal. Wait with follow_new_tasks, inspect get_team_result, and steer idle tasks once before deciding they are unusable. If you intentionally skip, cancel, or cannot wait for any submitted non-coordinator task, explain that exception in the final report.",
|
|
110860
110863
|
"After a `position: finisher` task completes and all submitted non-coordinator tasks are terminal or explicitly accounted for, inspect the team result with get_team_result and emit your own final completed report \u2014 do not wait for parent steering. If no finisher was submitted, the coordinator remains responsible for the final durable report under the same condition."
|
|
@@ -111920,8 +111923,9 @@ async function runStartTeamStrategy(ctx, input) {
|
|
|
111920
111923
|
...role ? { role } : {},
|
|
111921
111924
|
...agent_kind ? { agent_kind } : {},
|
|
111922
111925
|
...model ? { model } : {},
|
|
111923
|
-
|
|
111924
|
-
...adapter_options ? { adapter_options } : {}
|
|
111926
|
+
timeout_ms: input.coordinator?.timeout_ms ?? null,
|
|
111927
|
+
...adapter_options ? { adapter_options } : {},
|
|
111928
|
+
metadata: { long_lived: true }
|
|
111925
111929
|
});
|
|
111926
111930
|
if (!submitted.accepted) {
|
|
111927
111931
|
return failure("coordinator_submit_failed", submitted.error.message);
|
|
@@ -112711,7 +112715,7 @@ async function runWaitTeam(ctx, input) {
|
|
|
112711
112715
|
status: aggregateTeamStatus(latest2),
|
|
112712
112716
|
mode: input.mode ?? "all",
|
|
112713
112717
|
done: false,
|
|
112714
|
-
timed_out:
|
|
112718
|
+
timed_out: true,
|
|
112715
112719
|
team_sequence: maxSeq,
|
|
112716
112720
|
scope: { team_id: team2.id, session_id: team2.session_id },
|
|
112717
112721
|
tasks: [],
|
|
@@ -112753,6 +112757,7 @@ async function runWaitTeam(ctx, input) {
|
|
|
112753
112757
|
run_summary: buildTeamRunSummary(ctx, latest),
|
|
112754
112758
|
...nextActionHint ? { next_action_hint: nextActionHint } : {},
|
|
112755
112759
|
...cleanupHint ? { cleanup_hint: cleanupHint } : {},
|
|
112760
|
+
...input.since_team_sequence !== undefined ? { team_sequence: getMaxTeamSequence(ctx.db, team2.id) ?? 0 } : {},
|
|
112756
112761
|
...wait.error ? { error: wait.error } : {}
|
|
112757
112762
|
};
|
|
112758
112763
|
}
|
|
@@ -113667,7 +113672,7 @@ init_src2();
|
|
|
113667
113672
|
// packages/cli/package.json
|
|
113668
113673
|
var package_default2 = {
|
|
113669
113674
|
name: "@cuekit/cli",
|
|
113670
|
-
version: "0.0.
|
|
113675
|
+
version: "0.0.14",
|
|
113671
113676
|
description: "cuekit \u2014 delegation substrate for coding agents",
|
|
113672
113677
|
type: "module",
|
|
113673
113678
|
exports: {
|
|
@@ -113685,15 +113690,7 @@ var package_default2 = {
|
|
|
113685
113690
|
typecheck: "tsc --noEmit",
|
|
113686
113691
|
test: "bun test"
|
|
113687
113692
|
},
|
|
113688
|
-
dependencies: {
|
|
113689
|
-
"@cuekit/adapters": "^0.0.12",
|
|
113690
|
-
"@cuekit/agent-profiles": "^0.0.12",
|
|
113691
|
-
"@cuekit/core": "^0.0.12",
|
|
113692
|
-
"@cuekit/mcp": "^0.0.12",
|
|
113693
|
-
"@cuekit/project-config": "^0.0.12",
|
|
113694
|
-
"@cuekit/store": "^0.0.12",
|
|
113695
|
-
"@cuekit/tui": "^0.0.12"
|
|
113696
|
-
},
|
|
113693
|
+
dependencies: {},
|
|
113697
113694
|
engines: {
|
|
113698
113695
|
bun: ">=1.2.0"
|
|
113699
113696
|
},
|
|
@@ -113716,6 +113713,14 @@ var package_default2 = {
|
|
|
113716
113713
|
homepage: "https://github.com/takemo101/cuekit#readme",
|
|
113717
113714
|
bugs: {
|
|
113718
113715
|
url: "https://github.com/takemo101/cuekit/issues"
|
|
113716
|
+
},
|
|
113717
|
+
optionalDependencies: {
|
|
113718
|
+
"@opentui/core-darwin-arm64": "0.2.1",
|
|
113719
|
+
"@opentui/core-darwin-x64": "0.2.1",
|
|
113720
|
+
"@opentui/core-linux-arm64": "0.2.1",
|
|
113721
|
+
"@opentui/core-linux-x64": "0.2.1",
|
|
113722
|
+
"@opentui/core-win32-arm64": "0.2.1",
|
|
113723
|
+
"@opentui/core-win32-x64": "0.2.1"
|
|
113719
113724
|
}
|
|
113720
113725
|
};
|
|
113721
113726
|
|