@loompad/cli 1.2.3 → 1.2.4
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 +14 -0
- package/README.md +10 -0
- package/dist/cli/index.js +26 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/core/orchestra.d.ts +1 -1
- package/dist/core/orchestra.js +7 -2
- package/dist/core/orchestra.js.map +1 -1
- package/dist/daemon/client.d.ts +3 -0
- package/dist/daemon/client.js +3 -0
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/routes/project-team.js +17 -0
- package/dist/daemon/routes/project-team.js.map +1 -1
- package/dist/daemon/runner.js +22 -9
- package/dist/daemon/runner.js.map +1 -1
- package/dist/daemon/team-coordinator.d.ts +1 -1
- package/dist/daemon/team-coordinator.js +2 -2
- package/dist/daemon/team-coordinator.js.map +1 -1
- package/dist/daemon/team.d.ts +33 -0
- package/dist/daemon/team.js +48 -0
- package/dist/daemon/team.js.map +1 -1
- package/dist/web/app.css +8 -0
- package/dist/web/app.js +44 -1
- package/dist/web/app.js.map +2 -2
- package/docs/release-notes/v1.2.4.md +13 -0
- package/docs/teams.md +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.4] — 2026-10-22
|
|
11
|
+
|
|
12
|
+
Team auto-orchestration, set up in one step and steadier on a teammate's machine.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`loom team auto` — two machines, one goal, set up in one step.** `loom team auto` says whether team auto-orchestration is ready in this project, which teammates' agents a goal would get, and what's missing; `loom team auto on` shares the project, writes `loom.team.json` with `runners.shared` when the repo has none (commit and merge it), and turns on this machine's shared runner. The Team tab shows the same as a **Two machines, one goal** card with a **Turn on** button.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **A teammate's task could still fail to commit on their machine.** The clone's own Loom takes its end-of-turn checkpoint in the git index at the same moment the task commits, and could undo the task's staging ("nothing to commit"). The runner now builds the task's commit in a private index, so nothing else in the clone can disturb it.
|
|
21
|
+
- `loom crew status` in a project with several crews said "which crew?" instead of listing them; it lists every crew unless you name one.
|
|
22
|
+
- **A follow-up to a teammate's task re-ran the original prompt.** When the orchestrator sent a follow-up ("also fix the test"), the teammate's machine got the task from scratch. It now gets the follow-up, on top of the first attempt's work, with the original task for context.
|
|
23
|
+
|
|
10
24
|
## [1.2.3] — 2026-10-22
|
|
11
25
|
|
|
12
26
|
Teams that work together on their own: one goal splits across teammates' machines. Plus Simple mode, hub hardening, and the fourth field round.
|
package/README.md
CHANGED
|
@@ -1560,6 +1560,16 @@ loom team # who's doing what, right now
|
|
|
1560
1560
|
- **Worker commits carry `Loom-Goal`, `Loom-Task`, `Loom-Agent` and `Loom-Member`
|
|
1561
1561
|
trailers.** `git log` alone tells you which goal, task and agent wrote a line.
|
|
1562
1562
|
|
|
1563
|
+
**Two people, one goal — the agents split it themselves.** When teammates turn
|
|
1564
|
+
on team auto-orchestration (`loom team auto on`, or **Turn on** in the Team tab),
|
|
1565
|
+
a goal you start splits across both machines. Your orchestrator gets their agents
|
|
1566
|
+
as `team:codex`, `team:opencode`…; a task sent to one is claimed by their Loom on
|
|
1567
|
+
its own, run with **their** agent and subscription, and merged back into your
|
|
1568
|
+
goal's branch — still one PR. A teammate who goes offline doesn't stall you: an
|
|
1569
|
+
unclaimed task returns to your orchestrator after 10 minutes. `loom team auto`
|
|
1570
|
+
says what's missing; `loom orchestrate "…" --solo` keeps a goal on your machine.
|
|
1571
|
+
See [docs/teams.md](docs/teams.md#two-people-one-goal-team-auto-orchestration).
|
|
1572
|
+
|
|
1563
1573
|
**Phase 2 (stop colliding) is built too:**
|
|
1564
1574
|
- **Declaring touches.** On a team project, every orchestra task declares the files
|
|
1565
1575
|
it will `touch`, and Loom takes a lease on them.
|
package/dist/cli/index.js
CHANGED
|
@@ -1894,12 +1894,17 @@ program
|
|
|
1894
1894
|
console.log(pc.dim(`no crews here yet — loom crew create [${templates.join("|")}] [name]`));
|
|
1895
1895
|
return;
|
|
1896
1896
|
}
|
|
1897
|
+
// status shows every crew unless one is named; everything else needs to know which
|
|
1898
|
+
if (a === "status" && !opts.crew) {
|
|
1899
|
+
for (const c of crews)
|
|
1900
|
+
printCrew(c);
|
|
1901
|
+
return;
|
|
1902
|
+
}
|
|
1897
1903
|
const crew = opts.crew ? crews.find((c) => c.id === opts.crew || c.name === opts.crew) : crews.length === 1 ? crews[0] : undefined;
|
|
1898
1904
|
if (!crew)
|
|
1899
1905
|
throw new Error(`which crew? --crew ${crews.map((c) => c.id).join(" | ")}`);
|
|
1900
1906
|
if (a === "status") {
|
|
1901
|
-
|
|
1902
|
-
printCrew(c);
|
|
1907
|
+
printCrew(crew);
|
|
1903
1908
|
return;
|
|
1904
1909
|
}
|
|
1905
1910
|
if (a === "diff") {
|
|
@@ -1955,7 +1960,7 @@ function printCrew(c) {
|
|
|
1955
1960
|
}
|
|
1956
1961
|
program
|
|
1957
1962
|
.command("team [action] [args...]")
|
|
1958
|
-
.description("Loom Teams: status | signin [hub] | create <name> | invite | join <link> | share | unshare | brain [inbox|promote|resolve|correct|trust|private] | landing | doctor [fix] | adopt <pr> | deploys | release-notes <since> | webhook [--repo r] [--install] | remove <github> | leave")
|
|
1963
|
+
.description("Loom Teams: status | auto [on] | signin [hub] | create <name> | invite | join <link> | share | unshare | brain [inbox|promote|resolve|correct|trust|private] | landing | doctor [fix] | adopt <pr> | deploys | release-notes <since> | webhook [--repo r] [--install] | remove <github> | leave")
|
|
1959
1964
|
.option("--github <login>", "your GitHub login (defaults to the gh CLI's)")
|
|
1960
1965
|
.option("--repo <owner/name>", "webhook: which repo (defaults to this project's)")
|
|
1961
1966
|
.option("--install", "webhook: create it on the repo with gh (needs repo admin)")
|
|
@@ -1971,6 +1976,24 @@ program
|
|
|
1971
1976
|
try {
|
|
1972
1977
|
if (a === "status")
|
|
1973
1978
|
return void printTeam(await client.team());
|
|
1979
|
+
if (a === "auto") {
|
|
1980
|
+
// team auto-orchestration: your goals split across teammates' machines, theirs across yours
|
|
1981
|
+
const project = await currentProject(client);
|
|
1982
|
+
const st = await client.teamAuto(project.id, arg === "on");
|
|
1983
|
+
if (st.wrotePolicy)
|
|
1984
|
+
console.log(`${pc.green("✓")} wrote loom.team.json (runners.shared) — commit and merge it; policy is reviewed like code`);
|
|
1985
|
+
const mark = (ok) => (ok ? pc.green("✓") : pc.dim("·"));
|
|
1986
|
+
console.log(`${mark(st.shared)} project shared with your team`);
|
|
1987
|
+
console.log(`${mark(st.policyShared)} repo policy lets teammates' runners take its work`);
|
|
1988
|
+
console.log(`${mark(st.myRunner.running && st.myRunner.shared)} your runner is on and shared (teammates' goals can use your agents)`);
|
|
1989
|
+
const on = st.teammates.filter((t) => t.online);
|
|
1990
|
+
console.log(`${mark(on.length > 0)} teammates' runners online: ${on.length ? on.map((t) => `${t.github} (${t.kinds.join(", ")})`).join(", ") : "none yet"}`);
|
|
1991
|
+
if (st.ready)
|
|
1992
|
+
console.log(`\n${pc.green("ready")} — goals you start get ${st.workers.join(", ")} as workers. ${pc.dim("loom orchestrate \"…\" (--solo to keep one local)")}`);
|
|
1993
|
+
else
|
|
1994
|
+
console.log(`\n${pc.yellow("not yet")} — ${st.missing.join("; ")}`);
|
|
1995
|
+
return;
|
|
1996
|
+
}
|
|
1974
1997
|
if (a === "signin") {
|
|
1975
1998
|
const { hostedHubUrl, hostedSupabaseUrl, publishableKeyFor } = await import("../core/hosted.js");
|
|
1976
1999
|
const supabaseUrl = hostedSupabaseUrl(arg);
|