@theaileverage/marionette 0.2.1 → 0.3.0
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/CHANGELOG.md +16 -0
- package/CONTRIBUTING.md +28 -2
- package/DESIGN.md +3 -3
- package/ORCHESTRATION.md +2 -2
- package/README.md +39 -235
- package/RELEASING.md +13 -11
- package/THIRD_PARTY_NOTICES.md +236 -0
- package/VERIFICATION.md +22 -0
- package/dist/cli.js +37558 -10372
- package/dist/herdr-protocol.d.ts +1916 -0
- package/dist/herdr-protocol.js +108 -0
- package/dist/herdr-sdk.d.ts +106 -0
- package/dist/herdr-sdk.js +111 -0
- package/dist/herdr-streams.d.ts +49 -0
- package/dist/herdr-streams.js +160 -0
- package/dist/herdr-transport.d.ts +54 -0
- package/dist/herdr-transport.js +232 -0
- package/dist/mcp.js +24292 -2694
- package/documentation/effect-compatibility.md +56 -0
- package/documentation/effect-runtime.md +73 -0
- package/package.json +52 -22
- package/public/assets/{index-BCi4LMak.js → index-DhL3znDT.js} +12 -12
- package/public/index.html +1 -1
- package/skills/marionette/SKILL.md +70 -0
- package/skills/marionette/references/coordination.md +63 -0
- package/skills/marionette/references/herdr-sdk.md +147 -0
- package/vendor/herdr-0.9.0/LICENSE +201 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0 — 2026-09-08
|
|
4
|
+
|
|
5
|
+
- **Runtime change:** the CLI and supervisor now require Bun 1.3.14+. `npx` remains supported when Bun is on PATH. Development, tests, and CI use Bun with a frozen lockfile.
|
|
6
|
+
- Compose application workflows and resource lifetimes with Effect v4, including typed errors, scoped polling, graceful shutdown, and cancellable subprocesses and sockets.
|
|
7
|
+
- Use Bun's SQLite driver while preserving the version-2 database format, synchronous transactions, lease fencing, and recovery behavior.
|
|
8
|
+
- Enforce Effect diagnostics and anti-slop lint rules, install the project Effect skill, and expand verification to 127 tests plus isolated package checks.
|
|
9
|
+
|
|
10
|
+
Upgrade by stopping the existing supervisor, starting this version against the same state directory, and rerunning setup. Existing worker runtime paths and SQLite state are preserved.
|
|
11
|
+
|
|
12
|
+
## 0.2.2 — 2026-09-08
|
|
13
|
+
|
|
14
|
+
- Ship a Marionette agent skill with setup, task coordination, recovery, and SDK guidance.
|
|
15
|
+
- Place new workers in appropriately sized sibling panes, with overflow tabs, durable creation recovery, and cleanup that preserves sibling workers.
|
|
16
|
+
- Export a dependency-free Herdr SDK covering all 102 Herdr 0.9.0/protocol-22 schema methods plus persistent graphics streams, with generated TypeScript types, cancellable event subscriptions, bounded buffering, and file-frame acknowledgements.
|
|
17
|
+
- Verify graphics payloads, placement, replacement, and layer cleanup through the real Herdr server/client renderer with a simulated Kitty-capable terminal. Expand the regression suite to 117 tests.
|
|
18
|
+
|
|
3
19
|
## 0.2.1 — 2026-09-08
|
|
4
20
|
|
|
5
21
|
- Separate verification, terminal release, delivery, evidence archival and Git collection lifecycles. Task completion continues to preserve branches and worktrees.
|
package/CONTRIBUTING.md
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
-
Use
|
|
3
|
+
Use Bun 1.3.14 or newer and install dependencies with `bun install --frozen-lockfile`. Run `bun run check`, `bun run test`, `bun run build` and `bun run format:check` before opening a pull request. Describe the concrete behavior change and its validation. Keep tests deterministic; the standard suite must not start paid agent sessions or depend on a developer's Herdr configuration.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The project pins Bun, Effect v4, and TypeScript 7. Commit `bun.lock`; do not generate an npm lockfile. `bun install --frozen-lockfile` runs the `prepare` script to
|
|
6
|
+
patch the local TypeScript and Oxlint binaries with `@effect/tsgo`. If dependencies
|
|
7
|
+
were installed with lifecycle scripts disabled, run `bun run prepare` before
|
|
8
|
+
checking code. `bun run check` includes Effect compiler diagnostics and Oxlint;
|
|
9
|
+
`bun run effect:diagnostics` prints the Effect diagnostics separately. Run
|
|
10
|
+
`bun run tooling:check` to verify that valid Effect code passes and deliberate
|
|
11
|
+
floating Effects and unsafe casts fail. CI performs this check after installation.
|
|
12
|
+
`bun run runtime:check` exercises failed startup and concurrent shutdown through
|
|
13
|
+
the real server boundary; it requires permission to bind loopback sockets.
|
|
14
|
+
|
|
15
|
+
Read the [Effect skill](.agents/skills/effect/SKILL.md) and its relevant references
|
|
16
|
+
before changing application workflows. The skill is from
|
|
17
|
+
[kitlangton/skills](https://github.com/kitlangton/skills/tree/main/skills/effect).
|
|
18
|
+
Use the installed `effect` package source to verify APIs for the pinned release.
|
|
19
|
+
The [runtime guide](documentation/effect-runtime.md) explains resource ownership,
|
|
20
|
+
transport boundaries, and the durable-state invariants the migration preserves.
|
|
21
|
+
For VS Code or Cursor, install the TypeScript 7 extension and select the workspace
|
|
22
|
+
TypeScript version; `.vscode/settings.json` configures the native language server.
|
|
23
|
+
|
|
24
|
+
The [vendored anti-slop rules](tools/oxlint/anti-slop/UPSTREAM.md) enforce evidence
|
|
25
|
+
for casts, parsed boundaries, and Effect service imports. All generic rules and
|
|
26
|
+
the Effect rule group are errors. Fix the underlying contract instead of disabling
|
|
27
|
+
rules. Generated Herdr protocol types, vendor code, built output, agent assets and
|
|
28
|
+
local runtime state are excluded from lint. Keep `oxlint` and `@oxlint/plugins`
|
|
29
|
+
at the same exact version and within `@effect/tsgo`'s supported versions.
|
|
30
|
+
|
|
31
|
+
Keep generated bundles, local agent configuration, `.env` files, `.marionette` state, `.runtime` fixtures and credentials out of commits. The reviewed `.agents/skills/effect` guidance is tracked; other local agent configuration remains ignored. Live validation scripts are opt-in and use explicitly named isolated sessions. Never point them at someone else's active session.
|
|
6
32
|
|
|
7
33
|
Changes enter `main` through pull requests. Release preparation and publication follow [RELEASING.md](RELEASING.md). Marionette is licensed under [MIT](LICENSE); bundled third-party licenses are preserved in `THIRD_PARTY_NOTICES.md`.
|
package/DESIGN.md
CHANGED
|
@@ -38,7 +38,7 @@ Completion leaves the branch and worktree available. The lead recommends review,
|
|
|
38
38
|
|
|
39
39
|
Tasks normally follow `queued → preparing → running → verifying → completed/failed`. Dependencies, concurrency and ownership can retain `queued`. Questions or native screens produce `blocked`; pause produces `paused`. Cancel/redirect await an interrupted worker before acting. The revised objective fences obsolete reports immediately.
|
|
40
40
|
|
|
41
|
-
Before `tab.create`, the run is persisted as `creating
|
|
41
|
+
Before `tab.create` or `pane.split`, the run is persisted as `creating`, with the split target and pre-creation pane membership when applicable. Layout allocation is serialized per project; new workers share tabs only when all live members match saved pane-scoped run identities. Geometry and a four-pane cap determine whether to split or create another tab. Returned identifiers are saved before `agent.start`; the agent must become interactively ready before any task prompt is sent. `prompting` is persisted before `agent.prompt`. Native startup and input screens never trigger automatic approvals. The transport validates response IDs and handles fragmented NDJSON; loss before acknowledgement is treated as ambiguous.
|
|
42
42
|
|
|
43
43
|
A crash in `creating` or `prompting`, or while a control is `sending`, requires explicit reconciliation. A run in `starting` is inspected and continued in its existing pane. Running attempts reattach; verification safely reruns. Identity mismatch suspends control. This is conservative at-most-once automatic dispatch with visible uncertainty, not a claim of exactly-once external execution.
|
|
44
44
|
|
|
@@ -66,8 +66,8 @@ Lead wait delivery persists waiting, ready, sending, delivered or uncertain stat
|
|
|
66
66
|
|
|
67
67
|
## Resource retirement
|
|
68
68
|
|
|
69
|
-
The cleanup service separates run release from worktree delivery/archive/collection. Completed integrated outcomes enable conservative automatic
|
|
69
|
+
The cleanup service separates run release from worktree delivery/archive/collection. Completed integrated outcomes enable conservative automatic worker-pane release (legacy runs retain exclusive-tab release); failed/cancelled runs require inspection. Closure persists `closing → closed` or `uncertain`, pins the full native identity and original terminal, and never replays an ambiguous close. It does not close project sessions or workspaces.
|
|
70
70
|
|
|
71
71
|
Managed-checkout collection is disabled until explicitly requested or covered by an authorized retention policy. All tasks sharing the checkout are locked during inspection; task mutations, child submission, project registration and evidence assessment are fenced while cleanup awaits external reads. Archives seal terminal tasks and preserve file evidence, run diagnostics and a Git bundle. File writes and directory entries are flushed before committing the archive record. Collection verifies live files and archive digests before non-forced worktree removal. Original task references resolve to archived bytes only after recorded collection and actual checkout disappearance; tampering still invalidates acceptance. Delivery records retain pinned HEAD/target commits. Published branches can be collected later after a new merged delivery decision. Explicit abandonment retains a bundle before compare-and-delete of the exact branch tip. Partial Git operations preserve their phase and are explicitly inspectable/retryable.
|
|
72
72
|
|
|
73
|
-
Closing a native
|
|
73
|
+
Closing a native terminal and invoking Git have unavoidable external-process boundaries. Herdr protocol 20 has no atomic conditional-close operation; identity is checked immediately before the close, but operators must not repurpose a terminal concurrently with its cleanup. Git checks and branch-tip comparisons likewise do not replace coordination with external tools editing a checkout. Marionette fences its own concurrent mutations and refuses unsafe observed states.
|
package/ORCHESTRATION.md
CHANGED
|
@@ -114,9 +114,9 @@ Cleanup has five stages: verify the result, release execution resources, record
|
|
|
114
114
|
|
|
115
115
|
`cleanup.preview` takes `taskId` and returns run identities, cleanup states, blocking consumers, delivery, archive and project policy without deleting anything. The dashboard exposes these operations under **Delivery and cleanup** in task details. Every mutation requires the current lead `lease` and a meaningful `reason`.
|
|
116
116
|
|
|
117
|
-
- `cleanup.release` takes `taskId` and optional `runId`. After the lead has inspected the result and decided that no native continuation is needed, it preserves bounded output and closes the settled worker's
|
|
117
|
+
- `cleanup.release` takes `taskId` and optional `runId`. After the lead has inspected the result and decided that no native continuation is needed, it preserves bounded output and closes the settled worker's pane. Sibling panes stay open. Legacy runs without pane-scoped ownership retain exclusive single-pane tab release. The exact workspace, tab, pane, terminal, agent name/kind and native session must still match. Changed worker identities, busy agents, pending controls, lead waits, active dependent tasks and waiting parents prevent closure. Failed/cancelled results need this explicit inspection; their files remain intact.
|
|
118
118
|
- Automatic release defaults on and waits for a completed integrated outcome, a settled completed task, and no active consumers. It runs at most once per ten-second scan. Failed, blocked, paused, yielding and uncertain work stays available. A failed preflight is retained for inspection instead of being retried continuously.
|
|
119
|
-
- A close intent is durable before `tab.close
|
|
119
|
+
- A close intent is durable before `pane.close` (or `tab.close` for legacy runs). Lost acknowledgements or restart during closure become `uncertain` and never replay automatically. `cleanup.reconcile` takes `taskId`, optional `runId`, and `resolution: "closed" | "not-closed"`. Closed requires the original pane and terminal to be absent (also the tab for legacy runs); not-closed requires the original settled identity. A later explicit release can retry a reconciled retained terminal. Closing a tab manually is also recognized only after confirming the original terminal is absent.
|
|
120
120
|
- `cleanup.deliver` records `disposition: "merged" | "published" | "abandoned"` and, except for abandonment, `targetRef`. It performs no commit, merge, fetch or push. Supply a full branch ref such as `refs/heads/main`; published work requires a refreshed remote-tracking ref such as `refs/remotes/origin/review`. The clean worktree's HEAD must be an ancestor of that target. Local remote-tracking metadata must be refreshed using the normal Git workflow first. Squash/rebase integration without ancestry proof needs manual review; it is not inferred from similar content. Modified, untracked and ignored files block delivery and collection. Preserve or remove those files explicitly; collection never forces their removal.
|
|
121
121
|
- `cleanup.archive` seals all finished tasks sharing a managed checkout after every recorded worker terminal has been released and all live consumers have finished. Completed tasks require integrated outcome completion. It stores receipt artifacts, file-check evidence and referenced outcome evidence with SHA-256 digests, a manifest containing reports/checks/output and public run identity, and a standalone Git bundle retaining committed history, including abandoned unique commits. Files and directories are flushed before the durable archive record is committed. Archives live in `<state>/archives/<archive-id>` and remain private. Sealed tasks cannot resume or retry; create a new assignment for further work.
|
|
122
122
|
- `cleanup.collect` requires the preview's exact `archiveId`, `taskId`, and optional `deleteBranch` (default false). It rechecks archive integrity, original worker absence, all tasks/projects sharing the checkout, Git identity, clean files, delivery ancestry and unchanged evidence. It removes the worktree through non-forced `git worktree remove`. Merged branch deletion rechecks ancestry and compares the branch tip against the archived commit with `git update-ref -d REF EXPECTED_COMMIT`; a moved tip is retained and exposes a recoverable partial result. Explicit abandonment plus `deleteBranch: true` permits compare-and-delete of the exact archived branch tip after checking that no checkout uses it. Published PR branches remain until a subsequent merged or abandoned delivery decision. That decision and branch collection can happen after the worktree has already been removed.
|
package/README.md
CHANGED
|
@@ -3,276 +3,80 @@
|
|
|
3
3
|
[](https://github.com/theaileverage/marionette/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/@theaileverage/marionette)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Coordinate Codex, Claude Code, and AGY workers through one lead conversation. Workers run in Herdr; a persistent local supervisor shares task state across MCP, CLI, and a dashboard.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
- **Delegate work:** assign owned paths, dependencies, and acceptance checks; use a shared directory or isolated Git worktrees.
|
|
9
|
+
- **Verify outcomes:** require current evidence and independent checks before marking work complete.
|
|
10
|
+
- **Keep context:** preserve decisions, worker state, and an inbox across lead handovers and supervisor restarts.
|
|
11
|
+
- **Stay in control:** agents retain their normal permission policies; ambiguous deliveries require reconciliation before retrying.
|
|
11
12
|
|
|
12
13
|
## Quick start
|
|
13
14
|
|
|
14
|
-
Requires **
|
|
15
|
+
Requires **macOS or Linux**, **Bun 1.3.14+**, **Herdr** on PATH, and your chosen agent CLIs installed and signed in.
|
|
15
16
|
|
|
16
17
|
From your project directory:
|
|
17
18
|
|
|
18
19
|
```sh
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
The guided setup lets you choose **Codex desktop, Codex CLI, Claude Code, or AGY** as lead and give it any display name. It starts the supervisor, creates or reuses a named Herdr session and project workspace, registers AGY trust for the project, and adds Marionette MCP to the selected agent through its native CLI. No model subscriptions or agent CLIs are installed by Marionette.
|
|
23
|
-
|
|
24
|
-
For a terminal lead, run:
|
|
25
|
-
|
|
26
|
-
```sh
|
|
27
|
-
npx @theaileverage/marionette lead
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
For Codex desktop, refresh MCP in Settings, then give the lead the prompt file printed by setup. The prompt includes the project and private lease file path. The desktop conversation must read that local file to obtain its lease. `lead --print` prints the bootstrap instructions for any selected lead without launching an interactive agent.
|
|
31
|
-
|
|
32
|
-
Open the private dashboard URL printed by:
|
|
33
|
-
|
|
34
|
-
```sh
|
|
35
|
-
npx @theaileverage/marionette dashboard
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
To install the shorter `marionette` command globally, use `npm install -g @theaileverage/marionette`.
|
|
39
|
-
|
|
40
|
-
## Setup for agents and scripts
|
|
41
|
-
|
|
42
|
-
The wizard and non-interactive setup use the same implementation. `--yes` accepts defaults; `--json` returns a JSON result and never prompts. Errors return `{ "ok": false, "error": "..." }` with a nonzero exit status when `--json` is used. Unknown options and config keys are rejected.
|
|
43
|
-
|
|
44
|
-
```sh
|
|
45
|
-
npx @theaileverage/marionette setup --yes --json \
|
|
46
|
-
--project /absolute/project --lead claude --lead-name Ada
|
|
47
|
-
|
|
48
|
-
npx @theaileverage/marionette setup --config setup.json --json
|
|
49
|
-
npx @theaileverage/marionette setup --config setup.json --dry-run
|
|
50
|
-
npx @theaileverage/marionette setup --schema
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Example `setup.json`:
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"project": "/absolute/project",
|
|
58
|
-
"name": "My project",
|
|
59
|
-
"lead": "claude",
|
|
60
|
-
"leadName": "Ada",
|
|
61
|
-
"trustAgy": true,
|
|
62
|
-
"mcp": "install"
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Optional configuration: `home`, `port`, `session`, `socket`, `workspace`, and `takeover`. CLI equivalents include `--home`, `--port`, `--session`, `--socket`, `--workspace`, and `--takeover`. Use `--mcp print` to produce the install command and STDIO configuration without changing a client, or `--mcp skip` to manage the connection yourself. `--no-trust-agy` disables automatic AGY trust. `init` is an alias for `setup`.
|
|
67
|
-
|
|
68
|
-
Setup is repeatable: it reuses the project workspace and current saved lease. Non-interactive reruns retain the saved lead name, agent, trust preference, and MCP mode unless overridden. Changing a lead requires a handover or an explicit `--takeover`; active workers continue. If setup reports a partial failure, resolve the stated issue and rerun the same command. A leftover `setup.lock` after a crash contains its owner PID; remove it only after confirming that process is gone.
|
|
69
|
-
|
|
70
|
-
AGY trust adds the exact canonical project directory to `~/.gemini/antigravity-cli/settings.json` under `trustedWorkspaces`. When enabled, each AGY worker's validated task directory is also registered before launch. Existing JSON settings, trusted roots, and file permissions are retained. This does not enable blanket tool approvals. Already-running AGY sessions may need restarting to read the setting. `MARIONETTE_AGY_SETTINGS` can select a separate settings file for tests.
|
|
71
|
-
|
|
72
|
-
## Local state and lifecycle
|
|
73
|
-
|
|
74
|
-
Default state lives in `$XDG_DATA_HOME/marionette` or `~/.local/share/marionette`. The project gets a private `.marionette/project.json` binding and a local ignore file. Commands inside that project discover its state directory, including from subdirectories. `--home` or `MARIONETTE_HOME` overrides discovery. Existing project-local `.marionette/config.json` installations remain discoverable.
|
|
75
|
-
|
|
76
|
-
The executable bundles and dashboard are copied into a versioned runtime below the state directory. Background supervisors, worker report commands, and MCP registrations use those durable paths and survive npm cache deletion. The npm package has no runtime npm dependencies or install hooks. New installations select a free loopback port starting at 4380; an explicit occupied port fails. Existing instance ports are preserved.
|
|
77
|
-
|
|
78
|
-
```sh
|
|
79
|
-
npx @theaileverage/marionette doctor
|
|
80
|
-
npx @theaileverage/marionette stop
|
|
81
|
-
npx @theaileverage/marionette start
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
`start` launches a detached supervisor; `serve` runs it in the foreground. Closing a lead or dashboard leaves it running. `stop` drains operations and preserves Herdr workers. After reboot, restart the selected Herdr session and Marionette manually. No login item is installed. Setup does not replace a running supervisor with a newer build: after an upgrade, stop and start it, then rerun setup to refresh MCP paths. Old versioned runtimes remain available to existing workers.
|
|
85
|
-
|
|
86
|
-
The dashboard binds only to `127.0.0.1`. Its private URL contains a fragment token, removed from the address bar after loading. Keep that link and lead lease files private. MCP registrations use an instance-specific name, such as `marionette-ab12cd34`, to preserve other installations.
|
|
87
|
-
|
|
88
|
-
## Develop from source
|
|
89
|
-
|
|
90
|
-
```sh
|
|
91
|
-
npm ci
|
|
92
|
-
npm run check
|
|
93
|
-
npm test
|
|
94
|
-
npm run build
|
|
95
|
-
node dist/cli.js setup
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
`npm pack` checks, tests, builds, and produces the same allowlisted tarball used for publishing. Only the bundled CLI/MCP executable, built dashboard, package metadata, and documentation are distributed; local state, logs, credentials, test artifacts, and source fixtures are excluded.
|
|
99
|
-
|
|
100
|
-
## Connect Herdr explicitly
|
|
101
|
-
|
|
102
|
-
Open or create the intended **named** session with Herdr's normal interface. Inspect the installed CLI using `herdr --help` and `herdr workspace` before choosing or creating a workspace. Marionette does not assume the focused pane, attach to the default session, or fabricate `HERDR_ENV`.
|
|
103
|
-
|
|
104
|
-
In **Connection → Connect a project**, supply the absolute project root, session name, absolute socket path, and workspace ID. The usual macOS socket path is `~/.config/herdr/sessions/SESSION/herdr.sock`; verify the actual path for your Herdr configuration. An existing workspace is required for this manual registration path; guided setup creates one. The default concurrency is three.
|
|
105
|
-
|
|
106
|
-
CLI equivalent, saved as `register.json` with your actual values:
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"name": "My project",
|
|
111
|
-
"root": "/absolute/project",
|
|
112
|
-
"session": "project-work",
|
|
113
|
-
"socketPath": "/Users/you/.config/herdr/sessions/project-work/herdr.sock",
|
|
114
|
-
"workspaceId": "w1",
|
|
115
|
-
"maxConcurrency": 3
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
```sh
|
|
120
|
-
node dist/cli.js call project.register --file register.json
|
|
121
|
-
node dist/cli.js projects
|
|
20
|
+
bunx --bun @theaileverage/marionette setup
|
|
122
21
|
```
|
|
123
22
|
|
|
124
|
-
|
|
23
|
+
You can also use `npx @theaileverage/marionette setup`. Bun must still be installed and on PATH; `npx` downloads the package but does not install Bun.
|
|
125
24
|
|
|
126
|
-
|
|
25
|
+
Setup starts the supervisor, connects a named Herdr session and project workspace, and configures MCP for your chosen lead: Codex desktop, Codex CLI, Claude Code, or AGY.
|
|
127
26
|
|
|
128
|
-
|
|
27
|
+
For a terminal lead:
|
|
129
28
|
|
|
130
29
|
```sh
|
|
131
|
-
|
|
30
|
+
bunx --bun @theaileverage/marionette lead
|
|
132
31
|
```
|
|
133
32
|
|
|
134
|
-
|
|
33
|
+
For Codex desktop, refresh MCP in Settings and give your conversation the prompt file printed by setup.
|
|
135
34
|
|
|
136
35
|
```sh
|
|
137
|
-
|
|
36
|
+
bunx --bun @theaileverage/marionette dashboard # Print the private dashboard URL
|
|
37
|
+
bunx --bun @theaileverage/marionette doctor # Diagnose connections
|
|
138
38
|
```
|
|
139
39
|
|
|
140
|
-
|
|
40
|
+
For scripted setup, use `setup --yes --json`; `setup --help` and `setup --schema` describe the available options. Install globally with `bun add --global @theaileverage/marionette` for the shorter `marionette` command.
|
|
141
41
|
|
|
142
|
-
|
|
42
|
+
## How it runs
|
|
143
43
|
|
|
144
|
-
|
|
44
|
+
The supervisor keeps working when you close the lead or dashboard. `stop` drains operations and preserves Herdr workers; `start` resumes the supervisor. Task completion preserves branches and worktrees until explicit delivery and cleanup.
|
|
145
45
|
|
|
146
|
-
|
|
46
|
+
State defaults to `~/.local/share/marionette` (or `$XDG_DATA_HOME/marionette`), with a project-local binding. Keep dashboard links and lease files private.
|
|
147
47
|
|
|
148
|
-
|
|
48
|
+
Herdr leads can resume from meaningful worker events. **Idle Codex desktop conversations resume on your next message**; the dashboard and durable inbox retain updates meanwhile.
|
|
149
49
|
|
|
150
|
-
|
|
50
|
+
## Agent skill and SDK
|
|
151
51
|
|
|
152
|
-
|
|
52
|
+
Copy [skills/marionette](skills/marionette/SKILL.md) into your agent's skill directory for coordination and recovery guidance.
|
|
153
53
|
|
|
154
|
-
|
|
54
|
+
The dependency-free Herdr SDK provides typed requests, event subscriptions, and graphics streams:
|
|
155
55
|
|
|
156
|
-
|
|
56
|
+
```js
|
|
57
|
+
import { HerdrClient } from '@theaileverage/marionette/herdr-sdk';
|
|
157
58
|
|
|
158
|
-
|
|
159
|
-
|
|
59
|
+
const herdr = HerdrClient.fromEnv(); // Inside a Herdr-managed environment
|
|
60
|
+
const { panes } = await herdr.pane.list(process.env.HERDR_WORKSPACE_ID);
|
|
160
61
|
```
|
|
161
62
|
|
|
162
|
-
|
|
163
|
-
- Use `{ "mode": "worktree" }` for Marionette to create a new branch and full Git checkout before launching the worker. `baseRef` is optional; the default is the source checkout's committed `HEAD` when preparation begins. Marionette resolves it to a commit once and persists it before creation. It never copies uncommitted or untracked source files.
|
|
164
|
-
- `cwd` still identifies the source working directory. For a monorepo subdirectory, Marionette uses the corresponding directory in the new checkout. Ownership and file checks must be relative paths and are validated again after relocation. A source directory missing from the selected revision fails preparation.
|
|
165
|
-
- Each managed task gets branch `marionette/<task-id>` and a checkout under `<instance-state-directory>/worktrees/<project-id>/<task-id>`. `task.worktree` exposes its state, path, branch, pinned base commit, source directory, and repository identity. `task.cwd` becomes the actual worker directory. The dashboard shows the execution choice and these details.
|
|
166
|
-
- Independent worktrees can edit the same repository files concurrently. Ownership remains a filesystem-path contract; it does not predict merge conflicts or protect shared external resources. Dependencies wait for completion but do not merge another task's changes into a worktree. Select an appropriate committed base when one task needs another's result.
|
|
167
|
-
- Worktree creation requires an existing Git repository and a valid commit. Failure starts no worker and never falls back silently to the shared checkout. Git hooks are disabled for supervisor worktree operations; dependency installation, submodule initialization, and other project setup remain explicit task instructions.
|
|
168
|
-
|
|
169
|
-
After verification, the lead recommends a next step and asks the user to choose unless already authorized: review locally, merge, or push the task branch and open a PR through the user's Git hosting workflow. Marionette retains the branch and worktree on completion, failure, and cancellation. It does not automatically commit, publish, or merge; the separate delivery/archive/cleanup lifecycle governs later removal. Ordinary Git and PR tools can operate in `task.cwd`. Retries reuse the same worktree and preserve worker commits and uncommitted changes.
|
|
63
|
+
See the [SDK guide](skills/marionette/references/herdr-sdk.md). Use Marionette task APIs to manage workers; direct SDK calls do not create assignments.
|
|
170
64
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
CLI example after obtaining a project ID and fresh briefing:
|
|
65
|
+
## Development
|
|
174
66
|
|
|
175
67
|
```sh
|
|
176
|
-
|
|
177
|
-
|
|
68
|
+
bun install --frozen-lockfile
|
|
69
|
+
bun run check
|
|
70
|
+
bun run test
|
|
71
|
+
bun run build
|
|
178
72
|
```
|
|
179
73
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
```json
|
|
183
|
-
{
|
|
184
|
-
"assignment": {
|
|
185
|
-
"projectId": "PROJECT_ID",
|
|
186
|
-
"key": "settings-screen-v1",
|
|
187
|
-
"title": "Build the settings screen",
|
|
188
|
-
"workstream": "Product",
|
|
189
|
-
"kind": "codex",
|
|
190
|
-
"prompt": "Build the settings screen and its behavior tests. You own only src/settings and tests/settings. Preserve other work.",
|
|
191
|
-
"ownership": ["src/settings", "tests/settings"],
|
|
192
|
-
"dependencies": [],
|
|
193
|
-
"checks": [
|
|
194
|
-
{ "type": "file", "path": "src/settings/index.tsx", "contains": "Settings" },
|
|
195
|
-
{
|
|
196
|
-
"type": "command",
|
|
197
|
-
"command": "npm",
|
|
198
|
-
"args": ["test", "--", "tests/settings"],
|
|
199
|
-
"timeoutMs": 30000
|
|
200
|
-
}
|
|
201
|
-
],
|
|
202
|
-
"maxAttempts": 2
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
```sh
|
|
208
|
-
node dist/cli.js call task.submit --file assignment.json --lease /private/tmp/marionette-lead.json
|
|
209
|
-
node dist/cli.js call task.get --json '{"taskId":"TASK_ID"}'
|
|
210
|
-
node dist/cli.js inbox PROJECT_ID --consumer desktop-lead
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Submission persists and returns without waiting for startup. Reuse the **same idempotency key and identical input** after a lost response. Reusing a key for different intent is rejected. Redirects and controls also require their own keys.
|
|
214
|
-
|
|
215
|
-
```sh
|
|
216
|
-
node dist/cli.js call task.control --lease /private/tmp/marionette-lead.json --json '{"taskId":"TASK_ID","key":"answer-currency-v1","type":"reply","text":"Use INR."}'
|
|
217
|
-
node dist/cli.js call decision.record --lease /private/tmp/marionette-lead.json --json '{"text":"Use INR throughout billing.","rationale":"Confirmed with the operator."}'
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
`redirect` replaces the objective and invalidates old reports. The MCP/CLI accepts replacement `checks`; dashboard redirects retain the displayed checks. `pause` interrupts and waits for the agent to settle. `reply` resumes a paused assignment or answers a blocked worker. `cancel` stops the task without closing its tab. Native permission dialogs require inspecting the actual output and resolving the specific prompt in Herdr or sending explicit keys through the dashboard. Marionette does not auto-approve permissions. If interruption does not settle within 30 seconds, the control fails visibly so the lead can resolve the native screen.
|
|
221
|
-
|
|
222
|
-
Workers receive an attempt-scoped report credential through their new pane environment. The supplied instructions explain `worker-report --file REPORT.json`, including revision, summary, artifact paths, and evidence. Credentials are not included in briefings. Workers must request normal sandbox approval if their report command needs permission to reach the local supervisor.
|
|
223
|
-
|
|
224
|
-
## Delivery and cleanup
|
|
225
|
-
|
|
226
|
-
Version 0.2.1 separates terminal release from delivery and Git cleanup. After integrated outcome completion, the supervisor can save worker diagnostics and close an eligible settled worker tab automatically. Failed/cancelled work needs explicit inspection; blocked, paused, waiting and uncertain workers stay intact.
|
|
227
|
-
|
|
228
|
-
Task completion preserves branches and worktrees. Use the task drawer's **Delivery and cleanup** panel or `cleanup.preview`, `cleanup.release`, `cleanup.deliver`, `cleanup.archive`, and `cleanup.collect` through CLI/MCP. Record merged, published or explicitly abandoned work, preserve evidence and committed history, then collect only the exact eligible checkout. A published PR branch stays available for later review and merge. Archives preserve completion evidence after the worktree is removed.
|
|
229
|
-
|
|
230
|
-
Automatic worktree collection is disabled by default. `cleanup.configure` can authorize a retention delay and optional merged-branch deletion. Dirty/untracked/ignored files, active consumers, changed resource identities and ambiguous operations prevent removal. Project Herdr sessions and workspaces remain. See [the full cleanup contract](ORCHESTRATION.md#delivery-archival-and-cleanup-in-021) for safeguards, recovery, and API inputs.
|
|
231
|
-
|
|
232
|
-
## Handover
|
|
233
|
-
|
|
234
|
-
`lead_handover` transfers control atomically and returns the receiving lead's lease and a current briefing. The previous owner/token/epoch immediately stops authorizing writes; existing workers continue.
|
|
235
|
-
|
|
236
|
-
```sh
|
|
237
|
-
node dist/cli.js call lead.handover --lease /private/tmp/marionette-lead.json --json '{"toOwner":"terminal-lead","reason":"Continue inside Herdr"}' --save-lease /private/tmp/marionette-terminal-lead.json
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
Give the receiving lead the private lease file path. It reads the same briefing and inbox through MCP or CLI and uses the handed-over lease. Dashboard handover downloads this file and relinquishes its control. If the old lead is unavailable, explicitly take over with `lead_acquire`, the latest `expectedEpoch`, `takeover: true`, and a reason. This is a visible fenced takeover, not an automatic lease expiry.
|
|
241
|
-
|
|
242
|
-
## Completion and notifications
|
|
243
|
-
|
|
244
|
-
Completion requires a current-revision worker receipt, a settled worker identity, and independent checks. File checks verify regular-file presence, optional content/hash, and a changed digest from dispatch unless `allowUnchanged: true`. Command checks run without a shell, with bounded time/output and process-group termination on timeout. Reported artifacts must belong to the assignment. A worker saying “done,” a green terminal status, or its own claimed test result does not independently pass verification.
|
|
245
|
-
|
|
246
|
-
**An MCP server does not automatically wake an idle Codex desktop conversation.** Marionette uses a durable per-consumer inbox and a dashboard that polls every two seconds. While the dashboard is open, new completion/failure/question events produce visible alerts. Optional browser/OS notifications require **Desktop alerts** permission and an open dashboard. Browser closure does not lose the events; opening the inbox later retrieves unacknowledged events. MCP clients read on subsequent turns. No background conversation injection or desktop automation is installed.
|
|
247
|
-
|
|
248
|
-
The inbox displays up to 200 unacknowledged events per page. Marking them read advances only that dashboard's cursor; repeated acknowledgement exposes the next page. New-event alert polling is independent of this backlog. Other consumers retain their own cursors.
|
|
249
|
-
|
|
250
|
-
## Recovery and operating boundaries
|
|
251
|
-
|
|
252
|
-
- Restarting the supervisor reattaches using the saved workspace, terminal, agent name/kind, and native session identity. It does not repeat a prompt because a socket disconnected.
|
|
253
|
-
- A crash during pane creation, prompt delivery, or control delivery produces an `uncertain` task. Inspect the original pane and use `task_reconcile` with `delivered` or `not-delivered` and actual evidence. Do not guess. No automatic replay occurs.
|
|
254
|
-
- If creation lost its acknowledgement, no task prompt was attempted. `not-delivered` reconciliation checks for an absent tab or one matching untouched shell. An occupied or ambiguous tab is refused. Original tabs are retained. If the identity cannot be established, resolve the named pane/session through Herdr before retrying.
|
|
255
|
-
- A crash during startup blocks for inspection and continuation of the existing pane. Restart during verification reruns checks. Design checks to be safe to repeat; Marionette cannot make arbitrary commands transactional.
|
|
256
|
-
- Retries require a failed/cancelled task and a settled previous worker, and consume the assignment's maximum of one to three attempts. They are explicit, never automatic for ambiguous work.
|
|
257
|
-
- Managed worktree creation persists `planned → creating → ready` before worker launch. Restart reuses a matching registered checkout. A creation interrupted before `ready` is reused only if clean at the pinned base; missing, incomplete, or mismatched checkouts fail preparation for inspection without reset, pruning, or destructive recreation. Once ready, retries preserve edits. An interrupted creation that cannot be validated requires manual inspection and repair or a new assignment.
|
|
258
|
-
- Ownership is a scheduling and reporting contract, **not an OS filesystem sandbox**. Agents retain their normal CLI permissions. Use isolated worktrees and each agent's permission controls where stronger isolation is required. Verification commands are trusted lead-selected local code.
|
|
259
|
-
- Marionette is a single-user local product. It does not provide remote multi-user authentication, deployment, billing, automatic Git merges, or session cleanup. Preserve existing Herdr sessions and use explicit project connections.
|
|
260
|
-
|
|
261
|
-
Private instance data is under `.marionette/`: configuration/token, SQLite WAL state, supervisor PID lock, and log. Stop the supervisor before making a consistent file backup of this directory. Keep the entire directory private. The repository ignores it, dependencies, build outputs, and `.runtime/` test artifacts. Do not remove state to resolve a connection problem.
|
|
262
|
-
|
|
263
|
-
## Development and verification
|
|
264
|
-
|
|
265
|
-
```sh
|
|
266
|
-
npm run check
|
|
267
|
-
npm test
|
|
268
|
-
npm run build
|
|
269
|
-
npm run format:check
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
The tests use isolated temporary databases and a labeled Herdr protocol double for deterministic failure injection, plus real Unix-socket transport and HTTP/STDIO MCP integration. They do not start paid agent work. The test runner needs permission to listen on local sockets.
|
|
273
|
-
|
|
274
|
-
See [VERIFICATION.md](VERIFICATION.md) for the real three-agent acceptance evidence, browser results, and tested versions. [DESIGN.md](DESIGN.md) describes persistence, state transitions, and trust boundaries. `scripts/live-validation.mjs` inspects the opt-in live fixture retained on this machine; `start` intentionally refuses to duplicate an existing exercise. Its real results and private leases remain in `.runtime/`.
|
|
74
|
+
The source uses Effect v4, TypeScript diagnostics from `@effect/tsgo`, and anti-slop lint rules. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, checks, and the Effect skill.
|
|
275
75
|
|
|
276
|
-
##
|
|
76
|
+
## Documentation
|
|
277
77
|
|
|
278
|
-
|
|
78
|
+
- [Orchestration](ORCHESTRATION.md) — outcomes, models, task trees, handovers, and cleanup
|
|
79
|
+
- [Agent guide](skills/marionette/SKILL.md) — setup, assignments, controls, and recovery
|
|
80
|
+
- [Design](DESIGN.md) — persistence and trust boundaries
|
|
81
|
+
- [Verification](VERIFICATION.md) — tested behavior and operating limits
|
|
82
|
+
- [Changelog](CHANGELOG.md) · [Releases](RELEASING.md) · [MIT license](LICENSE)
|
package/RELEASING.md
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
1
|
# Releasing Marionette
|
|
2
2
|
|
|
3
|
-
The public repository is [theaileverage/marionette](https://github.com/theaileverage/marionette). Source changes go through pull requests into `main`. GitHub Actions runs formatting, metadata validation, type checks, tests, a production build and an installed-package smoke test on Linux and macOS with
|
|
3
|
+
The public repository is [theaileverage/marionette](https://github.com/theaileverage/marionette). Source changes go through pull requests into `main`. GitHub Actions runs formatting, metadata validation, type checks, tests, a production build and an installed-package smoke test on Linux and macOS with the pinned Bun runtime. These checks use protocol fixtures, not paid agent sessions.
|
|
4
4
|
|
|
5
5
|
## Prepare a version
|
|
6
6
|
|
|
7
7
|
From a clean checkout, create a branch and run:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
git switch -c release/0.
|
|
11
|
-
|
|
10
|
+
git switch -c release/0.3.0
|
|
11
|
+
bun run release:prepare 0.3.0
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
The helper updates `package.json`, `
|
|
14
|
+
The helper updates `package.json`, `src/version.ts` and a dated changelog section. The dependency-only `bun.lock` does not need a version bump. Replace the placeholder with concrete release notes. Do not change the setup protocol number unless the protocol changes. Update verification evidence when behavior changes, then run:
|
|
15
15
|
|
|
16
16
|
```sh
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
bun run format
|
|
18
|
+
bun run release:check
|
|
19
|
+
bun pm pack --destination /private/tmp
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Commit the release preparation and open a pull request. `Required CI` must pass before merging. A tag must point at a commit contained in `main`; it must exactly match the package,
|
|
22
|
+
Commit the release preparation and open a pull request. `Required CI` must pass before merging. A tag must point at a commit contained in `main`; it must exactly match the package, runtime version and changelog. Stable versions go to npm `latest`; prereleases such as `0.3.0-beta.1` go to `next`.
|
|
23
23
|
|
|
24
24
|
## Publish the merged version
|
|
25
25
|
|
|
26
26
|
```sh
|
|
27
27
|
git switch main
|
|
28
28
|
git pull --ff-only
|
|
29
|
-
git tag -a v0.
|
|
30
|
-
git push origin v0.
|
|
29
|
+
git tag -a v0.3.0 -m 'Release 0.3.0'
|
|
30
|
+
git push origin v0.3.0
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
Node and npm remain isolated to the npm OIDC publishing step; application builds, tests, and package smoke checks run on Bun.
|
|
34
|
+
|
|
33
35
|
The `Release` workflow rebuilds and verifies the package, publishes the tested tarball using npm OIDC, compares the registry integrity, then creates a GitHub release with the tarball and `SHA256SUMS`. It uses pinned official actions, read-only checkout credentials, a dedicated `npm` environment, and an explicitly scoped OIDC permission. No npm token is stored in GitHub.
|
|
34
36
|
|
|
35
37
|
If a run fails after npm publication, rerun the failed job. Existing package integrity must match before the workflow continues; it never overwrites an npm version or a differing GitHub asset. You can also dispatch on the existing tag:
|
|
36
38
|
|
|
37
39
|
```sh
|
|
38
|
-
gh workflow run release.yml --ref v0.
|
|
40
|
+
gh workflow run release.yml --ref v0.3.0 -f tag=v0.3.0
|
|
39
41
|
```
|
|
40
42
|
|
|
41
43
|
Do not move or delete published tags. Fix a bad release with a new version. Registry publication is irreversible in the usual release workflow; removing a GitHub release does not remove its npm package.
|