@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.
Files changed (134) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +31 -10
  3. package/dist/adapters/antigravity-cli.d.ts +2 -0
  4. package/dist/adapters/antigravity-cli.js +27 -4
  5. package/dist/adapters/antigravity-cli.js.map +1 -1
  6. package/dist/adapters/model.js +1 -1
  7. package/dist/adapters/model.js.map +1 -1
  8. package/dist/adapters/opencode.d.ts +4 -0
  9. package/dist/adapters/opencode.js +18 -0
  10. package/dist/adapters/opencode.js.map +1 -1
  11. package/dist/cli/doctor.d.ts +38 -1
  12. package/dist/cli/doctor.js +157 -3
  13. package/dist/cli/doctor.js.map +1 -1
  14. package/dist/cli/index.js +357 -20
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/ui.js +11 -7
  17. package/dist/cli/ui.js.map +1 -1
  18. package/dist/core/auto-policy.d.ts +46 -0
  19. package/dist/core/auto-policy.js +181 -0
  20. package/dist/core/auto-policy.js.map +1 -0
  21. package/dist/core/council.d.ts +55 -0
  22. package/dist/core/council.js +73 -0
  23. package/dist/core/council.js.map +1 -0
  24. package/dist/core/crew-protocol.js +4 -1
  25. package/dist/core/crew-protocol.js.map +1 -1
  26. package/dist/core/crew.d.ts +13 -1
  27. package/dist/core/crew.js +40 -6
  28. package/dist/core/crew.js.map +1 -1
  29. package/dist/core/digest.d.ts +2 -0
  30. package/dist/core/digest.js +9 -0
  31. package/dist/core/digest.js.map +1 -1
  32. package/dist/core/loops.js +22 -2
  33. package/dist/core/loops.js.map +1 -1
  34. package/dist/core/orchestra.d.ts +16 -0
  35. package/dist/core/orchestra.js +45 -2
  36. package/dist/core/orchestra.js.map +1 -1
  37. package/dist/core/permissions.js +2 -2
  38. package/dist/core/permissions.js.map +1 -1
  39. package/dist/core/prices.d.ts +66 -0
  40. package/dist/core/prices.js +109 -0
  41. package/dist/core/prices.js.map +1 -0
  42. package/dist/core/proof.d.ts +13 -1
  43. package/dist/core/proof.js +89 -17
  44. package/dist/core/proof.js.map +1 -1
  45. package/dist/core/providers.d.ts +13 -0
  46. package/dist/core/providers.js +17 -0
  47. package/dist/core/providers.js.map +1 -1
  48. package/dist/core/replay.js +14 -0
  49. package/dist/core/replay.js.map +1 -1
  50. package/dist/core/review.d.ts +60 -0
  51. package/dist/core/review.js +121 -0
  52. package/dist/core/review.js.map +1 -0
  53. package/dist/core/routes.js +14 -0
  54. package/dist/core/routes.js.map +1 -1
  55. package/dist/core/setup.d.ts +27 -0
  56. package/dist/core/setup.js +39 -7
  57. package/dist/core/setup.js.map +1 -1
  58. package/dist/core/shield.js +7 -3
  59. package/dist/core/shield.js.map +1 -1
  60. package/dist/core/shift.d.ts +2 -0
  61. package/dist/core/shift.js +14 -2
  62. package/dist/core/shift.js.map +1 -1
  63. package/dist/core/turn-wait.d.ts +20 -0
  64. package/dist/core/turn-wait.js +39 -0
  65. package/dist/core/turn-wait.js.map +1 -0
  66. package/dist/core/usage.d.ts +7 -1
  67. package/dist/core/usage.js +11 -3
  68. package/dist/core/usage.js.map +1 -1
  69. package/dist/daemon/client.d.ts +60 -1
  70. package/dist/daemon/client.js +40 -1
  71. package/dist/daemon/client.js.map +1 -1
  72. package/dist/daemon/council.d.ts +98 -0
  73. package/dist/daemon/council.js +254 -0
  74. package/dist/daemon/council.js.map +1 -0
  75. package/dist/daemon/proof.d.ts +6 -0
  76. package/dist/daemon/proof.js +32 -9
  77. package/dist/daemon/proof.js.map +1 -1
  78. package/dist/daemon/push.js +7 -0
  79. package/dist/daemon/push.js.map +1 -1
  80. package/dist/daemon/review.d.ts +95 -0
  81. package/dist/daemon/review.js +154 -0
  82. package/dist/daemon/review.js.map +1 -0
  83. package/dist/daemon/routes/council.d.ts +4 -0
  84. package/dist/daemon/routes/council.js +29 -0
  85. package/dist/daemon/routes/council.js.map +1 -0
  86. package/dist/daemon/routes/crews.js +2 -0
  87. package/dist/daemon/routes/crews.js.map +1 -1
  88. package/dist/daemon/routes/messages.js +8 -2
  89. package/dist/daemon/routes/messages.js.map +1 -1
  90. package/dist/daemon/routes/review.d.ts +4 -0
  91. package/dist/daemon/routes/review.js +40 -0
  92. package/dist/daemon/routes/review.js.map +1 -0
  93. package/dist/daemon/routes/routing.js +2 -1
  94. package/dist/daemon/routes/routing.js.map +1 -1
  95. package/dist/daemon/routes/setup.d.ts +2 -1
  96. package/dist/daemon/routes/setup.js +22 -6
  97. package/dist/daemon/routes/setup.js.map +1 -1
  98. package/dist/daemon/runtime/accounting.d.ts +6 -0
  99. package/dist/daemon/runtime/accounting.js +37 -1
  100. package/dist/daemon/runtime/accounting.js.map +1 -1
  101. package/dist/daemon/runtime/briefings.d.ts +8 -3
  102. package/dist/daemon/runtime/briefings.js +26 -14
  103. package/dist/daemon/runtime/briefings.js.map +1 -1
  104. package/dist/daemon/runtime/queue.d.ts +7 -0
  105. package/dist/daemon/runtime/queue.js +13 -1
  106. package/dist/daemon/runtime/queue.js.map +1 -1
  107. package/dist/daemon/runtime/relay.d.ts +2 -0
  108. package/dist/daemon/runtime/relay.js +7 -0
  109. package/dist/daemon/runtime/relay.js.map +1 -1
  110. package/dist/daemon/runtime/turns.d.ts +2 -0
  111. package/dist/daemon/runtime/turns.js +1 -0
  112. package/dist/daemon/runtime/turns.js.map +1 -1
  113. package/dist/daemon/runtime-support.js +1 -1
  114. package/dist/daemon/runtime-support.js.map +1 -1
  115. package/dist/daemon/runtime.d.ts +65 -3
  116. package/dist/daemon/runtime.js +238 -5
  117. package/dist/daemon/runtime.js.map +1 -1
  118. package/dist/daemon/server.js +5 -1
  119. package/dist/daemon/server.js.map +1 -1
  120. package/dist/daemon/shift.js +1 -1
  121. package/dist/daemon/shift.js.map +1 -1
  122. package/dist/providers/agent.js +6 -0
  123. package/dist/providers/agent.js.map +1 -1
  124. package/dist/providers/claude/adapter.d.ts +3 -0
  125. package/dist/providers/claude/adapter.js +20 -1
  126. package/dist/providers/claude/adapter.js.map +1 -1
  127. package/dist/types.d.ts +31 -1
  128. package/dist/types.js.map +1 -1
  129. package/dist/web/app.css +51 -0
  130. package/dist/web/app.js +172 -18
  131. package/dist/web/app.js.map +3 -3
  132. package/docs/release-notes/v1.2.0.md +48 -0
  133. package/docs/release-notes/v1.2.1.md +40 -0
  134. package/package.json +1 -1
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Review: the runner (#253). Each reviewer is a read-only subtask in the
3
+ * review's own chat — none takes the baton, so nobody is asked to hand off
4
+ * for a read — and once the last one has answered, one `review` card collects
5
+ * every finding to accept (it becomes a project decision) or reject. The
6
+ * reading of replies is core/review.ts.
7
+ *
8
+ * Events, one kind, `payload.phase`:
9
+ * started { reviewId, chat, target, agents, focus? }
10
+ * done { reviewId, chat, target, results[], findings[], summary }
11
+ * decided { reviewId, findingId, decision, note? }
12
+ */
13
+ import { randomUUID } from "node:crypto";
14
+ import { collectFindings, decisionText, reviewPrompt, reviewSummary, targetLabel } from "../core/review.js";
15
+ /** What a target looks like on a card: the diff itself stays in the brief. */
16
+ const slim = (t) => (t.kind === "file" ? { kind: "file", file: t.file } : t.kind === "text" ? { kind: "text", label: targetLabel(t) } : { kind: t.kind });
17
+ export class ReviewRunner {
18
+ host;
19
+ pending = new Map();
20
+ /** Reviews still waiting on a reviewer. */
21
+ get running() { return this.pending.size; }
22
+ constructor(host) {
23
+ this.host = host;
24
+ // a review the daemon restarted under will never hear back: close it, saying so
25
+ for (const e of host.list({ kinds: ["review"] })) {
26
+ if (e.payload.phase !== "started")
27
+ continue;
28
+ const id = String(e.payload.reviewId);
29
+ if (host.list({ kinds: ["review"], chat: String(e.chat ?? "main") }).some((d) => d.payload.phase === "done" && d.payload.reviewId === id))
30
+ continue;
31
+ const agents = e.payload.agents ?? [];
32
+ this.finish(id, String(e.chat), e.payload.target, agents, new Map(agents.map((a) => [a, { ok: false, message: "Loom restarted before it answered" }])), e.ts);
33
+ }
34
+ }
35
+ /** The reviewers, deduplicated — or why they can't review. */
36
+ check(names) {
37
+ const agents = [...new Set(names.map((a) => a.trim()).filter(Boolean))];
38
+ if (!agents.length)
39
+ throw new Error("name at least one agent to review");
40
+ if (agents.length > this.host.maxReviewers)
41
+ throw new Error(`${agents.length} reviewers — ${this.host.maxReviewers} at a time is the limit`);
42
+ for (const a of agents) {
43
+ if (!this.host.hasAgent(a))
44
+ throw new Error(`no agent "${a}" in this project`);
45
+ if (!this.host.canReview(a))
46
+ throw new Error(`"${a}" can't run a review (it's a bridge, or switched off)`);
47
+ }
48
+ return agents;
49
+ }
50
+ async start(input) {
51
+ const agents = this.check(input.agents);
52
+ if (input.target.kind === "file" && !input.target.file.trim())
53
+ throw new Error("which file?");
54
+ const reviewId = randomUUID().slice(0, 6);
55
+ const label = targetLabel(input.target);
56
+ const chat = input.chat ?? this.host.createChat(`🔍 Review · ${label}`.slice(0, 60)).id;
57
+ const target = slim(input.target);
58
+ // the parent a child is filed under: whoever holds the baton, which a review never takes
59
+ const parent = this.host.holder() ?? agents[0];
60
+ const run = { chat, target, agents, settled: new Map(), startedAt: Date.now() };
61
+ this.pending.set(reviewId, run);
62
+ this.host.append({ kind: "review", chat, payload: { phase: "started", reviewId, chat, target, agents, ...(input.focus ? { focus: input.focus } : {}) } });
63
+ const task = reviewPrompt(input.target, input.focus);
64
+ const limit = this.host.reviewerTimeoutMs?.() ?? 15 * 60_000;
65
+ for (const agentId of agents) {
66
+ let timer;
67
+ const settle = (o) => {
68
+ if (timer)
69
+ clearTimeout(timer);
70
+ if (run.settled.has(agentId))
71
+ return; // a late answer after the time ran out
72
+ run.settled.set(agentId, o);
73
+ if (run.settled.size === agents.length && this.pending.delete(reviewId))
74
+ this.finish(reviewId, chat, target, agents, run.settled, run.startedAt);
75
+ };
76
+ // one slow reviewer (a free model in a queue) shouldn't hold everyone's findings hostage
77
+ timer = setTimeout(() => {
78
+ const took = limit >= 60_000 ? `${Math.round(limit / 60_000)} min` : `${Math.round(limit / 1000)}s`;
79
+ settle({ ok: false, message: `took longer than ${took} — left out (review.timeoutMin in .loom/config.json)` });
80
+ void this.host.stopReviewer?.(agentId).catch(() => { });
81
+ }, limit);
82
+ timer.unref?.();
83
+ try {
84
+ await this.host.spawn(parent, { agentId, task, chat, readOnly: true, onSettled: settle });
85
+ }
86
+ catch (err) {
87
+ settle({ ok: false, message: err instanceof Error ? err.message : String(err) });
88
+ }
89
+ }
90
+ return { reviewId, chat, target, agents, status: "running" };
91
+ }
92
+ /** The reviewer's answer: its last reply in the review's chat. */
93
+ replyOf(chat, agent, since) {
94
+ const msgs = this.host.list({ chat, agentId: agent, kinds: ["message"], sinceTs: since }).filter((m) => !m.payload.reasoning && typeof m.payload.text === "string");
95
+ return String(msgs.at(-1)?.payload.text ?? "");
96
+ }
97
+ editsOf(chat, agent, since) {
98
+ const paths = this.host.list({ chat, agentId: agent, kinds: ["file_edit"], sinceTs: since }).map((e) => String(e.payload.path ?? "")).filter(Boolean);
99
+ return [...new Set(paths)];
100
+ }
101
+ finish(reviewId, chat, target, agents, settled, since) {
102
+ const results = agents.map((agent) => {
103
+ const s = settled.get(agent);
104
+ const reply = this.replyOf(chat, agent, since);
105
+ const edited = this.editsOf(chat, agent, since);
106
+ // a turn that ended without a word didn't review anything (#278)
107
+ const answered = s?.ok && reply.trim().length > 0;
108
+ const base = answered ? { agent, status: "done", reply: reply.slice(0, 6000) }
109
+ : { agent, status: "failed", error: s?.ok ? "it finished without a reply" : s?.message ?? "no answer", reply: reply.slice(0, 6000) };
110
+ return edited.length ? { ...base, edited } : base;
111
+ });
112
+ const findings = collectFindings(reviewId, results.filter((r) => r.status === "done").map((r) => ({ agent: r.agent, reply: r.reply })));
113
+ this.host.append({ kind: "review", chat, payload: { phase: "done", reviewId, chat, target, results, findings, summary: reviewSummary(results, findings) } });
114
+ }
115
+ doneEvent(reviewId) {
116
+ return this.host.list({ kinds: ["review"] }).find((e) => e.payload.phase === "done" && e.payload.reviewId === reviewId);
117
+ }
118
+ status(reviewId) {
119
+ const started = this.host.list({ kinds: ["review"] }).find((e) => e.payload.phase === "started" && e.payload.reviewId === reviewId);
120
+ if (!started)
121
+ return null;
122
+ const base = { reviewId, chat: String(started.payload.chat), target: started.payload.target, agents: started.payload.agents };
123
+ const done = this.doneEvent(reviewId);
124
+ if (!done)
125
+ return { ...base, status: "running" };
126
+ const decided = new Map(this.host.list({ kinds: ["review"], chat: base.chat }).filter((e) => e.payload.phase === "decided" && e.payload.reviewId === reviewId)
127
+ .map((e) => [String(e.payload.findingId), { decision: e.payload.decision, ...(e.payload.note ? { note: String(e.payload.note) } : {}) }]));
128
+ return { ...base, status: "done", results: done.payload.results, summary: String(done.payload.summary),
129
+ findings: done.payload.findings.map((f) => ({ ...f, ...decided.get(f.id) })) };
130
+ }
131
+ /** Accept (it becomes a project decision every agent is briefed with) or reject one finding. */
132
+ decide(findingId, decision, note) {
133
+ if (decision !== "accepted" && decision !== "rejected")
134
+ throw new Error("accept or reject");
135
+ const reviewId = findingId.split(".")[0];
136
+ const done = this.doneEvent(reviewId);
137
+ if (!done)
138
+ throw new Error(this.status(reviewId) ? "that review is still running" : `no review finding "${findingId}"`);
139
+ const finding = done.payload.findings.find((f) => f.id === findingId);
140
+ if (!finding)
141
+ throw new Error(`no finding "${findingId}" in review ${reviewId}`);
142
+ const was = this.status(reviewId).findings.find((f) => f.id === findingId).decision;
143
+ this.host.append({ kind: "review", chat: String(done.chat ?? done.payload.chat), payload: { phase: "decided", reviewId, findingId, decision, ...(note ? { note } : {}), text: finding.text } });
144
+ if (decision === "accepted" && was !== "accepted")
145
+ this.host.decide(decisionText(finding, note));
146
+ return { finding, decision };
147
+ }
148
+ /** The latest reviews, newest first. */
149
+ recent(limit = 10) {
150
+ return this.host.list({ kinds: ["review"] }).filter((e) => e.payload.phase === "started").slice(-limit).reverse()
151
+ .map((e) => this.status(String(e.payload.reviewId))).filter(Boolean);
152
+ }
153
+ }
154
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/daemon/review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Express } from 'express';
2
+ import type { WithRuntime } from './context.js';
3
+ /** Register Council routes (daemon/council.ts) in the order established by LoomDaemon.routes(). */
4
+ export declare function registerCouncilRoutes(app: Express, withRuntime: WithRuntime): void;
@@ -0,0 +1,29 @@
1
+ /** Register Council routes (daemon/council.ts) in the order established by LoomDaemon.routes(). */
2
+ export function registerCouncilRoutes(app, withRuntime) {
3
+ // Start one: { goal, planner, reviewers: string[] | "a,b" }
4
+ app.post("/api/projects/:id/councils", withRuntime(async (rt, req, res) => {
5
+ const b = (req.body ?? {});
6
+ const reviewers = Array.isArray(b.reviewers) ? b.reviewers.map(String) : typeof b.reviewers === "string" ? b.reviewers.split(",").map((r) => r.trim()).filter(Boolean) : [];
7
+ try {
8
+ res.json({ council: rt.councils.start({ goal: String(b.goal ?? ""), planner: String(b.planner ?? ""), reviewers }) });
9
+ }
10
+ catch (err) {
11
+ res.status(400).json({ error: err instanceof Error ? err.message : String(err) });
12
+ }
13
+ }));
14
+ app.get("/api/projects/:id/councils", withRuntime(async (rt, _req, res) => void res.json({ active: rt.councils.active, councils: rt.councils.recent() })));
15
+ app.get("/api/projects/:id/councils/:councilId", withRuntime(async (rt, req, res) => {
16
+ const council = rt.councils.status(String(req.params.councilId));
17
+ if (!council)
18
+ return void res.status(404).json({ error: "no such council" });
19
+ res.json({ council });
20
+ }));
21
+ // Stop after the current stage (a turn in progress is interrupted).
22
+ app.delete("/api/projects/:id/councils", withRuntime(async (rt, _req, res) => {
23
+ const council = await rt.councils.stop();
24
+ if (!council)
25
+ return void res.status(404).json({ error: "no council is running" });
26
+ res.json({ council });
27
+ }));
28
+ }
29
+ //# sourceMappingURL=council.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"council.js","sourceRoot":"","sources":["../../../src/daemon/routes/council.ts"],"names":[],"mappings":"AAGA,mGAAmG;AACnG,MAAM,UAAU,qBAAqB,CAAC,GAAY,EAAE,WAAwB;IAC1E,4DAA4D;IAC5D,GAAG,CAAC,IAAI,CACN,4BAA4B,EAC5B,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACjC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAA+D,CAAC;QACzF,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5K,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QACxH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,GAAG,CAAC,GAAG,CAAC,4BAA4B,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAE3J,GAAG,CAAC,GAAG,CACL,uCAAuC,EACvC,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC7E,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CACH,CAAC;IAEF,oEAAoE;IACpE,GAAG,CAAC,MAAM,CACR,4BAA4B,EAC5B,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACnF,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -24,6 +24,8 @@ export function registerCrewsRoutes(app, withRuntime) {
24
24
  try {
25
25
  res.json({ crew: rt.crews.create({
26
26
  ...(b.name ? { name: String(b.name) } : {}),
27
+ ...(b.seats && typeof b.seats === "object" ? { seats: { ...(b.seats.lead ? { lead: String(b.seats.lead) } : {}), ...(Array.isArray(b.seats.builders) ? { builders: b.seats.builders.map(String) } : {}),
28
+ ...(b.seats.reviewer ? { reviewer: String(b.seats.reviewer) } : {}), ...(b.seats.tester ? { tester: String(b.seats.tester) } : {}) } } : {}),
27
29
  ...(b.template ? { template: String(b.template) } : {}),
28
30
  ...(Array.isArray(b.teammates) ? { teammates: b.teammates } : {}),
29
31
  ...(typeof b.planApproval === "boolean" ? { planApproval: b.planApproval } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"crews.js","sourceRoot":"","sources":["../../../src/daemon/routes/crews.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crews.js","sourceRoot":"","sources":["../../../src/daemon/routes/crews.ts"],"names":[],"mappings":"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"}
@@ -24,18 +24,23 @@ export function registerMessagesRoutes(app, withRuntime) {
24
24
  const opening = chat && since === undefined && before === undefined;
25
25
  res.json({ events, ...(opening ? { live: rt.liveNow(chat) } : {}) });
26
26
  }));
27
+ // How heavy an agent's session in a chat is, and whether its cache has likely gone cold —
28
+ // so a short question can be warned before it re-reads 170k tokens (#280)
29
+ app.get("/api/projects/:id/agents/:agentId/session", withRuntime(async (rt, req, res) => {
30
+ res.json({ session: rt.sessionWeight(String(req.params.agentId), String(req.query.chat ?? "main")) });
31
+ }));
27
32
  app.post("/api/projects/:id/messages", withRuntime(async (rt, req, res) => {
28
33
  if (rt.continuity) {
29
34
  try {
30
35
  parseBounded(z.strictObject({ text: Text.min(1), agentId: Id.optional(), chat: Id.optional(),
31
- plan: z.boolean().optional(), requestId: Id.optional(), length: z.enum(["brief", "normal", "detailed"]).optional() }), req.body);
36
+ plan: z.boolean().optional(), fresh: z.boolean().optional(), requestId: Id.optional(), length: z.enum(["brief", "normal", "detailed"]).optional() }), req.body);
32
37
  }
33
38
  catch (error) {
34
39
  res.status(400).json({ error: error instanceof Error ? error.message : "invalid continuity request", code: "invalid" });
35
40
  return;
36
41
  }
37
42
  }
38
- const { text, agentId, chat, plan, requestId, length } = (req.body ?? {});
43
+ const { text, agentId, chat, plan, fresh, requestId, length } = (req.body ?? {});
39
44
  if (!text?.trim())
40
45
  return void res.status(400).json({ error: "missing text" });
41
46
  let result;
@@ -43,6 +48,7 @@ export function registerMessagesRoutes(app, withRuntime) {
43
48
  result = await rt.sendMessage(text, agentId, {
44
49
  ...(chat ? { chat } : {}),
45
50
  ...(plan ? { plan: true } : {}),
51
+ ...(fresh ? { fresh: true } : {}),
46
52
  ...(requestId ? { requestId } : {}),
47
53
  ...(length === "brief" || length === "detailed" ? { length } : {}),
48
54
  });
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/daemon/routes/messages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/daemon/routes/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Express } from 'express';
2
+ import type { WithRuntime } from './context.js';
3
+ /** Register Review routes (daemon/review.ts) in the order established by LoomDaemon.routes(). */
4
+ export declare function registerReviewRoutes(app: Express, withRuntime: WithRuntime): void;
@@ -0,0 +1,40 @@
1
+ /** Register Review routes (daemon/review.ts) in the order established by LoomDaemon.routes(). */
2
+ export function registerReviewRoutes(app, withRuntime) {
3
+ const bad = (res, err) => res.status(400).json({ error: err instanceof Error ? err.message : String(err) });
4
+ // Start one: { agents: string[], file?, text?, focus? } — no file and no text reviews the uncommitted changes.
5
+ app.post("/api/projects/:id/reviews", withRuntime(async (rt, req, res) => {
6
+ const b = (req.body ?? {});
7
+ const agents = Array.isArray(b.agents) ? b.agents.map(String) : typeof b.agents === "string" ? b.agents.split(",") : [];
8
+ try {
9
+ const review = await rt.startReview({
10
+ agents,
11
+ ...(typeof b.file === "string" && b.file ? { file: b.file } : {}),
12
+ ...(typeof b.text === "string" && b.text ? { text: b.text } : {}),
13
+ ...(typeof b.focus === "string" && b.focus ? { focus: b.focus } : {}),
14
+ });
15
+ res.json({ review });
16
+ }
17
+ catch (err) {
18
+ bad(res, err);
19
+ }
20
+ }));
21
+ app.get("/api/projects/:id/reviews", withRuntime(async (rt, _req, res) => void res.json({ reviews: rt.reviews.recent() })));
22
+ app.get("/api/projects/:id/reviews/:reviewId", withRuntime(async (rt, req, res) => {
23
+ const review = rt.reviews.status(String(req.params.reviewId));
24
+ if (!review)
25
+ return void res.status(404).json({ error: "no such review" });
26
+ res.json({ review });
27
+ }));
28
+ // Accept (it becomes a decision) or reject one finding: { decision: "accepted" | "rejected", note? }
29
+ app.post("/api/projects/:id/findings/:findingId", withRuntime(async (rt, req, res) => {
30
+ const b = (req.body ?? {});
31
+ const decision = b.decision === "accept" ? "accepted" : b.decision === "reject" ? "rejected" : b.decision;
32
+ try {
33
+ res.json(rt.reviews.decide(String(req.params.findingId), decision, typeof b.note === "string" && b.note.trim() ? b.note.trim() : undefined));
34
+ }
35
+ catch (err) {
36
+ bad(res, err);
37
+ }
38
+ }));
39
+ }
40
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/daemon/routes/review.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { usageReport } from '../../core/usage.js';
2
+ import { priceBook } from '../../core/prices.js';
2
3
  /** Register routing routes in the order established by LoomDaemon.routes(). */
3
4
  export function registerRoutingRoutes(app, withRuntime) {
4
5
  app.post("/api/projects/:id/route", withRuntime(async (rt, req, res) => {
@@ -34,7 +35,7 @@ export function registerRoutingRoutes(app, withRuntime) {
34
35
  }
35
36
  // the report skips everything before `since`: don't read (and parse) it
36
37
  const events = rt.log.list({ kinds: ["status", "run_complete", "tool_call", "error", "message", "needs_input", "turn_diff"], sinceTs: since });
37
- const usage = usageReport(events, { since, kinds, models });
38
+ const usage = usageReport(events, { since, kinds, models, prices: priceBook() });
38
39
  const titles = new Map(rt.chats().map((c) => [c.id, c.title]));
39
40
  res.json({ days, usage: { ...usage, byChat: usage.byChat.map((c) => ({ ...c, title: titles.get(c.chat) ?? (c.chat === "main" ? "Main" : c.chat) })) } });
40
41
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../../src/daemon/routes/routing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../../src/daemon/routes/routing.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
1
  import type { Express } from 'express';
2
+ import type { RouteContext } from './context.js';
2
3
  /** Register setup routes in the order established by LoomDaemon.routes(). */
3
- export declare function registerSetupRoutes(app: Express): void;
4
+ export declare function registerSetupRoutes(app: Express, ctx: Pick<RouteContext, "runtimes">): void;
@@ -1,8 +1,9 @@
1
+ import { readProjectConfig } from "../../core/registry.js";
1
2
  import { findProject } from "../../core/registry.js";
2
- import { setupReport } from "../../core/setup.js";
3
+ import { setupReport, signInCommand } from "../../core/setup.js";
3
4
  import { forgetProbes } from "../../adapters/base.js";
4
5
  /** Register setup routes in the order established by LoomDaemon.routes(). */
5
- export function registerSetupRoutes(app) {
6
+ export function registerSetupRoutes(app, ctx) {
6
7
  /**
7
8
  * What this machine still needs — the same answer `loom doctor` gives.
8
9
  *
@@ -31,15 +32,30 @@ export function registerSetupRoutes(app) {
31
32
  forgetProbes();
32
33
  void (async () => {
33
34
  try {
34
- const { envChecks, projectChecks } = await import("../../cli/doctor.js");
35
- const checks = await envChecks();
35
+ const { envChecks, projectChecks, providerChecks, freeModelTrouble, envFacts } = await import("../../cli/doctor.js");
36
+ const [checks, providers] = await Promise.all([envChecks(), providerChecks()]);
37
+ // a turn that failed "not signed in" outranks the CLI's own sign-in file (#274)
38
+ for (const rt of ctx.runtimes.values()) {
39
+ for (const s of rt.learnedSignOuts()) {
40
+ const i = checks.findIndex((c) => c.name === s.kind);
41
+ if (i >= 0 && checks[i].status !== "fail")
42
+ checks[i] = { name: s.kind, status: "fail", detail: `a turn by ${s.agentId} failed: “${s.message}”${signInCommand(s.kind) ? ` — ${signInCommand(s.kind)}` : ""}` };
43
+ }
44
+ }
45
+ checks.push(...providers);
36
46
  const projId = req.query.project;
37
47
  if (projId) {
38
48
  const info = findProject(projId);
39
- if (info)
49
+ if (info) {
40
50
  checks.push(...projectChecks(info.dir));
51
+ const rt = ctx.runtimes.get(info.id);
52
+ const agents = readProjectConfig(info.dir)?.agents ?? [];
53
+ if (rt)
54
+ checks.push(...freeModelTrouble(rt.log.list({ kinds: ["error"], sinceTs: Date.now() - 86_400_000 }), agents));
55
+ }
41
56
  }
42
- res.json({ checks });
57
+ // what this daemon process sees — PATH and key NAMES, never values — so `loom doctor` can compare it with the shell
58
+ res.json({ checks, facts: envFacts() });
43
59
  }
44
60
  catch (err) {
45
61
  res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/daemon/routes/setup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,6EAA6E;AAC7E,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAE9C;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAClC,YAAY,EAAE,CAAC,CAAC,8EAA8E;QAC9F,KAAK,WAAW,EAAE;aACf,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aAClC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH;;;;;OAKG;IACH,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAClC,YAAY,EAAE,CAAC;QACf,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;gBACzE,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;gBACjC,MAAM,MAAM,GAAI,GAAG,CAAC,KAAgC,CAAC,OAAO,CAAC;gBAC7D,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;oBACjC,IAAI,IAAI;wBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBACpD,CAAC;gBACD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YACvB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/daemon/routes/setup.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,10 @@ export declare class RuntimeAccounting {
25
25
  tokensIn: number;
26
26
  tokensOut: number;
27
27
  }>;
28
+ /** Whether an agent's current turn has reported money yet — a turn that ends without any is unpriced. */
29
+ private pricedTurn;
30
+ /** Unpriced turns' tokens, per agent per model, priced only when asked (the price list may arrive later). */
31
+ private unpriced;
28
32
  /** Each agent's latest turns — cost and time — for the pre-flight forecast (core/forecast.ts). */
29
33
  private recent;
30
34
  private recentFor;
@@ -32,6 +36,8 @@ export declare class RuntimeAccounting {
32
36
  forecast(agentId: string): Forecast | null;
33
37
  rehydrateCosts(): void;
34
38
  trackCost(event: LoomEvent): void;
39
+ /** An agent's unpriced tokens at API prices; undefined when there are none, or no price for them. */
40
+ private estimateFor;
35
41
  costSummary(): CostSummary;
36
42
  /** Per-agent spend budgets (USD/day), set from the Observatory burn-rate panel. */
37
43
  budgets(): Record<string, number>;
@@ -1,5 +1,6 @@
1
1
  import { readProjectState, writeProjectState } from "../../core/registry.js";
2
2
  import { Recent, forecastFrom } from "../../core/forecast.js";
3
+ import { estimateUsd, priceBook } from "../../core/prices.js";
3
4
  import { BUDGET_PAUSE_REASON, BudgetExceededError, QuarantinedError, startOfDay } from '../runtime-support.js';
4
5
  /** Owns accounting state for exactly one open project. */
5
6
  export class RuntimeAccounting {
@@ -12,6 +13,10 @@ export class RuntimeAccounting {
12
13
  // -------------------------------------------------------------------------
13
14
  costs = { totalUsd: 0, turns: 0, totalMs: 0, tokensIn: 0, tokensOut: 0 };
14
15
  costsByAgent = new Map();
16
+ /** Whether an agent's current turn has reported money yet — a turn that ends without any is unpriced. */
17
+ pricedTurn = new Map();
18
+ /** Unpriced turns' tokens, per agent per model, priced only when asked (the price list may arrive later). */
19
+ unpriced = new Map();
15
20
  /** Each agent's latest turns — cost and time — for the pre-flight forecast (core/forecast.ts). */
16
21
  recent = new Map();
17
22
  recentFor(agentId) {
@@ -41,6 +46,7 @@ export class RuntimeAccounting {
41
46
  if (event.kind === "status" && event.payload.state === "turn_cost") {
42
47
  const usd = Number(event.payload.costUsd ?? 0);
43
48
  if (usd > 0) {
49
+ this.pricedTurn.set(agentId, true);
44
50
  this.recentFor(agentId).usd.push(usd);
45
51
  this.costs.totalUsd += usd;
46
52
  entry.usd += usd;
@@ -82,13 +88,43 @@ export class RuntimeAccounting {
82
88
  entry.tokensIn += tin;
83
89
  entry.tokensOut += tout;
84
90
  this.costsByAgent.set(agentId, entry);
91
+ const priced = this.pricedTurn.get(agentId) || Number(event.payload.costUsd ?? 0) > 0;
92
+ this.pricedTurn.delete(agentId);
93
+ if (!priced && (tin || tout) && event.payload.model) {
94
+ const byModel = this.unpriced.get(agentId) ?? new Map();
95
+ const m = byModel.get(String(event.payload.model)) ?? { tokensIn: 0, tokensOut: 0, cachedIn: 0 };
96
+ m.tokensIn += tin;
97
+ m.tokensOut += tout;
98
+ m.cachedIn += Number(event.payload.cachedInputTokens ?? 0) || 0;
99
+ byModel.set(String(event.payload.model), m);
100
+ this.unpriced.set(agentId, byModel);
101
+ }
102
+ }
103
+ }
104
+ /** An agent's unpriced tokens at API prices; undefined when there are none, or no price for them. */
105
+ estimateFor(agentId) {
106
+ const byModel = this.unpriced.get(agentId);
107
+ if (!byModel)
108
+ return undefined;
109
+ const book = priceBook();
110
+ let usd;
111
+ for (const [model, t] of byModel) {
112
+ const est = estimateUsd({ model, ...t }, book);
113
+ if (est !== undefined)
114
+ usd = (usd ?? 0) + est;
85
115
  }
116
+ return usd;
86
117
  }
87
118
  costSummary() {
88
119
  const byAgent = [...this.costsByAgent.entries()]
89
- .map(([agentId, c]) => ({ agentId, ...c }))
120
+ .map(([agentId, c]) => {
121
+ const estUsd = this.estimateFor(agentId);
122
+ return { agentId, ...c, ...(estUsd !== undefined ? { estUsd } : {}) };
123
+ })
90
124
  .sort((a, b) => b.usd - a.usd || b.turns - a.turns);
125
+ const estimated = byAgent.filter((a) => a.estUsd !== undefined);
91
126
  return {
127
+ ...(estimated.length ? { estUsd: estimated.reduce((sum, a) => sum + a.estUsd, 0) } : {}),
92
128
  totalUsd: this.costs.totalUsd,
93
129
  turns: this.costs.turns,
94
130
  totalMs: this.costs.totalMs,