agent-horde 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -88,7 +88,7 @@ pi install npm:agent-horde
88
88
  Or from the repository, pinned to a tag:
89
89
 
90
90
  ```
91
- pi install git:github.com/eliyastein/agent-horde@v0.1.1
91
+ pi install git:github.com/eliyastein/agent-horde@v0.1.2
92
92
  ```
93
93
 
94
94
  To hack on it, clone and install in place. pi loads the files from the clone, so edits take effect
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-horde",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Run a horde of pi agents on one task: shared ledgers, peer review, an auditable event log, and a live dashboard",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -114,13 +114,16 @@ function windowOf(graph: RunGraph, window: GraphWindow): { t0: number; t1: numbe
114
114
  return { t0, t1: requested > t0 ? requested : t0 + 1_000 };
115
115
  }
116
116
 
117
- /** Rows within a lane: a node takes the first row whose last occupant ends before it starts. */
118
- function packLane(nodes: GraphNode[], x: (t: number) => number, top: number): { placed: Placed[]; rows: number } {
117
+ /**
118
+ * Rows within a lane: a node takes the first row whose last occupant ends before it starts. A box
119
+ * anchored near the end of the axis is pulled left so its right edge stays inside the plot.
120
+ */
121
+ function packLane(nodes: GraphNode[], x: (t: number) => number, top: number, plotEnd: number): { placed: Placed[]; rows: number } {
119
122
  const rowEnds: number[] = [];
120
123
  const placed: Placed[] = [];
121
124
  for (const node of nodes) {
122
125
  const w = nodeWidth(node);
123
- const left = node.marker ? x(node.at) - DOT_R : x(node.at);
126
+ const left = node.marker ? x(node.at) - DOT_R : Math.min(x(node.at), plotEnd - w);
124
127
  let row = rowEnds.findIndex((end) => end + GAP <= left);
125
128
  if (row === -1) row = rowEnds.length;
126
129
  rowEnds[row] = left + w;
@@ -138,7 +141,7 @@ function layoutGraph(graph: RunGraph, window: GraphWindow): Layout {
138
141
  let y = HEADER_H;
139
142
  for (const lane of graph.lanes) {
140
143
  const own = visible.filter((node) => node.lane === lane.id);
141
- const packed = packLane(own, x, y);
144
+ const packed = packLane(own, x, y, LABEL_W + plotW);
142
145
  for (const item of packed.placed) placed.set(item.node.id, item);
143
146
  const h = PAD * 2 + packed.rows * ROW_H;
144
147
  bands.push({ lane, y, h });
@@ -156,6 +159,14 @@ function renderDefs(): string {
156
159
  return `<defs>${markers.join("")}</defs>`;
157
160
  }
158
161
 
162
+ /** The full label if the band is wide enough, else the bare id, else nothing; the band's title keeps the full text. */
163
+ function phaseText(id: string, label: string, bandW: number): string | undefined {
164
+ const fits = (text: string): boolean => text.length * CHAR_W + 6 <= bandW;
165
+ if (fits(label)) return label;
166
+ if (fits(id)) return id;
167
+ return undefined;
168
+ }
169
+
159
170
  function renderPhases(graph: RunGraph, layout: Layout): string {
160
171
  const bottom = layout.height - layout.axisH;
161
172
  return graph.phases
@@ -166,9 +177,10 @@ function renderPhases(graph: RunGraph, layout: Layout): string {
166
177
  const x0 = layout.x(from);
167
178
  const w = Math.max(1, layout.x(to) - x0);
168
179
  const label = `${phase.id} +${formatElapsed(phase.from - graph.start)} to +${formatElapsed(phase.to - graph.start)}`;
180
+ const text = phaseText(phase.id, label, w);
169
181
  return (
170
- `<rect class="phase${index % 2 ? " phase-alt" : ""}" x="${px(x0)}" y="${HEADER_H - 16}" width="${px(w)}" height="${px(bottom - HEADER_H + 16)}"/>` +
171
- `<text x="${px(x0 + 3)}" y="${HEADER_H - 5}" class="phase-label"><title>${e(label)}</title>${e(label)}</text>`
182
+ `<rect class="phase${index % 2 ? " phase-alt" : ""}" x="${px(x0)}" y="${HEADER_H - 16}" width="${px(w)}" height="${px(bottom - HEADER_H + 16)}"><title>${e(label)}</title></rect>` +
183
+ (text === undefined ? "" : `<text x="${px(x0 + 3)}" y="${HEADER_H - 5}" class="phase-label">${e(text)}</text>`)
172
184
  );
173
185
  })
174
186
  .join("");