@loompad/cli 1.1.2 → 1.2.1
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 +61 -0
- package/README.md +31 -10
- package/dist/adapters/antigravity-cli.d.ts +2 -0
- package/dist/adapters/antigravity-cli.js +27 -4
- package/dist/adapters/antigravity-cli.js.map +1 -1
- package/dist/adapters/model.js +1 -1
- package/dist/adapters/model.js.map +1 -1
- package/dist/adapters/opencode.d.ts +4 -0
- package/dist/adapters/opencode.js +18 -0
- package/dist/adapters/opencode.js.map +1 -1
- package/dist/cli/doctor.d.ts +38 -1
- package/dist/cli/doctor.js +157 -3
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.js +357 -20
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ui.js +11 -7
- package/dist/cli/ui.js.map +1 -1
- package/dist/core/auto-policy.d.ts +46 -0
- package/dist/core/auto-policy.js +181 -0
- package/dist/core/auto-policy.js.map +1 -0
- package/dist/core/council.d.ts +55 -0
- package/dist/core/council.js +73 -0
- package/dist/core/council.js.map +1 -0
- package/dist/core/crew-protocol.js +4 -1
- package/dist/core/crew-protocol.js.map +1 -1
- package/dist/core/crew.d.ts +13 -1
- package/dist/core/crew.js +40 -6
- package/dist/core/crew.js.map +1 -1
- package/dist/core/digest.d.ts +2 -0
- package/dist/core/digest.js +9 -0
- package/dist/core/digest.js.map +1 -1
- package/dist/core/loops.js +22 -2
- package/dist/core/loops.js.map +1 -1
- package/dist/core/orchestra.d.ts +16 -0
- package/dist/core/orchestra.js +45 -2
- package/dist/core/orchestra.js.map +1 -1
- package/dist/core/permissions.js +2 -2
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/prices.d.ts +66 -0
- package/dist/core/prices.js +109 -0
- package/dist/core/prices.js.map +1 -0
- package/dist/core/proof.d.ts +13 -1
- package/dist/core/proof.js +89 -17
- package/dist/core/proof.js.map +1 -1
- package/dist/core/providers.d.ts +13 -0
- package/dist/core/providers.js +17 -0
- package/dist/core/providers.js.map +1 -1
- package/dist/core/replay.js +14 -0
- package/dist/core/replay.js.map +1 -1
- package/dist/core/review.d.ts +60 -0
- package/dist/core/review.js +121 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/routes.js +14 -0
- package/dist/core/routes.js.map +1 -1
- package/dist/core/setup.d.ts +27 -0
- package/dist/core/setup.js +39 -7
- package/dist/core/setup.js.map +1 -1
- package/dist/core/shield.js +7 -3
- package/dist/core/shield.js.map +1 -1
- package/dist/core/shift.d.ts +2 -0
- package/dist/core/shift.js +14 -2
- package/dist/core/shift.js.map +1 -1
- package/dist/core/turn-wait.d.ts +20 -0
- package/dist/core/turn-wait.js +39 -0
- package/dist/core/turn-wait.js.map +1 -0
- package/dist/core/usage.d.ts +7 -1
- package/dist/core/usage.js +11 -3
- package/dist/core/usage.js.map +1 -1
- package/dist/daemon/client.d.ts +60 -1
- package/dist/daemon/client.js +40 -1
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/council.d.ts +98 -0
- package/dist/daemon/council.js +254 -0
- package/dist/daemon/council.js.map +1 -0
- package/dist/daemon/proof.d.ts +6 -0
- package/dist/daemon/proof.js +32 -9
- package/dist/daemon/proof.js.map +1 -1
- package/dist/daemon/push.js +7 -0
- package/dist/daemon/push.js.map +1 -1
- package/dist/daemon/review.d.ts +95 -0
- package/dist/daemon/review.js +154 -0
- package/dist/daemon/review.js.map +1 -0
- package/dist/daemon/routes/council.d.ts +4 -0
- package/dist/daemon/routes/council.js +29 -0
- package/dist/daemon/routes/council.js.map +1 -0
- package/dist/daemon/routes/crews.js +2 -0
- package/dist/daemon/routes/crews.js.map +1 -1
- package/dist/daemon/routes/messages.js +8 -2
- package/dist/daemon/routes/messages.js.map +1 -1
- package/dist/daemon/routes/review.d.ts +4 -0
- package/dist/daemon/routes/review.js +40 -0
- package/dist/daemon/routes/review.js.map +1 -0
- package/dist/daemon/routes/routing.js +2 -1
- package/dist/daemon/routes/routing.js.map +1 -1
- package/dist/daemon/routes/setup.d.ts +2 -1
- package/dist/daemon/routes/setup.js +22 -6
- package/dist/daemon/routes/setup.js.map +1 -1
- package/dist/daemon/runtime/accounting.d.ts +6 -0
- package/dist/daemon/runtime/accounting.js +37 -1
- package/dist/daemon/runtime/accounting.js.map +1 -1
- package/dist/daemon/runtime/briefings.d.ts +8 -3
- package/dist/daemon/runtime/briefings.js +26 -14
- package/dist/daemon/runtime/briefings.js.map +1 -1
- package/dist/daemon/runtime/queue.d.ts +7 -0
- package/dist/daemon/runtime/queue.js +13 -1
- package/dist/daemon/runtime/queue.js.map +1 -1
- package/dist/daemon/runtime/relay.d.ts +2 -0
- package/dist/daemon/runtime/relay.js +7 -0
- package/dist/daemon/runtime/relay.js.map +1 -1
- package/dist/daemon/runtime/turns.d.ts +2 -0
- package/dist/daemon/runtime/turns.js +1 -0
- package/dist/daemon/runtime/turns.js.map +1 -1
- package/dist/daemon/runtime-support.js +1 -1
- package/dist/daemon/runtime-support.js.map +1 -1
- package/dist/daemon/runtime.d.ts +65 -3
- package/dist/daemon/runtime.js +238 -5
- package/dist/daemon/runtime.js.map +1 -1
- package/dist/daemon/server.js +5 -1
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/shift.js +1 -1
- package/dist/daemon/shift.js.map +1 -1
- package/dist/providers/agent.js +6 -0
- package/dist/providers/agent.js.map +1 -1
- package/dist/providers/claude/adapter.d.ts +3 -0
- package/dist/providers/claude/adapter.js +20 -1
- package/dist/providers/claude/adapter.js.map +1 -1
- package/dist/types.d.ts +31 -1
- package/dist/types.js.map +1 -1
- package/dist/web/app.css +51 -0
- package/dist/web/app.js +172 -18
- package/dist/web/app.js.map +3 -3
- package/docs/release-notes/v1.2.0.md +48 -0
- package/docs/release-notes/v1.2.1.md +40 -0
- package/package.json +1 -1
package/dist/core/digest.js
CHANGED
|
@@ -81,6 +81,15 @@ export function digest(events, since, agentLabel = (x) => x) {
|
|
|
81
81
|
}
|
|
82
82
|
// Newest first: the last thing that happened is the thing you want first.
|
|
83
83
|
lines.sort((a, b) => b.at - a.at);
|
|
84
|
+
// the same error three times is one line that says ×3 (#297)
|
|
85
|
+
for (let i = 0; i < lines.length; i++) {
|
|
86
|
+
for (let j = lines.length - 1; j > i; j--) {
|
|
87
|
+
if (lines[j].kind === lines[i].kind && lines[j].text === lines[i].text) {
|
|
88
|
+
lines[i].count = (lines[i].count ?? 1) + (lines[j].count ?? 1);
|
|
89
|
+
lines.splice(j, 1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
84
93
|
if (costUsd > 0 || turns > 0) {
|
|
85
94
|
lines.unshift({
|
|
86
95
|
at: Date.now(),
|
package/dist/core/digest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/core/digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/core/digest.ts"],"names":[],"mappings":"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"}
|
package/dist/core/loops.js
CHANGED
|
@@ -23,7 +23,25 @@ export function signature(p) {
|
|
|
23
23
|
const tool = String(p.tool ?? p.name ?? "").trim();
|
|
24
24
|
if (!tool)
|
|
25
25
|
return null;
|
|
26
|
-
|
|
26
|
+
const summary = String(p.summary ?? "").replace(/\s+/g, " ").trim();
|
|
27
|
+
// "Edit: Edit: tests/x.py" said the tool twice when the summary already names it
|
|
28
|
+
const label = summary.toLowerCase().startsWith(`${tool.toLowerCase()}:`) ? summary.slice(0, 200) : `${tool}: ${summary.slice(0, 200)}`;
|
|
29
|
+
// an edit is the same call only if it changes the same thing the same way: five edits to one file are work
|
|
30
|
+
const input = p.input;
|
|
31
|
+
if (isWrite(tool) && input) {
|
|
32
|
+
const change = [input.old_string, input.new_string, input.content, input.edits, input.patch].filter((x) => x !== undefined);
|
|
33
|
+
if (change.length)
|
|
34
|
+
return `${label} #${hash(JSON.stringify(change))}`;
|
|
35
|
+
}
|
|
36
|
+
return label;
|
|
37
|
+
}
|
|
38
|
+
const WRITE_TOOLS = /^(?:edit|multiedit|write|str_replace(?:_editor)?|apply_patch|write_file|notebookedit|file_change|patch)$/i;
|
|
39
|
+
const isWrite = (tool) => WRITE_TOOLS.test(tool);
|
|
40
|
+
function hash(s) {
|
|
41
|
+
let h = 2166136261;
|
|
42
|
+
for (let i = 0; i < s.length; i++)
|
|
43
|
+
h = Math.imul(h ^ s.charCodeAt(i), 16777619);
|
|
44
|
+
return (h >>> 0).toString(36);
|
|
27
45
|
}
|
|
28
46
|
export class LoopWatch {
|
|
29
47
|
turns = new Map();
|
|
@@ -59,7 +77,9 @@ export class LoopWatch {
|
|
|
59
77
|
turn.said.add(`f:${sig}`);
|
|
60
78
|
return { agentId: e.agentId, chat, kind: "failing", call: sig, count: c.failed, ...(output ? { output } : {}) };
|
|
61
79
|
}
|
|
62
|
-
|
|
80
|
+
// an edit we can't tell apart from the last (no input logged) never counts as repeating — only failing does (#286)
|
|
81
|
+
const blindWrite = isWrite(String(p.tool ?? p.name ?? "").trim()) && !/ #[0-9a-z]+$/.test(sig);
|
|
82
|
+
if (!blindWrite && c.n === REPEATING_AT && !turn.said.has(`f:${sig}`) && !turn.said.has(`r:${sig}`)) {
|
|
63
83
|
turn.said.add(`r:${sig}`);
|
|
64
84
|
return { agentId: e.agentId, chat, kind: "repeating", call: sig, count: c.n };
|
|
65
85
|
}
|
package/dist/core/loops.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loops.js","sourceRoot":"","sources":["../../src/core/loops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAeH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAI9B,qGAAqG;AACrG,MAAM,UAAU,SAAS,CAAC,CAA0B;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;QACvD,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM;YAC/F,CAAC,CAAC,MAAM,CAAE,CAAC,CAAC,KAA6C,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,IAAI,OAAO,CAAC,IAAI,EAAE;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"loops.js","sourceRoot":"","sources":["../../src/core/loops.ts"],"names":[],"mappings":"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"}
|
package/dist/core/orchestra.d.ts
CHANGED
|
@@ -273,10 +273,21 @@ export interface OrchestraStartOptions {
|
|
|
273
273
|
chat?: string;
|
|
274
274
|
}
|
|
275
275
|
/** What orchestra needs from the project that owns it. */
|
|
276
|
+
/**
|
|
277
|
+
* Where a project's orchestra worktrees go: under ~/.loom — unless the project
|
|
278
|
+
* lives on another volume (an external drive), where a sibling folder keeps
|
|
279
|
+
* the gigabytes on the project's own disk rather than the one that's tight
|
|
280
|
+
* (#295). `orchestra.worktreeDir` in .loom/config.json decides outright.
|
|
281
|
+
*/
|
|
282
|
+
export declare function orchestraWorktreeRoot(projectDir: string, projectId: string, override?: string): string;
|
|
283
|
+
/** Finished runs keep their worktrees this long, then they're removed (the branches stay). */
|
|
284
|
+
export declare const ORCHESTRA_KEEP_DAYS = 7;
|
|
276
285
|
export interface OrchestraHost {
|
|
277
286
|
projectId: string;
|
|
278
287
|
projectName: string;
|
|
279
288
|
projectDir: string;
|
|
289
|
+
/** `orchestra.worktreeDir` from the project's config, if set. */
|
|
290
|
+
worktreeDir?(): string | undefined;
|
|
280
291
|
/** Adapter entries of the roster (enabled only). */
|
|
281
292
|
roster(): AgentConfig[];
|
|
282
293
|
/** Kinds installed on this machine but not on the roster, usable as workers. */
|
|
@@ -535,6 +546,11 @@ export declare class OrchestraEngine {
|
|
|
535
546
|
}>;
|
|
536
547
|
/** What one task changed on its branch since the run began — a race entrant's diff. */
|
|
537
548
|
taskDiff(runId: string, taskId: string): Promise<string>;
|
|
549
|
+
/**
|
|
550
|
+
* Remove the worktrees of runs that finished more than `days` ago — they're
|
|
551
|
+
* on their branches; the checkouts are only disk (#295). Returns the runs swept.
|
|
552
|
+
*/
|
|
553
|
+
sweep(days?: number, now?: number): Promise<string[]>;
|
|
538
554
|
/** Remove a finished run's worktrees (the branch stays for the record). */
|
|
539
555
|
cleanup(runId: string): Promise<void>;
|
|
540
556
|
shutdown(): Promise<void>;
|
package/dist/core/orchestra.js
CHANGED
|
@@ -38,6 +38,29 @@ import { blockedBy } from "./goal-lanes.js";
|
|
|
38
38
|
import { cutStack } from "./team-landing.js";
|
|
39
39
|
/** How much of a goal's budget may go before it says something. */
|
|
40
40
|
export const BUDGET_WARN_AT = 0.8;
|
|
41
|
+
/** What orchestra needs from the project that owns it. */
|
|
42
|
+
/**
|
|
43
|
+
* Where a project's orchestra worktrees go: under ~/.loom — unless the project
|
|
44
|
+
* lives on another volume (an external drive), where a sibling folder keeps
|
|
45
|
+
* the gigabytes on the project's own disk rather than the one that's tight
|
|
46
|
+
* (#295). `orchestra.worktreeDir` in .loom/config.json decides outright.
|
|
47
|
+
*/
|
|
48
|
+
export function orchestraWorktreeRoot(projectDir, projectId, override) {
|
|
49
|
+
if (override?.trim())
|
|
50
|
+
return path.resolve(projectDir, override.trim(), projectId);
|
|
51
|
+
const home = path.join(loomHome(), "orchestra", projectId);
|
|
52
|
+
try {
|
|
53
|
+
const sameDisk = fs.statSync(projectDir).dev === fs.statSync(loomHome()).dev;
|
|
54
|
+
if (sameDisk)
|
|
55
|
+
return home;
|
|
56
|
+
return path.join(path.dirname(projectDir), ".loom-worktrees", `${path.basename(projectDir)}-${projectId}`);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return home;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Finished runs keep their worktrees this long, then they're removed (the branches stay). */
|
|
63
|
+
export const ORCHESTRA_KEEP_DAYS = 7;
|
|
41
64
|
/**
|
|
42
65
|
* Pull the actions out of an orchestrator reply.
|
|
43
66
|
*
|
|
@@ -644,7 +667,7 @@ export class OrchestraEngine {
|
|
|
644
667
|
// Integration and task branches are siblings under one prefix: git can't
|
|
645
668
|
// hold both `a/b` and `a/b/c` as refs.
|
|
646
669
|
const branch = `loom/orchestra/${id}/main`;
|
|
647
|
-
const wtRoot = path.join(
|
|
670
|
+
const wtRoot = path.join(orchestraWorktreeRoot(this.host.projectDir, this.host.projectId, this.host.worktreeDir?.()), id);
|
|
648
671
|
const integration = path.join(wtRoot, "integration");
|
|
649
672
|
fs.mkdirSync(wtRoot, { recursive: true });
|
|
650
673
|
await this.gitLock.run(() => createWorktree(dir, integration, branch, baseCommit));
|
|
@@ -880,7 +903,7 @@ export class OrchestraEngine {
|
|
|
880
903
|
if (existing && !isTerminal(existing.status))
|
|
881
904
|
throw new Error(`run ${id} is active here already`);
|
|
882
905
|
await git(["fetch", "-q", "origin", `+refs/loom/run/${id}/*:refs/remotes/loom-run/${id}/*`], dir);
|
|
883
|
-
const wtRoot = path.join(
|
|
906
|
+
const wtRoot = path.join(orchestraWorktreeRoot(this.host.projectDir, this.host.projectId, this.host.worktreeDir?.()), id);
|
|
884
907
|
// a copy left here by an earlier move goes first
|
|
885
908
|
if (existing) {
|
|
886
909
|
const old = [existing.dir, ...existing.tasks.map((t) => t.dir).filter((d) => !!d)];
|
|
@@ -1104,6 +1127,26 @@ export class OrchestraEngine {
|
|
|
1104
1127
|
const patch = await git(["diff", `${run.baseCommit}...${task.branch}`], this.host.projectDir).catch(() => "");
|
|
1105
1128
|
return patch.length > 400_000 ? `${patch.slice(0, 400_000)}\n… (truncated)` : patch;
|
|
1106
1129
|
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Remove the worktrees of runs that finished more than `days` ago — they're
|
|
1132
|
+
* on their branches; the checkouts are only disk (#295). Returns the runs swept.
|
|
1133
|
+
*/
|
|
1134
|
+
async sweep(days = ORCHESTRA_KEEP_DAYS, now = Date.now()) {
|
|
1135
|
+
const swept = [];
|
|
1136
|
+
for (const run of [...this.runs.values()]) {
|
|
1137
|
+
if (!isTerminal(run.status) || now - (run.updatedAt ?? 0) < days * 86_400_000)
|
|
1138
|
+
continue;
|
|
1139
|
+
if (!run.dir || !fs.existsSync(run.dir))
|
|
1140
|
+
continue;
|
|
1141
|
+
await this.cleanup(run.id).catch(() => { });
|
|
1142
|
+
// the run's folder goes too once its worktrees are out of it
|
|
1143
|
+
const root = path.dirname(run.dir);
|
|
1144
|
+
if (path.basename(root) === run.id)
|
|
1145
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
1146
|
+
swept.push(run.id);
|
|
1147
|
+
}
|
|
1148
|
+
return swept;
|
|
1149
|
+
}
|
|
1107
1150
|
/** Remove a finished run's worktrees (the branch stays for the record). */
|
|
1108
1151
|
async cleanup(runId) {
|
|
1109
1152
|
const run = this.mustGet(runId);
|