@loompad/cli 1.2.2 → 1.2.3
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 +28 -0
- package/dist/cli/index.js +33 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/core/crew.d.ts +16 -1
- package/dist/core/crew.js +26 -2
- package/dist/core/crew.js.map +1 -1
- package/dist/core/orchestra.d.ts +36 -0
- package/dist/core/orchestra.js +149 -82
- package/dist/core/orchestra.js.map +1 -1
- package/dist/core/team-hub.d.ts +2 -1
- package/dist/core/team-hub.js +1 -1
- package/dist/core/team-hub.js.map +1 -1
- package/dist/core/team-leases.d.ts +7 -0
- package/dist/core/team-leases.js +19 -0
- package/dist/core/team-leases.js.map +1 -1
- package/dist/daemon/client.d.ts +9 -1
- package/dist/daemon/client.js +2 -2
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/routes/brain.js +2 -2
- package/dist/daemon/routes/brain.js.map +1 -1
- package/dist/daemon/routes/orchestra.js +1 -0
- package/dist/daemon/routes/orchestra.js.map +1 -1
- package/dist/daemon/runner.d.ts +11 -0
- package/dist/daemon/runner.js +96 -3
- package/dist/daemon/runner.js.map +1 -1
- package/dist/daemon/runtime/briefings.js +12 -1
- package/dist/daemon/runtime/briefings.js.map +1 -1
- package/dist/daemon/runtime.d.ts +9 -2
- package/dist/daemon/runtime.js +8 -4
- package/dist/daemon/runtime.js.map +1 -1
- package/dist/daemon/team-coordinator.d.ts +27 -3
- package/dist/daemon/team-coordinator.js +54 -2
- package/dist/daemon/team-coordinator.js.map +1 -1
- package/dist/daemon/team.d.ts +9 -1
- package/dist/daemon/team.js +44 -1
- package/dist/daemon/team.js.map +1 -1
- package/dist/hub/supabase-client.d.ts +4 -2
- package/dist/hub/supabase-client.js +21 -12
- package/dist/hub/supabase-client.js.map +1 -1
- package/dist/web/app.css +4 -0
- package/dist/web/app.js +96 -27
- package/dist/web/app.js.map +3 -3
- package/docs/release-notes/v1.2.3.md +29 -0
- package/docs/teams.md +28 -0
- package/package.json +1 -1
package/dist/core/crew.d.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* crews across people are later phases (§11).
|
|
20
20
|
*/
|
|
21
21
|
import type { TeamPolicy } from "./team-policy.js";
|
|
22
|
-
import type
|
|
22
|
+
import { type OrchestraCoordinator, type TaskHold, type OrchestraRun } from "./orchestra.js";
|
|
23
23
|
import { type ContinuityEngine } from "./continuity/engine.js";
|
|
24
24
|
import type { Adapter, AgentConfig, ChatInfo, EventKind, LoomEvent } from "../types.js";
|
|
25
25
|
import { type BoardTask } from "./registry.js";
|
|
@@ -182,6 +182,8 @@ export interface CrewHost {
|
|
|
182
182
|
projectId: string;
|
|
183
183
|
projectName: string;
|
|
184
184
|
projectDir: string;
|
|
185
|
+
/** `orchestra.worktreeDir` from the project config — crews share orchestra's root (#328). */
|
|
186
|
+
worktreeDir?: () => string | undefined;
|
|
185
187
|
crews(): CrewConfig[];
|
|
186
188
|
saveCrews(crews: CrewConfig[]): void;
|
|
187
189
|
roster(): AgentConfig[];
|
|
@@ -249,6 +251,13 @@ export interface CrewSeats {
|
|
|
249
251
|
}
|
|
250
252
|
/** The template's seats, with the ones you named filled by those agents (builders in turn). */
|
|
251
253
|
export declare function seatCrew(teammates: CrewTeammate[], seats?: CrewSeats): CrewTeammate[];
|
|
254
|
+
/**
|
|
255
|
+
* Where a project's crew worktrees go: orchestra's root (#295) — under ~/.loom
|
|
256
|
+
* on the same disk, beside the project when it lives on another volume, or
|
|
257
|
+
* `orchestra.worktreeDir` — so a crew's checkouts don't fill the internal disk
|
|
258
|
+
* either (#328).
|
|
259
|
+
*/
|
|
260
|
+
export declare function crewWorktreeRoot(projectDir: string, projectId: string, override?: string): string;
|
|
252
261
|
export declare class CrewEngine {
|
|
253
262
|
private readonly host;
|
|
254
263
|
private states;
|
|
@@ -276,6 +285,12 @@ export declare class CrewEngine {
|
|
|
276
285
|
private testControllers;
|
|
277
286
|
private teamRechecks;
|
|
278
287
|
private deliveries;
|
|
288
|
+
/**
|
|
289
|
+
* A crew checkout's folder under the worktree root. One a crew already has at
|
|
290
|
+
* the old ~/.loom/crews spot stays where it is — a native seat's workspace
|
|
291
|
+
* lives across goals — so only new checkouts move.
|
|
292
|
+
*/
|
|
293
|
+
private worktreePath;
|
|
279
294
|
constructor(host: CrewHost);
|
|
280
295
|
/** The agents a teammate can be. */
|
|
281
296
|
roster(): AgentConfig[];
|
package/dist/core/crew.js
CHANGED
|
@@ -26,6 +26,7 @@ import { digest } from "./continuity/contracts.js";
|
|
|
26
26
|
import { coordinationRun, crewRunId } from "./crew-coordination.js";
|
|
27
27
|
import { DEFAULT_CREW_POLICY } from "./crew-policy.js";
|
|
28
28
|
import { vendorOf } from "./team-landing.js";
|
|
29
|
+
import { orchestraWorktreeRoot } from "./orchestra.js";
|
|
29
30
|
import fs from "node:fs";
|
|
30
31
|
import path from "node:path";
|
|
31
32
|
import { randomUUID } from "node:crypto";
|
|
@@ -120,6 +121,16 @@ async function git(args, cwd) {
|
|
|
120
121
|
const { stdout } = await exec("git", args, { cwd, maxBuffer: 32 * 1024 * 1024 });
|
|
121
122
|
return stdout;
|
|
122
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Where a project's crew worktrees go: orchestra's root (#295) — under ~/.loom
|
|
126
|
+
* on the same disk, beside the project when it lives on another volume, or
|
|
127
|
+
* `orchestra.worktreeDir` — so a crew's checkouts don't fill the internal disk
|
|
128
|
+
* either (#328).
|
|
129
|
+
*/
|
|
130
|
+
export function crewWorktreeRoot(projectDir, projectId, override) {
|
|
131
|
+
const orchestra = orchestraWorktreeRoot(projectDir, projectId, override);
|
|
132
|
+
return orchestra === path.join(loomHome(), "orchestra", projectId) ? path.join(loomHome(), "crews", projectId) : path.join(orchestra, "crews");
|
|
133
|
+
}
|
|
123
134
|
export class CrewEngine {
|
|
124
135
|
host;
|
|
125
136
|
states = new Map();
|
|
@@ -149,6 +160,17 @@ export class CrewEngine {
|
|
|
149
160
|
testControllers = new Map();
|
|
150
161
|
teamRechecks = new Map();
|
|
151
162
|
deliveries = new Map();
|
|
163
|
+
/**
|
|
164
|
+
* A crew checkout's folder under the worktree root. One a crew already has at
|
|
165
|
+
* the old ~/.loom/crews spot stays where it is — a native seat's workspace
|
|
166
|
+
* lives across goals — so only new checkouts move.
|
|
167
|
+
*/
|
|
168
|
+
worktreePath(crewId, ...parts) {
|
|
169
|
+
const legacy = path.join(loomHome(), "crews", this.host.projectId, crewId, ...parts);
|
|
170
|
+
if (fs.existsSync(legacy))
|
|
171
|
+
return legacy;
|
|
172
|
+
return path.join(crewWorktreeRoot(this.host.projectDir, this.host.projectId, this.host.worktreeDir?.()), crewId, ...parts);
|
|
173
|
+
}
|
|
152
174
|
constructor(host) {
|
|
153
175
|
this.host = host;
|
|
154
176
|
// A goal that was mid-turn when Loom stopped is interrupted, not lost:
|
|
@@ -348,7 +370,7 @@ export class CrewEngine {
|
|
|
348
370
|
const branch = `loom/crew/${cfg.id}/${gid}`;
|
|
349
371
|
// Native sessions retain their workspace identity between goals. Branches
|
|
350
372
|
// remain per goal; switching a clean, stopped checkout changes its snapshot.
|
|
351
|
-
const dir =
|
|
373
|
+
const dir = this.worktreePath(cfg.id, this.host.native?.() ? "workspace" : gid);
|
|
352
374
|
fs.mkdirSync(path.dirname(dir), { recursive: true });
|
|
353
375
|
await this.serial(async () => {
|
|
354
376
|
if (fs.existsSync(dir)) {
|
|
@@ -1070,7 +1092,7 @@ export class CrewEngine {
|
|
|
1070
1092
|
}
|
|
1071
1093
|
const base = (await git(["rev-parse", "HEAD"], g.dir)).trim();
|
|
1072
1094
|
const branch = `${g.branch}-card-${card.id}`;
|
|
1073
|
-
const dir =
|
|
1095
|
+
const dir = this.worktreePath(cfg.id, this.host.native?.() ? `seat-${card.builder}` : `cards-${g.id}`, this.host.native?.() ? "workspace" : card.id);
|
|
1074
1096
|
fs.mkdirSync(path.dirname(dir), { recursive: true });
|
|
1075
1097
|
await this.serial(async () => {
|
|
1076
1098
|
if (fs.existsSync(dir)) {
|
|
@@ -1363,6 +1385,8 @@ export class CrewEngine {
|
|
|
1363
1385
|
this.save(st);
|
|
1364
1386
|
this.phase(cfg, st, status === "completed" ? "completed" : "failed", {
|
|
1365
1387
|
branch: g.branch, cards: g.cards.length, ...(g.summary ? { summary: g.summary } : {}), ...(error ? { error } : {}), costUsd: g.costUsd,
|
|
1388
|
+
// which cards failed, by id — what `loom crew accept --card` takes (#329)
|
|
1389
|
+
...(status === "failed" ? { failedCards: g.cards.filter(c => c.stage === "failed").map(c => ({ id: c.id, title: c.title, ...(c.error ? { error: c.error.slice(0, 300) } : {}) })) } : {}),
|
|
1366
1390
|
});
|
|
1367
1391
|
const stopping = this.stopAgents(cfg.id).finally(() => this.stopping.delete(cfg.id));
|
|
1368
1392
|
this.stopping.set(cfg.id, stopping);
|