@songsid/agend 2.2.0 → 2.3.0-beta.1
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/agent-cli.js +248 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.d.ts +2 -0
- package/dist/agent-endpoint.js +25 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.d.ts +30 -0
- package/dist/agent-file-read.js +129 -0
- package/dist/agent-file-read.js.map +1 -0
- package/dist/agent-whats-new.js +13 -0
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/atomic-write.js +9 -1
- package/dist/atomic-write.js.map +1 -1
- package/dist/auth-api.js +17 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/antigravity.js +3 -3
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/launch-effort.js +1 -1
- package/dist/backend/launch-effort.js.map +1 -1
- package/dist/backend/muse.js +10 -2
- package/dist/backend/muse.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +2 -0
- package/dist/channel/adapters/discord.js +17 -2
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +8 -1
- package/dist/channel/adapters/telegram.js +74 -4
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +34 -0
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +15 -0
- package/dist/config-validator.js +17 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.js +244 -20
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-context.d.ts +5 -0
- package/dist/fleet-manager.d.ts +89 -0
- package/dist/fleet-manager.js +401 -25
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +258 -0
- package/dist/instance-avatar.js +3 -0
- package/dist/instance-avatar.js.map +1 -1
- package/dist/instance-config-impact.js +3 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.js +9 -4
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/needs-you-hub.d.ts +4 -0
- package/dist/needs-you-hub.js +31 -6
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +1 -13
- package/dist/needs-you.js +3 -37
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.d.ts +5 -0
- package/dist/outbound-handlers.js +30 -9
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +64 -0
- package/dist/outbound-schemas.js +50 -0
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +14 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/repo-worktree-guard.d.ts +36 -0
- package/dist/repo-worktree-guard.js +143 -0
- package/dist/repo-worktree-guard.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +58 -1
- package/dist/scheduler/scheduler.js +176 -10
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/settings-api.js +74 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +8 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +16 -2
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.js +5 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/tool-permissions.js +50 -0
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +10 -6
- package/dist/topic-commands.js +21 -17
- package/dist/topic-commands.js.map +1 -1
- package/dist/topic-link.d.ts +128 -0
- package/dist/topic-link.js +269 -0
- package/dist/topic-link.js.map +1 -0
- package/dist/types.d.ts +13 -0
- package/dist/ui/app-effects.js +187 -0
- package/dist/ui/chat-effect-posters.js +42 -0
- package/dist/ui/chat-effects.js +72 -0
- package/dist/ui/chat-live-replies.js +58 -0
- package/dist/ui/chat-render.js +4 -4
- package/dist/ui/chat-store.js +9 -3
- package/dist/ui/chat-strings.js +15 -0
- package/dist/ui/chat-thread.js +47 -21
- package/dist/ui/chat-tour.js +1 -1
- package/dist/ui/effect-trial-controller.js +119 -0
- package/dist/ui/effect-trial-offer.js +31 -0
- package/dist/ui/effect-trial-panel.js +37 -0
- package/dist/ui/image-lightbox.js +1 -1
- package/dist/ui/panel-chat.js +85 -17
- package/dist/ui/panel-details.js +18 -5
- package/dist/ui/panel-fleet.js +3 -3
- package/dist/ui/panel-log.js +6 -6
- package/dist/ui/panel-needs.js +3 -3
- package/dist/ui/panel-settings.js +8 -5
- package/dist/ui/preview-panel.js +25 -9
- package/dist/ui/settings-appearance.js +325 -0
- package/dist/ui/settings-effects.js +201 -0
- package/dist/ui/settings-mods.js +257 -0
- package/dist/ui/settings-owner-effects.js +80 -0
- package/dist/ui/settings-strings.js +245 -0
- package/dist/ui/shared/agend-auth.js +27 -3
- package/dist/ui/shared/agent-widget.js +248 -0
- package/dist/ui/shared/app-i18n.js +2 -0
- package/dist/ui/shared/app-prefs.js +30 -10
- package/dist/ui/shared/app-route.js +23 -1
- package/dist/ui/shared/app-session.js +1 -1
- package/dist/ui/shared/app-shell.js +29 -16
- package/dist/ui/shared/app-store.js +2 -0
- package/dist/ui/shared/app-stream.js +12 -7
- package/dist/ui/shared/app-themes.js +188 -0
- package/dist/ui/shared/app.css +214 -1
- package/dist/ui/shared/app.js +6 -0
- package/dist/ui/shared/card-strings.js +28 -0
- package/dist/ui/shared/effect-app-runtime.js +248 -0
- package/dist/ui/shared/effect-baseline.js +64 -0
- package/dist/ui/shared/effect-chat-runtime.js +154 -0
- package/dist/ui/shared/effect-cursor.js +125 -0
- package/dist/ui/shared/effect-frame.js +127 -0
- package/dist/ui/shared/effect-geometry.js +122 -0
- package/dist/ui/shared/effect-host-style.js +10 -0
- package/dist/ui/shared/effect-owner-regions.js +74 -0
- package/dist/ui/shared/effect-owner-source.js +115 -0
- package/dist/ui/shared/effect-policy.js +137 -0
- package/dist/ui/shared/effect-poster-reader.js +98 -0
- package/dist/ui/shared/effect-posters.js +117 -0
- package/dist/ui/shared/effect-profiler.js +162 -0
- package/dist/ui/shared/effect-profiles.js +65 -0
- package/dist/ui/shared/effect-registry.js +496 -0
- package/dist/ui/shared/effect-runtime-loader.js +234 -0
- package/dist/ui/shared/effect-safety.js +153 -0
- package/dist/ui/shared/effect-stock-snapshot.js +34 -0
- package/dist/ui/shared/effect-stock-trust.js +165 -0
- package/dist/ui/shared/effect-trial-source.js +103 -0
- package/dist/ui/shared/effect-trial-stage.js +147 -0
- package/dist/ui/shared/header-tools.js +1 -1
- package/dist/ui/shared/identity-card.js +202 -0
- package/dist/ui/shared/identity-color.js +261 -0
- package/dist/ui/shared/instance-nav.js +22 -14
- package/dist/ui/shared/owner-css.js +221 -0
- package/dist/ui/shared/owner-effect-prefs.js +117 -0
- package/dist/ui/shared/panel-view.js +81 -8
- package/dist/ui/shared/signin.js +2 -0
- package/dist/ui/shared/ui-dialog.js +1 -1
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/ui-menu.js +1 -1
- package/dist/ui/shared/ui-toast.js +1 -1
- package/dist/ui/shared/view-strings.js +30 -0
- package/dist/ui/signin.html +1 -0
- package/dist/view-api.d.ts +29 -0
- package/dist/view-api.js +188 -8
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +42 -0
- package/dist/web-api.js +896 -36
- package/dist/web-api.js.map +1 -1
- package/dist/web-appearance-limits.d.ts +82 -0
- package/dist/web-appearance-limits.js +83 -0
- package/dist/web-appearance-limits.js.map +1 -0
- package/dist/web-appearance-policy.d.ts +66 -0
- package/dist/web-appearance-policy.js +94 -0
- package/dist/web-appearance-policy.js.map +1 -0
- package/dist/web-appearance-tools.d.ts +50 -0
- package/dist/web-appearance-tools.js +105 -0
- package/dist/web-appearance-tools.js.map +1 -0
- package/dist/web-appearance-view.d.ts +99 -0
- package/dist/web-appearance-view.js +163 -0
- package/dist/web-appearance-view.js.map +1 -0
- package/dist/web-appearance.d.ts +79 -0
- package/dist/web-appearance.js +298 -0
- package/dist/web-appearance.js.map +1 -0
- package/dist/web-asset-parts.d.ts +98 -0
- package/dist/web-asset-parts.js +133 -0
- package/dist/web-asset-parts.js.map +1 -0
- package/dist/web-auth.js +17 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-card.d.ts +96 -0
- package/dist/web-card.js +232 -0
- package/dist/web-card.js.map +1 -0
- package/dist/web-chat-history.d.ts +13 -0
- package/dist/web-chat-history.js +23 -2
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-effect-bundle.d.ts +28 -0
- package/dist/web-effect-bundle.js +126 -0
- package/dist/web-effect-bundle.js.map +1 -0
- package/dist/web-effect-canonical.d.ts +8 -0
- package/dist/web-effect-canonical.js +27 -0
- package/dist/web-effect-canonical.js.map +1 -0
- package/dist/web-effect-library.d.ts +114 -0
- package/dist/web-effect-library.js +530 -0
- package/dist/web-effect-library.js.map +1 -0
- package/dist/web-effect-poster.d.ts +8 -0
- package/dist/web-effect-poster.js +52 -0
- package/dist/web-effect-poster.js.map +1 -0
- package/dist/web-effect-profiles.d.ts +118 -0
- package/dist/web-effect-profiles.js +180 -0
- package/dist/web-effect-profiles.js.map +1 -0
- package/dist/web-effect-service.d.ts +86 -0
- package/dist/web-effect-service.js +312 -0
- package/dist/web-effect-service.js.map +1 -0
- package/dist/web-effect-tools.d.ts +47 -0
- package/dist/web-effect-tools.js +126 -0
- package/dist/web-effect-tools.js.map +1 -0
- package/dist/web-effect-trials.d.ts +86 -0
- package/dist/web-effect-trials.js +204 -0
- package/dist/web-effect-trials.js.map +1 -0
- package/dist/web-effect-upload.d.ts +29 -0
- package/dist/web-effect-upload.js +190 -0
- package/dist/web-effect-upload.js.map +1 -0
- package/dist/web-effect-worker.d.ts +8 -0
- package/dist/web-effect-worker.js +170 -0
- package/dist/web-effect-worker.js.map +1 -0
- package/dist/web-effect.d.ts +89 -0
- package/dist/web-effect.js +132 -0
- package/dist/web-effect.js.map +1 -0
- package/dist/web-identity-color.d.ts +87 -0
- package/dist/web-identity-color.js +209 -0
- package/dist/web-identity-color.js.map +1 -0
- package/dist/web-identity-palette.d.ts +113 -0
- package/dist/web-identity-palette.js +84 -0
- package/dist/web-identity-palette.js.map +1 -0
- package/dist/web-image-meta.d.ts +25 -0
- package/dist/web-image-meta.js +200 -0
- package/dist/web-image-meta.js.map +1 -0
- package/dist/web-mod-agent.d.ts +50 -0
- package/dist/web-mod-agent.js +203 -0
- package/dist/web-mod-agent.js.map +1 -0
- package/dist/web-mod-bundle.d.ts +144 -0
- package/dist/web-mod-bundle.js +464 -0
- package/dist/web-mod-bundle.js.map +1 -0
- package/dist/web-mod-export.d.ts +59 -0
- package/dist/web-mod-export.js +79 -0
- package/dist/web-mod-export.js.map +1 -0
- package/dist/web-mod-store.d.ts +283 -0
- package/dist/web-mod-store.js +624 -0
- package/dist/web-mod-store.js.map +1 -0
- package/dist/web-org.d.ts +3 -3
- package/dist/web-org.js +11 -17
- package/dist/web-org.js.map +1 -1
- package/dist/web-owner-css-store.d.ts +180 -0
- package/dist/web-owner-css-store.js +384 -0
- package/dist/web-owner-css-store.js.map +1 -0
- package/dist/web-owner-css.d.ts +58 -0
- package/dist/web-owner-css.js +552 -0
- package/dist/web-owner-css.js.map +1 -0
- package/dist/web-prefs.d.ts +48 -0
- package/dist/web-prefs.js +209 -33
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +9 -1
- package/dist/web-preview.js +24 -7
- package/dist/web-preview.js.map +1 -1
- package/dist/web-settings-patch.d.ts +18 -0
- package/dist/web-settings-patch.js +51 -0
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +1 -1
- package/dist/web-shell-routes.js +1 -1
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/web-theme-store.d.ts +218 -0
- package/dist/web-theme-store.js +516 -0
- package/dist/web-theme-store.js.map +1 -0
- package/dist/web-theme.d.ts +121 -0
- package/dist/web-theme.js +407 -0
- package/dist/web-theme.js.map +1 -0
- package/dist/web-widget.d.ts +72 -0
- package/dist/web-widget.js +245 -0
- package/dist/web-widget.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/** #1629: trusted bootstrap sources; uploaded JS runs only in a dedicated Worker, never a DOM realm. */
|
|
2
|
+
export const EFFECT_MAX_BYTES = 1024 * 1024;
|
|
3
|
+
export const EFFECT_MAX_PIXELS = 8 * 1024 * 1024;
|
|
4
|
+
// Shared by the trusted document and Worker. Closed signals only; no content-bearing fields are read.
|
|
5
|
+
export const EFFECT_SIGNAL_CHECK = String.raw `
|
|
6
|
+
function signal(d, instance) {
|
|
7
|
+
if (!d || Object.getPrototypeOf(d) !== Object.prototype || d.v !== 1 || !Number.isFinite(d.ts) || d.ts < 0) return false;
|
|
8
|
+
var keys = {state:['state'],reply:[],mention:[],theme:['mode'],env:['width','height','dpr','quality'],pointer:['kind','x','y','buttons']};
|
|
9
|
+
if (!Object.prototype.hasOwnProperty.call(keys,d.type)) return false;
|
|
10
|
+
var exact = ['v','type','ts'].concat(keys[d.type]);
|
|
11
|
+
if (['state','reply','mention'].indexOf(d.type) >= 0 && Object.prototype.hasOwnProperty.call(d,'instance')) {
|
|
12
|
+
if (typeof instance !== 'string' || d.instance !== instance) return false;
|
|
13
|
+
exact.push('instance');
|
|
14
|
+
}
|
|
15
|
+
if (d.type === 'pointer') for (var key of ['dx','dy']) if (Object.prototype.hasOwnProperty.call(d,key)) {
|
|
16
|
+
if (!Number.isFinite(d[key]) || Math.abs(d[key]) > 10000) return false;
|
|
17
|
+
exact.push(key);
|
|
18
|
+
}
|
|
19
|
+
if (Object.keys(d).sort().join(',') !== exact.sort().join(',')) return false;
|
|
20
|
+
switch (d.type) {
|
|
21
|
+
case 'state': return ['idle','working','needs_you','stopped'].indexOf(d.state) >= 0;
|
|
22
|
+
case 'reply': case 'mention': return true;
|
|
23
|
+
case 'theme': return ['light','dark'].indexOf(d.mode) >= 0;
|
|
24
|
+
case 'env': return Number.isInteger(d.width) && d.width >= 1 && d.width <= 4096 && Number.isInteger(d.height) && d.height >= 1 && d.height <= 4096 && d.width*d.height <= 8388608 && Number.isFinite(d.dpr) && d.dpr >= 0.5 && d.dpr <= 3 && ['normal','low'].indexOf(d.quality) >= 0;
|
|
25
|
+
case 'pointer': return ['move','down','up','click','wheel'].indexOf(d.kind) >= 0 && Number.isFinite(d.x) && d.x >= 0 && d.x <= 4096 && Number.isFinite(d.y) && d.y >= 0 && d.y <= 4096 && Number.isInteger(d.buttons) && d.buttons >= 0 && d.buttons <= 31;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
/** The private port never reaches user callbacks, including through poisoned native getters/schedulers. */
|
|
31
|
+
export function effectWorkerSource() {
|
|
32
|
+
return `"use strict";
|
|
33
|
+
(function () {
|
|
34
|
+
${EFFECT_SIGNAL_CHECK}
|
|
35
|
+
var defer = self.setTimeout.bind(self), load = self.importScripts.bind(self), end = self.close.bind(self), now = performance.now.bind(performance);
|
|
36
|
+
var read = Function.prototype.call.bind(Object.getOwnPropertyDescriptor(MessageEvent.prototype,'data').get);
|
|
37
|
+
var raf = typeof self.requestAnimationFrame === 'function' ? self.requestAnimationFrame.bind(self) : null;
|
|
38
|
+
var initialized = false;
|
|
39
|
+
function init(event) {
|
|
40
|
+
if (initialized) return;
|
|
41
|
+
var d = read(event);
|
|
42
|
+
if (!d || !d.port || !d.canvas || typeof d.codeUrl !== 'string') return;
|
|
43
|
+
initialized = true;
|
|
44
|
+
self.removeEventListener('message',init);
|
|
45
|
+
var port = d.port, post = port.postMessage.bind(port), callbacks = Object.create(null), ready = false;
|
|
46
|
+
var assets = Object.create(null);
|
|
47
|
+
d.assets.forEach(function (asset) { assets[asset.name] = asset.bitmap; });
|
|
48
|
+
var api = Object.freeze({
|
|
49
|
+
canvas: d.canvas,
|
|
50
|
+
params: Object.freeze(d.params),
|
|
51
|
+
asset: function (name) { return Object.prototype.hasOwnProperty.call(assets,name) ? assets[name] : undefined; },
|
|
52
|
+
on: function (kind,fn) {
|
|
53
|
+
if (['state','reply','mention','theme','env','pointer'].indexOf(kind) < 0 || typeof fn !== 'function') return;
|
|
54
|
+
if (!callbacks[kind]) callbacks[kind] = [];
|
|
55
|
+
if (callbacks[kind].length < 32) callbacks[kind].push(fn);
|
|
56
|
+
},
|
|
57
|
+
frame: function (fn) {
|
|
58
|
+
if (typeof fn !== 'function') return;
|
|
59
|
+
if (raf) { try { return raf(fn); } catch (_) {} }
|
|
60
|
+
return defer(function () { fn(now()); },16);
|
|
61
|
+
},
|
|
62
|
+
ready: function () { if (!ready) { ready = true; post({type:'ready'}); } }
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(self,'agend',{value:api,writable:false,configurable:false});
|
|
65
|
+
// Defence in depth against nested workers; termination and host budgets remain required.
|
|
66
|
+
['Worker','SharedWorker','importScripts','RTCPeerConnection','webkitRTCPeerConnection'].forEach(function (key) {
|
|
67
|
+
try { Object.defineProperty(self,key,{value:undefined,writable:false,configurable:false}); } catch (_) {}
|
|
68
|
+
});
|
|
69
|
+
port.addEventListener('message',function (event) {
|
|
70
|
+
var payload = read(event);
|
|
71
|
+
if (!signal(payload,d.instance)) return;
|
|
72
|
+
defer(function () {
|
|
73
|
+
var listeners = (callbacks[payload.type] || []).slice();
|
|
74
|
+
listeners.forEach(function (fn) { try { fn(payload); } catch (_) {} });
|
|
75
|
+
},0);
|
|
76
|
+
});
|
|
77
|
+
port.start();
|
|
78
|
+
// Separate script/global: never concatenate user code into a trusted lexical scope.
|
|
79
|
+
defer(function () { try { load(d.codeUrl); } catch (_) { end(); } },0);
|
|
80
|
+
}
|
|
81
|
+
self.addEventListener('message',init);
|
|
82
|
+
})();`;
|
|
83
|
+
}
|
|
84
|
+
function literal(value) {
|
|
85
|
+
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
86
|
+
}
|
|
87
|
+
/** No HTML input exists. The document realm contains only this shim and its single canvas. */
|
|
88
|
+
export function buildCanvasEffectShim(bootId, origins) {
|
|
89
|
+
const source = String.raw `(function () {
|
|
90
|
+
"use strict";
|
|
91
|
+
${EFFECT_SIGNAL_CHECK}
|
|
92
|
+
var BOOT=${literal(bootId)}, ORIGINS=${literal([...origins])}, MAX=${EFFECT_MAX_BYTES}, PIXELS=${EFFECT_MAX_PIXELS};
|
|
93
|
+
var WORKER=${literal(effectWorkerSource())};
|
|
94
|
+
var done=false, active=true, worker=null, host=null, link=null, urls=[], bitmaps=[], deadline=null, expires=null;
|
|
95
|
+
var defer=window.setTimeout.bind(window), cancel=window.clearTimeout.bind(window), now=performance.now.bind(performance);
|
|
96
|
+
var read=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(MessageEvent.prototype,'data').get);
|
|
97
|
+
function plain(d) { return !!d && Object.getPrototypeOf(d) === Object.prototype; }
|
|
98
|
+
function bytes(s) { try { return new TextEncoder().encode(s).length; } catch (_) { return Infinity; } }
|
|
99
|
+
function stop() {
|
|
100
|
+
if (!active) return;
|
|
101
|
+
active=false;
|
|
102
|
+
if (deadline !== null) cancel(deadline);
|
|
103
|
+
if (worker) worker.terminate();
|
|
104
|
+
if (host) host.close();
|
|
105
|
+
if (link) link.close();
|
|
106
|
+
urls.forEach(function (url) { URL.revokeObjectURL(url); });
|
|
107
|
+
bitmaps.forEach(function (bitmap) { try { bitmap.close(); } catch (_) {} });
|
|
108
|
+
}
|
|
109
|
+
window.addEventListener('pagehide',stop,{once:true});
|
|
110
|
+
async function render(event) {
|
|
111
|
+
if (done || !active || event.source !== window.parent || event.origin === 'null' || ORIGINS.indexOf(event.origin) < 0) return;
|
|
112
|
+
var d=read(event);
|
|
113
|
+
if (!plain(d) || Object.keys(d).sort().join(',') !== 'assets,ch,code,dpr,height,instance,params,type,v,width' || d.v !== 1 || d.type !== 'render') return;
|
|
114
|
+
if (typeof d.ch !== 'string' || !/^[0-9a-f]{16,64}$/.test(d.ch) || typeof d.code !== 'string' || bytes(d.code) > MAX) return;
|
|
115
|
+
if (d.instance !== null && (typeof d.instance !== 'string' || d.instance.length < 1 || d.instance.length > 128)) return;
|
|
116
|
+
if (!signal({v:1,type:'env',ts:0,width:d.width,height:d.height,dpr:d.dpr,quality:'normal'},d.instance)) return;
|
|
117
|
+
if (!plain(d.params) || Object.keys(d.params).length > 16 || !Array.isArray(d.assets) || d.assets.length > 16) return;
|
|
118
|
+
var names=new Set();
|
|
119
|
+
if (!Object.keys(d.params).every(function (key) {
|
|
120
|
+
var value=d.params[key];
|
|
121
|
+
return /^[a-z][a-z0-9_]{0,31}$/.test(key) && (typeof value === 'boolean' || typeof value === 'number' && Number.isFinite(value) || typeof value === 'string' && value.length <= 128);
|
|
122
|
+
})) return;
|
|
123
|
+
var size=bytes(d.code)+bytes(JSON.stringify(d.params));
|
|
124
|
+
if (Object.keys(d.assets).length !== d.assets.length) return;
|
|
125
|
+
if (!d.assets.every(function (asset) {
|
|
126
|
+
if (!plain(asset) || Object.keys(asset).sort().join(',') !== 'bytes,mime,name' || typeof asset.name !== 'string' || !/^assets\/[a-z0-9][a-z0-9_-]{0,63}\.(png|jpe?g|webp|gif)$/.test(asset.name) || names.has(asset.name)) return false;
|
|
127
|
+
if (['image/png','image/jpeg','image/webp','image/gif'].indexOf(asset.mime) < 0 || !(asset.bytes instanceof Uint8Array)) return false;
|
|
128
|
+
names.add(asset.name);size+=asset.bytes.byteLength;return true;
|
|
129
|
+
}) || size > MAX) return;
|
|
130
|
+
if (!event.ports || event.ports.length !== 1) return;
|
|
131
|
+
var port=event.ports[0];
|
|
132
|
+
if (!port || typeof port.postMessage !== 'function' || typeof port.addEventListener !== 'function' || typeof port.start !== 'function' || typeof port.close !== 'function') return;
|
|
133
|
+
done=true;host=port;window.removeEventListener('message',render);
|
|
134
|
+
expires=now()+10000;deadline=defer(stop,10000);
|
|
135
|
+
try {
|
|
136
|
+
if (typeof Worker !== 'function' || typeof OffscreenCanvas !== 'function' || typeof createImageBitmap !== 'function' || typeof HTMLCanvasElement.prototype.transferControlToOffscreen !== 'function') { stop();return; }
|
|
137
|
+
var assets=[], pixels=0;
|
|
138
|
+
for (var asset of d.assets) {
|
|
139
|
+
var bitmap=await createImageBitmap(new Blob([asset.bytes],{type:asset.mime}));
|
|
140
|
+
if (!active || now() >= expires) { bitmap.close();stop();return; }
|
|
141
|
+
bitmaps.push(bitmap);
|
|
142
|
+
if (bitmap.width < 1 || bitmap.height < 1 || bitmap.width > 4096 || bitmap.height > 4096 || bitmap.width*bitmap.height > PIXELS) { stop();return; }
|
|
143
|
+
pixels+=bitmap.width*bitmap.height;if(pixels > PIXELS) { stop();return; }
|
|
144
|
+
assets.push({name:asset.name,bitmap:bitmap});
|
|
145
|
+
}
|
|
146
|
+
if (!active || now() >= expires) { stop();return; }
|
|
147
|
+
var canvas=document.querySelector('canvas');canvas.width=d.width;canvas.height=d.height;
|
|
148
|
+
var offscreen=canvas.transferControlToOffscreen();
|
|
149
|
+
var codeUrl=URL.createObjectURL(new Blob([d.code],{type:'text/javascript'}));urls.push(codeUrl);
|
|
150
|
+
var workerUrl=URL.createObjectURL(new Blob([WORKER],{type:'text/javascript'}));urls.push(workerUrl);
|
|
151
|
+
worker=new Worker(workerUrl);var channel=new MessageChannel();link=channel.port1;
|
|
152
|
+
var ready=false, post=port.postMessage.bind(port);
|
|
153
|
+
// No diagnostic, cost, pong, command or error message is forwarded to the host.
|
|
154
|
+
link.addEventListener('message',function (event) {
|
|
155
|
+
var value=read(event);
|
|
156
|
+
if (active && !ready && now() >= expires) { stop();return; }
|
|
157
|
+
if (!active || ready || !plain(value) || Object.keys(value).join(',') !== 'type' || value.type !== 'ready') return;
|
|
158
|
+
ready=true;cancel(deadline);deadline=null;post({type:'ready'});
|
|
159
|
+
});link.start();
|
|
160
|
+
worker.addEventListener('error',stop);worker.addEventListener('messageerror',stop);
|
|
161
|
+
port.addEventListener('message',function (event) { var payload=read(event);if (active && signal(payload,d.instance)) link.postMessage(payload); });port.start();
|
|
162
|
+
worker.postMessage({port:channel.port2,canvas:offscreen,assets:assets,params:d.params,instance:d.instance,codeUrl:codeUrl},[channel.port2,offscreen].concat(bitmaps));
|
|
163
|
+
} catch (_) { stop(); }
|
|
164
|
+
}
|
|
165
|
+
window.addEventListener('message',render);
|
|
166
|
+
window.parent.postMessage({v:1,type:'ready',ch:null,boot:BOOT},'*');
|
|
167
|
+
})();`;
|
|
168
|
+
return `<!doctype html><html><head><meta charset="utf-8"><title>Effect</title><style>html,body{margin:0;width:100%;height:100%;overflow:hidden}canvas{display:block;width:100%;height:100%}</style></head><body><canvas></canvas><script>${source}</script></body></html>`;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=web-effect-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-effect-worker.js","sourceRoot":"","sources":["../src/web-effect-worker.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjD,sGAAsG;AACtG,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwB5C,CAAC;AAEF,2GAA2G;AAC3G,MAAM,UAAU,kBAAkB;IAChC,OAAO;;IAEL,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAgDjB,CAAC;AACP,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AACpH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,OAA0B;IAC9E,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA;;IAEvB,mBAAmB;aACV,OAAO,CAAC,MAAM,CAAC,aAAa,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,SAAS,gBAAgB,YAAY,iBAAiB;eACrG,OAAO,CAAC,kBAAkB,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA0EtC,CAAC;IACL,OAAO,oOAAoO,MAAM,yBAAyB,CAAC;AAC7Q,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/** CW1 effect manifests are metadata, never placement authority. Widgets are host-rendered elsewhere. */
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const WEB_EFFECT_ID: RegExp;
|
|
4
|
+
export declare const WEB_EFFECT_REGIONS: readonly ["chat", "sidebar", "header", "page", "box"];
|
|
5
|
+
export declare const WEB_EFFECT_WANTS: readonly ["pointer", "state", "reply", "mention", "theme"];
|
|
6
|
+
declare const manifest: z.ZodObject<{
|
|
7
|
+
v: z.ZodLiteral<1>;
|
|
8
|
+
kind: z.ZodDefault<z.ZodLiteral<"effect">>;
|
|
9
|
+
runtime: z.ZodLiteral<"canvas-worker-v1">;
|
|
10
|
+
worker: z.ZodLiteral<"worker.js">;
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
title: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
13
|
+
description: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
14
|
+
poster: z.ZodOptional<z.ZodLiteral<"poster.png">>;
|
|
15
|
+
regions: z.ZodArray<z.ZodEnum<{
|
|
16
|
+
chat: "chat";
|
|
17
|
+
sidebar: "sidebar";
|
|
18
|
+
header: "header";
|
|
19
|
+
page: "page";
|
|
20
|
+
box: "box";
|
|
21
|
+
}>>;
|
|
22
|
+
layer: z.ZodEnum<{
|
|
23
|
+
behind: "behind";
|
|
24
|
+
front: "front";
|
|
25
|
+
}>;
|
|
26
|
+
box: z.ZodOptional<z.ZodObject<{
|
|
27
|
+
anchor: z.ZodEnum<{
|
|
28
|
+
"top-left": "top-left";
|
|
29
|
+
"top-right": "top-right";
|
|
30
|
+
"bottom-left": "bottom-left";
|
|
31
|
+
"bottom-right": "bottom-right";
|
|
32
|
+
center: "center";
|
|
33
|
+
}>;
|
|
34
|
+
width: z.ZodNumber;
|
|
35
|
+
height: z.ZodNumber;
|
|
36
|
+
offset: z.ZodNumber;
|
|
37
|
+
}, z.core.$strict>>;
|
|
38
|
+
cursor: z.ZodOptional<z.ZodObject<{
|
|
39
|
+
hotspot: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
40
|
+
}, z.core.$strict>>;
|
|
41
|
+
wants: z.ZodArray<z.ZodEnum<{
|
|
42
|
+
mention: "mention";
|
|
43
|
+
state: "state";
|
|
44
|
+
theme: "theme";
|
|
45
|
+
pointer: "pointer";
|
|
46
|
+
reply: "reply";
|
|
47
|
+
}>>;
|
|
48
|
+
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
49
|
+
type: z.ZodLiteral<"number">;
|
|
50
|
+
min: z.ZodNumber;
|
|
51
|
+
max: z.ZodNumber;
|
|
52
|
+
step: z.ZodOptional<z.ZodNumber>;
|
|
53
|
+
default: z.ZodNumber;
|
|
54
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
55
|
+
type: z.ZodLiteral<"int">;
|
|
56
|
+
min: z.ZodNumber;
|
|
57
|
+
max: z.ZodNumber;
|
|
58
|
+
default: z.ZodNumber;
|
|
59
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
60
|
+
type: z.ZodLiteral<"bool">;
|
|
61
|
+
default: z.ZodBoolean;
|
|
62
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
63
|
+
type: z.ZodLiteral<"enum">;
|
|
64
|
+
values: z.ZodArray<z.ZodString>;
|
|
65
|
+
default: z.ZodString;
|
|
66
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
67
|
+
type: z.ZodLiteral<"color">;
|
|
68
|
+
default: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
69
|
+
}, z.core.$strict>], "type">>>;
|
|
70
|
+
}, z.core.$strict>;
|
|
71
|
+
export type WebEffectManifest = z.infer<typeof manifest>;
|
|
72
|
+
export type EffectParamValue = string | number | boolean;
|
|
73
|
+
export declare function parseWebEffectManifest(value: unknown): {
|
|
74
|
+
ok: true;
|
|
75
|
+
manifest: WebEffectManifest;
|
|
76
|
+
} | {
|
|
77
|
+
ok: false;
|
|
78
|
+
error: "invalid_manifest";
|
|
79
|
+
};
|
|
80
|
+
/** Defaults and overrides are resolved together before a placement or mod commit can write. */
|
|
81
|
+
export declare function resolveEffectParams(input: WebEffectManifest, overrides?: unknown): {
|
|
82
|
+
ok: true;
|
|
83
|
+
values: Record<string, EffectParamValue>;
|
|
84
|
+
overrides: Record<string, EffectParamValue>;
|
|
85
|
+
} | {
|
|
86
|
+
ok: false;
|
|
87
|
+
error: "invalid_params";
|
|
88
|
+
};
|
|
89
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/** CW1 effect manifests are metadata, never placement authority. Widgets are host-rendered elsewhere. */
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { canonicalText } from "./web-theme.js";
|
|
4
|
+
export const WEB_EFFECT_ID = /^[0-9a-f]{32}$/;
|
|
5
|
+
export const WEB_EFFECT_REGIONS = ["chat", "sidebar", "header", "page", "box"];
|
|
6
|
+
export const WEB_EFFECT_WANTS = ["pointer", "state", "reply", "mention", "theme"];
|
|
7
|
+
const slug = z.string().regex(/^[a-z0-9][a-z0-9-]{0,31}$/);
|
|
8
|
+
function text(max, min) {
|
|
9
|
+
return z.string().max(max * 10).transform((value, ctx) => {
|
|
10
|
+
const result = min === 0 && value === "" ? "" : canonicalText(value, Math.max(1, min), max);
|
|
11
|
+
if (result === null) {
|
|
12
|
+
ctx.addIssue({ code: "custom", message: "Invalid display text" });
|
|
13
|
+
return z.NEVER;
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const finite = z.number().finite().min(-1e9).max(1e9);
|
|
19
|
+
const numeric = z.strictObject({ type: z.literal("number"), min: finite, max: finite, step: z.number().finite().positive().max(2e9).optional(), default: finite });
|
|
20
|
+
const integer = z.strictObject({ type: z.literal("int"), min: finite.int(), max: finite.int(), default: finite.int() });
|
|
21
|
+
const param = z.discriminatedUnion("type", [
|
|
22
|
+
numeric, integer, z.strictObject({ type: z.literal("bool"), default: z.boolean() }),
|
|
23
|
+
z.strictObject({ type: z.literal("enum"), values: z.array(slug).min(1).max(16), default: slug }),
|
|
24
|
+
z.strictObject({ type: z.literal("color"), default: z.string().regex(/^#[0-9a-fA-F]{6}$/).transform(value => value.toLowerCase()) }),
|
|
25
|
+
]).refine(d => {
|
|
26
|
+
if (d.type === "enum")
|
|
27
|
+
return new Set(d.values).size === d.values.length && d.values.includes(d.default);
|
|
28
|
+
if (d.type === "number" || d.type === "int")
|
|
29
|
+
return d.min <= d.max && d.default >= d.min && d.default <= d.max && (d.type !== "number" || d.step === undefined || aligned(d.default, d.min, d.step));
|
|
30
|
+
return true;
|
|
31
|
+
});
|
|
32
|
+
function aligned(value, min, step) {
|
|
33
|
+
const distance = (value - min) / step;
|
|
34
|
+
return Number.isFinite(distance) && Math.abs(distance - Math.round(distance)) <= 1e-8;
|
|
35
|
+
}
|
|
36
|
+
const manifest = z.strictObject({
|
|
37
|
+
v: z.literal(1), kind: z.literal("effect").default("effect"), runtime: z.literal("canvas-worker-v1"), worker: z.literal("worker.js"),
|
|
38
|
+
name: slug, title: text(40, 1), description: text(200, 0).optional(), poster: z.literal("poster.png").optional(),
|
|
39
|
+
regions: z.array(z.enum(WEB_EFFECT_REGIONS)).min(1).max(5).refine(v => new Set(v).size === v.length),
|
|
40
|
+
layer: z.enum(["behind", "front"]),
|
|
41
|
+
box: z.strictObject({ anchor: z.enum(["top-left", "top-right", "bottom-left", "bottom-right", "center"]), width: z.number().int().min(32).max(480), height: z.number().int().min(32).max(480), offset: z.number().int().min(0).max(64) }).optional(),
|
|
42
|
+
cursor: z.strictObject({ hotspot: z.tuple([z.number().int().min(0).max(63), z.number().int().min(0).max(63)]) }).optional(),
|
|
43
|
+
wants: z.array(z.enum(WEB_EFFECT_WANTS)).max(5).refine(v => new Set(v).size === v.length),
|
|
44
|
+
params: z.record(z.string().regex(/^[a-z][a-z0-9_]{0,31}$/), param).refine(v => Object.keys(v).length <= 16).optional(),
|
|
45
|
+
});
|
|
46
|
+
/** Bounded data only. Do not invoke getters or interpret unreadable values as an absent field. */
|
|
47
|
+
function plainData(value) {
|
|
48
|
+
const pending = [{ value, depth: 0 }];
|
|
49
|
+
let nodes = 0;
|
|
50
|
+
while (pending.length) {
|
|
51
|
+
const { value, depth } = pending.pop();
|
|
52
|
+
if (++nodes > 1024 || depth > 8)
|
|
53
|
+
return false;
|
|
54
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
55
|
+
continue;
|
|
56
|
+
if (typeof value === "number") {
|
|
57
|
+
if (!Number.isFinite(value))
|
|
58
|
+
return false;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (typeof value !== "object")
|
|
62
|
+
return false;
|
|
63
|
+
const array = Array.isArray(value), proto = Object.getPrototypeOf(value);
|
|
64
|
+
if (array ? proto !== Array.prototype : proto !== Object.prototype && proto !== null)
|
|
65
|
+
return false;
|
|
66
|
+
const keys = Reflect.ownKeys(value);
|
|
67
|
+
if (keys.length > 33 || array && value.length > 32)
|
|
68
|
+
return false;
|
|
69
|
+
for (const key of keys) {
|
|
70
|
+
if (typeof key !== "string")
|
|
71
|
+
return false;
|
|
72
|
+
if (array && key === "length")
|
|
73
|
+
continue;
|
|
74
|
+
const field = Object.getOwnPropertyDescriptor(value, key);
|
|
75
|
+
if (!("value" in field))
|
|
76
|
+
return false;
|
|
77
|
+
pending.push({ value: field.value, depth: depth + 1 });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
export function parseWebEffectManifest(value) {
|
|
83
|
+
try {
|
|
84
|
+
if (!plainData(value))
|
|
85
|
+
return { ok: false, error: "invalid_manifest" };
|
|
86
|
+
const result = manifest.safeParse(value);
|
|
87
|
+
return result.success ? { ok: true, manifest: result.data } : { ok: false, error: "invalid_manifest" };
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return { ok: false, error: "invalid_manifest" };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Defaults and overrides are resolved together before a placement or mod commit can write. */
|
|
94
|
+
export function resolveEffectParams(input, overrides = {}) {
|
|
95
|
+
try {
|
|
96
|
+
if (!plainData(overrides) || !overrides || Array.isArray(overrides) || typeof overrides !== "object")
|
|
97
|
+
return { ok: false, error: "invalid_params" };
|
|
98
|
+
const schema = input.params ?? {};
|
|
99
|
+
for (const key of Object.keys(overrides))
|
|
100
|
+
if (!Object.hasOwn(schema, key))
|
|
101
|
+
return { ok: false, error: "invalid_params" };
|
|
102
|
+
const values = Object.create(null), changed = Object.create(null);
|
|
103
|
+
for (const [name, d] of Object.entries(schema)) {
|
|
104
|
+
let value = Object.hasOwn(overrides, name) ? overrides[name] : d.default;
|
|
105
|
+
if (d.type === "number" || d.type === "int") {
|
|
106
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < d.min || value > d.max || d.type === "int" && !Number.isSafeInteger(value) || d.type === "number" && d.step !== undefined && !aligned(value, d.min, d.step))
|
|
107
|
+
return { ok: false, error: "invalid_params" };
|
|
108
|
+
}
|
|
109
|
+
else if (d.type === "bool") {
|
|
110
|
+
if (typeof value !== "boolean")
|
|
111
|
+
return { ok: false, error: "invalid_params" };
|
|
112
|
+
}
|
|
113
|
+
else if (d.type === "enum") {
|
|
114
|
+
if (typeof value !== "string" || !d.values.includes(value))
|
|
115
|
+
return { ok: false, error: "invalid_params" };
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
if (typeof value !== "string" || !/^#[0-9a-fA-F]{6}$/.test(value))
|
|
119
|
+
return { ok: false, error: "invalid_params" };
|
|
120
|
+
value = value.toLowerCase();
|
|
121
|
+
}
|
|
122
|
+
values[name] = value;
|
|
123
|
+
if (value !== d.default)
|
|
124
|
+
changed[name] = value;
|
|
125
|
+
}
|
|
126
|
+
return { ok: true, values, overrides: changed };
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return { ok: false, error: "invalid_params" };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=web-effect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-effect.js","sourceRoot":"","sources":["../src/web-effect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
import { type ThemeMode } from "./web-theme.js";
|
|
3
|
+
import { type IdentityColor, type Placement } from "./web-identity-palette.js";
|
|
4
|
+
export { AUTO_PALETTE, autoIdentityColor, canonicalIdentityColor, canonicalPlacements, DEFAULT_PLACEMENTS, IDENTITY_PALETTE, identityColorValue, PLACEMENTS, type AutoId, type IdentityColor, type Placement, type PresetId } from "./web-identity-palette.js";
|
|
5
|
+
/** The sidebar's own background (src/ui/shared/tokens.css --bg-sidebar), where names are drawn as well as the page's. */
|
|
6
|
+
export declare const SIDEBAR_BG: Record<ThemeMode, string>;
|
|
7
|
+
export type IdentityColorSource = "person" | "agent" | "role" | "auto";
|
|
8
|
+
export type PlacementSource = "person" | "agent" | "host";
|
|
9
|
+
/**
|
|
10
|
+
* The shade of `hex` that name text uses on a page in `mode`: the colour itself if it reads at 4.5:1 against the
|
|
11
|
+
* page's and the sidebar's backgrounds, else the nearest step toward black (light page) or white (dark page) that does.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readableShade(hex: string, mode: ThemeMode): string;
|
|
14
|
+
/** The tiers one instance has, as the status frame carries them (`auto` always). */
|
|
15
|
+
export interface IdentityColorTiers {
|
|
16
|
+
person?: IdentityColor;
|
|
17
|
+
agent?: string;
|
|
18
|
+
role?: string;
|
|
19
|
+
auto: IdentityColor;
|
|
20
|
+
}
|
|
21
|
+
/** The placement tiers one instance has (the host's default is the viewer's prefs, not the instance's). */
|
|
22
|
+
export interface PlacementTiers {
|
|
23
|
+
person?: Placement[];
|
|
24
|
+
agent?: Placement[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The colour in force and where it comes from. `showThemes`: whether the viewer shows agents' themes (fx.show, not
|
|
28
|
+
* safe mode) — when not, the agent's tier is skipped, as the rest of the agent's theme is.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveIdentityColor(t: IdentityColorTiers, opts: {
|
|
31
|
+
showThemes: boolean;
|
|
32
|
+
}): {
|
|
33
|
+
color: IdentityColor;
|
|
34
|
+
source: IdentityColorSource;
|
|
35
|
+
};
|
|
36
|
+
/** Where the colour shows: a person's choice, else the agent's (themes shown), else the host's default, else ring + bar. */
|
|
37
|
+
export declare function resolvePlacements(t: PlacementTiers, opts: {
|
|
38
|
+
showThemes: boolean;
|
|
39
|
+
hostDefault?: unknown;
|
|
40
|
+
}): {
|
|
41
|
+
show: Placement[];
|
|
42
|
+
source: PlacementSource;
|
|
43
|
+
};
|
|
44
|
+
/** A person's choice for one instance: a colour, the places it shows, or both (null: not chosen — the next tier). */
|
|
45
|
+
export interface PersonIdentity {
|
|
46
|
+
color: IdentityColor | null;
|
|
47
|
+
show: Placement[] | null;
|
|
48
|
+
}
|
|
49
|
+
export type ColorWrite = {
|
|
50
|
+
ok: true;
|
|
51
|
+
} | {
|
|
52
|
+
ok: false;
|
|
53
|
+
status: 400 | 503;
|
|
54
|
+
error: string;
|
|
55
|
+
detail?: string;
|
|
56
|
+
};
|
|
57
|
+
/** The people's choices, one row per instance. */
|
|
58
|
+
export declare class IdentityColorStore {
|
|
59
|
+
private readonly openDb;
|
|
60
|
+
private readonly now;
|
|
61
|
+
constructor(openDb: () => Database.Database, now?: () => number);
|
|
62
|
+
get(name: string): PersonIdentity;
|
|
63
|
+
/** Every choice, for a status read: only when profiles.db exists and has the table — a read creates nothing. */
|
|
64
|
+
static all(dataDir: string, openDb: () => Database.Database): Map<string, PersonIdentity>;
|
|
65
|
+
/**
|
|
66
|
+
* A person's choice, field by field: only the fields given change; `null` (or "" for the colour) clears one — the next
|
|
67
|
+
* tier shows again. Both checked before anything is written. A row with nothing left is removed.
|
|
68
|
+
*/
|
|
69
|
+
set(name: string, patch: {
|
|
70
|
+
color?: unknown;
|
|
71
|
+
show?: unknown;
|
|
72
|
+
}): ColorWrite;
|
|
73
|
+
/** The patch, checked: `undefined` for a field not given, `null` to clear it. Writes nothing. */
|
|
74
|
+
check(patch: {
|
|
75
|
+
color?: unknown;
|
|
76
|
+
show?: unknown;
|
|
77
|
+
}): {
|
|
78
|
+
ok: true;
|
|
79
|
+
color?: IdentityColor | null;
|
|
80
|
+
show?: Placement[] | null;
|
|
81
|
+
} | {
|
|
82
|
+
ok: false;
|
|
83
|
+
status: 400;
|
|
84
|
+
error: string;
|
|
85
|
+
detail: string;
|
|
86
|
+
};
|
|
87
|
+
}
|