@ra3orblade/swarm 0.8.0 → 0.9.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/dist/swarm-hook.js +3 -1
- package/dist/swarm-mcp.js +35 -6
- package/dist/swarm.js +184 -9
- package/dist/swarmd.js +954 -75
- package/package.json +1 -1
- package/web/app.js +150 -11
- package/web/index.html +43 -0
- package/web/release-notes.js +1 -1
- package/web/viz.js +20 -3
package/web/viz.js
CHANGED
|
@@ -131,7 +131,7 @@ function turnStripRender(turns, height) {
|
|
|
131
131
|
* Session lanes over a time window. sessions: [{id,title,agent,projectId,startedAt,lastSeenAt,state,costUsd}]
|
|
132
132
|
* One row per session, grouped by project; bar from start to last-seen, coloured by agent.
|
|
133
133
|
*/
|
|
134
|
-
function timeline(sessions, { from, to, projName, now = Date.now() } = {}) {
|
|
134
|
+
function timeline(sessions, { from, to, projName, now = Date.now(), detail = null } = {}) {
|
|
135
135
|
const span = Math.max(1, to - from);
|
|
136
136
|
const x = (t) => Math.min(100, Math.max(0, (100 * (t - from)) / span));
|
|
137
137
|
const byProj = new Map();
|
|
@@ -150,10 +150,27 @@ function timeline(sessions, { from, to, projName, now = Date.now() } = {}) {
|
|
|
150
150
|
const b = Math.min(to, new Date(s.lastSeenAt).getTime());
|
|
151
151
|
const live = s.state === "active" || s.state === "waiting";
|
|
152
152
|
const tip = `<b>${attr(s.title ?? s.id.slice(0, 8))}</b><br><i style="background:${agentColor(s.agent)}"></i>${agentName(s.agent)} · ${s.state}<br>${hm(s.startedAt)} → ${hm(s.lastSeenAt)} · ${fmtUsd(s.costUsd)} · ${s.turns} turns`;
|
|
153
|
-
|
|
153
|
+
// M5.7: with per-turn timestamps the bar is a faint base + a tick per turn — the blank
|
|
154
|
+
// stretches between ticks are the idle gaps, visible instead of painted over.
|
|
155
|
+
const ts = (detail?.turns?.[s.id] ?? []).filter((t) => t >= a && t <= b);
|
|
156
|
+
const ticks = ts.map((t) => `<u style="left:${x(t)}%;background:${agentColor(s.agent)}"></u>`).join("");
|
|
157
|
+
const barCls = `${live ? "live" : ""}${ts.length ? " thin" : ""}`;
|
|
158
|
+
return `<div class="tl-row" data-s="${s.id}"><span class="tl-name">${attr(s.title ?? s.id.slice(0, 8))}</span><span class="tl-track">${gridLines}<i data-tip="${attr(tip)}" class="${barCls}" style="left:${x(a)}%;width:${Math.max(0.4, x(b) - x(a))}%;background:${agentColor(s.agent)};color:${agentColor(s.agent)}"></i>${ticks}</span></div>`;
|
|
154
159
|
})
|
|
155
160
|
.join("");
|
|
156
|
-
|
|
161
|
+
// M5.7: claim & lease overlay — one thin lane per project when any claim overlaps the window
|
|
162
|
+
const spans = (detail?.claims ?? []).filter((c) => c.projectId === pid && new Date(c.expiresAt).getTime() >= from && new Date(c.acquiredAt).getTime() <= to);
|
|
163
|
+
const lane = spans.length
|
|
164
|
+
? `<div class="tl-row claimlane"><span class="tl-name dim">claims</span><span class="tl-track">${gridLines}${spans
|
|
165
|
+
.map((c) => {
|
|
166
|
+
const a = Math.max(from, new Date(c.acquiredAt).getTime());
|
|
167
|
+
const b = Math.min(to, new Date(c.expiresAt).getTime());
|
|
168
|
+
const tip = `<b>${attr(c.task)}</b><br>${c.state} · ${attr(c.owner || "?")}<br>lease ${hm(c.acquiredAt)} → ${hm(c.expiresAt)}`;
|
|
169
|
+
return `<i data-tip="${attr(tip)}" class="claim ${c.state}" style="left:${x(a)}%;width:${Math.max(0.4, x(b) - x(a))}%"></i>`;
|
|
170
|
+
})
|
|
171
|
+
.join("")}</span></div>`
|
|
172
|
+
: "";
|
|
173
|
+
return `<div class="tl-group"><div class="tl-proj">${attr(projName(pid))}<small>${list.length}</small></div>${lane}${rows}</div>`;
|
|
157
174
|
});
|
|
158
175
|
return `<div class="tl"><div class="tl-row head"><span class="tl-name"></span><span class="tl-track">${axis}${nowLine}</span></div>${groups.join("")}</div>`;
|
|
159
176
|
}
|