@songsid/agend 2.3.0-beta.11 → 2.3.0-beta.13
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 +6 -0
- package/README.zh-TW.md +6 -0
- package/dist/agent-whats-new.js +14 -9
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
- package/dist/channel/adapters/discord-client-retirement.js +57 -0
- package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +2 -0
- package/dist/channel/adapters/discord.js +14 -4
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/cli.js +12 -79
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.js +13 -4
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +25 -0
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +44 -2
- package/dist/fleet-manager.js +229 -63
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +18 -0
- package/dist/fleet-process-handlers.js +69 -0
- package/dist/fleet-process-handlers.js.map +1 -0
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +2 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +20 -3
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +27 -5
- package/dist/instance-lifecycle.d.ts +2 -0
- package/dist/instance-lifecycle.js +11 -6
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/outbound-schemas.d.ts +14 -1
- package/dist/outbound-schemas.js +8 -2
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +4 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/restart-progress.d.ts +16 -1
- package/dist/restart-progress.js +74 -15
- package/dist/restart-progress.js.map +1 -1
- package/dist/settings-api.d.ts +4 -0
- package/dist/settings-api.js +27 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-confirmation.d.ts +3 -1
- package/dist/settings-confirmation.js +2 -0
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.js +2 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +11 -0
- package/dist/settings-http-confirmation.js +10 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/ui/app-effects.js +13 -1
- package/dist/ui/chat-effects.js +10 -3
- package/dist/ui/chat-store.js +32 -10
- package/dist/ui/chat-strings.js +18 -0
- package/dist/ui/chat-thread.js +5 -2
- package/dist/ui/effects-waker.js +70 -0
- package/dist/ui/fleet-canvas-layout.js +10 -4
- package/dist/ui/fleet-canvas.js +32 -2
- package/dist/ui/fleet-route-scene.js +207 -0
- package/dist/ui/fleet-route-worker.js +21 -0
- package/dist/ui/fleet-route.js +88 -0
- package/dist/ui/fleet-traffic.js +27 -11
- package/dist/ui/fleet-usage.js +35 -1
- package/dist/ui/panel-chat.js +67 -26
- package/dist/ui/panel-fleet.js +3 -3
- package/dist/ui/panel-settings.js +24 -0
- package/dist/ui/settings-appearance.js +2 -1
- package/dist/ui/settings-apply.js +3 -3
- package/dist/ui/settings-confirm.js +7 -2
- package/dist/ui/settings-owner-effects.js +6 -4
- package/dist/ui/settings-strings.js +2 -0
- package/dist/ui/shared/app-i18n.js +4 -0
- package/dist/ui/shared/app-prefs.js +12 -0
- package/dist/ui/shared/app-shell.js +38 -2
- package/dist/ui/shared/app-themes.js +116 -1
- package/dist/ui/shared/app.css +47 -3
- package/dist/ui/shared/card-strings.js +4 -0
- package/dist/ui/shared/effect-owner-source.js +8 -1
- package/dist/ui/shared/effect-registry.js +10 -2
- package/dist/ui/shared/identity-card.js +24 -6
- package/dist/ui/shared/identity-color.js +11 -7
- package/dist/ui/shared/owner-css.js +30 -1
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/ui-menu.js +9 -3
- package/dist/ui/shared/web-authorize.js +47 -0
- package/dist/web-api.d.ts +6 -2
- package/dist/web-api.js +68 -15
- package/dist/web-api.js.map +1 -1
- package/dist/web-appearance.js +3 -1
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-effect.d.ts +1 -1
- package/dist/web-host-guard.d.ts +11 -0
- package/dist/web-host-guard.js +11 -0
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-libavoid.d.ts +14 -0
- package/dist/web-libavoid.js +46 -0
- package/dist/web-libavoid.js.map +1 -0
- package/dist/web-owner-css-store.d.ts +44 -1
- package/dist/web-owner-css-store.js +70 -9
- package/dist/web-owner-css-store.js.map +1 -1
- package/dist/web-prefs.js +13 -0
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-settings-tools.d.ts +5 -0
- package/dist/web-settings-tools.js +38 -7
- package/dist/web-settings-tools.js.map +1 -1
- package/dist/web-theme.d.ts +29 -0
- package/dist/web-theme.js +89 -1
- package/dist/web-theme.js.map +1 -1
- package/dist/yaml-shared-nodes.d.ts +25 -0
- package/dist/yaml-shared-nodes.js +185 -0
- package/dist/yaml-shared-nodes.js.map +1 -0
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-http-confirmation.js","sourceRoot":"","sources":["../src/settings-http-confirmation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACrH,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAA8B,MAAM,sBAAsB,CAAC;AAC7G,OAAO,EAA6B,yBAAyB,EAA4B,MAAM,4BAA4B,CAAC;AAC5H,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"settings-http-confirmation.js","sourceRoot":"","sources":["../src/settings-http-confirmation.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/app-effects.js
CHANGED
|
@@ -105,12 +105,23 @@ export function startAppEffects({ store, window: host = window, factories = {} }
|
|
|
105
105
|
const name = navStore.get().route?.instance, v = value.instances?.find(i => i.name === name)?.effect_chat_v;
|
|
106
106
|
return typeof v === "string" && /^[a-f0-9]{32}$/.test(v) ? v : null;
|
|
107
107
|
}
|
|
108
|
+
// #2188: whether a dialog, menu or popover is open — a whole-document query when none is (the usual case), asked
|
|
109
|
+
// several times per sync. Read once per task: the cached value is dropped at the next microtask, and whenever the
|
|
110
|
+
// document changes (the MutationObserver below drops it before it reads).
|
|
111
|
+
let modalCache = null;
|
|
112
|
+
function modalOpen() {
|
|
113
|
+
if (modalCache === null) {
|
|
114
|
+
modalCache = !!doc.querySelector("dialog[open],.menu-list,.pop,[role=alertdialog],.oc-keep,.shell.sb-open");
|
|
115
|
+
Promise.resolve().then(() => { modalCache = null; });
|
|
116
|
+
}
|
|
117
|
+
return modalCache;
|
|
118
|
+
}
|
|
108
119
|
function context() {
|
|
109
120
|
return { safe: safeMode(), publicLink: doc.body.dataset.publicLink === "1", reducedMotion: motionBlocked(host), saveData: host.navigator?.connection?.saveData === true,
|
|
110
121
|
hidden: doc.visibilityState !== "visible", enabled: entry.api?.playbackAvailable !== false && typeof host.OffscreenCanvas === "function" && typeof host.Worker === "function" && typeof host.MutationObserver === "function" && typeof host.ResizeObserver === "function",
|
|
111
122
|
show: themesShown(), transportReady: effectBootstrapReady(host, host.location?.origin, doc.body.dataset.effectBoot),
|
|
112
123
|
constrained: constrainedDevice({ memory: host.navigator?.deviceMemory, cores: host.navigator?.hardwareConcurrency, coarse: coarse?.matches === true, width: host.innerWidth }),
|
|
113
|
-
modal:
|
|
124
|
+
modal: modalOpen(), openInstance: null };
|
|
114
125
|
}
|
|
115
126
|
function trialCurrent(name) {
|
|
116
127
|
const intent = trialIntent, nav = navStore.get();
|
|
@@ -221,6 +232,7 @@ export function startAppEffects({ store, window: host = window, factories = {} }
|
|
|
221
232
|
};
|
|
222
233
|
const barriers = typeof host.MutationObserver === "function" ? new host.MutationObserver(records => {
|
|
223
234
|
if (entry.dead) return;
|
|
235
|
+
modalCache = null; // the document changed: a dialog may have opened or closed (read it again)
|
|
224
236
|
const value = context().modal, drag = cursorDragging(); if (value !== modal || drag !== dragging) { modal = value; dragging = drag; sync(); }
|
|
225
237
|
if (Array.isArray(records) && records.some(r => r.target?.closest?.("#app") || r.target === doc.getElementById?.("app"))) surfaceChanged();
|
|
226
238
|
}) : null;
|
package/dist/ui/chat-effects.js
CHANGED
|
@@ -9,7 +9,7 @@ import { navigate } from "/assets/app-nav.js";
|
|
|
9
9
|
import { toast } from "/assets/ui-toast.js";
|
|
10
10
|
import { setThemesShown, themesShown, themesStore } from "/assets/app-themes.js";
|
|
11
11
|
import { setFollowsReducedMotion } from "/assets/fx-motion.js";
|
|
12
|
-
import { getAppEffects } from "./
|
|
12
|
+
import { getAppEffects, wakeEffects, effectsLoaded, onEffectsAwake } from "./effects-waker.js";
|
|
13
13
|
|
|
14
14
|
register("chatFx", {
|
|
15
15
|
en: { stock: "Off: the page layout could not be verified ({0}). Reload and report this code if it persists.", transport: "Off: the isolated effect frame could not start. Reload to try again.", enableHere: "Turn effects on here", playMotion: "Play effects anyway", leaveSafe: "Leave safe mode", viewerShow: "Show themes, effects and widgets here", clock: "Off: the page timing clock is unavailable. Reload to try again.", gatesUnknown: "Off: the playback conditions could not be verified.", resource: "Off: this effect could not be loaded or verified. Reload to try again.", frontQueue: "Waiting for a foreground slot.", consent: "This page has older playback information. Reload to use the isolated effect player.", previewMissing: "Off: the isolated effect frame is unavailable. Reload to try again.", unsupported: "Off: this browser lacks required Canvas Worker or layout support.", calibration: "Starting the effect.", baseline: "This page has older playback information. Reload to try again.", safetyUnknown: "Stopped: this device's safety history could not be verified. Reload to check it.", rawReason: "Playback blocked: {0}", missingRow: "Playback state is unavailable (runtime_unavailable).", region: "Off: this effect does not declare the chat region.", blocked: "Placed effects are blocked for this viewer:", deviceSetting: "Open device preferences", webSetting: "Open Web settings", reloadHint: "Reload page",
|
|
@@ -78,8 +78,13 @@ function ReasonAction({ reason, onClose = () => {} }) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
const NO_PLAYBACK = () => {};
|
|
81
|
-
export function ChatEffects({ name, lease, element, store, open, onClose, onPlayback = NO_PLAYBACK }) {
|
|
81
|
+
export function ChatEffects({ name, lease, element, store, open, onClose, onPlayback = NO_PLAYBACK, active = true }) {
|
|
82
82
|
const cssLife = useStore(ownerCssLifecycle);
|
|
83
|
+
// #2193: `active` — this chat has placements (its status row says so). While the runtime sleeps, a chat with none
|
|
84
|
+
// attaches and reads nothing (the dialog says "No effects in this chat"); one with some wakes it and attaches once it
|
|
85
|
+
// runs. Once it runs (woken by anything — a Try card needs its chat attached), every chat attaches as before.
|
|
86
|
+
const [awake, setAwake] = useState(() => getAppEffects() !== null || effectsLoaded());
|
|
87
|
+
useEffect(() => (awake ? undefined : onEffectsAwake(() => setAwake(true))), [awake]);
|
|
83
88
|
useStore(themesStore); // Viewer-local off/on is visible immediately, independent of runtime callbacks.
|
|
84
89
|
// Which effects were running just before this dialog opened ("was running" is said in the past, never shown as
|
|
85
90
|
// current). The ⋯ menu that opens it is a barrier too, so "just before" is within RECENT_MS of the observed stop.
|
|
@@ -100,6 +105,8 @@ export function ChatEffects({ name, lease, element, store, open, onClose, onPlay
|
|
|
100
105
|
lease.hold(cleanup);
|
|
101
106
|
try {
|
|
102
107
|
setBusy(false); onClose(); setCanWrite(false); setState(null);
|
|
108
|
+
if (!active && !awake) { setState({ error: null, rows: [], effects: [], loading: false }); return cleanup; }
|
|
109
|
+
if (!awake) { void wakeEffects(); return cleanup; } // "Checking effects…" until it runs
|
|
103
110
|
const host = window, owner = getAppEffects(host);
|
|
104
111
|
const current = () => live && lease.current();
|
|
105
112
|
if (!owner) { setState({ error: null, rows: [], effects: [], unavailable: true, reason: typeof host.OffscreenCanvas !== "function" || typeof host.Worker !== "function" ? "unsupported_host" : "runtime_unavailable" }); return cleanup; }
|
|
@@ -132,7 +139,7 @@ export function ChatEffects({ name, lease, element, store, open, onClose, onPlay
|
|
|
132
139
|
if (lease.current()) setState({ error: "runtime_unavailable", rows: [], effects: [] });
|
|
133
140
|
return cleanup;
|
|
134
141
|
}
|
|
135
|
-
}, [name, lease]);
|
|
142
|
+
}, [name, lease, active, awake]);
|
|
136
143
|
const rows = state?.rows ?? [], effects = state?.effects ?? [];
|
|
137
144
|
if (open && !wasOpen.current) {
|
|
138
145
|
const now = performance.now();
|
package/dist/ui/chat-store.js
CHANGED
|
@@ -42,7 +42,7 @@ const COMPACT_PAGE_LIMIT_MS = 11 * 60_000;
|
|
|
42
42
|
/** Build a store. `deps` (fetch, toast, announce, t, now) are injected so tests can drive every path. */
|
|
43
43
|
export function createChatStore(deps) {
|
|
44
44
|
const s = {
|
|
45
|
-
msgs: {}, drafts: {}, failedSends: {}, pendingFiles: {}, sending: {}, inFlightFiles: {},
|
|
45
|
+
msgs: {}, drafts: {}, failedSends: {}, pendingFiles: {}, sending: {}, inFlightFiles: {}, sendFailures: {}, instanceStatus: {}, waking: {},
|
|
46
46
|
prompts: {}, workingSince: {}, stopping: {}, cancelling: {}, scrollMemo: {}, historyRead: new Set(), rbBusy: new Set(),
|
|
47
47
|
pollMine: readPollMine(),
|
|
48
48
|
// #1823 (#1828 review): the server's clock minus this device's. A poll's deadline is the server's; a page whose clock
|
|
@@ -61,9 +61,10 @@ export function createChatStore(deps) {
|
|
|
61
61
|
|
|
62
62
|
/** Tell subscribers what changed: `kind` "msgs" (the thread redraws) or "state" (everything else). */
|
|
63
63
|
function changed(instance, kind = "state") { for (const fn of [...subs]) fn(instance, kind); }
|
|
64
|
-
async function api(method, path, body) {
|
|
64
|
+
async function api(method, path, body, signal) {
|
|
65
65
|
const o = { method, headers: { "Content-Type": "application/json" } };
|
|
66
66
|
if (body) o.body = JSON.stringify(body);
|
|
67
|
+
if (signal) o.signal = signal;
|
|
67
68
|
const r = await deps.fetch(path, o);
|
|
68
69
|
return r.json();
|
|
69
70
|
}
|
|
@@ -82,6 +83,7 @@ export function createChatStore(deps) {
|
|
|
82
83
|
function applyStatus(d) {
|
|
83
84
|
if (!d || !Array.isArray(d.instances)) return;
|
|
84
85
|
for (const i of d.instances) {
|
|
86
|
+
s.instanceStatus[i.name] = i.status;
|
|
85
87
|
noteExec(i.name, (i.execution_state !== undefined ? i.execution_state : i.state) ?? null);
|
|
86
88
|
const waits = i.state === "awaiting_input" ? (typeof i.interaction_summary === "string" ? i.interaction_summary : "") : null;
|
|
87
89
|
if (i.name === s.current && waits != null && s.awaiting[i.name] == null) deps.announce(tf("chat.awaiting", i.name));
|
|
@@ -142,12 +144,17 @@ export function createChatStore(deps) {
|
|
|
142
144
|
if (!r || !r.answered) deps.toast(r && r.error ? r.error : t("chat.disconnected"), false);
|
|
143
145
|
}
|
|
144
146
|
|
|
145
|
-
/**
|
|
146
|
-
|
|
147
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Read an instance's history once per page (the first time a person opens its chat). #2188: `signal` — the chat was
|
|
149
|
+
* left before the answer came (clicking down the sidebar): the read is aborted, nothing is merged, and the next visit
|
|
150
|
+
* reads again.
|
|
151
|
+
*/
|
|
152
|
+
async function openHistory(name, lease, signal) {
|
|
153
|
+
if (s.historyRead.has(name) || signal?.aborted) return false;
|
|
148
154
|
s.historyRead.add(name);
|
|
149
155
|
try {
|
|
150
|
-
const r = await api("GET", `/ui/history?instance=${encodeURIComponent(name)}&limit=200
|
|
156
|
+
const r = await api("GET", `/ui/history?instance=${encodeURIComponent(name)}&limit=200`, undefined, signal);
|
|
157
|
+
if (signal?.aborted) { s.historyRead.delete(name); return false; }
|
|
151
158
|
if (!r || !Array.isArray(r.messages)) { s.historyRead.delete(name); return true; }
|
|
152
159
|
// Kept even when the person has moved on: the store is page-lived, and the answer belongs to `name`.
|
|
153
160
|
for (const m of r.messages) liveReplies.message(m);
|
|
@@ -246,6 +253,8 @@ export function createChatStore(deps) {
|
|
|
246
253
|
const files = (s.pendingFiles[target] || []).slice();
|
|
247
254
|
if ((!txt && !files.length) || !target || s.sending[target]) return;
|
|
248
255
|
s.sending[target] = true;
|
|
256
|
+
s.waking[target] = s.instanceStatus[target] === "paused";
|
|
257
|
+
delete s.sendFailures[target];
|
|
249
258
|
s.drafts[target] = "";
|
|
250
259
|
s.pendingFiles[target] = []; s.inFlightFiles[target] = files;
|
|
251
260
|
changed(target);
|
|
@@ -257,6 +266,7 @@ export function createChatStore(deps) {
|
|
|
257
266
|
r = await api("POST", "/ui/send", ids.length ? { instance: target, message: txt, attachments: ids } : { instance: target, message: txt });
|
|
258
267
|
} catch (err) { r = { error: err && err.message ? err.message : t("chat.disconnected") }; }
|
|
259
268
|
s.sending[target] = false;
|
|
269
|
+
delete s.waking[target];
|
|
260
270
|
delete s.inFlightFiles[target];
|
|
261
271
|
if (r && !r.error) { changed(target); return; }
|
|
262
272
|
if (files.length) s.pendingFiles[target] = R().checkFiles(files, s.pendingFiles[target] || []).kept;
|
|
@@ -265,9 +275,21 @@ export function createChatStore(deps) {
|
|
|
265
275
|
if (R().settleFailedSend(target, s.current, shown, shown ? (s.drafts[target] || "") : "") === "restore") s.drafts[target] = txt;
|
|
266
276
|
else s.failedSends[target] = s.failedSends[target] ? `${s.failedSends[target]}\n${txt}` : txt;
|
|
267
277
|
}
|
|
278
|
+
const why = r && r.reason;
|
|
279
|
+
const key = typeof why === "string" ? `chat.sendFailure_${why}` : "";
|
|
280
|
+
const localized = key ? t(key) : "";
|
|
281
|
+
const error = localized && localized !== key ? localized : (r && r.error ? r.error : t("chat.disconnected"));
|
|
282
|
+
s.sendFailures[target] = { error, text: txt, files };
|
|
268
283
|
changed(target);
|
|
269
|
-
deps.toast(
|
|
284
|
+
deps.toast(error, false);
|
|
285
|
+
}
|
|
286
|
+
function canRetrySend(target) {
|
|
287
|
+
const failed = s.sendFailures[target], files = s.pendingFiles[target] || [];
|
|
288
|
+
return !!failed && !s.sending[target] && !s.failedSends[target]
|
|
289
|
+
&& (s.drafts[target] || "").trim() === failed.text
|
|
290
|
+
&& files.length === failed.files.length && files.every((f, i) => f === failed.files[i]);
|
|
270
291
|
}
|
|
292
|
+
function retrySend(target) { if (canRetrySend(target)) return send(target); }
|
|
271
293
|
function addFiles(target, list) {
|
|
272
294
|
if (!target) return;
|
|
273
295
|
const inFlight = s.inFlightFiles[target] || [];
|
|
@@ -307,8 +329,8 @@ export function createChatStore(deps) {
|
|
|
307
329
|
changed(target);
|
|
308
330
|
}
|
|
309
331
|
function discardFailed(target) { delete s.failedSends[target]; changed(target); }
|
|
310
|
-
/** Typing
|
|
311
|
-
function setDraft(target, value) { s.drafts[target] = value; }
|
|
332
|
+
/** Typing stays local, except a failed send's Retry button must follow edits too. */
|
|
333
|
+
function setDraft(target, value) { s.drafts[target] = value; if (s.sendFailures[target]) changed(target); }
|
|
312
334
|
|
|
313
335
|
// ── Stop the reply under way (the composer's Stop, or Esc). Set before the request goes, so a held Esc or a second
|
|
314
336
|
// click sends nothing more (#1317); "Stopping…" until the agent goes idle, or a minute passes.
|
|
@@ -402,7 +424,7 @@ export function createChatStore(deps) {
|
|
|
402
424
|
attach, applyStatus, applyActivity, ingest, applyDeliveries, openHistory,
|
|
403
425
|
onPrompt, applyPrompts, resolvePrompt, answerPrompt, answerByNonce, holdPrompt, releasePrompt, promptsFor,
|
|
404
426
|
applyReplyButtons, clickReplyButton,
|
|
405
|
-
uploadFile, send, addFiles, removeFile, attachPastedText, fileBackAsText, isPasted, putBack, discardFailed, setDraft,
|
|
427
|
+
uploadFile, send, canRetrySend, retrySend, addFiles, removeFile, attachPastedText, fileBackAsText, isPasted, putBack, discardFailed, setDraft,
|
|
406
428
|
cancelReply, isUser, runCommand, dismissCommand, commandFree,
|
|
407
429
|
};
|
|
408
430
|
}
|
package/dist/ui/chat-strings.js
CHANGED
|
@@ -3,6 +3,14 @@ import { register } from "/assets/app-i18n.js";
|
|
|
3
3
|
|
|
4
4
|
register("chat", {
|
|
5
5
|
en: {
|
|
6
|
+
waking: "Waking {0}…", retrySend: "Retry send",
|
|
7
|
+
sendFailure_wake_capacity: "No slot is free to wake this instance. Retry when another instance is idle.",
|
|
8
|
+
sendFailure_wake_credentials: "The instance could not sign in. Check its account on the host, then retry.",
|
|
9
|
+
sendFailure_wake_timeout: "The instance did not become ready in time. Retry, or check its status on the host.",
|
|
10
|
+
sendFailure_instance_stopped: "This instance was stopped or removed. Start it on the host before retrying.",
|
|
11
|
+
sendFailure_delivery_unavailable: "The instance could not receive this message. Check its status on the host, then retry.",
|
|
12
|
+
sendFailure_delivery_changed: "The session or instance changed before this message was sent. Sign in again if needed, then retry.",
|
|
13
|
+
|
|
6
14
|
effectTrialReason_checking: "Checking this session…",
|
|
7
15
|
effectTrialReason_localAdmin: "Sign in as an admin outside the public link to Try.",
|
|
8
16
|
effectTrialReason_chatChanged: "Open the chat that offered this trial.",
|
|
@@ -114,6 +122,7 @@ register("chat", {
|
|
|
114
122
|
dNoActivity: "No activity in the last hour.", dWorking: "Working…",
|
|
115
123
|
// #1629: a person's control over an agent's own web theme.
|
|
116
124
|
themeLock: "Lock theme", themeUnlock: "Unlock theme", themeReset: "Reset theme…", themeResetGo: "Reset",
|
|
125
|
+
pageColours: "Page colours", pageAgentOn: "The agent's choice (on)", pageAgentOff: "The agent's choice (off)", pageWhole: "On the whole page", pageChatOnly: "Only its chat",
|
|
117
126
|
themeResetConfirm: "Reset {0}'s theme to the default? Its colours, picture and working label go; a lock stays.",
|
|
118
127
|
themeResetDone: "{0}'s theme was reset.", themeLocked: "{0}'s theme is locked: the agent can't change it.", themeUnlocked: "{0}'s theme is unlocked.",
|
|
119
128
|
themeFailed: "The theme was not changed ({0}).",
|
|
@@ -128,6 +137,14 @@ register("chat", {
|
|
|
128
137
|
configured: "(configured)", fleetDefault: "(fleet default)",
|
|
129
138
|
},
|
|
130
139
|
"zh-TW": {
|
|
140
|
+
waking: "正在喚醒 {0}…", retrySend: "重試傳送",
|
|
141
|
+
sendFailure_wake_capacity: "目前沒有空位可喚醒這個實例。請等其他實例閒置後重試。",
|
|
142
|
+
sendFailure_wake_credentials: "實例無法登入。請先在主機檢查它的帳號,再重試。",
|
|
143
|
+
sendFailure_wake_timeout: "實例未能及時就緒。請重試,或在主機檢查它的狀態。",
|
|
144
|
+
sendFailure_instance_stopped: "這個實例已停止或移除。請先在主機啟動它,再重試。",
|
|
145
|
+
sendFailure_delivery_unavailable: "實例目前無法接收這則訊息。請在主機檢查它的狀態,再重試。",
|
|
146
|
+
sendFailure_delivery_changed: "訊息送出前,登入或實例狀態已改變。必要時請重新登入,再重試。",
|
|
147
|
+
|
|
131
148
|
effectTrialReason_checking: "正在確認工作階段…",
|
|
132
149
|
effectTrialReason_localAdmin: "請在公開連結以外的儀表板以管理員登入後試播。",
|
|
133
150
|
effectTrialReason_chatChanged: "請開啟發出試播邀請的聊天。",
|
|
@@ -236,6 +253,7 @@ register("chat", {
|
|
|
236
253
|
dEditInSettings: "到設定編輯", dPause: "暫停", dWake: "喚醒", dPaused: "{0} 已暫停", dWoken: "{0} 正在喚醒", dActionFailed: "沒有成功,請再試一次。",
|
|
237
254
|
dNoActivity: "最近一小時沒有活動。", dWorking: "處理中…",
|
|
238
255
|
themeLock: "鎖定主題", themeUnlock: "解除主題鎖定", themeReset: "重設主題…", themeResetGo: "重設",
|
|
256
|
+
pageColours: "頁面配色", pageAgentOn: "依 agent 的設定(開)", pageAgentOff: "依 agent 的設定(關)", pageWhole: "整個頁面", pageChatOnly: "只在它的聊天",
|
|
239
257
|
themeResetConfirm: "要把 {0} 的主題重設為預設嗎?顏色、圖片和處理中文字都會移除;鎖定會保留。",
|
|
240
258
|
themeResetDone: "已重設 {0} 的主題。", themeLocked: "已鎖定 {0} 的主題:agent 無法變更。", themeUnlocked: "已解除 {0} 的主題鎖定。",
|
|
241
259
|
themeFailed: "主題沒有變更({0})。",
|
package/dist/ui/chat-thread.js
CHANGED
|
@@ -532,10 +532,13 @@ export function createThread(list, scroller, opts) {
|
|
|
532
532
|
* were drawn above, the whole view moved by the change in that fraction (0.6–0.7 px — the faint jitter of a chat
|
|
533
533
|
* opened cold). A sub-pixel margin above the list keeps the thread's height whole, so the bottom never moves.
|
|
534
534
|
*/
|
|
535
|
+
// #2188: one read (the list's box excludes its own margin, so nothing is reset first) and a write only on a change —
|
|
536
|
+
// a reset-then-measure laid a 200-message thread out twice on every pinned draw (2.3 s at 4× CPU on a kept chat).
|
|
537
|
+
let snapped = null;
|
|
535
538
|
function snap() {
|
|
536
|
-
list.style.setProperty("--thread-snap", "0px");
|
|
537
539
|
const h = list.getBoundingClientRect().height, f = h - Math.floor(h);
|
|
538
|
-
|
|
540
|
+
const want = f > 0.001 && f < 0.999 ? (1 - f) + "px" : "0px";
|
|
541
|
+
if (want !== snapped) { snapped = want; list.style.setProperty("--thread-snap", want); }
|
|
539
542
|
}
|
|
540
543
|
// Sizes change without a scroll event (layout after the render, the dock under the thread): while pinned, the view
|
|
541
544
|
// stays flush with the bottom; a reader who scrolled up is never moved.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// #2193: the web effects runtime stays unloaded until there is something it could play for this viewer. Before that,
|
|
2
|
+
// this module is all there is: a few store subscriptions comparing fields the page already has (no observer, listener,
|
|
3
|
+
// timer, layer or request). The runtime itself (app-effects.js and everything it imports) is the reviewed code,
|
|
4
|
+
// unchanged; it is imported and started here, once, the first time one of these holds:
|
|
5
|
+
// - the open chat has Canvas Worker placements: its status row's effect_chat_v (the hash of its placements, taken
|
|
6
|
+
// before the server's region filtering — so it can only wake for nothing, never miss something) is not the hash of
|
|
7
|
+
// an empty list;
|
|
8
|
+
// - the signed-in person has a personal effect slot chosen (fx.page/header/sidebar/box/cursor — app-prefs);
|
|
9
|
+
// - an agent's "Try" offer is shown (wakeEffects() from the chat), or Settings saved a personal effect.
|
|
10
|
+
// Once started it stays for the page: the runtime is one episode per window (a disposed one cannot start again).
|
|
11
|
+
// Owner CSS is not the runtime's: owner-css.js is installed by the app shell and works with the runtime never loaded.
|
|
12
|
+
import { appStore } from "/assets/app-store.js";
|
|
13
|
+
import { navStore } from "/assets/app-nav.js";
|
|
14
|
+
import { ownerEffectsChosen, onOwnerEffectsChanged } from "/assets/app-prefs.js";
|
|
15
|
+
|
|
16
|
+
/** effect_chat_v of a chat with no placements: sha256(JSON.stringify([])), first 32 hex (fleet-manager's status row). */
|
|
17
|
+
export const EMPTY_CHAT_EFFECTS = "4f53cda18c2baa0c0354bb5f9a3ecbe5";
|
|
18
|
+
|
|
19
|
+
let mod = null, waking = null, chatStore = null, started = false;
|
|
20
|
+
const awakeListeners = new Set();
|
|
21
|
+
|
|
22
|
+
/** Whether `name`'s chat has Canvas Worker placements (as the status rows say). */
|
|
23
|
+
export function chatHasEffects(name, app = appStore.get()) {
|
|
24
|
+
const v = name ? app.instances?.find(i => i.name === name)?.effect_chat_v : undefined;
|
|
25
|
+
return typeof v === "string" && /^[a-f0-9]{32}$/.test(v) && v !== EMPTY_CHAT_EFFECTS;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The running effects owner, or null while dormant (or when it could not start: as getAppEffects always was). */
|
|
29
|
+
export function getAppEffects(host) { return mod ? mod.getAppEffects(host) : null; }
|
|
30
|
+
|
|
31
|
+
/** Whether the runtime has been asked to start on this page. */
|
|
32
|
+
export function effectsAwake() { return waking !== null; }
|
|
33
|
+
/** Whether its module has loaded (started, or found it could not: getAppEffects() then says which). */
|
|
34
|
+
export function effectsLoaded() { return mod !== null; }
|
|
35
|
+
|
|
36
|
+
/** Called once the runtime has started (or immediately when it already has). Returns the unsubscribe. */
|
|
37
|
+
export function onEffectsAwake(fn) {
|
|
38
|
+
if (typeof fn !== "function") return () => {};
|
|
39
|
+
if (mod) { try { fn(); } catch { /* a listener's error is its own */ } return () => {}; }
|
|
40
|
+
awakeListeners.add(fn); return () => awakeListeners.delete(fn);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Load and start the runtime (once per page). Resolves to the owner, or null when it could not start. */
|
|
44
|
+
export function wakeEffects() {
|
|
45
|
+
if (waking) return waking;
|
|
46
|
+
waking = import("./app-effects.js").then(m => {
|
|
47
|
+
mod = m;
|
|
48
|
+
const owner = chatStore ? m.startAppEffects({ store: chatStore }) : null;
|
|
49
|
+
for (const fn of [...awakeListeners]) { try { fn(); } catch { /* the rest still hear */ } }
|
|
50
|
+
awakeListeners.clear();
|
|
51
|
+
return owner;
|
|
52
|
+
}, () => null);
|
|
53
|
+
return waking;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Wake when the open chat has placements or the person has a personal effect. */
|
|
57
|
+
function check() {
|
|
58
|
+
if (waking) return;
|
|
59
|
+
const route = navStore.get().route;
|
|
60
|
+
if ((route?.panel === "chat" && chatHasEffects(route.instance)) || ownerEffectsChosen()) void wakeEffects();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Boot (once per page, with the Chat store the runtime binds to). Starts nothing but the watch. */
|
|
64
|
+
export function startEffectsWaker({ store }) {
|
|
65
|
+
chatStore = store;
|
|
66
|
+
if (started) return;
|
|
67
|
+
started = true;
|
|
68
|
+
appStore.subscribe(check); navStore.subscribe(check); onOwnerEffectsChanged(check);
|
|
69
|
+
check();
|
|
70
|
+
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// #1918: the org canvas's layout (fleet-canvas.js draws it; fleet-traffic.js routes lines through its empty lanes).
|
|
2
2
|
// Fixed slots, no layout engine: the same structure always gives the same picture.
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Sizes in canvas units. NW×NH a member card, LW×LH a General card; FOLDED a folded (or empty) team's height. GAP and
|
|
6
|
+
* PAD (#2182): the gutters between cards and a box's padding are the traffic lines' channels inside a box — wide
|
|
7
|
+
* enough that the router (fleet-route-scene.js) keeps a few lines apart in each; a phone's narrow packing keeps the
|
|
8
|
+
* tighter GAP_NARROW and PAD_NARROW, so General and the first team still open at a readable size. A layout says which
|
|
9
|
+
* it used (L.gap, L.pad).
|
|
10
|
+
*/
|
|
11
|
+
export const OC = { NW: 184, NH: 56, GAP: 28, PAD: 32, GAP_NARROW: 18, PAD_NARROW: 24, HEAD: 34, TEAM_GAP: 72, ROW_GAP: 96, ROW_MAX: 1400, ROW_MAX_NARROW: 460, LW: 232, LH: 68, TOP_Y: 20, BUS: 44, FOLDED: 64, TRUNK: -30 };
|
|
6
12
|
const colsFor = (n, narrow) => (n <= 1 ? 1 : n <= 4 || narrow ? 2 : 3);
|
|
7
13
|
/** The key a team folds by (per device): its name; the instances in no team have one of their own no team name can be. */
|
|
8
14
|
export const REST_KEY = "\u0000rest";
|
|
@@ -13,7 +19,7 @@ export const REST_KEY = "\u0000rest";
|
|
|
13
19
|
* size of the whole. `narrow`: a phone's packing.
|
|
14
20
|
*/
|
|
15
21
|
export function canvasLayout(view, folded = new Set(), { narrow = false, label = (s, n) => `${n} ${s}` } = {}) {
|
|
16
|
-
const { NW, NH, GAP, PAD
|
|
22
|
+
const { NW, NH, HEAD } = OC, GAP = narrow ? OC.GAP_NARROW : OC.GAP, PAD = narrow ? OC.PAD_NARROW : OC.PAD;
|
|
17
23
|
const groups = [...view.teams.map((tm) => ({ key: tm.name, name: tm.name, loose: false, nodes: tm.nodes, counts: tm.counts })),
|
|
18
24
|
...(view.rest.nodes.length ? [{ key: REST_KEY, name: null, loose: true, nodes: view.rest.nodes, counts: view.rest.counts }] : [])];
|
|
19
25
|
const rows = [];
|
|
@@ -49,7 +55,7 @@ export function canvasLayout(view, folded = new Set(), { narrow = false, label =
|
|
|
49
55
|
const width = Math.max(rowsW, topW);
|
|
50
56
|
const tops = view.top.map((node, i) => ({ node, key: `\u0000top/${node.name}`, x: width / 2 - topW / 2 + i * (OC.LW + GAP), y: OC.TOP_Y, w: OC.LW, h: OC.LH }));
|
|
51
57
|
const height = boxes.length ? y - OC.ROW_GAP : tops.length ? OC.TOP_Y + OC.LH : 0;
|
|
52
|
-
return { tops, boxes, width, height, tree: treeLines(tops, boxes) };
|
|
58
|
+
return { tops, boxes, width, height, tree: treeLines(tops, boxes), gap: GAP, pad: PAD };
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
/** A folded team's summary line height, and a label's width estimate (canvas units: wide for CJK, narrow otherwise). */
|
package/dist/ui/fleet-canvas.js
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
// change). The live state is the app store's (fleet-org.js buildOrgView), so the canvas moves with the stream.
|
|
16
16
|
// - Live traffic (fleet-traffic.js): the messages between instances, drawn between the team boxes and the cards (never
|
|
17
17
|
// hidden under a box, never across a name). Live on or off per device; the list says it in words ("Sending: …").
|
|
18
|
+
// #2182: routed around the cards and through the boxes' doors by libavoid in a worker (fleet-route-scene.js), each
|
|
19
|
+
// line from card to card; the lanes are the fallback.
|
|
18
20
|
import { html, useEffect, useLayoutEffect, useMemo, useRef, useState } from "/assets/app-html.js";
|
|
19
21
|
import { appStore } from "/assets/app-store.js";
|
|
20
22
|
import { t, register } from "/assets/app-i18n.js";
|
|
@@ -27,6 +29,8 @@ import { identityClasses, identityOf, paintIdentity, useIdentityColors } from "/
|
|
|
27
29
|
import { buildOrgView, OrgChart, OrgSummary } from "./fleet-org.js";
|
|
28
30
|
import { OC, REST_KEY, SUM_LINE, canvasLayout, openingRegion, summaryRows } from "./fleet-canvas-layout.js";
|
|
29
31
|
import { createTrafficStore, FAR_K, POLL_MS, sendingBy, trafficEdges } from "./fleet-traffic.js";
|
|
32
|
+
import { routeScene } from "./fleet-route-scene.js";
|
|
33
|
+
import { createRouteClient } from "./fleet-route.js";
|
|
30
34
|
|
|
31
35
|
register("orgc", {
|
|
32
36
|
en: {
|
|
@@ -201,7 +205,7 @@ function TrafficLayer({ edges, q }) {
|
|
|
201
205
|
const still = reducedMotion();
|
|
202
206
|
return html`<g class="oc-flows" aria-hidden="true">${edges.map((e) => {
|
|
203
207
|
const dim = q && !e.names.some((n) => n.toLowerCase().includes(q));
|
|
204
|
-
return html`<g key=${e.key} class=${`oc-fl${dim ? " dim" : ""}`}>
|
|
208
|
+
return html`<g key=${e.key} class=${`oc-fl${dim ? " dim" : ""}`} data-routed=${e.routed ? "1" : undefined}>
|
|
205
209
|
<path class="oc-flow-halo" d=${e.d} />
|
|
206
210
|
<path class=${`oc-flow h-${e.hue} ph-${e.phase}`} d=${e.d} marker-start=${`url(#oc-src-${MARKER(e)})`} marker-end=${`url(#oc-ah-${MARKER(e)})`} />
|
|
207
211
|
${e.phase === "live" && !still ? html`<circle class=${`oc-pulse h-${e.hue}`} r="4"><animateMotion dur=${`${Math.max(1.6, e.pts.length * 0.3)}s`} repeatCount="indefinite" path=${e.d} /></circle>` : null}
|
|
@@ -269,6 +273,32 @@ function useTraffic(lease, on) {
|
|
|
269
273
|
return useMemo(() => (on ? store.items() : []), [rev, on]);
|
|
270
274
|
}
|
|
271
275
|
|
|
276
|
+
/**
|
|
277
|
+
* #2182: the traffic lines, routed around the canvas by libavoid in a worker (fleet-route.js) once it answers; until
|
|
278
|
+
* then, and zoomed out (one line per team pair), along the lanes (fleet-traffic.js route()). An answer is kept while the
|
|
279
|
+
* layout it was routed on is the one drawn: a line it has not seen yet takes its lane until the next answer.
|
|
280
|
+
*/
|
|
281
|
+
let routeClient = null;
|
|
282
|
+
function useTrafficRoutes(traffic, L, far) {
|
|
283
|
+
const lanes = useMemo(() => (traffic ? trafficEdges(traffic, L, { far }) : []), [traffic, L, far]);
|
|
284
|
+
const scene = useMemo(() => (far || !lanes.length ? null : routeScene(L, lanes)), [lanes, L, far]);
|
|
285
|
+
const [answer, setAnswer] = useState(null); // { shapes, map }
|
|
286
|
+
// The layout as the router sees it: a status frame re-making the same layout keeps the answer (and asks nothing).
|
|
287
|
+
const shapes = scene ? JSON.stringify(scene.shapes) : null;
|
|
288
|
+
const ask = scene && scene.conns.length ? JSON.stringify(scene) : null;
|
|
289
|
+
useEffect(() => {
|
|
290
|
+
if (!ask) return undefined;
|
|
291
|
+
routeClient ??= createRouteClient();
|
|
292
|
+
if (!routeClient.available) return undefined;
|
|
293
|
+
let live = true;
|
|
294
|
+
routeClient.route(JSON.parse(ask)).then((map) => { if (live && map) setAnswer({ shapes, map }); });
|
|
295
|
+
return () => { live = false; };
|
|
296
|
+
}, [ask]);
|
|
297
|
+
useEffect(() => () => { routeClient?.close(); routeClient = null; }, []);
|
|
298
|
+
return useMemo(() => (answer && answer.shapes === shapes && traffic ? trafficEdges(traffic, L, { far, routed: answer.map }) : lanes),
|
|
299
|
+
[lanes, answer, shapes, L, far, traffic]);
|
|
300
|
+
}
|
|
301
|
+
|
|
272
302
|
/** The canvas body: `view` buildOrgView's answer; `folded` the folded teams' keys; `q` the search needle; `traffic` the live items (null: Live is off). */
|
|
273
303
|
function Canvas({ view, folded, onFold, q, jump, traffic }) {
|
|
274
304
|
const [narrow] = useState(() => typeof matchMedia === "function" && matchMedia("(max-width: 640px)").matches);
|
|
@@ -308,7 +338,7 @@ function Canvas({ view, folded, onFold, q, jump, traffic }) {
|
|
|
308
338
|
vp.current = narrow ? fitView(openingRegion(L), size(), { margin: 12, minK: 0.75 }) : fitView(whole(), size(), { widthOnly: true, maxK: 1, minK: 0.6 });
|
|
309
339
|
setFar(vp.current.k < FAR_K);
|
|
310
340
|
}, []);
|
|
311
|
-
const edges =
|
|
341
|
+
const edges = useTrafficRoutes(traffic, L, far);
|
|
312
342
|
// Preact owns the markup, not the transform: put it back after every render.
|
|
313
343
|
useLayoutEffect(apply);
|
|
314
344
|
// A search's Enter: the first match, unfolded (by the panel) and then brought into view — once. It waits for the
|