@songsid/agend 2.3.3-beta.5 → 2.3.3-beta.6

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 (42) hide show
  1. package/dist/backend/claude-code.js +4 -2
  2. package/dist/backend/claude-code.js.map +1 -1
  3. package/dist/backend/grok.js +57 -11
  4. package/dist/backend/grok.js.map +1 -1
  5. package/dist/backend/types.d.ts +18 -0
  6. package/dist/backend/types.js.map +1 -1
  7. package/dist/daemon.d.ts +6 -0
  8. package/dist/daemon.js +17 -0
  9. package/dist/daemon.js.map +1 -1
  10. package/dist/fleet-manager.d.ts +5 -0
  11. package/dist/fleet-manager.js +24 -1
  12. package/dist/fleet-manager.js.map +1 -1
  13. package/dist/instance-lifecycle.d.ts +6 -0
  14. package/dist/instance-lifecycle.js +19 -3
  15. package/dist/instance-lifecycle.js.map +1 -1
  16. package/dist/locale.js +12 -4
  17. package/dist/locale.js.map +1 -1
  18. package/dist/outbound-schemas.js +1 -1
  19. package/dist/outbound-schemas.js.map +1 -1
  20. package/dist/settings-confirmation.d.ts +17 -3
  21. package/dist/settings-confirmation.js +8 -5
  22. package/dist/settings-confirmation.js.map +1 -1
  23. package/dist/settings-http-confirmation.js +31 -1
  24. package/dist/settings-http-confirmation.js.map +1 -1
  25. package/dist/topic-commands.d.ts +21 -5
  26. package/dist/topic-commands.js +92 -36
  27. package/dist/topic-commands.js.map +1 -1
  28. package/dist/ui/chat-strings.js +6 -4
  29. package/dist/ui/chat-thread.js +45 -15
  30. package/dist/ui/fleet-office-skin.js +37 -14
  31. package/dist/ui/fleet-office.js +31 -7
  32. package/dist/ui/html-attachment.js +22 -8
  33. package/dist/ui/preview-panel.js +9 -6
  34. package/dist/ui/preview.js +10 -3
  35. package/dist/ui/settings-confirm.js +18 -0
  36. package/dist/ui/shared/app-i18n.js +13 -2
  37. package/dist/ui/shared/app-shell.js +35 -1
  38. package/dist/ui/shared/app.css +15 -0
  39. package/dist/web-preview.d.ts +5 -2
  40. package/dist/web-preview.js +6 -3
  41. package/dist/web-preview.js.map +1 -1
  42. package/package.json +1 -1
@@ -27,7 +27,7 @@
27
27
  // @property {(ctx, item, active, ms, env) => void} [drawFurniture] zones: one furniture item (active: activeWhen holds)
28
28
  // @property {(ctx, L, env) => void} [drawForeground] zones: a pack's foreground over the whole 1280×720 scene, above
29
29
  // the people, furniture and items in the air, below the crowd counts, name tags and bubbles
30
- // @property {(ctx, x, y, look, env) => void} [drawTag] zones: a name tag under feet at (x, y)
30
+ // @property {(ctx, x, y, look, env, compact?) => void} [drawTag] zones: a name tag under feet at (x, y) (compact: #2860)
31
31
  // @property {(ctx, area, n, env) => void} [drawCrowd] zones: an area's "+n" (who found no spot in it)
32
32
  // @property {(ctx, desk, look, ms, env) => void} drawCharacter the occupant in its pose at time `ms` (0: still); in
33
33
  // zones `desk` is the character's box at its current position (its feet at desk.seat); walking, `look.heading` is
