@songsid/agend 2.2.0-alpha.3 → 2.2.0-alpha.5
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/auth-api.js +4 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/discord-general.d.ts +15 -0
- package/dist/discord-general.js +24 -0
- package/dist/discord-general.js.map +1 -0
- package/dist/fleet-manager.d.ts +9 -0
- package/dist/fleet-manager.js +22 -15
- package/dist/fleet-manager.js.map +1 -1
- package/dist/locale.js +8 -2
- package/dist/locale.js.map +1 -1
- package/dist/public-link-progress.d.ts +3 -1
- package/dist/public-link-progress.js +15 -1
- package/dist/public-link-progress.js.map +1 -1
- package/dist/public-web-gateway.js +3 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +4 -2
- package/dist/public-web-link.js +10 -8
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.js +4 -1
- package/dist/quickstart-api.js.map +1 -1
- package/dist/topic-commands.js +4 -2
- package/dist/topic-commands.js.map +1 -1
- package/dist/tunnel/cloudflared-install.d.ts +25 -1
- package/dist/tunnel/cloudflared-install.js +181 -10
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/deb-extract.d.ts +9 -0
- package/dist/tunnel/deb-extract.js +94 -0
- package/dist/tunnel/deb-extract.js.map +1 -0
- package/dist/ui/app.html +3 -0
- package/dist/ui/chat-strings.js +50 -0
- package/dist/ui/chat-thread.js +16 -1
- package/dist/ui/icons/apple-touch-icon.png +0 -0
- package/dist/ui/icons/favicon.ico +0 -0
- package/dist/ui/icons/favicon.svg +8 -0
- package/dist/ui/image-lightbox.js +104 -0
- package/dist/ui/panel-chat.js +16 -54
- package/dist/ui/panel-details.js +146 -0
- package/dist/ui/panel-fleet.js +2 -1
- package/dist/ui/panel-settings.js +18 -0
- package/dist/ui/preview-panel.js +9 -4
- package/dist/ui/preview.js +36 -13
- package/dist/ui/settings-request.js +9 -0
- package/dist/ui/shared/app-i18n.js +4 -2
- package/dist/ui/shared/app-route.js +7 -2
- package/dist/ui/shared/app-shell.js +22 -8
- package/dist/ui/shared/app.css +43 -0
- package/dist/ui/shared/app.js +6 -0
- package/dist/ui/shared/header-tools.js +93 -0
- package/dist/ui/shared/instance-nav.js +7 -4
- package/dist/ui/shared/instance-switch.js +16 -0
- package/dist/ui/shared/panel-view.js +14 -153
- package/dist/ui/shared/read-stream.js +26 -0
- package/dist/ui/shared/ui-icons.js +1 -0
- package/dist/ui/shared/usage-dialog.js +125 -0
- package/dist/ui/shared/view-strings.js +2 -2
- package/dist/ui/signin.html +3 -0
- package/dist/update-install.js +3 -1
- package/dist/update-install.js.map +1 -1
- package/dist/web-api.d.ts +16 -0
- package/dist/web-api.js +31 -4
- package/dist/web-api.js.map +1 -1
- package/dist/web-icons.d.ts +21 -0
- package/dist/web-icons.js +38 -0
- package/dist/web-icons.js.map +1 -0
- package/dist/web-preview.d.ts +9 -0
- package/dist/web-preview.js +15 -9
- package/dist/web-preview.js.map +1 -1
- package/dist/web-shell-routes.d.ts +4 -0
- package/dist/web-shell-routes.js +9 -0
- package/dist/web-shell-routes.js.map +1 -1
- package/launcher/old-updater-note.cjs +48 -0
- package/launcher/postinstall.cjs +8 -1
- package/package.json +1 -1
- package/scripts/preinstall-guard.cjs +5 -2
|
@@ -11,6 +11,11 @@ import { t } from "./app-i18n.js";
|
|
|
11
11
|
import { appStore, createStore, useStore } from "./app-store.js";
|
|
12
12
|
import { useLease } from "./app-ctx.js";
|
|
13
13
|
import { PanelHeader, setTitle, onPanelKey, signInHref } from "./app-shell.js";
|
|
14
|
+
import { InstanceSwitch } from "./instance-switch.js";
|
|
15
|
+
import { HeaderTools, VIEW_SCALE, textSizeStore } from "./header-tools.js";
|
|
16
|
+
import { readStream } from "./read-stream.js";
|
|
17
|
+
// The usage dialog's metric row lives with the dialog now (usage-dialog.js); re-exported for what imported it here.
|
|
18
|
+
export { UsageMetric } from "./usage-dialog.js";
|
|
14
19
|
import { backendLabel, STATUS_KEYS } from "./instance-nav.js";
|
|
15
20
|
import { viewStore } from "./view-roster-store.js";
|
|
16
21
|
import { navigate } from "./app-nav.js";
|
|
@@ -97,32 +102,7 @@ export { viewStore };
|
|
|
97
102
|
|
|
98
103
|
// ── The panel ──
|
|
99
104
|
|
|
100
|
-
|
|
101
|
-
* One stream of reads under a lease (the pane, the roster, usage): one at a time, and only the newest may land. A tick
|
|
102
|
-
* while a read is on its way is skipped; a forced read (Refresh), or one started after the last has hung STUCK_MS,
|
|
103
|
-
* supersedes it — and a superseded read's answer is dropped at every step: its response, its body, its commit
|
|
104
|
-
* (#1448 review: an interval alone starts overlapping reads, and lease.current() only tells navigations apart).
|
|
105
|
-
*/
|
|
106
|
-
const STUCK_MS = 10_000;
|
|
107
|
-
const clock = () => (typeof performance !== "undefined" ? performance.now() : Date.now());
|
|
108
|
-
export function readStream(lease) {
|
|
109
|
-
let gen = 0, busy = false, since = 0;
|
|
110
|
-
return {
|
|
111
|
-
/** A token for a new read, or 0 when this one should not start. */
|
|
112
|
-
begin(force = false) {
|
|
113
|
-
const at = clock();
|
|
114
|
-
if (busy && !force && at - since < STUCK_MS) return 0;
|
|
115
|
-
busy = true; since = at;
|
|
116
|
-
return ++gen;
|
|
117
|
-
},
|
|
118
|
-
/** May this read still land? */
|
|
119
|
-
live: (token) => token === gen && lease.current(),
|
|
120
|
-
end(token) { if (token === gen) busy = false; },
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const DENSITY = { fit: 1, comfortable: 1.25, compact: 0.8 };
|
|
125
|
-
const DENSITY_ORDER = ["fit", "comfortable", "compact"];
|
|
105
|
+
// readStream: one stream of reads under a lease (read-stream.js; View's pane and roster use it).
|
|
126
106
|
const MIN_PX = 12, MAX_PX = 22;
|
|
127
107
|
|
|
128
108
|
export function ViewPanel({ route, navKey }) {
|
|
@@ -134,8 +114,9 @@ export function ViewPanel({ route, navKey }) {
|
|
|
134
114
|
const [dialog, setDialogState] = useState(null);
|
|
135
115
|
const setDialog = (kind) => setDialogState(kind ? { kind, key: navKey } : null);
|
|
136
116
|
const open = dialog && dialog.key === navKey ? dialog.kind : null;
|
|
137
|
-
|
|
138
|
-
const
|
|
117
|
+
// #1523 N3: the text size is the page's one setting (header-tools.js); View's own extra choice is Fit.
|
|
118
|
+
const ts = useStore(textSizeStore);
|
|
119
|
+
const density = ts.viewFit ? "fit" : ts.size;
|
|
139
120
|
const name = route.instance;
|
|
140
121
|
const it = name ? v.roster.find((r) => r.instance_name === name) : null;
|
|
141
122
|
|
|
@@ -164,13 +145,6 @@ export function ViewPanel({ route, navKey }) {
|
|
|
164
145
|
lease.interval(load, 5000);
|
|
165
146
|
lease.on(document, "visibilitychange", () => { if (!document.hidden) load(); });
|
|
166
147
|
}, [lease]);
|
|
167
|
-
// Usage: whether the fleet offers it (a 404 means off). The read also warms the server's 5-minute cache.
|
|
168
|
-
useEffect(() => {
|
|
169
|
-
(async () => {
|
|
170
|
-
try { const r = await lease.fetch("/api/ai-usage"); if (lease.current()) setUsageAvailable(r.status !== 404); }
|
|
171
|
-
catch { /* stays hidden */ }
|
|
172
|
-
})();
|
|
173
|
-
}, [lease]);
|
|
174
148
|
// /view on its own: the instance this browser looked at last, else the first one.
|
|
175
149
|
useEffect(() => {
|
|
176
150
|
if (name || !v.loaded || !v.roster.length) return;
|
|
@@ -187,15 +161,8 @@ export function ViewPanel({ route, navKey }) {
|
|
|
187
161
|
if (f) { e.preventDefault(); f.focus(); }
|
|
188
162
|
})), [lease]);
|
|
189
163
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
store("agend_view_density", next);
|
|
193
|
-
setDensity(next);
|
|
194
|
-
};
|
|
195
|
-
const densityName = tn(`density${density.charAt(0).toUpperCase()}${density.slice(1)}`);
|
|
196
|
-
const actions = html`
|
|
197
|
-
<button type="button" class="btn btn-ghost btn-sm" onClick=${cycleDensity} title=${tn("textSize", { size: densityName })} aria-label=${tn("textSize", { size: densityName })}><${Icon} name="type" size=${16} /><span class="hide-narrow" aria-hidden="true">${densityName}</span></button>
|
|
198
|
-
${usageAvailable ? html`<button type="button" class="btn btn-ghost btn-sm" onClick=${() => setDialog("usage")} aria-label=${tn("usageButton")} title=${tn("usageButton")}><${Icon} name="chart" size=${16} /><span class="hide-narrow" aria-hidden="true">${tn("usageButton")}</span></button>` : null}
|
|
164
|
+
// Aa and ◔ are every page's (HeaderTools); Help is View's own.
|
|
165
|
+
const actions = html`<${HeaderTools} view=${true} navKey=${navKey} />
|
|
199
166
|
<button type="button" class="icon-btn" onClick=${() => setDialog("help")} aria-label=${tn("helpButton")} title=${tn("helpButton")}><${Icon} name="info" /></button>`;
|
|
200
167
|
|
|
201
168
|
let body;
|
|
@@ -209,10 +176,10 @@ export function ViewPanel({ route, navKey }) {
|
|
|
209
176
|
|
|
210
177
|
return html`<div class="panel p-view">
|
|
211
178
|
<${PanelHeader} title=${it ? (it.display_name || it.instance_name) : tn("title")}
|
|
212
|
-
sub=${it ? html`<span class="status"><span class=${`dot ${it.status === "running" ? "ok" : it.status === "crashed" ? "bad" : "off"}`} aria-hidden="true"></span>${tn(STATUS_KEYS[it.status] || "statusUnknown")}</span>` : null}
|
|
179
|
+
sub=${it ? html`<span class="status"><span class=${`dot ${it.status === "running" ? "ok" : it.status === "crashed" ? "bad" : "off"}`} aria-hidden="true"></span>${tn(STATUS_KEYS[it.status] || "statusUnknown")}</span>` : null}
|
|
180
|
+
nav=${it && !viewOnly ? html`<${InstanceSwitch} name=${name} current="view" />` : null}>${actions}</${PanelHeader}>
|
|
213
181
|
${body}
|
|
214
182
|
${open === "edit" && it ? html`<${EditProfile} key=${navKey} it=${it} onClose=${() => setDialog(null)} />` : null}
|
|
215
|
-
${open === "usage" ? html`<${UsageDialog} onClose=${() => setDialog(null)} />` : null}
|
|
216
183
|
${open === "help" ? html`<${HelpDialog} onClose=${() => setDialog(null)} />` : null}
|
|
217
184
|
</div>`;
|
|
218
185
|
}
|
|
@@ -234,7 +201,7 @@ function Terminal({ name, lease, density }) {
|
|
|
234
201
|
const lh = parseFloat(pcs.lineHeight) / parseFloat(pcs.fontSize);
|
|
235
202
|
const lineH = Number.isFinite(lh) && lh > 0 ? lh : 1.2;
|
|
236
203
|
let size = Math.min(innerW / (g.cols * glyphRatio(p)), innerH / (g.rows * lineH)) * 0.995;
|
|
237
|
-
size = Math.max(MIN_PX, Math.min(size, MAX_PX)) * (
|
|
204
|
+
size = Math.max(MIN_PX, Math.min(size, MAX_PX)) * (density === "fit" ? 1 : VIEW_SCALE[density] || 1);
|
|
238
205
|
size = Math.max(8, Math.min(size, 32));
|
|
239
206
|
g.key = key;
|
|
240
207
|
if (Math.abs(size - g.applied) < 0.75) return;
|
|
@@ -369,109 +336,3 @@ function HelpDialog({ onClose }) {
|
|
|
369
336
|
<ul class="help-list">${["help1", "help2", "help3", "help4", "help5", "help6"].map((k) => html`<li key=${k}>${tn(k)}</li>`)}</ul>
|
|
370
337
|
</${Dialog}>`;
|
|
371
338
|
}
|
|
372
|
-
|
|
373
|
-
// ── AI usage ── Every provider the fleet's logins report; refreshed every 60 s while this dialog is open (passive).
|
|
374
|
-
const USAGE_ORDER_KEY = "agend_view_usage_order";
|
|
375
|
-
function usageText(fallback, ref) {
|
|
376
|
-
if (!ref || typeof ref.key !== "string") return fallback == null ? "" : String(fallback);
|
|
377
|
-
return (Array.isArray(ref.args) ? ref.args : []).reduce((text, value, i) => text.split(`{${i}}`).join(String(value)), t(`view.${ref.key}`));
|
|
378
|
-
}
|
|
379
|
-
function usageDuration(ms) {
|
|
380
|
-
const total = Math.max(1, Math.ceil(ms / 60000));
|
|
381
|
-
const d = Math.floor(total / 1440), h = Math.floor((total % 1440) / 60), m = total % 60;
|
|
382
|
-
if (total >= 2880) return usageText("", { key: "usage.duration.days_hours", args: [d, h] });
|
|
383
|
-
if (total >= 60) return usageText("", { key: "usage.duration.hours_minutes", args: [Math.floor(total / 60), m] });
|
|
384
|
-
return usageText("", { key: "usage.duration.minutes", args: [total] });
|
|
385
|
-
}
|
|
386
|
-
function resetText(iso) {
|
|
387
|
-
if (!iso) return "";
|
|
388
|
-
const ms = new Date(iso).getTime() - Date.now();
|
|
389
|
-
if (Number.isNaN(ms)) return "";
|
|
390
|
-
if (ms <= 0) return tn("usage.reset.soon");
|
|
391
|
-
return usageText("", { key: "usage.reset.in", args: [usageDuration(ms)] });
|
|
392
|
-
}
|
|
393
|
-
function expiryText(iso) {
|
|
394
|
-
if (!iso) return "";
|
|
395
|
-
const at = new Date(iso), ms = at.getTime() - Date.now();
|
|
396
|
-
if (!(ms > 0)) return "";
|
|
397
|
-
return usageText("", { key: "usage.ticket_expiry", args: [`${at.getMonth() + 1}/${at.getDate()}`, usageDuration(ms)] });
|
|
398
|
-
}
|
|
399
|
-
export function UsageMetric({ m }) {
|
|
400
|
-
const bar = useRef(null);
|
|
401
|
-
const label = usageText(m.label, m.labelI18n);
|
|
402
|
-
const note = m.note ? usageText(m.note, m.noteI18n) : "";
|
|
403
|
-
const pct = m.type === "percent" ? Math.min(100, Math.max(0, m.used ?? 0)) : 0;
|
|
404
|
-
useLayoutEffect(() => { if (bar.current) bar.current.style.width = `${pct}%`; }, [pct]); // CSSOM (#1300)
|
|
405
|
-
if (m.type === "percent") {
|
|
406
|
-
const cls = pct >= 90 ? "crit" : pct >= 70 ? "warn" : "";
|
|
407
|
-
const word = pct >= 90 ? tn("usageNear") : pct >= 70 ? tn("usageHigh") : "";
|
|
408
|
-
const sub = [note, resetText(m.resetsAt)].filter(Boolean).join(" · ");
|
|
409
|
-
return html`<div class="u-metric"><div class="u-row"><span class="u-label">${label}</span>${word ? html`<span class=${`u-status ${cls}`}>${word}</span>` : null}
|
|
410
|
-
<span class=${`u-pct ${cls}`}>${pct.toFixed(0)}<span class="u-unit">%</span></span></div>
|
|
411
|
-
<div class="u-meter"><div ref=${bar} class=${`u-fill ${cls}`}></div></div>${sub ? html`<div class="u-sub">${sub}</div>` : null}</div>`;
|
|
412
|
-
}
|
|
413
|
-
if (m.type === "dollars") {
|
|
414
|
-
const val = m.limit ? `$${(m.used ?? 0).toFixed(2)} / $${m.limit.toFixed(2)}` : `$${(m.used ?? 0).toFixed(2)}`;
|
|
415
|
-
return html`<div class="u-metric"><div class="u-row"><span class="u-label">${label}</span><span class="u-val">${val}</span></div>${note ? html`<div class="u-sub">${note}</div>` : null}</div>`;
|
|
416
|
-
}
|
|
417
|
-
const val = `${usageText(m.value ?? "", m.valueI18n)} ${usageText(m.unit ?? "", m.unitI18n)}`.trim();
|
|
418
|
-
const sub = [note, expiryText(m.expiresAt)].filter(Boolean).join(" · ");
|
|
419
|
-
return html`<div class="u-metric"><div class="u-row"><span class="u-label">${label}</span><span class="u-val">${val}</span></div>${sub ? html`<div class="u-sub">${sub}</div>` : null}</div>`;
|
|
420
|
-
}
|
|
421
|
-
function UsageDialog({ onClose }) {
|
|
422
|
-
const lease = useLease("usage-dialog");
|
|
423
|
-
const [data, setData] = useState(undefined); // undefined: loading; null: failed
|
|
424
|
-
const [order, setOrder] = useState(() => { try { const a = JSON.parse(stored(USAGE_ORDER_KEY) || "[]"); return Array.isArray(a) ? a.filter((x) => typeof x === "string") : []; } catch { return []; } });
|
|
425
|
-
const reads = useMemo(() => readStream(lease), [lease]);
|
|
426
|
-
// Refresh (force) supersedes a read on its way; the minute's tick waits for it.
|
|
427
|
-
const load = async (force) => {
|
|
428
|
-
const token = reads.begin(force);
|
|
429
|
-
if (!token) return;
|
|
430
|
-
try {
|
|
431
|
-
const r = await lease.fetch(`/api/ai-usage${force ? "?force=1" : ""}`);
|
|
432
|
-
if (!reads.live(token)) return;
|
|
433
|
-
const d = await r.json();
|
|
434
|
-
if (reads.live(token)) setData(d);
|
|
435
|
-
} catch { if (reads.live(token)) setData(null); }
|
|
436
|
-
finally { reads.end(token); }
|
|
437
|
-
};
|
|
438
|
-
useEffect(() => { load(false); lease.interval(() => load(false), 60_000); }, [lease]);
|
|
439
|
-
const key = (p) => String(p.id || p.name || "");
|
|
440
|
-
const ordered = (providers) => {
|
|
441
|
-
const rank = new Map(order.map((id, i) => [id, i]));
|
|
442
|
-
return providers.map((p, i) => ({ p, i })).sort((a, b) => {
|
|
443
|
-
const ar = rank.has(key(a.p)) ? rank.get(key(a.p)) : Infinity, br = rank.has(key(b.p)) ? rank.get(key(b.p)) : Infinity;
|
|
444
|
-
return ar === br ? a.i - b.i : ar - br;
|
|
445
|
-
}).map((e) => e.p);
|
|
446
|
-
};
|
|
447
|
-
const move = (id, delta, providers) => {
|
|
448
|
-
const ids = ordered(providers).map(key);
|
|
449
|
-
const from = ids.indexOf(id), to = from + delta;
|
|
450
|
-
if (from < 0 || to < 0 || to >= ids.length) return;
|
|
451
|
-
[ids[from], ids[to]] = [ids[to], ids[from]];
|
|
452
|
-
setOrder(ids); store(USAGE_ORDER_KEY, JSON.stringify(ids));
|
|
453
|
-
};
|
|
454
|
-
let content;
|
|
455
|
-
if (data === undefined) content = html`<${Skeleton} lines=${4} />`;
|
|
456
|
-
else if (!data || !Array.isArray(data.providers)) content = html`<${ErrorState} message=${tn("usageFail")} onRetry=${() => load(true)} />`;
|
|
457
|
-
else {
|
|
458
|
-
const providers = ordered(data.providers);
|
|
459
|
-
content = html`${!providers.length ? html`<p class="note">${tn("usage.empty_active")}</p>` : null}
|
|
460
|
-
${providers.map((p, i) => html`<section key=${key(p)} class="u-provider">
|
|
461
|
-
<div class="u-head"><strong>${p.name}</strong>${p.plan ? html`<span class="pill">${p.plan}</span>` : null}
|
|
462
|
-
<span class="u-order">
|
|
463
|
-
<button type="button" class="icon-btn" disabled=${i === 0} aria-label=${tn("usageMoveUp")} title=${tn("usageMoveUp")} onClick=${() => move(key(p), -1, data.providers)}><${Icon} name="up" size=${14} /></button>
|
|
464
|
-
<button type="button" class="icon-btn" disabled=${i === providers.length - 1} aria-label=${tn("usageMoveDown")} title=${tn("usageMoveDown")} onClick=${() => move(key(p), 1, data.providers)}><${Icon} name="down" size=${14} /></button>
|
|
465
|
-
</span></div>
|
|
466
|
-
${p.stale ? html`<p class="note">${usageText(p.hint || "", p.hintI18n)}</p>` : null}
|
|
467
|
-
${p.status === "error" && !p.transient ? html`<p class="u-err">${usageText(p.error || tn("usage.error_fallback"), p.errorI18n)}</p>`
|
|
468
|
-
: p.status === "error" && p.transient ? html`<p class="note">${usageText(p.error || tn("usage.error_fallback"), p.errorI18n)}</p>`
|
|
469
|
-
: p.status === "no-credentials" ? html`<p class="note">${tn("usage.not_logged_in")}</p>${p.hint ? html`<p class="note">${usageText(p.hint, p.hintI18n)}</p>` : null}`
|
|
470
|
-
: html`${(p.metrics || []).map((m, j) => html`<${UsageMetric} key=${j} m=${m} />`)}
|
|
471
|
-
${!p.stale && p.hint ? html`<p class="note">${usageText(p.hint, p.hintI18n)}</p>` : !(p.metrics || []).length ? html`<p class="note">${tn("usage.no_data")}</p>` : null}`}
|
|
472
|
-
</section>`)}
|
|
473
|
-
<div class="u-foot"><span class="note">${tn("usageUpdated")} ${new Date(data.fetchedAt).toLocaleTimeString()}</span>
|
|
474
|
-
<button type="button" class="btn btn-sm" onClick=${() => load(true)}>${tn("usageRefresh")}</button></div>`;
|
|
475
|
-
}
|
|
476
|
-
return html`<${Dialog} title=${tn("usage.title")} onClose=${onClose} wide=${true}>${content}</${Dialog}>`;
|
|
477
|
-
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// One stream of reads under a lease (moved from panel-view.js for #1523 N3: View's pane and roster, and the usage
|
|
2
|
+
// dialog every page's header opens, share it).
|
|
3
|
+
/**
|
|
4
|
+
* One stream of reads under a lease (the pane, the roster, usage): one at a time, and only the newest may land. A tick
|
|
5
|
+
* while a read is on its way is skipped; a forced read (Refresh), or one started after the last has hung STUCK_MS,
|
|
6
|
+
* supersedes it — and a superseded read's answer is dropped at every step: its response, its body, its commit
|
|
7
|
+
* (#1448 review: an interval alone starts overlapping reads, and lease.current() only tells navigations apart).
|
|
8
|
+
*/
|
|
9
|
+
const STUCK_MS = 10_000;
|
|
10
|
+
const clock = () => (typeof performance !== "undefined" ? performance.now() : Date.now());
|
|
11
|
+
export function readStream(lease) {
|
|
12
|
+
let gen = 0, busy = false, since = 0;
|
|
13
|
+
return {
|
|
14
|
+
/** A token for a new read, or 0 when this one should not start. */
|
|
15
|
+
begin(force = false) {
|
|
16
|
+
const at = clock();
|
|
17
|
+
if (busy && !force && at - since < STUCK_MS) return 0;
|
|
18
|
+
busy = true; since = at;
|
|
19
|
+
return ++gen;
|
|
20
|
+
},
|
|
21
|
+
/** May this read still land? */
|
|
22
|
+
live: (token) => token === gen && lease.current(),
|
|
23
|
+
end(token) { if (token === gen) busy = false; },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -52,6 +52,7 @@ const P = {
|
|
|
52
52
|
org: () => html`<rect x="9" y="2" width="6" height="5" rx="1"/><rect x="2" y="17" width="6" height="5" rx="1"/><rect x="16" y="17" width="6" height="5" rx="1"/><path d="M12 7v5M5 17v-5h14v5"/>`,
|
|
53
53
|
panel: () => html`<rect x="3" y="4" width="18" height="16" rx="2"/><path d="M14 4v16"/>`,
|
|
54
54
|
back: () => html`<path d="M19 12H5M12 19l-7-7 7-7"/>`,
|
|
55
|
+
forward: () => html`<path d="M5 12h14M12 5l7 7-7 7"/>`,
|
|
55
56
|
external: () => html`<path d="M14 4h6v6M20 4l-9 9"/><path d="M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/>`,
|
|
56
57
|
};
|
|
57
58
|
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// #1523 N3 (§3.4): the AI usage dialog, opened from every page's header (◔). Moved from panel-view.js. Public
|
|
2
|
+
// (/assets/): View's anonymous reader opens it too. It reads /api/ai-usage every 60 s while open (passive, #1374).
|
|
3
|
+
import { html, useEffect, useLayoutEffect, useMemo, useRef, useState } from "./app-html.js";
|
|
4
|
+
import { t } from "./app-i18n.js";
|
|
5
|
+
import { useLease } from "./app-ctx.js";
|
|
6
|
+
import { readStream } from "./read-stream.js";
|
|
7
|
+
import { Dialog } from "./ui-dialog.js";
|
|
8
|
+
import { ErrorState, Skeleton } from "./ui-states.js";
|
|
9
|
+
import { Icon } from "./ui-icons.js";
|
|
10
|
+
import "./view-strings.js";
|
|
11
|
+
|
|
12
|
+
function tn(key, values = {}) {
|
|
13
|
+
let s = t(`view.${key}`);
|
|
14
|
+
for (const [k, v] of Object.entries(values)) s = s.split(`{${k}}`).join(String(v));
|
|
15
|
+
return s;
|
|
16
|
+
}
|
|
17
|
+
const stored = (k) => { try { return localStorage.getItem(k); } catch { return null; } };
|
|
18
|
+
const store = (k, v) => { try { localStorage.setItem(k, v); } catch { /* this page only */ } };
|
|
19
|
+
|
|
20
|
+
// ── AI usage ── Every provider the fleet's logins report; refreshed every 60 s while this dialog is open (passive).
|
|
21
|
+
const USAGE_ORDER_KEY = "agend_view_usage_order";
|
|
22
|
+
function usageText(fallback, ref) {
|
|
23
|
+
if (!ref || typeof ref.key !== "string") return fallback == null ? "" : String(fallback);
|
|
24
|
+
return (Array.isArray(ref.args) ? ref.args : []).reduce((text, value, i) => text.split(`{${i}}`).join(String(value)), t(`view.${ref.key}`));
|
|
25
|
+
}
|
|
26
|
+
function usageDuration(ms) {
|
|
27
|
+
const total = Math.max(1, Math.ceil(ms / 60000));
|
|
28
|
+
const d = Math.floor(total / 1440), h = Math.floor((total % 1440) / 60), m = total % 60;
|
|
29
|
+
if (total >= 2880) return usageText("", { key: "usage.duration.days_hours", args: [d, h] });
|
|
30
|
+
if (total >= 60) return usageText("", { key: "usage.duration.hours_minutes", args: [Math.floor(total / 60), m] });
|
|
31
|
+
return usageText("", { key: "usage.duration.minutes", args: [total] });
|
|
32
|
+
}
|
|
33
|
+
function resetText(iso) {
|
|
34
|
+
if (!iso) return "";
|
|
35
|
+
const ms = new Date(iso).getTime() - Date.now();
|
|
36
|
+
if (Number.isNaN(ms)) return "";
|
|
37
|
+
if (ms <= 0) return tn("usage.reset.soon");
|
|
38
|
+
return usageText("", { key: "usage.reset.in", args: [usageDuration(ms)] });
|
|
39
|
+
}
|
|
40
|
+
function expiryText(iso) {
|
|
41
|
+
if (!iso) return "";
|
|
42
|
+
const at = new Date(iso), ms = at.getTime() - Date.now();
|
|
43
|
+
if (!(ms > 0)) return "";
|
|
44
|
+
return usageText("", { key: "usage.ticket_expiry", args: [`${at.getMonth() + 1}/${at.getDate()}`, usageDuration(ms)] });
|
|
45
|
+
}
|
|
46
|
+
export function UsageMetric({ m }) {
|
|
47
|
+
const bar = useRef(null);
|
|
48
|
+
const label = usageText(m.label, m.labelI18n);
|
|
49
|
+
const note = m.note ? usageText(m.note, m.noteI18n) : "";
|
|
50
|
+
const pct = m.type === "percent" ? Math.min(100, Math.max(0, m.used ?? 0)) : 0;
|
|
51
|
+
useLayoutEffect(() => { if (bar.current) bar.current.style.width = `${pct}%`; }, [pct]); // CSSOM (#1300)
|
|
52
|
+
if (m.type === "percent") {
|
|
53
|
+
const cls = pct >= 90 ? "crit" : pct >= 70 ? "warn" : "";
|
|
54
|
+
const word = pct >= 90 ? tn("usageNear") : pct >= 70 ? tn("usageHigh") : "";
|
|
55
|
+
const sub = [note, resetText(m.resetsAt)].filter(Boolean).join(" · ");
|
|
56
|
+
return html`<div class="u-metric"><div class="u-row"><span class="u-label">${label}</span>${word ? html`<span class=${`u-status ${cls}`}>${word}</span>` : null}
|
|
57
|
+
<span class=${`u-pct ${cls}`}>${pct.toFixed(0)}<span class="u-unit">%</span></span></div>
|
|
58
|
+
<div class="u-meter"><div ref=${bar} class=${`u-fill ${cls}`}></div></div>${sub ? html`<div class="u-sub">${sub}</div>` : null}</div>`;
|
|
59
|
+
}
|
|
60
|
+
if (m.type === "dollars") {
|
|
61
|
+
const val = m.limit ? `$${(m.used ?? 0).toFixed(2)} / $${m.limit.toFixed(2)}` : `$${(m.used ?? 0).toFixed(2)}`;
|
|
62
|
+
return html`<div class="u-metric"><div class="u-row"><span class="u-label">${label}</span><span class="u-val">${val}</span></div>${note ? html`<div class="u-sub">${note}</div>` : null}</div>`;
|
|
63
|
+
}
|
|
64
|
+
const val = `${usageText(m.value ?? "", m.valueI18n)} ${usageText(m.unit ?? "", m.unitI18n)}`.trim();
|
|
65
|
+
const sub = [note, expiryText(m.expiresAt)].filter(Boolean).join(" · ");
|
|
66
|
+
return html`<div class="u-metric"><div class="u-row"><span class="u-label">${label}</span><span class="u-val">${val}</span></div>${sub ? html`<div class="u-sub">${sub}</div>` : null}</div>`;
|
|
67
|
+
}
|
|
68
|
+
/** `owner`: the navigation that opened it — its reads and the minute's timer live and end with it. */
|
|
69
|
+
export function UsageDialog({ onClose, owner = "" }) {
|
|
70
|
+
const lease = useLease(`usage-dialog:${owner}`);
|
|
71
|
+
const [data, setData] = useState(undefined); // undefined: loading; null: failed
|
|
72
|
+
const [order, setOrder] = useState(() => { try { const a = JSON.parse(stored(USAGE_ORDER_KEY) || "[]"); return Array.isArray(a) ? a.filter((x) => typeof x === "string") : []; } catch { return []; } });
|
|
73
|
+
const reads = useMemo(() => readStream(lease), [lease]);
|
|
74
|
+
// Refresh (force) supersedes a read on its way; the minute's tick waits for it.
|
|
75
|
+
const load = async (force) => {
|
|
76
|
+
const token = reads.begin(force);
|
|
77
|
+
if (!token) return;
|
|
78
|
+
try {
|
|
79
|
+
const r = await lease.fetch(`/api/ai-usage${force ? "?force=1" : ""}`);
|
|
80
|
+
if (!reads.live(token)) return;
|
|
81
|
+
const d = await r.json();
|
|
82
|
+
if (reads.live(token)) setData(d);
|
|
83
|
+
} catch { if (reads.live(token)) setData(null); }
|
|
84
|
+
finally { reads.end(token); }
|
|
85
|
+
};
|
|
86
|
+
useEffect(() => { load(false); lease.interval(() => load(false), 60_000); }, [lease]);
|
|
87
|
+
const key = (p) => String(p.id || p.name || "");
|
|
88
|
+
const ordered = (providers) => {
|
|
89
|
+
const rank = new Map(order.map((id, i) => [id, i]));
|
|
90
|
+
return providers.map((p, i) => ({ p, i })).sort((a, b) => {
|
|
91
|
+
const ar = rank.has(key(a.p)) ? rank.get(key(a.p)) : Infinity, br = rank.has(key(b.p)) ? rank.get(key(b.p)) : Infinity;
|
|
92
|
+
return ar === br ? a.i - b.i : ar - br;
|
|
93
|
+
}).map((e) => e.p);
|
|
94
|
+
};
|
|
95
|
+
const move = (id, delta, providers) => {
|
|
96
|
+
const ids = ordered(providers).map(key);
|
|
97
|
+
const from = ids.indexOf(id), to = from + delta;
|
|
98
|
+
if (from < 0 || to < 0 || to >= ids.length) return;
|
|
99
|
+
[ids[from], ids[to]] = [ids[to], ids[from]];
|
|
100
|
+
setOrder(ids); store(USAGE_ORDER_KEY, JSON.stringify(ids));
|
|
101
|
+
};
|
|
102
|
+
let content;
|
|
103
|
+
if (data === undefined) content = html`<${Skeleton} lines=${4} />`;
|
|
104
|
+
else if (!data || !Array.isArray(data.providers)) content = html`<${ErrorState} message=${tn("usageFail")} onRetry=${() => load(true)} />`;
|
|
105
|
+
else {
|
|
106
|
+
const providers = ordered(data.providers);
|
|
107
|
+
content = html`${!providers.length ? html`<p class="note">${tn("usage.empty_active")}</p>` : null}
|
|
108
|
+
${providers.map((p, i) => html`<section key=${key(p)} class="u-provider">
|
|
109
|
+
<div class="u-head"><strong>${p.name}</strong>${p.plan ? html`<span class="pill">${p.plan}</span>` : null}
|
|
110
|
+
<span class="u-order">
|
|
111
|
+
<button type="button" class="icon-btn" disabled=${i === 0} aria-label=${tn("usageMoveUp")} title=${tn("usageMoveUp")} onClick=${() => move(key(p), -1, data.providers)}><${Icon} name="up" size=${14} /></button>
|
|
112
|
+
<button type="button" class="icon-btn" disabled=${i === providers.length - 1} aria-label=${tn("usageMoveDown")} title=${tn("usageMoveDown")} onClick=${() => move(key(p), 1, data.providers)}><${Icon} name="down" size=${14} /></button>
|
|
113
|
+
</span></div>
|
|
114
|
+
${p.stale ? html`<p class="note">${usageText(p.hint || "", p.hintI18n)}</p>` : null}
|
|
115
|
+
${p.status === "error" && !p.transient ? html`<p class="u-err">${usageText(p.error || tn("usage.error_fallback"), p.errorI18n)}</p>`
|
|
116
|
+
: p.status === "error" && p.transient ? html`<p class="note">${usageText(p.error || tn("usage.error_fallback"), p.errorI18n)}</p>`
|
|
117
|
+
: p.status === "no-credentials" ? html`<p class="note">${tn("usage.not_logged_in")}</p>${p.hint ? html`<p class="note">${usageText(p.hint, p.hintI18n)}</p>` : null}`
|
|
118
|
+
: html`${(p.metrics || []).map((m, j) => html`<${UsageMetric} key=${j} m=${m} />`)}
|
|
119
|
+
${!p.stale && p.hint ? html`<p class="note">${usageText(p.hint, p.hintI18n)}</p>` : !(p.metrics || []).length ? html`<p class="note">${tn("usage.no_data")}</p>` : null}`}
|
|
120
|
+
</section>`)}
|
|
121
|
+
<div class="u-foot"><span class="note">${tn("usageUpdated")} ${new Date(data.fetchedAt).toLocaleTimeString()}</span>
|
|
122
|
+
<button type="button" class="btn btn-sm" onClick=${() => load(true)}>${tn("usageRefresh")}</button></div>`;
|
|
123
|
+
}
|
|
124
|
+
return html`<${Dialog} title=${tn("usage.title")} onClose=${onClose} wide=${true}>${content}</${Dialog}>`;
|
|
125
|
+
}
|
|
@@ -23,7 +23,7 @@ register("view", {
|
|
|
23
23
|
"help1": "Pick an instance in the list: its live terminal shows here.",
|
|
24
24
|
"help2": "Click a group's name to fold it or open it again.",
|
|
25
25
|
"help3": "Edit profile changes the display name, role, description and avatar.",
|
|
26
|
-
"help5": "Text size cycles Fit →
|
|
26
|
+
"help5": "Text size cycles Fit → S → M → L. S, M and L are the size every page shares; Fit sizes the terminal to its box.",
|
|
27
27
|
"densityFit": "Fit",
|
|
28
28
|
"densityComfortable": "Comfortable",
|
|
29
29
|
"densityCompact": "Compact",
|
|
@@ -180,7 +180,7 @@ register("view", {
|
|
|
180
180
|
"help1": "在清單裡選一個 instance:它的即時終端畫面會顯示在這裡。",
|
|
181
181
|
"help2": "點群組名稱可以收合或展開。",
|
|
182
182
|
"help3": "「編輯個人資料」可修改顯示名稱、角色、描述和頭像。",
|
|
183
|
-
"help5": "「字級」會在剛好填滿 →
|
|
183
|
+
"help5": "「字級」會在剛好填滿 → 小 → 中 → 大之間切換。小、中、大是所有頁面共用的字級;剛好填滿讓終端畫面符合框的大小。",
|
|
184
184
|
"densityFit": "剛好填滿",
|
|
185
185
|
"densityComfortable": "舒適",
|
|
186
186
|
"densityCompact": "精簡",
|
package/dist/ui/signin.html
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
<meta name="referrer" content="no-referrer">
|
|
7
7
|
<meta name="robots" content="noindex">
|
|
8
8
|
<title>AgEnD — Sign in</title>
|
|
9
|
+
<link rel="icon" href="/favicon.ico" sizes="16x16 32x32 64x64">
|
|
10
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml" sizes="any">
|
|
11
|
+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
|
|
9
12
|
<script src="/assets/theme.js"></script>
|
|
10
13
|
<link rel="stylesheet" href="/assets/tokens.css">
|
|
11
14
|
<style>
|
package/dist/update-install.js
CHANGED
|
@@ -198,7 +198,9 @@ export function runUpdateInstall(plan, runner) {
|
|
|
198
198
|
// every npm call uses the same binary that will be recorded in the outcome.
|
|
199
199
|
const npmBin = resolvedNpmPath ?? "npm";
|
|
200
200
|
// C1: lock the prefix npm is about to change — read in the install environment, as npm itself sees it — before npm.
|
|
201
|
-
|
|
201
|
+
// #1487: this updater never unlinks first, so a refused install keeps the previous one; the install hooks read this to
|
|
202
|
+
// tell that apart from AgEnD 2.1's updater, which removes it before installing (launcher/old-updater-note.cjs).
|
|
203
|
+
const env = { AGEND_UPDATE_KEEPS_PREVIOUS: "1" };
|
|
202
204
|
let rollback;
|
|
203
205
|
if (plan.lock) {
|
|
204
206
|
const prefix = inInstallEnv(runner, plan, [npmBin, "prefix", "-g"], { timeoutMs: 15_000 });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-install.js","sourceRoot":"","sources":["../src/update-install.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"update-install.js","sourceRoot":"","sources":["../src/update-install.ts"],"names":[],"mappings":"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"}
|
package/dist/web-api.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export interface WebApiContext {
|
|
|
33
33
|
};
|
|
34
34
|
web?: {
|
|
35
35
|
echo_to_channel?: boolean;
|
|
36
|
+
usage_panel?: boolean;
|
|
36
37
|
};
|
|
37
38
|
defaults?: {
|
|
38
39
|
backend?: string;
|
|
@@ -81,6 +82,15 @@ export interface WebApiContext {
|
|
|
81
82
|
getInstanceStatus(name: string): "running" | "paused" | "stopped" | "crashed";
|
|
82
83
|
/** A ClassicBot room (registered in classicBot.yaml, not fleet.yaml) — shown on the dashboard like any instance. */
|
|
83
84
|
isClassicInstance?(name: string): boolean;
|
|
85
|
+
/** #1523 N2: a ClassicBot room's own summary for Details (classicBot.yaml, not fleet.yaml), or null. */
|
|
86
|
+
classicRoomFor?(name: string): {
|
|
87
|
+
name: string;
|
|
88
|
+
channel_id: string;
|
|
89
|
+
adapter_id: string | null;
|
|
90
|
+
backend: string;
|
|
91
|
+
display_name: string | null;
|
|
92
|
+
description: string | null;
|
|
93
|
+
} | null;
|
|
84
94
|
/**
|
|
85
95
|
* Post an owner web-chat echo to `instance`'s opted-in ClassicBot channels
|
|
86
96
|
* (#1320 part B). Resolves the entries and adapters itself; returns how
|
|
@@ -197,6 +207,12 @@ export interface AppShellContext {
|
|
|
197
207
|
previewForUi?(hostHeader: string | undefined, secure: boolean): (PreviewAvailability & {
|
|
198
208
|
boot: string | null;
|
|
199
209
|
}) | null;
|
|
210
|
+
/** #1523 N3: `web.usage_panel` — the header's ◔ is offered unless it is false (the page needs no probe read for it). */
|
|
211
|
+
readonly fleetConfig?: {
|
|
212
|
+
web?: {
|
|
213
|
+
usage_panel?: boolean;
|
|
214
|
+
};
|
|
215
|
+
} | null;
|
|
200
216
|
}
|
|
201
217
|
export type AppShellMode = "full" | "view-only";
|
|
202
218
|
/** The app shell page for one entry, under the panels' CSP; it may frame exactly <preview origin>/frame, and only
|
package/dist/web-api.js
CHANGED
|
@@ -621,11 +621,16 @@ export function handleWebRequest(req, res, url, ctx) {
|
|
|
621
621
|
const detailMatch = path.match(/^\/ui\/instance\/(.+)$/);
|
|
622
622
|
if (method === "GET" && detailMatch) {
|
|
623
623
|
const name = decodeURIComponent(detailMatch[1]);
|
|
624
|
-
|
|
625
|
-
|
|
624
|
+
// An own key only: an inherited name ("constructor") is no instance. #1523 N2: a ClassicBot room is one too — its
|
|
625
|
+
// own summary (classicBot.yaml), never read as a fleet.yaml agent.
|
|
626
|
+
const instances = ctx.fleetConfig?.instances ?? {};
|
|
627
|
+
const fleetConfig = Object.prototype.hasOwnProperty.call(instances, name) ? instances[name] : undefined;
|
|
628
|
+
const room = fleetConfig ? null : ctx.classicRoomFor?.(name) ?? null;
|
|
629
|
+
if (!fleetConfig && !room) {
|
|
626
630
|
json(res, 404, { error: `Instance not found: ${name}` });
|
|
627
631
|
return true;
|
|
628
632
|
}
|
|
633
|
+
const config = fleetConfig ?? { working_directory: "", backend: room.backend, display_name: room.display_name ?? undefined, description: room.description ?? undefined };
|
|
629
634
|
const statusFile = join(ctx.getInstanceDir(name), "statusline.json");
|
|
630
635
|
let statusline = {};
|
|
631
636
|
try {
|
|
@@ -650,12 +655,30 @@ export function handleWebRequest(req, res, url, ctx) {
|
|
|
650
655
|
const effortResolved = ctx.resolveInstanceEffort?.(name);
|
|
651
656
|
const effort = (effortStrategy === "unsupported" || isAgy) ? null : (effortResolved?.effort ?? null);
|
|
652
657
|
const effort_source = (effortStrategy === "unsupported" || isAgy) ? null : (effortResolved?.source ?? "unset");
|
|
658
|
+
// The instance's other fleet.yaml fields this read shows (the context's type names only the ones it always needed).
|
|
659
|
+
const more = config;
|
|
660
|
+
// Where it is bound, as the fleet resolves it (getInstanceAdapterId): no channel_id means the first connection —
|
|
661
|
+
// "web only" only when the fleet has none (#1561 review).
|
|
662
|
+
const fc = ctx.fleetConfig;
|
|
663
|
+
const connections = fc?.channels ?? (fc?.channel ? [fc.channel] : []);
|
|
664
|
+
const first = connections[0] ? (connections[0].id ?? connections[0].type ?? null) : null;
|
|
665
|
+
const explicit = typeof more.channel_id === "string" ? more.channel_id : null;
|
|
653
666
|
json(res, 200, {
|
|
654
667
|
name,
|
|
655
668
|
status: ctx.getInstanceStatus(name),
|
|
656
669
|
description: config.description,
|
|
657
670
|
display_name: config.display_name,
|
|
658
|
-
working_directory: config.working_directory,
|
|
671
|
+
working_directory: room ? null : config.working_directory,
|
|
672
|
+
// #1523 N2 (Q1 = B): the read-only config summary on Details — tags and where it is bound. Nothing secret.
|
|
673
|
+
kind: room ? "classic" : "agent",
|
|
674
|
+
tags: room ? ["classic"] : Array.isArray(more.tags) ? more.tags.filter((x) => typeof x === "string") : [],
|
|
675
|
+
binding: room ? null : {
|
|
676
|
+
channel_id: explicit ?? first,
|
|
677
|
+
implicit: explicit === null && first !== null, // bound to the first connection by default
|
|
678
|
+
topic_id: config.topic_id != null ? String(config.topic_id) : null,
|
|
679
|
+
general_topic: more.general_topic === true,
|
|
680
|
+
},
|
|
681
|
+
...(room ? { room: { name: room.name, channel_id: room.channel_id, adapter_id: room.adapter_id } } : {}),
|
|
659
682
|
backend,
|
|
660
683
|
context_pct,
|
|
661
684
|
model,
|
|
@@ -1184,7 +1207,11 @@ function shellBodyTag(req, ctx, mode) {
|
|
|
1184
1207
|
const p = shellPreview(req, ctx, mode);
|
|
1185
1208
|
const attr = (v) => String(v ?? "").replace(/[&<>"']/g, c => `&#${c.charCodeAt(0)};`);
|
|
1186
1209
|
return `<body data-mode="${mode}"${mode === "full" && gatewayRequestContext(req) ? ' data-web-transport="poll"' : ""} data-dashboard-origin="${attr(p?.dashboardOrigin)}" data-preview-origin="${attr(p?.previewOrigin)}"`
|
|
1187
|
-
+ ` data-preview-boot="${attr(p?.previewOrigin ? p.boot : "")}" data-preview-reason="${attr(p ? p.reason : "Previews are not available on this fleet.")}"
|
|
1210
|
+
+ ` data-preview-boot="${attr(p?.previewOrigin ? p.boot : "")}" data-preview-reason="${attr(p ? p.reason : "Previews are not available on this fleet.")}"`
|
|
1211
|
+
// #1554: no availability asked (the public link, or not the full app) still says why, in the page's language.
|
|
1212
|
+
+ ` data-preview-reason-code="${attr(p ? p.code ?? "" : gatewayRequestContext(req) ? "publicLink" : "notOffered")}"`
|
|
1213
|
+
// #1523 N3: whether the fleet serves /api/ai-usage (web.usage_panel), for every page's ◔.
|
|
1214
|
+
+ ` data-usage-panel="${ctx.fleetConfig?.web?.usage_panel === false ? "0" : "1"}">`;
|
|
1188
1215
|
}
|
|
1189
1216
|
/** The app shell page for one entry, under the panels' CSP; it may frame exactly <preview origin>/frame, and only
|
|
1190
1217
|
* when this load chose one. */
|