playmakerlabs 0.0.0-stage → 0.1.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/.claude-plugin/marketplace.json +14 -0
- package/.claude-plugin/plugin.json +29 -0
- package/LICENSE +21 -0
- package/README.md +256 -2
- package/cli/playmaker.mjs +126 -0
- package/hooks/hooks.json +30 -0
- package/package.json +45 -4
- package/scripts/board.mjs +422 -0
- package/scripts/detect-agents.mjs +74 -0
- package/scripts/lib/launch.mjs +114 -0
- package/scripts/lib/providers.mjs +76 -0
- package/scripts/lib/util.mjs +118 -0
- package/scripts/spawn.mjs +204 -0
- package/scripts/status.mjs +84 -0
- package/scripts/task-watch.mjs +57 -0
- package/skills/orchestrate/SKILL.md +96 -0
- package/skills/orchestrate/references/board.md +81 -0
- package/skills/orchestrate/references/brief-template.md +47 -0
- package/skills/orchestrate/references/coordination.md +61 -0
- package/skills/orchestrate/references/providers.md +28 -0
- package/skills/run/SKILL.md +78 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sinteselabs-playmaker",
|
|
3
|
+
"description": "Playmaker: parallel multi-agent orchestration for Claude Code, by Síntese Labs.",
|
|
4
|
+
"owner": {
|
|
5
|
+
"name": "Síntese Labs"
|
|
6
|
+
},
|
|
7
|
+
"plugins": [
|
|
8
|
+
{
|
|
9
|
+
"name": "playmaker",
|
|
10
|
+
"source": "./",
|
|
11
|
+
"description": "Offers to run parallel work with the agent CLIs you already have installed, and coordinates the workers through git worktrees and Lore."
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "playmaker",
|
|
3
|
+
"displayName": "Playmaker",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Notices when there is enough parallelizable work, offers to run it with the agent CLIs you already have installed (Claude Code, Codex, Gemini/Antigravity, Copilot), and coordinates the workers through git worktrees and Lore.",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Síntese Labs"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/sinteselabs/Playmaker",
|
|
10
|
+
"repository": "https://github.com/sinteselabs/Playmaker",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": ["multi-agent", "orchestration", "parallel", "worktree", "lore"],
|
|
13
|
+
"userConfig": {
|
|
14
|
+
"proactive": {
|
|
15
|
+
"type": "boolean",
|
|
16
|
+
"title": "Proactive offers",
|
|
17
|
+
"description": "Let Playmaker nudge Claude to offer parallel execution when many tasks are open. Turn off to use only the /playmaker:orchestrate skill on demand.",
|
|
18
|
+
"default": true
|
|
19
|
+
},
|
|
20
|
+
"min_tasks": {
|
|
21
|
+
"type": "number",
|
|
22
|
+
"title": "Open tasks before nudging",
|
|
23
|
+
"description": "How many open tasks in the session task list trigger the nudge.",
|
|
24
|
+
"default": 4,
|
|
25
|
+
"min": 2,
|
|
26
|
+
"max": 20
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Síntese Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,257 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# 🎯 Playmaker
|
|
4
|
+
|
|
5
|
+
> **Your agent notices when the work can run in parallel, and offers to manage it.**
|
|
6
|
+
|
|
7
|
+
A plugin and a set of skills that turn the agent you are talking to into the
|
|
8
|
+
manager of a parallel run: it proposes the split, you approve, and workers run
|
|
9
|
+
on the agent CLIs you already have installed and signed in (Claude Code, Codex,
|
|
10
|
+
Gemini, Antigravity, Copilot), each in its own git worktree and branch.
|
|
11
|
+
|
|
12
|
+
[](https://www.npmjs.com/package/playmakerlabs)
|
|
13
|
+
[](LICENSE)
|
|
14
|
+
[](package.json)
|
|
15
|
+
[](https://agentskills.io)
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Who talks to whom
|
|
22
|
+
|
|
23
|
+
Only the manager talks to the workers, and only through two things: the brief
|
|
24
|
+
it hands out and the report it gets back. Workers do not talk to each other and
|
|
25
|
+
do not talk to you. The manager talks to you when it makes the offer, when it
|
|
26
|
+
needs a decision, and when everything is finished.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
you <-> manager (Playmaker) -> worker A (worktree + branch)
|
|
30
|
+
-> worker B (worktree + branch)
|
|
31
|
+
-> worker C (worktree + branch)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## What it does
|
|
35
|
+
|
|
36
|
+
**Notices.** A hook counts the open tasks in the session (`TaskCreate`,
|
|
37
|
+
`TaskUpdate`, `TodoWrite`). Past a threshold (4 by default) it adds one short,
|
|
38
|
+
factual note to the context. That is only a nudge. The `orchestrate` skill
|
|
39
|
+
decides whether a parallel run is worth it, and it also triggers on its own when
|
|
40
|
+
you talk about parallel agents, multi-agent work or orchestration.
|
|
41
|
+
|
|
42
|
+
**Offers, once.** The skill checks that the tasks are independent (different
|
|
43
|
+
files, clear dependencies, big enough to be worth a worker). If they are, it
|
|
44
|
+
sends one message with the split, a suggested provider per task, the cost, the
|
|
45
|
+
merge policy (automatic when the gates pass, or ask before each merge) and
|
|
46
|
+
whether the run is autonomous. Nothing starts without your "yes", unless you
|
|
47
|
+
already said "parallel run". If you say no, it drops that plan.
|
|
48
|
+
|
|
49
|
+
**Builds the board.** `.playmaker/board.json` holds the tasks, the files each
|
|
50
|
+
one owns (`owns`), dependencies, shared files, exclusive resources and the
|
|
51
|
+
project's gates.
|
|
52
|
+
|
|
53
|
+
**Runs the loop (the `run` skill).**
|
|
54
|
+
|
|
55
|
+
1. `board ready` computes the batch: tasks whose dependencies are merged and
|
|
56
|
+
that collide with nothing running (files, shared files, resources), up to the
|
|
57
|
+
worker cap (4 by default).
|
|
58
|
+
2. `board start` creates one worktree and branch per task and starts each worker
|
|
59
|
+
in the background.
|
|
60
|
+
3. `board wait` runs in the background. When a worker delivers or fails, the
|
|
61
|
+
agent is woken up.
|
|
62
|
+
4. The manager reads the report, checks the real diff and runs
|
|
63
|
+
`board integrate`: rebase on the current base, gates run by the manager
|
|
64
|
+
itself, fast-forward merge, status `To test`, worktree and branch removed.
|
|
65
|
+
5. If that fails, the task goes back for rework with the reason in its brief.
|
|
66
|
+
After two failed rounds it is parked as `ReFix`, and the manager does not try
|
|
67
|
+
to fix it.
|
|
68
|
+
6. A delivery unblocks new tasks, which start right away. When nothing is
|
|
69
|
+
running or ready, the manager gives you the final report (and sends a push
|
|
70
|
+
notification if the tool is available).
|
|
71
|
+
|
|
72
|
+
The manager never implements a delegated task. Only the manager merges. Only
|
|
73
|
+
you promote a task to `Done`: `board set <task> done` requires
|
|
74
|
+
`--confirmed-by-user`.
|
|
75
|
+
|
|
76
|
+
**Two lighter tiers**, when a board is overkill: native subagents (Claude only,
|
|
77
|
+
no board) and agent teams (Claude Code teammates that message each other,
|
|
78
|
+
experimental, needs `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`).
|
|
79
|
+
|
|
80
|
+
## What the tools already do, and what Playmaker adds
|
|
81
|
+
|
|
82
|
+
The native multi-agent features start agents of their own provider: Codex
|
|
83
|
+
subagents inherit the session's provider, and Claude Code agent teams only start
|
|
84
|
+
Claude teammates. With Bash allowed, either one can call another CLI and use it
|
|
85
|
+
as a worker. Playmaker does not create that ability, it organises it: a task
|
|
86
|
+
board, collision-free batches, one worktree and branch per worker, background
|
|
87
|
+
execution, gates run by the manager, merges that never rewrite history, retries
|
|
88
|
+
and `ReFix`.
|
|
89
|
+
|
|
90
|
+
## Quick start
|
|
91
|
+
|
|
92
|
+
Requires Node 22 or newer and git.
|
|
93
|
+
|
|
94
|
+
### 1. Claude Code plugin (recommended)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
claude plugin marketplace add sinteselabs/Playmaker
|
|
98
|
+
claude plugin install playmaker@sinteselabs-playmaker
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
From inside a session: `/plugin marketplace add sinteselabs/Playmaker`, then
|
|
102
|
+
`/plugin install playmaker@sinteselabs-playmaker`. This is the only way that
|
|
103
|
+
brings the hooks, so it is the only way the agent offers a parallel run on its
|
|
104
|
+
own.
|
|
105
|
+
|
|
106
|
+
On install it asks two things (also under `/config`):
|
|
107
|
+
|
|
108
|
+
- **Proactive offers**: turns the automatic nudge on or off. With it off the
|
|
109
|
+
skills still work on demand (`/playmaker:orchestrate`, `/playmaker:run`).
|
|
110
|
+
- **Open tasks before nudging**: how many open tasks trigger the note (2 to 20).
|
|
111
|
+
|
|
112
|
+
### 2. claude.ai, the desktop app and Cowork
|
|
113
|
+
|
|
114
|
+
Open **[Customize → Plugins](https://claude.ai/customize/plugins)**, then
|
|
115
|
+
**Add → Add marketplace**, and paste:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
sinteselabs/Playmaker
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 3. The CLI, in one project folder
|
|
122
|
+
|
|
123
|
+
For Codex, Antigravity or any agent that reads skills from the project:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx playmakerlabs init
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
It copies the two skills as `playmaker-orchestrate` and `playmaker-run` into
|
|
130
|
+
`.claude/skills/` and `.agents/skills/` (`--agent claude|codex|antigravity` for
|
|
131
|
+
one only, `--dry-run` to see what it would write). It never overwrites a file
|
|
132
|
+
that is already there. The copies call the board through
|
|
133
|
+
`npx playmakerlabs@<version>`, pinned to the version that wrote them. Hooks are
|
|
134
|
+
a Claude Code plugin feature, so with the CLI the skills work on demand only.
|
|
135
|
+
|
|
136
|
+
## Board commands
|
|
137
|
+
|
|
138
|
+
From the plugin they are `node "${CLAUDE_PLUGIN_ROOT}/scripts/board.mjs" ...`;
|
|
139
|
+
from the CLI, `npx playmakerlabs board ...`.
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
board validate checks the board (ids, deps, cycles, ownership collisions)
|
|
143
|
+
board show [--json] state of every task
|
|
144
|
+
board ready [--json] what runs now, and why the rest is held
|
|
145
|
+
board start [--dry-run] starts the batch
|
|
146
|
+
board wait [--timeout-min N] waits for a delivery or a failure (run it in the background)
|
|
147
|
+
board integrate <task> rebase, gates, ff-only merge
|
|
148
|
+
board set <task> <status> [--note ".."] [--confirmed-by-user]
|
|
149
|
+
board report [--json] summary for the final report
|
|
150
|
+
status [run] [--json] [--overlap] per-worker view
|
|
151
|
+
detect which agent CLIs are installed
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The board format is in
|
|
155
|
+
[`skills/orchestrate/references/board.md`](skills/orchestrate/references/board.md).
|
|
156
|
+
Statuses: Not started, In progress, To test, ReFix, Done, Postpone, plus
|
|
157
|
+
`delivered` (worker finished, not integrated yet) and `rework` (failed round,
|
|
158
|
+
will be retried).
|
|
159
|
+
|
|
160
|
+
`spawn --plan plan.json` is still there as a single-batch launcher, with no
|
|
161
|
+
board and no integration (at most 6 workers).
|
|
162
|
+
|
|
163
|
+
## Safety that is already in the code
|
|
164
|
+
|
|
165
|
+
- **No CLI starts with a bypass flag**: no `--yolo`,
|
|
166
|
+
`--dangerously-skip-permissions`, `danger-full-access` or `--allow-all-tools`.
|
|
167
|
+
Each CLI's default mode lets the worker edit files in its worktree. If you want
|
|
168
|
+
one of those flags for a task, you name it and it goes in that task's
|
|
169
|
+
`extraArgs`.
|
|
170
|
+
- **30-minute timeout per worker**, configurable per board and per task.
|
|
171
|
+
- **Integration refuses to run** if the main worktree is not on the base branch
|
|
172
|
+
or has uncommitted changes.
|
|
173
|
+
- **The brief never goes on the command line**, only a short prompt telling the
|
|
174
|
+
worker to read `.playmaker/brief.md`. That avoids quoting and length problems
|
|
175
|
+
on Windows.
|
|
176
|
+
- **Everything lives in `.playmaker/`**, excluded from git through
|
|
177
|
+
`.git/info/exclude`. No worktree or branch is left behind after a merge.
|
|
178
|
+
- **Nothing is pushed** to a remote unless you ask.
|
|
179
|
+
|
|
180
|
+
The command line of each CLI and its caveats are in
|
|
181
|
+
[`skills/orchestrate/references/providers.md`](skills/orchestrate/references/providers.md).
|
|
182
|
+
|
|
183
|
+
## Lore, optional
|
|
184
|
+
|
|
185
|
+
[Lore](https://github.com/akitaonrails/ai-memory) is used as shared memory on top
|
|
186
|
+
of files and git, never as a requirement. When a run starts, the `run` skill
|
|
187
|
+
looks for a `parallel-run` rule with `memory_query` and follows the team's live
|
|
188
|
+
rule where it differs from the plugin's defaults. With your "yes", it can also
|
|
189
|
+
record the run's plan as a page that expires, leave a handoff if the session
|
|
190
|
+
ends before the workers do, and use the inbox when a task belongs to another
|
|
191
|
+
repository. The details are in
|
|
192
|
+
[`skills/orchestrate/references/coordination.md`](skills/orchestrate/references/coordination.md).
|
|
193
|
+
|
|
194
|
+
Lore messages go between **projects** and are delivered once, so they are not
|
|
195
|
+
part of the loop: the workers of a run belong to the same project and only talk
|
|
196
|
+
to the manager.
|
|
197
|
+
|
|
198
|
+
## Known limits
|
|
199
|
+
|
|
200
|
+
- **Gates in a fresh worktree.** Gates run in a newly created worktree, so they
|
|
201
|
+
must include installing dependencies (for example `npm ci && npm test`).
|
|
202
|
+
Without it, every integration fails.
|
|
203
|
+
- **No board writes during `wait`.** Do not run `integrate`, `start` or `set`
|
|
204
|
+
while a `wait` is active. Read-only commands (`show`, `ready`, `report`) are
|
|
205
|
+
fine.
|
|
206
|
+
- **Windows.** The code handles the `.cmd` shims of npm-installed CLIs, but the
|
|
207
|
+
end-to-end tests run on macOS and Linux (the fake CLIs are shell scripts). Run
|
|
208
|
+
`board start --dry-run` on your machine before the first real run.
|
|
209
|
+
- **Flags not yet verified in a real run**: Gemini `--approval-mode` values
|
|
210
|
+
other than `auto_edit`, the quoting of Copilot `shell(...)` rules on Windows,
|
|
211
|
+
and Antigravity permission rules. They are marked in `providers.md`.
|
|
212
|
+
- **Merge policy and autonomous mode** are followed by the manager (they are in
|
|
213
|
+
the board and the skill), not enforced by the script.
|
|
214
|
+
- **A per-provider "unsafe" option** does not exist yet. The bypass flag is per
|
|
215
|
+
task, in `extraArgs`.
|
|
216
|
+
- **Codex.** The skills follow the Agent Skills format and install with
|
|
217
|
+
`npx playmakerlabs init`, but the hooks are Claude Code only, and the Codex
|
|
218
|
+
side has not been tested end to end.
|
|
219
|
+
|
|
220
|
+
## Tests
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npm test # the CLI: init, passthrough, help, version (Windows, macOS, Linux)
|
|
224
|
+
npm run test:e2e # the full loop and the launcher (macOS, Linux)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The end-to-end board test brings up fake CLIs, runs six tasks with
|
|
228
|
+
dependencies, a collision and a shared file, makes a gate fail and the task get
|
|
229
|
+
redone, and checks that at the end everything is at `To test`, main is clean and
|
|
230
|
+
no worktree or branch is left. The smoke test covers the single-batch launcher,
|
|
231
|
+
the hooks (silent below the threshold, one note per session, off by
|
|
232
|
+
configuration) and the validation errors.
|
|
233
|
+
|
|
234
|
+
Before a release, also run `claude plugin validate .`.
|
|
235
|
+
|
|
236
|
+
## Layout
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
.claude-plugin/plugin.json manifest and options
|
|
240
|
+
hooks/hooks.json SessionStart and PostToolUse
|
|
241
|
+
skills/orchestrate/ when to offer, how to offer, how to build the board
|
|
242
|
+
skills/orchestrate/references/ board, brief, providers, coordination and Lore
|
|
243
|
+
skills/run/ the manager loop
|
|
244
|
+
scripts/board.mjs board: ready, start, wait, integrate, set, report
|
|
245
|
+
scripts/spawn.mjs worker supervisor and single-batch launcher
|
|
246
|
+
scripts/status.mjs worker state and file overlap
|
|
247
|
+
scripts/detect-agents.mjs detects installed CLIs
|
|
248
|
+
scripts/task-watch.mjs counts open tasks and gives the nudge
|
|
249
|
+
scripts/lib/launch.mjs worktree, brief and start of each worker
|
|
250
|
+
scripts/lib/providers.mjs how each CLI is started
|
|
251
|
+
cli/playmaker.mjs the npm CLI: init and the scripts above
|
|
252
|
+
tests/ end-to-end and CLI tests
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
[MIT](LICENSE), by Síntese Labs.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The Playmaker CLI, for agents that load skills from a project folder instead of a plugin.
|
|
3
|
+
// playmaker init [--dry-run] [--agent claude|codex|antigravity]
|
|
4
|
+
// playmaker board|status|spawn|detect [args] the plugin's scripts, unchanged
|
|
5
|
+
//
|
|
6
|
+
// `init` copies the skills where each agent reads them. Inside the plugin the skills call
|
|
7
|
+
// `node "${CLAUDE_PLUGIN_ROOT}/scripts/<name>.mjs"`; the copies call this CLI instead,
|
|
8
|
+
// pinned to the version that wrote them, so skills and scripts never drift apart.
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { spawnSync } from 'node:child_process';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
|
|
14
|
+
const PACKAGE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
15
|
+
const { name: PACKAGE_NAME, version } = JSON.parse(fs.readFileSync(path.join(PACKAGE, 'package.json'), 'utf8'));
|
|
16
|
+
|
|
17
|
+
const SCRIPTS = { board: 'board.mjs', status: 'status.mjs', spawn: 'spawn.mjs', detect: 'detect-agents.mjs' };
|
|
18
|
+
const AGENTS = { claude: '.claude/skills', codex: '.agents/skills', antigravity: '.agents/skills' };
|
|
19
|
+
const SKILLS = ['orchestrate', 'run'];
|
|
20
|
+
|
|
21
|
+
const usage = `playmaker ${version}
|
|
22
|
+
|
|
23
|
+
Usage: playmaker <command> [options]
|
|
24
|
+
|
|
25
|
+
init copy the Playmaker skills into this project
|
|
26
|
+
--dry-run say what would be written, write nothing
|
|
27
|
+
--agent claude, codex or antigravity (default: all)
|
|
28
|
+
board the task board: validate, show, ready, start, wait, integrate, set, report
|
|
29
|
+
status state of the workers of a run [run] [--json] [--overlap]
|
|
30
|
+
spawn one-batch launcher: --plan plan.json [--dry-run]
|
|
31
|
+
detect which agent CLIs are installed
|
|
32
|
+
|
|
33
|
+
--help this text
|
|
34
|
+
--version the version
|
|
35
|
+
|
|
36
|
+
Installed as a Claude Code plugin, Playmaker needs none of this: the plugin
|
|
37
|
+
carries the skills, the scripts and the hooks.`;
|
|
38
|
+
|
|
39
|
+
/** Skill text as it should read outside the plugin: prefixed names, scripts called through this CLI. */
|
|
40
|
+
export function forProject(text) {
|
|
41
|
+
const cli = `npx -y ${PACKAGE_NAME}@${version}`;
|
|
42
|
+
const command = Object.fromEntries(Object.entries(SCRIPTS).map(([cmd, file]) => [file, cmd]));
|
|
43
|
+
return text
|
|
44
|
+
.replace(/^name: (orchestrate|run)(?=\r?$)/m, 'name: playmaker-$1')
|
|
45
|
+
.replace(/playmaker:(orchestrate|run)\b/g, 'playmaker-$1')
|
|
46
|
+
.replace(/node "\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/([a-z-]+\.mjs)"/g, (match, file) => (command[file] ? `${cli} ${command[file]}` : match));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function filesUnder(dir) {
|
|
50
|
+
const found = [];
|
|
51
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
52
|
+
const here = path.join(dir, entry.name);
|
|
53
|
+
if (entry.isDirectory()) found.push(...filesUnder(here));
|
|
54
|
+
else if (entry.isFile()) found.push(here);
|
|
55
|
+
}
|
|
56
|
+
return found;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function init(argv, folder, write) {
|
|
60
|
+
let pretend = false;
|
|
61
|
+
let agent = null;
|
|
62
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
63
|
+
if (argv[i] === '--dry-run') pretend = true;
|
|
64
|
+
else if (argv[i] === '--agent') {
|
|
65
|
+
agent = (argv[++i] || '').toLowerCase();
|
|
66
|
+
if (!AGENTS[agent]) {
|
|
67
|
+
write(`--agent takes one of: ${Object.keys(AGENTS).join(', ')}`);
|
|
68
|
+
return 2;
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
write(`unknown option ${argv[i]}\n\n${usage}`);
|
|
72
|
+
return 2;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const targets = [...new Set((agent ? [agent] : Object.keys(AGENTS)).map((a) => AGENTS[a]))];
|
|
77
|
+
let created = 0;
|
|
78
|
+
let kept = 0;
|
|
79
|
+
for (const target of targets) {
|
|
80
|
+
for (const skill of SKILLS) {
|
|
81
|
+
const from = path.join(PACKAGE, 'skills', skill);
|
|
82
|
+
for (const file of filesUnder(from)) {
|
|
83
|
+
const rel = path.join(...target.split('/'), `playmaker-${skill}`, path.relative(from, file));
|
|
84
|
+
const dest = path.join(folder, rel);
|
|
85
|
+
if (fs.existsSync(dest)) {
|
|
86
|
+
kept += 1;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
created += 1;
|
|
90
|
+
write(` ${pretend ? 'would create' : 'created'} ${rel.split(path.sep).join('/')}`);
|
|
91
|
+
if (pretend) continue;
|
|
92
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
93
|
+
fs.writeFileSync(dest, forProject(fs.readFileSync(file, 'utf8')));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (kept) write(` kept ${kept} file${kept === 1 ? '' : 's'} that were already there`);
|
|
98
|
+
write(pretend ? `\nPlaymaker ${version}: ${created} file(s) would be written. Nothing was written.` : `\nPlaymaker ${version}: ${created} file(s) written.`);
|
|
99
|
+
if (!pretend) write('The skills are playmaker-orchestrate and playmaker-run. The hooks that offer a parallel run on their own come only with the Claude Code plugin.');
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function run(argv, folder, write) {
|
|
104
|
+
const [command, ...rest] = argv;
|
|
105
|
+
if (!command || ['--help', '-h', 'help'].includes(command)) {
|
|
106
|
+
write(usage);
|
|
107
|
+
return command ? 0 : 2;
|
|
108
|
+
}
|
|
109
|
+
if (command === '--version' || command === '-v') {
|
|
110
|
+
write(version);
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
if (command === 'init') return init(rest, folder, write);
|
|
114
|
+
if (SCRIPTS[command]) {
|
|
115
|
+
const args = command === 'detect' && !rest.length ? ['--print'] : rest;
|
|
116
|
+
const child = spawnSync(process.execPath, [path.join(PACKAGE, 'scripts', SCRIPTS[command]), ...args], { cwd: folder, stdio: 'inherit' });
|
|
117
|
+
return child.status ?? 1;
|
|
118
|
+
}
|
|
119
|
+
write(`unknown command ${command}\n\n${usage}`);
|
|
120
|
+
return 2;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Run only when called, not when a test imports it. realpath because npm links the bin.
|
|
124
|
+
if (process.argv[1] && fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url))) {
|
|
125
|
+
process.exitCode = run(process.argv.slice(2), process.cwd(), (line) => process.stdout.write(`${line}\n`));
|
|
126
|
+
}
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "startup|resume",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node",
|
|
10
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/detect-agents.mjs", "--hook"],
|
|
11
|
+
"timeout": 10
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"PostToolUse": [
|
|
17
|
+
{
|
|
18
|
+
"matcher": "TaskCreate|TaskUpdate|TodoWrite",
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "node",
|
|
23
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/task-watch.mjs"],
|
|
24
|
+
"timeout": 10
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playmakerlabs",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Parallel multi-agent orchestration: one manager agent runs workers on the CLIs you already have (Claude Code, Codex, Gemini, Antigravity, Copilot) in isolated git worktrees.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"playmaker": "cli/playmaker.mjs"
|
|
9
|
+
},
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=22"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
".claude-plugin/",
|
|
15
|
+
"cli/",
|
|
16
|
+
"hooks/",
|
|
17
|
+
"scripts/",
|
|
18
|
+
"skills/",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "node tests/cli.mjs",
|
|
24
|
+
"test:e2e": "node tests/board.mjs && node tests/smoke.mjs"
|
|
25
|
+
},
|
|
26
|
+
"author": "Síntese Labs",
|
|
27
|
+
"homepage": "https://github.com/sinteselabs/Playmaker#readme",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/sinteselabs/Playmaker/issues"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/sinteselabs/Playmaker.git"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"agent-skills",
|
|
37
|
+
"multi-agent",
|
|
38
|
+
"orchestration",
|
|
39
|
+
"parallel",
|
|
40
|
+
"git-worktree",
|
|
41
|
+
"claude-code",
|
|
42
|
+
"codex",
|
|
43
|
+
"gemini",
|
|
44
|
+
"antigravity",
|
|
45
|
+
"copilot"
|
|
46
|
+
]
|
|
47
|
+
}
|