@@ -293,21 +293,44 @@ function drawBubble(ctx, x, y, text, env, lift = 0) {
293
293
  /** A zones name tag's widest text (logical units): longer names are cut with an ellipsis. */
294
294
  export const TAG_TEXT_W = 84;
295
295
  const TAG_FONT = "600 10px system-ui, sans-serif";
296
+ /**
297
+ * #2860: the compact tag a crowded area keeps on (it used to show tags on hover only, #2513): a smaller font, a smaller
298
+ * plate, a shorter cut, the same level badge.
299
+ */
300
+ const COMPACT = { font: "500 9px system-ui, sans-serif", textW: 48, pad: 6, top: 2, h: 11 };
301
+ const NORMAL = { font: TAG_FONT, textW: TAG_TEXT_W, pad: 10, top: 3, h: 14 };
296
302
  /** The box a name tag under feet at (x, y) takes (what drawTag draws; bubbles keep clear of it, #2513). */
297
- export function tagBox(ctx, x, y, label) {
303
+ export function tagBox(ctx, x, y, label, compact = false) {
304
+ const k = compact ? COMPACT : NORMAL;
305
+ ctx.save();
306
+ ctx.font = k.font;
307
+ const t = fitText(ctx, label, k.textW), w = Math.ceil((ctx.measureText ? ctx.measureText(t).width : t.length * 6) + k.pad);
308
+ ctx.restore();
309
+ return { x: Math.round(x - w / 2), y: y + k.top, w, h: k.h, text: t };
310
+ }
311
+ /** #2860: what a tag covers with its level badge: on a full tag's top-left corner (half outside); left of a compact one. */
312
+ export function tagFootprint(ctx, box, badge, compact = false) {
313
+ if (!badge) return box;
314
+ if (compact) { const w = badgeWidth(ctx, badge) + 1; return { x: box.x - w, y: box.y, w: box.w + w, h: box.h }; }
315
+ return { x: box.x - 10, y: box.y - 7, w: box.w + 10, h: box.h + 7 };
316
+ }
317
+ function badgeWidth(ctx, badge) {
318
+ if (badge.mark) return 8;
298
319
  ctx.save();
299
- ctx.font = TAG_FONT;
300
- const t = fitText(ctx, label, TAG_TEXT_W), w = Math.ceil((ctx.measureText ? ctx.measureText(t).width : t.length * 6) + 10);
320
+ ctx.font = BADGE_FONT;
321
+ const w = Math.max(12, Math.ceil((ctx.measureText ? ctx.measureText(badge.text).width : badge.text.length * 5) + 6));
301
322
  ctx.restore();
302
- return { x: Math.round(x - w / 2), y: y + 3, w, h: 14, text: t };
323
+ return w;
303
324
  }
304
325
  /**
305
326
  * #2661: a level badge on a name tag's top-left corner (x, y: the tag's corner), overlapping its edge like an app's
306
327
  * badge — it takes none of the tag's width. `badge`: { text, tier } (fleet-office-levels.js badgeOf), or { mark } for a
307
328
  * pinned title that hides the number: a small diamond.
308
329
  */
309
- export function drawBadge(ctx, x, y, badge, pal) {
330
+ export function drawBadge(ctx, x, y, badge, pal, inline = false) {
310
331
  if (!badge) return;
332
+ // #2860 inline (a compact tag): (x, y) is the tag's left edge and middle; the badge sits just left of it, whole.
333
+ if (inline) { const w = badgeWidth(ctx, badge); x = x - 1 - w + (badge.mark ? w / 2 : w / 2 - 3); y = y + (badge.mark ? 0 : 1); }
311
334
  const c = tierColours(badge.tier, pal);
312
335
  ctx.save();
313
336
  ctx.globalAlpha = 1;
@@ -331,18 +354,18 @@ export function drawBadge(ctx, x, y, badge, pal) {
331
354
  }
332
355
  const BADGE_FONT = "700 8px system-ui, sans-serif";
333
356
 
334
- /** Zones: a name tag under someone's feet at (x, y). */
335
- function drawTag(ctx, x, y, look, env) {
357
+ /** Zones: a name tag under someone's feet at (x, y); `compact` (#2860): the smaller one a crowded area keeps on. */
358
+ function drawTag(ctx, x, y, look, env, compact = false) {
336
359
  const { pal } = env;
360
+ const b = tagBox(ctx, x, y, look.label, compact);
337
361
  ctx.save();
338
362
  if (look.dim) ctx.globalAlpha = 0.35;
339
- ctx.font = TAG_FONT;
340
- const t = fitText(ctx, look.label, TAG_TEXT_W), w = Math.ceil((ctx.measureText ? ctx.measureText(t).width : t.length * 6) + 10);
341
- ctx.fillStyle = pal.surface; ctx.fillRect(Math.round(x - w / 2), y + 3, w, 14);
342
- ctx.strokeStyle = look.match ? pal.focus : pal.border; ctx.lineWidth = look.match ? 2 : 1; ctx.strokeRect(Math.round(x - w / 2) + 0.5, y + 3.5, w - 1, 13);
343
- ctx.fillStyle = pal.text; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(t, x, y + 10.5);
363
+ ctx.font = compact ? COMPACT.font : TAG_FONT;
364
+ ctx.fillStyle = pal.surface; ctx.fillRect(b.x, b.y, b.w, b.h);
365
+ ctx.strokeStyle = look.match ? pal.focus : pal.border; ctx.lineWidth = look.match ? 2 : 1; ctx.strokeRect(b.x + 0.5, b.y + 0.5, b.w - 1, b.h - 1);
366
+ ctx.fillStyle = pal.text; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(b.text, x, b.y + b.h / 2 + 0.5);
344
367
  ctx.restore();
345
- if (look.badge) drawBadge(ctx, Math.round(x - w / 2), y + 3, look.badge, pal);
368
+ if (look.badge) compact ? drawBadge(ctx, b.x, b.y + b.h / 2, look.badge, pal, true) : drawBadge(ctx, b.x, b.y, look.badge, pal);
346
369
  }
347
370
 
348
371
  /**
@@ -33,8 +33,8 @@
33
33
  // any part — an office names it as its style; one this page cannot load is drawn as Desks, and says so.
34
34
  // - Crowds (#2513): an area with more people than seats packs the rest into a tighter grid, then counts who is left
35
35
  // ("+N", in its corner, never over its name); there idle and asleep people say nothing, at most a few speak (calls
36
- // first, then work), no bubble covers a name tag, and the tags show on hover or focus only. "Hide paused and stopped"
37
- // (per browser) leaves the sleepers out.
36
+ // first, then work), no bubble covers a name tag, and the tags are compact (#2860; one that would touch another shows
37
+ // on hover or focus only). "Hide paused and stopped" (per browser) leaves the sleepers out.
38
38
  // - Share… (#2636; an admin, on the dashboard reached directly or over the public link): a link anyone can open to watch an office live, read-only,
39
39
  // until it ends (office-share-dialog.js; the page it opens is office-share-page.js).
40
40
  // - Edit layout (an admin, a stored office on a zones skin): fleet-office-layout.js, saved as the office's overrides.
@@ -64,7 +64,7 @@ import { nodeText, stateWords } from "./fleet-org.js";
64
64
  import { hits, needle } from "./fleet-canvas-layout.js";
65
65
  import { AUTO_ID, LOBBY, autoLayout, backingScale, coatOf, createFlights, customLayout, deskAt, desksOf, filterOk, lampOf, layoutOk, lightOf, membersOf,
66
66
  officePose, officeRooms, signOf, workOn } from "./fleet-office-model.js";
67
- import { BUILT_IN_SKINS, CHAR_DEPTH, DEFAULT_PAL, bubbleBox, loadCozySkin, loadPackSkin, modeOf, skinFor, tagBox } from "./fleet-office-skin.js";
67
+ import { BUILT_IN_SKINS, CHAR_DEPTH, DEFAULT_PAL, bubbleBox, loadCozySkin, loadPackSkin, modeOf, skinFor, tagBox, tagFootprint } from "./fleet-office-skin.js";
68
68
  import { CALLING, activeFurniture, bubbleAt, hiddenBy, bubbleRank, NIGHT, WANDER, createMail, createWalkers, isNight, linesFor, npcKey, personAt, placeBubbles, thinBubbles, walkTargets, zonesLayout } from "./fleet-office-zones.js";
69
69
  import { actsOk, createOfficeStore } from "./fleet-office-store.js";
70
70
  import { badgeOf, fixedOf } from "./fleet-office-levels.js";
@@ -131,6 +131,8 @@ const deviceRatio = () => Math.max(0.5, Math.min(4, Number(globalThis.devicePixe
131
131
  const SIZE0 = { w: 960, h: 600 };
132
132
  /** #2554: All offices' Fit keeps this many CSS px clear round the tiles (the zoom controls' column and a margin). */
133
133
  const FIT_PAD = 60;
134
+ /** #2860: how far below its place a crowded area's compact tag drops when a neighbour's is in the way (a tag's height + 1). */
135
+ const COMPACT_ROW = 12;
134
136
  /** #2554: in All offices a tile's name tags show (always) from this many CSS px a unit up; below it on hover only. */
135
137
  export const TAG_MIN_K = 0.75;
136
138
  const PAN_KEYS = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] };
@@ -418,13 +420,19 @@ export function drawPart(ctx, p, a, ox, oy, ms, still, hot, env, tagsOff = false
418
420
  if (sk.drawForeground) sk.drawForeground(ctx, p.L, env);
419
421
  // Who found no spot in an area: a count in its corner (never over its name).
420
422
  for (const [ar, n] of p.L.crowd || []) if (p.L.areas[ar] && sk.drawCrowd) sk.drawCrowd(ctx, p.L.areas[ar], n, env);
421
- // In an area over capacity the name tags show on hover or focus only (#2513: a crowd's tags covered each other).
423
+ // In an area over capacity (#2513: a crowd's full tags covered each other) everyone keeps a compact tag (#2860:
424
+ // in Cozy, the default, most of a fleet is in a crowd, and hover-only hid names and levels); one that would touch
425
+ // a tag already drawn, its badge included, is left to hover or focus. The full tags go first.
422
426
  const over = p.L.over || new Set();
427
+ const crowded = (q) => over.has(q.d.area) && q.d.key !== hot && !q.look.match;
423
428
  const tagged = (q) => !((tagsOff || over.has(q.d.area)) && q.d.key !== hot && !q.look.match);
429
+ const taken = [];
430
+ const touches = (b) => taken.some((o) => b.x < o.x + o.w && o.x < b.x + b.w && b.y < o.y + o.h && o.y < b.y + b.h);
424
431
  for (const q of people) {
425
432
  if (live.hidden.has(q.look.name) || !tagged(q)) continue;
426
433
  sk.drawTag(ctx, q.at.x, q.at.y, q.look, env);
427
- tags.push(tagBox(ctx, q.at.x, q.at.y, q.look.label));
434
+ const box = tagBox(ctx, q.at.x, q.at.y, q.look.label);
435
+ tags.push(box); taken.push(tagFootprint(ctx, box, q.look.badge));
428
436
  }
429
437
  // A furniture item's own name (#2574: an NPC drawn as furniture), tagged like a person; none on a tile too small to read.
430
438
  // #2698: an item hiding its people carries their tags too, in one row at its tag point (its own first; each keeps
@@ -434,7 +442,10 @@ export function drawPart(ctx, p, a, ox, oy, ms, still, hot, env, tagsOff = false
434
442
  for (const f of furniture) {
435
443
  const on = people.filter((q) => live.hidden.get(q.look.name) === f.id);
436
444
  if (!on.length) {
437
- if (!tagsOff && f.label) { const nl = npcLook(p, f); sk.drawTag(ctx, f.x, f.y, nl, env); tags.push(tagBox(ctx, f.x, f.y, nl.label)); }
445
+ if (!tagsOff && f.label) {
446
+ const nl = npcLook(p, f), box = tagBox(ctx, f.x, f.y, nl.label);
447
+ sk.drawTag(ctx, f.x, f.y, nl, env); tags.push(box); taken.push(tagFootprint(ctx, box, nl.badge));
448
+ }
438
449
  continue;
439
450
  }
440
451
  const order = new Map((f.activeFor || []).map((n, i) => [n, i]));
@@ -447,11 +458,24 @@ export function drawPart(ctx, p, a, ox, oy, ms, still, hot, env, tagsOff = false
447
458
  if (q ? !tagged(q) : tagsOff) continue;
448
459
  sk.drawTag(ctx, r.x, f.y, r.look, env);
449
460
  const box = tagBox(ctx, r.x, f.y, r.look.label);
450
- tags.push(box);
461
+ tags.push(box); taken.push(tagFootprint(ctx, box, r.look.badge));
451
462
  if (q) held.push({ name: q.look.name, id: f.id, box });
452
463
  }
453
464
  }
454
465
  p.heldTags = held;
466
+ // The crowd's compact tags go last, clear of every full tag above: people's, an item's own name and the row it
467
+ // carries (#2862 review). A crowd's grid is tighter than a compact tag is wide (OVERFLOW.STEPS down to 32): a
468
+ // neighbour's tag goes a row lower (COMPACT_ROW) rather than out, so a row of people reads as two staggered rows.
469
+ if (!tagsOff) for (const q of people) {
470
+ if (live.hidden.has(q.look.name) || !crowded(q)) continue;
471
+ for (const dy of [0, COMPACT_ROW]) {
472
+ const box = tagBox(ctx, q.at.x, q.at.y + dy, q.look.label, true), foot = tagFootprint(ctx, box, q.look.badge, true);
473
+ if (touches(foot)) continue;
474
+ sk.drawTag(ctx, q.at.x, q.at.y + dy, q.look, env, true);
475
+ tags.push(box); taken.push(foot);
476
+ break;
477
+ }
478
+ }
455
479
  } else {
456
480
  for (const d of p.desks) { const look = p.looks.get(d.key); sk.drawCharacter(ctx, d, actPosed(p, look), ms, env); speakers.push({ look, x: d.x + 58, y: d.y + 12, area: p.roomOf.get(d.key) ?? null }); }
457
481
  blit(p.layers.front);
@@ -3,24 +3,38 @@
3
3
  // card. What runs is then handed to the preview frame exactly like a block's (AgendPreview.start): the file URL itself
4
4
  // is never opened or framed on the dashboard's origin.
5
5
 
6
- /** The same cap as a block's (preview.js LIMITS.maxBytes): UTF-8 bytes of the HTML. */
7
- export const HTML_ATTACHMENT_MAX = 1024 * 1024;
6
+ /**
7
+ * #2863: the sizes a preview takes (UTF-8 bytes of the HTML), the same as a block's (preview.js LIMITS): up to ASK it
8
+ * runs at once; above it the person is asked first ("Preview anyway?"); above MAX there is no preview, only the
9
+ * download. MAX is the frame's own ceiling (web-preview.ts PREVIEW_HTML_MAX_BYTES).
10
+ */
11
+ export const HTML_PREVIEW_ASK = 8 * 1024 * 1024;
12
+ export const HTML_PREVIEW_MAX = 50 * 1024 * 1024;
8
13
 
9
14
  /**
10
- * Read an attachment's HTML: { ok: true, code } or { ok: false, reason } with reason "over" (the file is over the
11
- * cap: its listed size is checked before anything is fetched, the bytes again after), "gone" (the fleet no longer
12
- * serves that id — the file changed, or the fleet restarted), or "failed".
15
+ * Read an attachment's HTML: { ok: true, code } or { ok: false, reason } with reason "large" (above `ask` and not
16
+ * `anyway`: nothing is fetched when its listed size says so; `size` is what it is), "over" (above `max`: its listed size
17
+ * is checked before anything is fetched, the bytes again after), "gone" (the fleet no longer serves that id — the file
18
+ * changed, or the fleet restarted), or "failed". The text card reads with its own, single cap (ask = max).
13
19
  */
14
- export async function loadHtmlAttachment(att, fetchImpl = globalThis.fetch) {
20
+ export async function loadHtmlAttachment(att, fetchImpl = globalThis.fetch, { ask = HTML_PREVIEW_ASK, max = HTML_PREVIEW_MAX, anyway = false } = {}) {
15
21
  if (!att || typeof att.id !== "string" || !/^[0-9a-f]{32}$/.test(att.id)) return { ok: false, reason: "failed" };
16
- if (typeof att.size === "number" && att.size > HTML_ATTACHMENT_MAX) return { ok: false, reason: "over" };
22
+ if (typeof att.size === "number" && att.size > max) return { ok: false, reason: "over" };
23
+ if (typeof att.size === "number" && att.size > ask && !anyway) return { ok: false, reason: "large", size: att.size };
17
24
  let res;
18
25
  try { res = await fetchImpl(`/ui/file/${att.id}`, { credentials: "same-origin", cache: "no-store" }); }
19
26
  catch { return { ok: false, reason: "failed" }; }
20
27
  if (!res || !res.ok) return { ok: false, reason: res && res.status === 404 ? "gone" : "failed" };
21
28
  let bytes;
22
29
  try { bytes = await res.arrayBuffer(); } catch { return { ok: false, reason: "failed" }; }
23
- if (bytes.byteLength > HTML_ATTACHMENT_MAX) return { ok: false, reason: "over" };
30
+ if (bytes.byteLength > max) return { ok: false, reason: "over" };
31
+ if (bytes.byteLength > ask && !anyway) return { ok: false, reason: "large", size: bytes.byteLength };
24
32
  // UTF-8, as a block's text is; a BOM is dropped.
25
33
  return { ok: true, code: new TextDecoder("utf-8").decode(bytes) };
26
34
  }
35
+
36
+ /** #2863: a size as the person reads it: "12.3 MB" (1 MB = 1024 × 1024 bytes, as the caps are). */
37
+ export function sizeLabel(bytes) {
38
+ const mb = bytes / (1024 * 1024);
39
+ return `${mb >= 10 ? Math.round(mb) : Math.round(mb * 10) / 10} MB`;
40
+ }
@@ -152,11 +152,12 @@ export function PreviewPanel({ name, split, msgs, subscribe, keyOf, reveal, down
152
152
  const [, dayTick] = useState(0);
153
153
  useEffect(() => (open ? onDayChange(() => dayTick(n => n + 1)) : undefined), [!!open]);
154
154
 
155
- const ui = { state: (s, reason) => setRun({ state: s === "starting" || s === "running" ? s : "idle", reason: reason || "" }) };
156
- const start = () => {
155
+ // #2863: "large" — over 8 MB, nothing runs until "Preview anyway" (or the card's, which opened it with `anyway`).
156
+ const ui = { state: (s, reason) => setRun({ state: s === "starting" || s === "running" || s === "large" ? s : "idle", reason: reason || "" }) };
157
+ const start = (anyway) => {
157
158
  if (!open || !holder.current) return;
158
159
  setView("preview");
159
- P().start(frameKey(open.key), holder.current, open.code, ui, { fill: true });
160
+ P().start(frameKey(open.key), holder.current, open.code, ui, anyway === true || open.anyway ? { fill: true, anyway: true } : { fill: true });
160
161
  };
161
162
  const stop = () => { if (open) P().stop(frameKey(open.key), "stopped", ""); };
162
163
  // A new block in the panel: what ran before is gone (openPanel stopped it); the card's click starts it here — or,
@@ -224,7 +225,8 @@ export function PreviewPanel({ name, split, msgs, subscribe, keyOf, reveal, down
224
225
  if (newer.code != null) { openPanel(newer); return; }
225
226
  const was = open && open.key, mine = reading.current = newer;
226
227
  setNewerNote(t("chat.pvLoading"));
227
- const r = await loadHtmlAttachment(newer.att);
228
+ // A click on the newer version reads it whatever its size (up to the 50 MB ceiling); over 8 MB the panel then asks.
229
+ const r = await loadHtmlAttachment(newer.att, undefined, { anyway: true });
228
230
  if (reading.current !== mine) return;
229
231
  reading.current = null;
230
232
  const now = panelStore.get().open;
@@ -270,9 +272,10 @@ export function PreviewPanel({ name, split, msgs, subscribe, keyOf, reveal, down
270
272
  <button type="button" class=${`btn btn-sm${view === "code" ? " on" : ""}`} aria-pressed=${view === "code" ? "true" : "false"} onClick=${() => setView("code")}><${Icon} name="code" size=${14} />${t("chat.pvCode")}</button>
271
273
  </div>
272
274
  <span class="grow"></span>
273
- ${going ? html`<button type="button" class="btn btn-sm pv-panel-reload" title=${t("chat.pvReload")} onClick=${() => { stop(); start(); }}><${Icon} name="restart" size=${14} /><span class="lbl">${t("chat.pvReload")}</span></button>
275
+ ${going ? html`<button type="button" class="btn btn-sm pv-panel-reload" title=${t("chat.pvReload")} onClick=${() => { stop(); start(true); }}><${Icon} name="restart" size=${14} /><span class="lbl">${t("chat.pvReload")}</span></button>
274
276
  <button type="button" class="btn btn-sm pv-panel-stop" title=${t("chat.pvStop")} onClick=${stop}><${Icon} name="stop" size=${14} /><span class="lbl">${t("chat.pvStop")}</span></button>`
275
- : html`<button type="button" class="btn btn-sm btn-primary pv-panel-run" title=${t("chat.pvPreview")} disabled=${!a.ok} onClick=${start}><${Icon} name="play" size=${14} /><span class="lbl">${t("chat.pvPreview")}</span></button>`}
277
+ : run.state === "large" ? html`<button type="button" class="btn btn-sm btn-primary pv-panel-anyway" title=${t("chat.pvAnyway")} disabled=${!a.ok} onClick=${() => start(true)}><${Icon} name="play" size=${14} /><span class="lbl">${t("chat.pvAnyway")}</span></button>`
278
+ : html`<button type="button" class="btn btn-sm btn-primary pv-panel-run" title=${t("chat.pvPreview")} disabled=${!a.ok} onClick=${() => start()}><${Icon} name="play" size=${14} /><span class="lbl">${t("chat.pvPreview")}</span></button>`}
276
279
  <button type="button" class="btn btn-sm pv-panel-dl" title=${t("chat.pvDownload")} onClick=${() => download(open.code, fileName)}><${Icon} name="download" size=${14} /><span class="lbl">${t("chat.pvDownload")}</span></button>
277
280
  </div>
278
281
  ${newer && newer.key !== open.key ? html`<div class="pv-newer" role="status"><span>${t("chat.pvNewer", timeOf(newer.ts))}</span>
@@ -20,7 +20,9 @@
20
20
  })(typeof globalThis !== "undefined" ? globalThis : this, function (root) {
21
21
  "use strict";
22
22
 
23
- var LIMITS = { maxBytes: 1024 * 1024, minHeight: 40, maxHeight: 4000, readyMs: 3000, watchdogMs: 10000, resizePerSec: 10, minDelta: 2, growthFreeze: 5, growthWindowMs: 2000 };
23
+ // #2863: askBytes — above it the person is asked first ("Preview anyway?"); maxBytes — above it only a download (the
24
+ // frame's own ceiling, web-preview.ts PREVIEW_HTML_MAX_BYTES; html-attachment.js reads with the same two).
25
+ var LIMITS = { askBytes: 8 * 1024 * 1024, maxBytes: 50 * 1024 * 1024, minHeight: 40, maxHeight: 4000, readyMs: 3000, watchdogMs: 10000, resizePerSec: 10, minDelta: 2, growthFreeze: 5, growthWindowMs: 2000 };
24
26
  var OPT_IN_KEY = "agend_html_preview"; // localStorage: "on" — this device allows previews
25
27
  var NEVER_KEY = "agend_html_preview_never"; // sessionStorage: "1" — never preview on this device (this session)
26
28
  // #1568: the banner was acknowledged ("I understand"). localStorage: the sign-in's session handle — hidden while the
@@ -54,6 +56,8 @@
54
56
  function now() { return root.performance && typeof root.performance.now === "function" ? root.performance.now() : Date.now(); }
55
57
  function store(kind) { try { return root[kind] || null; } catch (e) { return null; } }
56
58
  function utf8Bytes(s) { try { return new root.TextEncoder().encode(s).length; } catch (e) { return String(s).length * 3; } }
59
+ /** #2863: "12 MB" / "8.4 MB" (1 MB = 1024 × 1024 bytes, as the caps are; html-attachment.js sizeLabel). */
60
+ function sizeLabel(bytes) { var mb = bytes / (1024 * 1024); return (mb >= 10 ? Math.round(mb) : Math.round(mb * 10) / 10) + " MB"; }
57
61
  function randomCh() {
58
62
  var b = new Uint8Array(16);
59
63
  root.crypto.getRandomValues(b);
@@ -229,7 +233,8 @@
229
233
 
230
234
  /**
231
235
  * Run `html` in `holder` (a node of the card) for `key`. `ui` is told what happened: ui.state(name, reason) with
232
- * "starting" | "running" | "stopped" | "unavailable". One preview at a time: any other running one stops first.
236
+ * "starting" | "running" | "stopped" | "unavailable" | "large" (#2863: over LIMITS.askBytes — nothing runs until it is
237
+ * asked again with opts.anyway, the person's "Preview anyway"). One preview at a time: any other running one stops first.
233
238
  * opts.fill (#1481, the side panel): the frame fills its holder — the same frame from mountPreview, only sized by the
234
239
  * panel instead of by the frame's height messages, which it then ignores.
235
240
  */
@@ -239,7 +244,9 @@
239
244
  function start(key, holder, html, ui, opts) {
240
245
  var a = availability();
241
246
  if (!a.ok) { ui.state("unavailable", a.reason); return false; }
242
- if (typeof html !== "string" || utf8Bytes(html) > LIMITS.maxBytes) { ui.state("unavailable", say("pvHtmlOver", "This HTML is over 1 MiB; it is not previewed.")); return false; }
247
+ var bytes = typeof html === "string" ? utf8Bytes(html) : Infinity;
248
+ if (bytes > LIMITS.maxBytes) { ui.state("unavailable", say("pvHtmlOver", "This HTML is over 50 MB; it is not previewed. Download it to open it.")); return false; }
249
+ if (bytes > LIMITS.askBytes && !(opts && opts.anyway)) { ui.state("large", say("pvLarge", "This file is large ({0}). Preview anyway?", sizeLabel(bytes))); return false; }
243
250
  stopAll("another");
244
251
  starts++;
245
252
  var doc = holder.ownerDocument;
@@ -65,6 +65,8 @@ function publish() {
65
65
  // Monotonic: when the server's countdown reaches zero on this page's clock.
66
66
  deadline: at + Math.max(0, Number(view.remaining_ms) || 0),
67
67
  withdraw: view.can_withdraw && view.state === "pending" ? () => withdraw(view.id) : null,
68
+ // #2868: this browser may confirm it itself now (the server's read says so; it checks again on the click).
69
+ applyNow: view.can_self_confirm && view.state === "pending" ? () => applyNow(view.id) : null,
68
70
  dismiss: TERMINAL.has(view.state) ? () => forget(view.id) : null,
69
71
  })),
70
72
  });
@@ -150,6 +152,22 @@ export async function withdraw(id) {
150
152
  return false;
151
153
  }
152
154
 
155
+ /**
156
+ * #2868: "Apply now" — confirm this session's own pending request from this browser (#2170's rule, asked again by the
157
+ * server). Its answer is followed like any other; a refusal (no longer allowed here) leaves it waiting and is { ok: false }.
158
+ */
159
+ export async function applyNow(id) {
160
+ const e = tracked.get(id);
161
+ if (!e) return { ok: false };
162
+ const token = ticket(e);
163
+ let res;
164
+ try { res = await api(`/api/settings/pending/${encodeURIComponent(id)}/confirm`, { method: "POST", body: "{}" }); } catch { return { ok: false }; }
165
+ if (isPendingResponse(res) && res.body.pending_change.id === id) { update(res.body.pending_change, token); schedule(); return { ok: true }; }
166
+ // Refused (403: not allowed here any more): read it again, so "Apply now" goes until the server offers it again.
167
+ if (e.view.can_self_confirm) update({ ...e.view, can_self_confirm: false }, token);
168
+ return { ok: false, status: res.status };
169
+ }
170
+
153
171
  /** This session's requests still open on the server (after a reload): followed like new ones. */
154
172
  export async function attach() {
155
173
  let res;
@@ -89,7 +89,13 @@ register("app", {
89
89
  pendingWeb: "Confirmed by your account (this browser is web-verified). General is told.",
90
90
  pending_applied: "Confirmed and applied", pending_rejected: "Not applied", pending_expired: "Expired — nothing was changed",
91
91
  pending_stale: "Not applied — settings changed meanwhile", pending_failed: "Confirmed, but applying it failed",
92
- pendingChat: "A fleet admin confirms this in chat (General topic).", pendingHost: "Confirm it on the host: {0}", pendingLeft: "{0} left", withdraw: "Withdraw",
92
+ pendingLeft: "{0} left", withdraw: "Withdraw",
93
+ // #2868: where to confirm it, said plainly; the host's command folded away unless it is the only way.
94
+ pendingPosting: "Sending the confirm card to General…", pendingChatWhere: "To apply it, press Confirm on the card in General on {0}.",
95
+ pendingHostOnly: "No General can take the confirm card. Confirm it on the host: {0}", pendingAdvanced: "Advanced: confirm on the host",
96
+ pendingSelf: "This browser is verified, so you can also apply it here.", pendingApplyNow: "Apply now",
97
+ pendingApplyRefused: "This browser can't apply it here now — confirm it in General.",
98
+ pendingAuthorize: "Authorize this browser to apply changes like this here next time, without General.",
93
99
  opWriting: "Applying settings… {0}/{1}", opWaiting: "Settings: waiting for confirmation in chat", opApplying: "Applying settings…",
94
100
  opDone: "Settings applied", opRestart: "Settings saved — AgEnD needs a restart to use them", opPartial: "Some settings were not applied",
95
101
  opFailed: "Settings were not applied", openSettings: "Open Settings",
@@ -131,7 +137,12 @@ register("app", {
131
137
  pendingWeb: "由你的帳號確認(這個瀏覽器已通過網頁驗證),也會通知 General。",
132
138
  pending_applied: "已確認並套用", pending_rejected: "未套用", pending_expired: "已逾時——沒有任何變更",
133
139
  pending_stale: "未套用——設定在這期間已變動", pending_failed: "已確認,但套用失敗",
134
- pendingChat: "由 fleet 管理員在聊天(General topic)中確認。", pendingHost: "請在主機上確認:{0}", pendingLeft: "剩 {0}", withdraw: "撤回",
140
+ pendingLeft: "剩 {0}", withdraw: "撤回",
141
+ pendingPosting: "正在把確認卡送到 General…", pendingChatWhere: "要套用,請到 {0} 的 General,在確認卡上按「確認」。",
142
+ pendingHostOnly: "沒有可以接收確認卡的 General。請在主機上確認:{0}", pendingAdvanced: "進階:在主機上確認",
143
+ pendingSelf: "這個瀏覽器已通過驗證,也可以直接在這裡套用。", pendingApplyNow: "直接套用",
144
+ pendingApplyRefused: "這個瀏覽器現在無法直接套用,請到 General 確認。",
145
+ pendingAuthorize: "授權這個瀏覽器,之後這類變更可以直接套用,不必到 General。",
135
146
  opWriting: "正在套用設定… {0}/{1}", opWaiting: "設定:等待在聊天中確認", opApplying: "正在套用設定…",
136
147
  opDone: "設定已套用", opRestart: "設定已儲存——需要重新啟動 AgEnD 才會生效", opPartial: "部分設定沒有套用",
137
148
  opFailed: "設定沒有套用", openSettings: "開啟設定",
@@ -17,6 +17,7 @@ import { applyPageTheme, pageNow, resolvedMode, themesStore } from "./app-themes
17
17
  import { ErrorState, Skeleton } from "./ui-states.js";
18
18
  import { InstanceNav, RosterNav, namesStore, setNamesPrimary } from "./instance-nav.js";
19
19
  import { usageRailStore } from "./header-tools.js";
20
+ import { useWebAuthorization } from "./web-authorize.js";
20
21
  import { RightRail, sidePanelStore } from "./side-panel.js";
21
22
  import { OwnerCssKeepBar } from "./owner-css.js";
22
23
  import { AgentWidget, fleetBinds, sidebarWidget, sidebarWidgetStore } from "./agent-widget.js";
@@ -575,13 +576,46 @@ export function PendingChanges({ inline = false } = {}) {
575
576
  ${p.dismiss ? html`<button type="button" class="icon-btn" aria-label=${t("app.close")} title=${t("app.close")} onClick=${p.dismiss}><${Icon} name="close" size=${14} /></button>` : null}</div>
576
577
  ${p.label ? html`<div class="pending-label">${p.label}</div>` : null}
577
578
  ${Array.isArray(p.summary) && p.summary.length ? html`<ul class="pending-summary">${p.summary.map((line, i) => html`<li key=${i}>${line}</li>`)}</ul>` : null}
578
- ${p.state === "pending" ? html`<p class="note">${p.confirmation && p.confirmation.kind === "host_cli" ? t("app.pendingHost", `agend settings confirm ${p.id}`) : t("app.pendingChat")}</p>` : null}
579
+ ${p.state === "pending" ? html`<${PendingHow} p=${p} />` : null}
579
580
  ${(p.state === "applying" || p.state === "applied") && p.confirmation && p.confirmation.kind === "web" ? html`<p class="note">${t("app.pendingWeb")}</p>` : null}
580
581
  ${p.state !== "pending" && p.state !== "applying" && p.state !== "applied" && p.outcome && p.outcome.message ? html`<p class="note">${p.outcome.message}</p>` : null}
581
582
  ${p.withdraw ? html`<div class="pending-actions"><button type="button" class="btn btn-sm" onClick=${p.withdraw}>${t("app.withdraw")}</button></div>` : null}
582
583
  </section>`)}</div>`;
583
584
  }
584
585
 
586
+ /** #2868: where the confirm card was posted: "Discord", or "Discord (team-b)" for a connection with an id of its own. */
587
+ function whereText(where) {
588
+ const names = (Array.isArray(where) ? where : []).map((w) => `${PLATFORM_NAMES[w.platform] || w.platform}${w.connection && w.connection !== w.platform ? ` (${w.connection})` : ""}`);
589
+ return names.length ? [...new Set(names)].join(" / ") : "Discord / Telegram";
590
+ }
591
+ /**
592
+ * #2868: how a pending change is confirmed, in the order a person can act on it. First where: the General card (naming
593
+ * the platform it was posted on), or the host's command when no General could take it. Then, when this browser could
594
+ * confirm it itself (the server's read says so: #2170's rule), "Apply now"; when it isn't verified but could be,
595
+ * "Authorize this browser" (the same DM card as the composer's). The host's command otherwise sits folded under
596
+ * "Advanced".
597
+ */
598
+ function PendingHow({ p }) {
599
+ const a = useWebAuthorization();
600
+ const [refused, setRefused] = useState(false);
601
+ const c = p.confirmation || {}, cmd = `agend settings confirm ${p.id}`;
602
+ const lead = c.kind === "posting" ? t("app.pendingPosting") : c.kind === "host_cli" ? t("app.pendingHostOnly", cmd) : t("app.pendingChatWhere", whereText(c.where));
603
+ // A browser that isn't verified but could be: authorizing it makes this one (and later ones) "Apply now".
604
+ const route = c.kind !== "host_cli" && !p.applyNow && a.st;
605
+ const canAsk = route && a.st.state === "none" && (a.st.reason === "not_authorized" || a.st.reason === "authorization_expired");
606
+ const asking = route && a.st.state === "pending";
607
+ const apply = async () => { setRefused(false); const r = await p.applyNow(); if (!r || !r.ok) setRefused(true); };
608
+ return html`<p class="note">${lead}</p>
609
+ ${p.applyNow ? html`<div class="pending-self"><span class="note">${t("app.pendingSelf")}</span>
610
+ <button type="button" class="btn btn-sm btn-primary" onClick=${apply}>${t("app.pendingApplyNow")}</button></div>` : null}
611
+ ${refused && !p.applyNow ? html`<p class="note" role="status">${t("app.pendingApplyRefused")}</p>` : null}
612
+ ${canAsk ? html`<div class="pending-self"><span class="note">${t("app.pendingAuthorize")}</span>
613
+ <button type="button" class="btn btn-sm" onClick=${a.ask}>${t("webauth.authorize")}</button></div>` : null}
614
+ ${asking ? html`<p class="note">${t("webauth.waiting", mmss(a.left))}</p>` : null}
615
+ ${a.notice && (canAsk || asking) ? html`<p class="note" role="status">${a.notice}</p>` : null}
616
+ ${c.kind !== "host_cli" ? html`<details class="pending-host"><summary>${t("app.pendingAdvanced")}</summary><code>${cmd}</code></details>` : null}`;
617
+ }
618
+
585
619
  /** Settings' Apply, followed from another panel: one line, and the way back to it (§5: progress shows in any panel). */
586
620
  function OperationLine({ route }) {
587
621
  const { settingsOp: op } = useStore(appStore);
@@ -1214,6 +1214,18 @@ body.side-resizing, body.side-resizing * { cursor: col-resize !important; user-s
1214
1214
  .v-filter-box input::placeholder { color: var(--text-3); }
1215
1215
  .v-filter-clear { width: 28px; height: 28px; }
1216
1216
  .v-filter .note { padding: var(--s-1) var(--s-1) 0; font-variant-numeric: tabular-nums; }
1217
+ /* A short viewport (a phone in landscape: about 300–480 px tall): the head, nav, filter and footer pinned around the
1218
+ list left it no room, and what did not fit was drawn over the footer (user report 2026-10-30). There the sidebar
1219
+ scrolls as one column: nothing shrinks, the list grows to its rows, the nav rows sit two to a row, and the filter
1220
+ stays in view at the bottom while the list scrolls past. Portrait phones and desktops are taller than this. */
1221
+ @media (max-height: 500px) {
1222
+ .sidebar { overflow-y: auto; overscroll-behavior: contain; }
1223
+ .sidebar > *, .view-roster > * { flex-shrink: 0; }
1224
+ .view-roster { flex: none; }
1225
+ .view-roster > .side-section { flex: none; overflow: visible; }
1226
+ .side-nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
1227
+ .v-filter { position: sticky; bottom: 0; z-index: 2; background: var(--bg-sidebar); }
1228
+ }
1217
1229
  /* alpha.2 (N1): status and CLI chips under the filter box — each a group of checkboxes under its header (#1700). */
1218
1230
  /* #1776: the "N / M" count is on the headers' row, at its right end — not a row of its own. The headers (and an open
1219
1231
  group's list, the reset) wrap in their own box beside it, so a filter's summary or a narrow sidebar moves a header
@@ -1516,6 +1528,9 @@ textarea.s-yaml { white-space: pre; overflow-x: auto; }
1516
1528
  .pending-label { color: var(--text-2); }
1517
1529
  .pending-summary { list-style: disc; padding-left: var(--s-5); color: var(--text-2); font-size: var(--fs-xs); }
1518
1530
  .pending-actions { display: flex; justify-content: flex-end; }
1531
+ .pending-self { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2); }
1532
+ .pending-host summary { cursor: pointer; color: var(--text-2); font-size: var(--fs-xs); }
1533
+ .pending-host code { display: block; margin-top: var(--s-1); font-size: var(--fs-xs); overflow-wrap: anywhere; user-select: all; }
1519
1534
  /* Settings' pending bar sits at the bottom of the page: toasts and request cards stand above it, never on its buttons. */
1520
1535
  .shell:has(.s-pending) .toasts { bottom: calc(var(--s-6) + 64px); }
1521
1536
  /* In a chat the composer owns the bottom (Stop reply, Send): toasts come in under the header instead (alpha.2 sweep). */
@@ -1,6 +1,9 @@
1
1
  import { type Server } from "node:http";
2
2
  import { type HostGuardConfig } from "./web-host-guard.js";
3
- /** The most HTML a preview takes (UTF-8 bytes): the parent refuses more before sending, the shim refuses it too. */
3
+ /**
4
+ * The most HTML a preview takes (UTF-8 bytes): the parent refuses more before sending (a download only), the shim refuses
5
+ * it too. #2863: 50 MiB, the default upload limit; the page asks first ("Preview anyway?") above 8 MiB.
6
+ */
4
7
  export declare const PREVIEW_HTML_MAX_BYTES: number;
5
8
  export interface PreviewWebConfig {
6
9
  preview?: unknown;
@@ -64,7 +67,7 @@ export declare function dashboardOrigins(settings: PreviewSettings, healthPort:
64
67
  export declare function previewFrameCsp(ancestors: readonly string[]): string;
65
68
  /**
66
69
  * The shim (design §4): posts `ready` with the listener's boot id; takes ONE `render` — from its parent window, from
67
- * an exact listed dashboard origin (never "null"), with exactly {v, type, ch, html}, html ≤ 1 MiB — removes the WebRTC
70
+ * an exact listed dashboard origin (never "null"), with exactly {v, type, ch, html}, html ≤ PREVIEW_HTML_MAX_BYTES — removes the WebRTC
68
71
  * entry points from its realm (defence in depth only), and writes a heartbeat/height prologue and the HTML into its
69
72
  * own document. Every later message is ignored.
70
73
  */
@@ -14,8 +14,11 @@
14
14
  import { randomBytes } from "node:crypto";
15
15
  import { createServer } from "node:http";
16
16
  import { allowedHostNames, hostnameOf, LOOPBACK_HOST_NAMES } from "./web-host-guard.js";
17
- /** The most HTML a preview takes (UTF-8 bytes): the parent refuses more before sending, the shim refuses it too. */
18
- export const PREVIEW_HTML_MAX_BYTES = 1024 * 1024;
17
+ /**
18
+ * The most HTML a preview takes (UTF-8 bytes): the parent refuses more before sending (a download only), the shim refuses
19
+ * it too. #2863: 50 MiB, the default upload limit; the page asks first ("Preview anyway?") above 8 MiB.
20
+ */
21
+ export const PREVIEW_HTML_MAX_BYTES = 50 * 1024 * 1024;
19
22
  /** The settings a fleet runs with: `web.preview`, `web.preview_port` (default health_port + 1), `web.preview_origin`. */
20
23
  export function previewSettings(web, healthPort) {
21
24
  // An ephemeral web listener (port 0: tests, harnesses) gets an ephemeral preview listener; its real port is filled
@@ -163,7 +166,7 @@ export function previewFrameCsp(ancestors) {
163
166
  }
164
167
  /**
165
168
  * The shim (design §4): posts `ready` with the listener's boot id; takes ONE `render` — from its parent window, from
166
- * an exact listed dashboard origin (never "null"), with exactly {v, type, ch, html}, html ≤ 1 MiB — removes the WebRTC
169
+ * an exact listed dashboard origin (never "null"), with exactly {v, type, ch, html}, html ≤ PREVIEW_HTML_MAX_BYTES — removes the WebRTC
167
170
  * entry points from its realm (defence in depth only), and writes a heartbeat/height prologue and the HTML into its
168
171
  * own document. Every later message is ignored.
169
172
  */
@@ -1 +1 @@
1
- {"version":3,"file":"web-preview.js","sourceRoot":"","sources":["../src/web-preview.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-preview.js","sourceRoot":"","sources":["../src/web-preview.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@songsid/agend",
3
- "version": "2.3.3-beta.5",
3
+ "version": "2.3.3-beta.6",
4
4
  "description": "Multi-agent fleet daemon — run coding CLIs (Claude, Muse, Codex, OpenCode) from Discord or Telegram",
5
5
  "type": "module",
6
6
  "bin": {