@songsid/agend 2.3.3-beta.4 → 2.3.3-beta.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.
Files changed (234) hide show
  1. package/dist/agent-cli.js +13 -112
  2. package/dist/agent-cli.js.map +1 -1
  3. package/dist/agent-endpoint.d.ts +0 -1
  4. package/dist/agent-endpoint.js +1 -9
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/agent-whats-new.d.ts +3 -6
  7. package/dist/agent-whats-new.js +7 -18
  8. package/dist/agent-whats-new.js.map +1 -1
  9. package/dist/auth-api.d.ts +0 -7
  10. package/dist/auth-api.js +1 -15
  11. package/dist/auth-api.js.map +1 -1
  12. package/dist/backend/codex.d.ts +1 -0
  13. package/dist/backend/codex.js +106 -15
  14. package/dist/backend/codex.js.map +1 -1
  15. package/dist/backend/types.d.ts +17 -0
  16. package/dist/backend/types.js.map +1 -1
  17. package/dist/bundled-skills.d.ts +4 -6
  18. package/dist/bundled-skills.js +10 -14
  19. package/dist/bundled-skills.js.map +1 -1
  20. package/dist/channel/mcp-server.js +5 -5
  21. package/dist/channel/mcp-server.js.map +1 -1
  22. package/dist/channel/mcp-tools.d.ts +1 -3
  23. package/dist/channel/mcp-tools.js +4 -58
  24. package/dist/channel/mcp-tools.js.map +1 -1
  25. package/dist/cli.js +3 -1
  26. package/dist/cli.js.map +1 -1
  27. package/dist/config-validator.js +6 -3
  28. package/dist/config-validator.js.map +1 -1
  29. package/dist/daemon.d.ts +11 -3
  30. package/dist/daemon.js +59 -107
  31. package/dist/daemon.js.map +1 -1
  32. package/dist/dashboard-live.d.ts +1 -1
  33. package/dist/dashboard-live.js +3 -3
  34. package/dist/dashboard-live.js.map +1 -1
  35. package/dist/dashboard-permissions.d.ts +1 -1
  36. package/dist/dashboard-permissions.js +1 -3
  37. package/dist/dashboard-permissions.js.map +1 -1
  38. package/dist/fleet-manager.d.ts +26 -44
  39. package/dist/fleet-manager.js +70 -226
  40. package/dist/fleet-manager.js.map +1 -1
  41. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +11 -1
  42. package/dist/general-knowledge/skills/session-management/SKILL.md +6 -0
  43. package/dist/general-knowledge/skills/web-appearance/SKILL.md +13 -204
  44. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +26 -63
  45. package/dist/instance-lifecycle.js +1 -1
  46. package/dist/instance-lifecycle.js.map +1 -1
  47. package/dist/locale.js +2 -0
  48. package/dist/locale.js.map +1 -1
  49. package/dist/outbound-handlers.js +19 -7
  50. package/dist/outbound-handlers.js.map +1 -1
  51. package/dist/outbound-schemas.d.ts +0 -62
  52. package/dist/outbound-schemas.js +2 -41
  53. package/dist/outbound-schemas.js.map +1 -1
  54. package/dist/public-web-gateway.js +0 -9
  55. package/dist/public-web-gateway.js.map +1 -1
  56. package/dist/public-web-link.d.ts +2 -0
  57. package/dist/public-web-link.js +5 -0
  58. package/dist/public-web-link.js.map +1 -1
  59. package/dist/search/search-docs.d.ts +1 -1
  60. package/dist/search/search-docs.js +2 -2
  61. package/dist/search/search-docs.js.map +1 -1
  62. package/dist/settings-api.d.ts +6 -0
  63. package/dist/settings-api.js +14 -2
  64. package/dist/settings-api.js.map +1 -1
  65. package/dist/settings-change.js +3 -1
  66. package/dist/settings-change.js.map +1 -1
  67. package/dist/tool-permissions.js +3 -10
  68. package/dist/tool-permissions.js.map +1 -1
  69. package/dist/topic-commands.d.ts +6 -2
  70. package/dist/topic-commands.js +2 -0
  71. package/dist/topic-commands.js.map +1 -1
  72. package/dist/types.d.ts +2 -1
  73. package/dist/ui/chat-ambient.js +4 -4
  74. package/dist/ui/chat-commands.js +3 -2
  75. package/dist/ui/chat-store.js +4 -1
  76. package/dist/ui/chat-strings.js +6 -42
  77. package/dist/ui/chat-thread.js +6 -44
  78. package/dist/ui/panel-chat.js +21 -50
  79. package/dist/ui/preview-panel.js +3 -15
  80. package/dist/ui/search-dialog.js +30 -14
  81. package/dist/ui/settings-appearance.js +1 -3
  82. package/dist/ui/settings-guests.js +13 -4
  83. package/dist/ui/settings-learn.js +1 -1
  84. package/dist/ui/settings-mods.js +5 -12
  85. package/dist/ui/settings-registry.js +0 -1
  86. package/dist/ui/settings-strings.js +6 -6
  87. package/dist/ui/shared/app-prefs.js +17 -17
  88. package/dist/ui/shared/app-shell.js +12 -8
  89. package/dist/ui/shared/app-store.js +6 -2
  90. package/dist/ui/shared/app.css +4 -36
  91. package/dist/ui/shared/app.js +5 -4
  92. package/dist/ui/shared/instance-nav.js +9 -9
  93. package/dist/ui/shared/instance-switch.js +8 -2
  94. package/dist/ui/shared/panel-view.js +22 -8
  95. package/dist/ui/shared/view-strings.js +6 -0
  96. package/dist/usage/usage-api.d.ts +3 -0
  97. package/dist/usage/usage-api.js +5 -1
  98. package/dist/usage/usage-api.js.map +1 -1
  99. package/dist/view-api.d.ts +2 -0
  100. package/dist/view-api.js +64 -0
  101. package/dist/view-api.js.map +1 -1
  102. package/dist/web-api.d.ts +9 -17
  103. package/dist/web-api.js +255 -371
  104. package/dist/web-api.js.map +1 -1
  105. package/dist/web-appearance-tools.d.ts +0 -2
  106. package/dist/web-appearance-tools.js +2 -5
  107. package/dist/web-appearance-tools.js.map +1 -1
  108. package/dist/web-appearance-view.d.ts +0 -6
  109. package/dist/web-appearance-view.js +0 -1
  110. package/dist/web-appearance-view.js.map +1 -1
  111. package/dist/web-appearance.d.ts +14 -7
  112. package/dist/web-appearance.js +5 -6
  113. package/dist/web-appearance.js.map +1 -1
  114. package/dist/web-asset-parts.d.ts +1 -17
  115. package/dist/web-asset-parts.js +1 -15
  116. package/dist/web-asset-parts.js.map +1 -1
  117. package/dist/web-auth.js +1 -7
  118. package/dist/web-auth.js.map +1 -1
  119. package/dist/web-chat-history.d.ts +3 -7
  120. package/dist/web-chat-history.js +10 -17
  121. package/dist/web-chat-history.js.map +1 -1
  122. package/dist/web-commands.d.ts +9 -1
  123. package/dist/web-commands.js +13 -0
  124. package/dist/web-commands.js.map +1 -1
  125. package/dist/web-experimental.d.ts +2 -11
  126. package/dist/web-experimental.js +8 -36
  127. package/dist/web-experimental.js.map +1 -1
  128. package/dist/web-guest-access.d.ts +40 -2
  129. package/dist/web-guest-access.js +50 -14
  130. package/dist/web-guest-access.js.map +1 -1
  131. package/dist/web-mod-bundle.d.ts +2 -45
  132. package/dist/web-mod-bundle.js +15 -63
  133. package/dist/web-mod-bundle.js.map +1 -1
  134. package/dist/web-mod-store.d.ts +3 -48
  135. package/dist/web-mod-store.js +30 -97
  136. package/dist/web-mod-store.js.map +1 -1
  137. package/dist/web-prefs.d.ts +13 -0
  138. package/dist/web-prefs.js +38 -0
  139. package/dist/web-prefs.js.map +1 -1
  140. package/dist/web-preview.d.ts +1 -11
  141. package/dist/web-preview.js +6 -20
  142. package/dist/web-preview.js.map +1 -1
  143. package/dist/web-session.d.ts +11 -3
  144. package/dist/web-session.js +22 -11
  145. package/dist/web-session.js.map +1 -1
  146. package/dist/web-settings-patch.d.ts +1 -0
  147. package/dist/web-settings-patch.js +6 -3
  148. package/dist/web-settings-patch.js.map +1 -1
  149. package/dist/web-settings-tools.d.ts +0 -13
  150. package/dist/web-settings-tools.js +12 -84
  151. package/dist/web-settings-tools.js.map +1 -1
  152. package/package.json +1 -1
  153. package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +0 -376
  154. package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +0 -672
  155. package/dist/ui/app-effects.js +0 -251
  156. package/dist/ui/chat-effect-posters.js +0 -42
  157. package/dist/ui/chat-effects.js +0 -167
  158. package/dist/ui/effect-trial-controller.js +0 -124
  159. package/dist/ui/effect-trial-offer.js +0 -2
  160. package/dist/ui/effect-trial-panel.js +0 -40
  161. package/dist/ui/effects-waker.js +0 -2
  162. package/dist/ui/settings-effects.js +0 -202
  163. package/dist/ui/settings-owner-effects.js +0 -82
  164. package/dist/ui/shared/effect-app-runtime.js +0 -299
  165. package/dist/ui/shared/effect-baseline.js +0 -64
  166. package/dist/ui/shared/effect-chat-runtime.js +0 -162
  167. package/dist/ui/shared/effect-cursor.js +0 -126
  168. package/dist/ui/shared/effect-display-metadata.js +0 -39
  169. package/dist/ui/shared/effect-frame.js +0 -146
  170. package/dist/ui/shared/effect-geometry.js +0 -137
  171. package/dist/ui/shared/effect-host-style.js +0 -10
  172. package/dist/ui/shared/effect-owner-regions.js +0 -74
  173. package/dist/ui/shared/effect-owner-source.js +0 -122
  174. package/dist/ui/shared/effect-policy.js +0 -151
  175. package/dist/ui/shared/effect-poster-reader.js +0 -98
  176. package/dist/ui/shared/effect-posters.js +0 -117
  177. package/dist/ui/shared/effect-profiler.js +0 -184
  178. package/dist/ui/shared/effect-profiles.js +0 -65
  179. package/dist/ui/shared/effect-registry.js +0 -545
  180. package/dist/ui/shared/effect-runtime-loader.js +0 -236
  181. package/dist/ui/shared/effect-safety.js +0 -153
  182. package/dist/ui/shared/effect-stock-snapshot.js +0 -43
  183. package/dist/ui/shared/effect-stock-trust.js +0 -217
  184. package/dist/ui/shared/effect-trial-shadow.js +0 -62
  185. package/dist/ui/shared/effect-trial-source.js +0 -103
  186. package/dist/ui/shared/effect-trial-stage.js +0 -170
  187. package/dist/ui/shared/effect-trial.css +0 -40
  188. package/dist/ui/shared/feature-flags.js +0 -127
  189. package/dist/ui/shared/owner-effect-prefs.js +0 -117
  190. package/dist/web-effect-bootstrap.d.ts +0 -12
  191. package/dist/web-effect-bootstrap.js +0 -49
  192. package/dist/web-effect-bootstrap.js.map +0 -1
  193. package/dist/web-effect-bundle.d.ts +0 -28
  194. package/dist/web-effect-bundle.js +0 -171
  195. package/dist/web-effect-bundle.js.map +0 -1
  196. package/dist/web-effect-canonical.d.ts +0 -8
  197. package/dist/web-effect-canonical.js +0 -27
  198. package/dist/web-effect-canonical.js.map +0 -1
  199. package/dist/web-effect-library.d.ts +0 -114
  200. package/dist/web-effect-library.js +0 -530
  201. package/dist/web-effect-library.js.map +0 -1
  202. package/dist/web-effect-playback.d.ts +0 -30
  203. package/dist/web-effect-playback.js +0 -71
  204. package/dist/web-effect-playback.js.map +0 -1
  205. package/dist/web-effect-poster.d.ts +0 -8
  206. package/dist/web-effect-poster.js +0 -52
  207. package/dist/web-effect-poster.js.map +0 -1
  208. package/dist/web-effect-profiles.d.ts +0 -118
  209. package/dist/web-effect-profiles.js +0 -181
  210. package/dist/web-effect-profiles.js.map +0 -1
  211. package/dist/web-effect-service.d.ts +0 -93
  212. package/dist/web-effect-service.js +0 -335
  213. package/dist/web-effect-service.js.map +0 -1
  214. package/dist/web-effect-tools.d.ts +0 -48
  215. package/dist/web-effect-tools.js +0 -129
  216. package/dist/web-effect-tools.js.map +0 -1
  217. package/dist/web-effect-trials.d.ts +0 -86
  218. package/dist/web-effect-trials.js +0 -204
  219. package/dist/web-effect-trials.js.map +0 -1
  220. package/dist/web-effect-upload.d.ts +0 -27
  221. package/dist/web-effect-upload.js +0 -185
  222. package/dist/web-effect-upload.js.map +0 -1
  223. package/dist/web-effect-worker.d.ts +0 -8
  224. package/dist/web-effect-worker.js +0 -170
  225. package/dist/web-effect-worker.js.map +0 -1
  226. package/dist/web-effect.d.ts +0 -103
  227. package/dist/web-effect.js +0 -153
  228. package/dist/web-effect.js.map +0 -1
  229. package/dist/web-experimental-http.d.ts +0 -2
  230. package/dist/web-experimental-http.js +0 -12
  231. package/dist/web-experimental-http.js.map +0 -1
  232. package/dist/web-mod-agent.d.ts +0 -50
  233. package/dist/web-mod-agent.js +0 -207
  234. package/dist/web-mod-agent.js.map +0 -1
@@ -1,127 +0,0 @@
1
- // Product feature policy only: this module imports no experimental runtime.
2
- import { appStore } from "./app-store.js";
3
- import { navStore } from "./app-nav.js";
4
- import { ownerEffectsChosen, onOwnerEffectsChanged } from "./app-prefs.js";
5
- import { register } from "./app-i18n.js";
6
- import { html, useEffect, useState } from "./app-html.js";
7
- register("cwControls", { en: { title: "Effects" }, "zh-TW": { title: "效果" } });
8
- export function canvasWorkerEnabled() { return appStore.get().canvasWorker === true; }
9
- export function onCanvasWorkerChange(fn) {
10
- let value = canvasWorkerEnabled();
11
- return appStore.subscribe(() => { const next = canvasWorkerEnabled(); if (next !== value) { value = next; fn(next); } });
12
- }
13
- export function useCanvasWorker() {
14
- const [value, setValue] = useState(canvasWorkerEnabled);
15
- useEffect(() => { setValue(canvasWorkerEnabled()); return onCanvasWorkerChange(setValue); }, []);
16
- return value;
17
- }
18
- // Never evaluate the optional module before admission. An obsolete import may finish, but cannot mount.
19
- export function experimentalComponent(load, select) {
20
- return function ExperimentalComponent(props) {
21
- const enabled = useCanvasWorker(), [component, setComponent] = useState(null);
22
- useEffect(() => {
23
- let current = true;
24
- if (enabled) load().then(module => { if (current && canvasWorkerEnabled()) setComponent(() => select(module)); }, () => {});
25
- return () => { current = false; };
26
- }, [enabled]);
27
- return enabled && component ? html`<${component} ...${props} />` : null;
28
- };
29
- }
30
-
31
- /** effect_chat_v of a chat with no placements: sha256(JSON.stringify([])), first 32 hex (fleet-manager's status row). */
32
- export const EMPTY_CHAT_EFFECTS = "4f53cda18c2baa0c0354bb5f9a3ecbe5";
33
-
34
- let mod = null, waking = null, chatStore = null, started = false, generation = 0, awakeGeneration = -1, retiring = Promise.resolve();
35
- const awakeListeners = new Set();
36
-
37
- /** Whether `name`'s chat has Canvas Worker placements (as the status rows say). */
38
- export function chatHasEffects(name, app = appStore.get()) {
39
- const v = name ? app.instances?.find(i => i.name === name)?.effect_chat_v : undefined;
40
- return canvasWorkerEnabled() && typeof v === "string" && /^[a-f0-9]{32}$/.test(v) && v !== EMPTY_CHAT_EFFECTS;
41
- }
42
-
43
- /** The running effects owner, or null while dormant (or when it could not start: as getAppEffects always was). */
44
- export function getAppEffects(host) { return canvasWorkerEnabled() && mod ? mod.getAppEffects(host) : null; }
45
-
46
- /** Whether the runtime has been asked to start on this page. */
47
- export function effectsAwake() { return waking !== null; }
48
- /** Whether its module has loaded (started, or found it could not: getAppEffects() then says which). */
49
- export function effectsLoaded() { return mod !== null && awakeGeneration === generation; }
50
-
51
- /** Follow every completed runtime episode, including a replacement after an experimental off/on. */
52
- export function onEffectsAwake(fn) {
53
- if (typeof fn !== "function") return () => {};
54
- awakeListeners.add(fn);
55
- if (effectsLoaded()) { try { fn(); } catch { /* a listener's error is its own */ } }
56
- return () => awakeListeners.delete(fn);
57
- }
58
-
59
- /** Load lazily; each explicitly enabled episode owns its startup and cancellation. */
60
- export function wakeEffects() {
61
- if (!canvasWorkerEnabled()) return Promise.resolve(null);
62
- if (waking) return waking;
63
- const episode = generation;
64
- waking = (mod ? Promise.resolve(mod) : import("/ui/js/app-effects.js")).then(async m => {
65
- mod = m;
66
- await retiring;
67
- if (episode !== generation || !canvasWorkerEnabled()) return null;
68
- const owner = chatStore ? m.startAppEffects({ store: chatStore }) : null;
69
- awakeGeneration = episode;
70
- for (const fn of [...awakeListeners]) { try { fn(); } catch { /* the rest still hear */ } }
71
- return owner;
72
- }, () => null);
73
- return waking;
74
- }
75
-
76
- /** Wake when the open chat has placements or the person has a personal effect. */
77
- function check() {
78
- if (!canvasWorkerEnabled()) {
79
- generation++;
80
- const owner = mod?.getAppEffects();
81
- if (owner) retiring = Promise.resolve(owner.dispose?.(true));
82
- waking = null;
83
- return;
84
- }
85
- if (waking) return;
86
- const route = navStore.get().route;
87
- if ((route?.panel === "chat" && chatHasEffects(route.instance)) || ownerEffectsChosen()) void wakeEffects();
88
- }
89
-
90
- /** Boot (once per page, with the Chat store the runtime binds to). Starts nothing but the watch. */
91
- export function startEffectsWaker({ store }) {
92
- chatStore = store;
93
- if (started) return;
94
- started = true;
95
- appStore.subscribe(check); navStore.subscribe(check); onOwnerEffectsChanged(check);
96
- check();
97
- }
98
-
99
- // Full Canvas Worker metadata stays in the experimental graph, never in ordinary chat boot.
100
- let metadata = null, metadataPending = null;
101
- const metadataListeners = new Set();
102
- export function onCanvasMetadataChange(fn) { metadataListeners.add(fn); return () => metadataListeners.delete(fn); }
103
- export function loadCanvasWorkerMetadata() {
104
- if (!canvasWorkerEnabled()) return Promise.resolve(null);
105
- if (metadata) return Promise.resolve(metadata);
106
- if (metadataPending?.episode === generation) return metadataPending.promise;
107
- const episode = generation, op = { episode, promise: null };
108
- metadataPending = op;
109
- op.promise = import("./effect-display-metadata.js").then(value => {
110
- if (episode !== generation || !canvasWorkerEnabled()) return null;
111
- metadata = value;
112
- for (const fn of [...metadataListeners]) { try { fn(); } catch { /* independent viewers */ } }
113
- appStore.set({ canvasMetadataEpoch: episode });
114
- return metadata;
115
- }, () => null).finally(() => { if (metadataPending === op) metadataPending = null; });
116
- return op.promise;
117
- }
118
- export function readCanvasTrialMessage(message) {
119
- if (!canvasWorkerEnabled()) return null;
120
- if (!metadata) { void loadCanvasWorkerMetadata(); return undefined; }
121
- return metadata.effectTrialMessage(message);
122
- }
123
- export function canvasWorkerMenuAvailable(host) {
124
- if (!canvasWorkerEnabled()) return false;
125
- if (!metadata) { void loadCanvasWorkerMetadata(); return false; }
126
- return metadata.chatEffectIdentity(host) !== null;
127
- }
@@ -1,117 +0,0 @@
1
- // #1629: host-authoritative personal choices. No local cache, migration, frame, code fetch or automatic resend.
2
- import { createStore, appStore } from "./app-store.js";
3
- import { OWNER_EFFECT_PREF_KEYS } from "./app-prefs.js";
4
- import { checkEffectOwnerSlots } from "./effect-runtime-loader.js";
5
- const KEYS = OWNER_EFFECT_PREF_KEYS, ID = /^[a-f0-9]{32}$/, EPOCH = /^[a-f0-9]{16}$/;
6
- const plain = x => !!x && typeof x === "object" && Object.getPrototypeOf(x) === Object.prototype;
7
- const own = (x, k) => Object.hasOwn(x, k);
8
- const unknownSlots = () => Object.fromEntries(KEYS.map(k => [k, { status: "unknown", id: null }]));
9
- const publicPage = () => typeof document === "undefined" || document.body?.dataset.publicLink === "1" || document.body?.dataset.mode === "view-only";
10
- function bootScope() {
11
- try {
12
- const x = JSON.parse(document.documentElement.getAttribute("data-prefs") || "null");
13
- return plain(x) && ["person", "operator"].includes(x.ownerScope) && typeof x.ownerEpoch === "string" && EPOCH.test(x.ownerEpoch)
14
- ? Object.freeze({ scope: x.ownerScope, epoch: x.ownerEpoch }) : null;
15
- } catch { return null; }
16
- }
17
- const owner = bootScope();
18
- export const ownerEffectsStore = createStore({ scope: owner?.scope ?? "none", status: "unknown", revoked: false, busy: false, slots: unknownSlots(), error: null });
19
- let watchers = 0, generation = 0, active = null, queuedRead = false, unsubscribe = null, rev = -1, seen = null, failedAt = -Infinity;
20
- const clock = () => { try { const n = performance.now(); return Number.isFinite(n) && n >= 0 ? n : null; } catch { return null; } };
21
- const eligible = () => !!owner && watchers > 0 && !publicPage() && !ownerEffectsStore.get().revoked;
22
- const current = op => eligible() && op.generation === generation && active === op;
23
- function revoke() {
24
- queuedRead = false;
25
- ownerEffectsStore.set({ status: "unknown", revoked: true, slots: unknownSlots(), error: "sign_in_changed" });
26
- }
27
- function unknown(error) { const n = clock(); failedAt = n === null ? Infinity : n; ownerEffectsStore.set({ status: "unknown", slots: unknownSlots(), error }); }
28
- function claim() {
29
- if (!eligible() || active) return null;
30
- const controller = new AbortController(), op = { controller, generation };
31
- active = op; ownerEffectsStore.set({ busy: true, error: null }); return op;
32
- }
33
- async function call(op, path, init = {}) {
34
- const started = clock();
35
- if (started === null || op.controller.signal.aborted) return { ok: false, status: 0, body: null };
36
- const timer = setTimeout(() => op.controller.abort(), 10000);
37
- try {
38
- const res = await fetch(path, { credentials: "same-origin", ...init, signal: op.controller.signal });
39
- let body = null; try { body = await res.json(); } catch { /* unknown */ }
40
- const ended = clock();
41
- if (op.controller.signal.aborted || ended === null || ended < started || ended - started >= 10000) return { ok: false, status: 0, body: null };
42
- return { ok: res.ok, status: res.status, body };
43
- } catch { return { ok: false, status: 0, body: null }; }
44
- finally { clearTimeout(timer); }
45
- }
46
- function finish(op) {
47
- if (active !== op) return;
48
- active = null; ownerEffectsStore.set({ busy: false });
49
- const again = queuedRead; queuedRead = false;
50
- const n = clock();
51
- if (again && eligible() && n !== null && n - failedAt >= 5000) refreshOwnerEffects();
52
- }
53
- /** An owner response is closed and bounded. Unavailable means a stored id, not an empty slot or private manifest. */
54
- export function checkOwnerSlots(body) { return checkEffectOwnerSlots(body); }
55
-
56
- async function read(op) {
57
- const r = await call(op, `/ui/effects/owner?ownerEpoch=${owner.epoch}`);
58
- if (!current(op)) return false;
59
- if ([401, 403, 409].includes(r.status)) { revoke(); return false; }
60
- const data = r.ok ? checkOwnerSlots(r.body) : null;
61
- if (!data) { unknown("unreadable"); return false; }
62
- if (data.rev < rev) { unknown("stale"); return false; }
63
- rev = data.rev; failedAt = -Infinity;
64
- ownerEffectsStore.set({ status: "known", slots: data.slots, error: null }); return true;
65
- }
66
- export async function refreshOwnerEffects() {
67
- if (!eligible()) return false;
68
- if (active) { queuedRead = true; return false; }
69
- const op = claim(); if (!op) return false;
70
- try { return await read(op); } finally { finish(op); }
71
- }
72
- /** One physical operation survives until settlement, including after abort. At most one coalesced read follows. */
73
- export function watchOwnerEffects() {
74
- watchers++;
75
- if (watchers === 1 && eligible()) {
76
- const check = () => {
77
- const next = appStore.get().prefsRev, n = clock();
78
- if (next !== seen || ownerEffectsStore.get().status === "unknown" && n !== null && n - failedAt >= 5000) { seen = next; refreshOwnerEffects(); }
79
- };
80
- unsubscribe = appStore.subscribe(check); check();
81
- }
82
- let ended = false;
83
- return () => {
84
- if (ended) return; ended = true;
85
- if (--watchers > 0) return;
86
- generation++; queuedRead = false; unsubscribe?.(); unsubscribe = null; active?.controller.abort();
87
- ownerEffectsStore.set({ status: "unknown", slots: unknownSlots(), error: null });
88
- };
89
- }
90
- export async function saveOwnerEffects(set) {
91
- if (!plain(set) || !Object.keys(set).length || Object.keys(set).some(k => !KEYS.includes(k) || set[k] !== null && (typeof set[k] !== "string" || !ID.test(set[k])))) return { ok: false, error: "invalid" };
92
- // Snapshot both data and immutable boot context before the first wait. No optimistic runtime selection.
93
- const values = { ...set }, op = claim(); if (!op) return { ok: false, error: "busy_or_unavailable" };
94
- let saved = false;
95
- try {
96
- const r = await call(op, "/ui/prefs", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ set: values, ownerEpoch: owner.epoch }) });
97
- if (!current(op)) return { ok: false, error: "superseded" };
98
- if ([401, 403, 409].includes(r.status)) { revoke(); return { ok: false, error: "sign_in_changed" }; }
99
- if (r.ok && plain(r.body) && (r.body.ownerEpoch !== owner.epoch || r.body.ownerScope !== owner.scope)) { revoke(); return { ok: false, error: "sign_in_changed" }; }
100
- if (!r.ok || !plain(r.body) || !plain(r.body.values) || !Number.isSafeInteger(r.body.rev) || r.body.rev < 0 || r.body.rev < rev || r.body.unreadable) { unknown("not_saved"); return { ok: false, error: "not_saved" }; }
101
- if (!Object.entries(values).every(([k, v]) => v === null ? !own(r.body.values, k) : r.body.values[k] === v)) { unknown("not_saved"); return { ok: false, error: "not_saved" }; }
102
- saved = true;
103
- const refreshed = await read(op); return { ok: refreshed, saved, error: refreshed ? null : "refresh_failed" };
104
- } finally { finish(op); }
105
- }
106
- /** Runtime adapter asks only for the exact, currently known selection; a cursor can never request Worker source. */
107
- export function ownerEffectUrl(key, id, kind = "resource") {
108
- const row = ownerEffectsStore.get().slots[key];
109
- if (!eligible() || ownerEffectsStore.get().status !== "known" || !KEYS.includes(key) || !row || row.status !== "available" || row.id !== id || !["resource", "poster", "cursor"].includes(kind) || kind === "resource" && key === "fx.cursor") return null;
110
- const path = kind === "resource" ? `/ui/effects/resource/${id}` : `/ui/effects/image/${id}/${kind}.png`;
111
- return `${path}?slot=${encodeURIComponent(key)}&ownerEpoch=${owner.epoch}`;
112
- }
113
- export function markOwnerEffectUnavailable(key, id) {
114
- const s = ownerEffectsStore.get(), row = s.slots[key];
115
- if (!eligible() || s.status !== "known" || !KEYS.includes(key) || row?.id !== id) return;
116
- ownerEffectsStore.set({ slots: { ...s.slots, [key]: { status: "unavailable", id } } });
117
- }
@@ -1,12 +0,0 @@
1
- import type { IncomingMessage, ServerResponse } from "node:http";
2
- /** #2118: fixed trusted document; no uploaded source, account data or resource authorization lives here. */
3
- export declare const EFFECT_BOOTSTRAP_PATH = "/effect-bootstrap";
4
- export declare function effectBootstrapResponse(boot: string): {
5
- body: Buffer;
6
- headers: Readonly<Record<string, string>>;
7
- };
8
- /** Call only after the listener's Host/shutdown admission. No session lookup/touch or credential parsing. */
9
- export declare function createEffectBootstrap(boot?: string): {
10
- readonly boot: string;
11
- handle(req: IncomingMessage, res: ServerResponse): boolean;
12
- };
@@ -1,49 +0,0 @@
1
- import { createHash, randomBytes } from "node:crypto";
2
- import { buildCanvasEffectShim } from "./web-effect-worker.js";
3
- import { gatewayRequestContext } from "./web-request-context.js";
4
- /** #2118: fixed trusted document; no uploaded source, account data or resource authorization lives here. */
5
- export const EFFECT_BOOTSTRAP_PATH = "/effect-bootstrap";
6
- export function effectBootstrapResponse(boot) {
7
- if (!/^[0-9a-f]{32}$/.test(boot))
8
- throw new Error("invalid effect bootstrap boot");
9
- // The URL's origin is the actual navigation origin, even though the sandboxed realm is opaque. Do not derive
10
- // the parent allowlist from Origin, forwarded headers, cookies, a preview listener or a request parameter.
11
- const html = buildCanvasEffectShim(boot, [], true), body = Buffer.from(html, "utf8");
12
- const script = /<script>([\s\S]*?)<\/script>/.exec(html)[1];
13
- const style = /<style>([\s\S]*?)<\/style>/.exec(html)[1];
14
- const hash = (value) => "'sha256-" + createHash("sha256").update(value).digest("base64") + "'";
15
- const csp = [
16
- "default-src 'none'", "script-src " + hash(script) + " blob:", "style-src " + hash(style),
17
- "worker-src blob:", "img-src data: blob:", "font-src 'none'", "media-src 'none'",
18
- "connect-src 'none'", "frame-src 'none'", "child-src 'none'", "object-src 'none'",
19
- "form-action 'none'", "base-uri 'none'", "manifest-src 'none'", "webrtc 'block'",
20
- "frame-ancestors 'self'", "sandbox allow-scripts",
21
- ].join("; ");
22
- return { body, headers: Object.freeze({
23
- "Content-Type": "text/html; charset=utf-8", "Content-Length": String(body.length),
24
- "Content-Security-Policy": csp, "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff",
25
- "Referrer-Policy": "no-referrer", "Cross-Origin-Resource-Policy": "same-origin",
26
- "Permissions-Policy": "camera=(), microphone=(), geolocation=(), clipboard-read=(), clipboard-write=(), usb=(), serial=(), hid=(), bluetooth=(), payment=(), display-capture=(), fullscreen=()",
27
- }) };
28
- }
29
- /** Call only after the listener's Host/shutdown admission. No session lookup/touch or credential parsing. */
30
- export function createEffectBootstrap(boot = randomBytes(16).toString("hex")) {
31
- const response = effectBootstrapResponse(boot);
32
- return Object.freeze({ boot, handle(req, res) {
33
- const raw = req.url ?? "/";
34
- if (raw.split(/[?#]/, 1)[0] !== EFFECT_BOOTSTRAP_PATH)
35
- return false;
36
- const gateway = gatewayRequestContext(req);
37
- if (raw !== EFFECT_BOOTSTRAP_PATH || req.method !== "GET" || gateway && !gateway.isCurrent()) {
38
- res.writeHead(404, { "Content-Length": "0", "Cache-Control": "no-store" });
39
- res.end();
40
- return true;
41
- }
42
- // The ordinary shell must stay unframable; this document is instead confined by response CSP sandbox.
43
- res.removeHeader("X-Frame-Options");
44
- res.writeHead(200, response.headers);
45
- res.end(response.body);
46
- return true;
47
- } });
48
- }
49
- //# sourceMappingURL=web-effect-bootstrap.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-effect-bootstrap.js","sourceRoot":"","sources":["../src/web-effect-bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,4GAA4G;AAC5G,MAAM,CAAC,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AAEzD,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnF,6GAA6G;IAC7G,2GAA2G;IAC3G,MAAM,IAAI,GAAG,qBAAqB,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC,CAAC,CAAE,CAAC;IAC9D,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC,CAAC,CAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;IACvG,MAAM,GAAG,GAAG;QACV,oBAAoB,EAAE,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;QACzF,kBAAkB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,kBAAkB;QAChF,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB;QACjF,oBAAoB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB;QAChF,wBAAwB,EAAE,uBAAuB;KAClD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;YACpC,cAAc,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACjF,yBAAyB,EAAE,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,wBAAwB,EAAE,SAAS;YAChG,iBAAiB,EAAE,aAAa,EAAE,8BAA8B,EAAE,aAAa;YAC/E,oBAAoB,EAAE,yKAAyK;SAChM,CAAC,EAAE,CAAC;AACP,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,qBAAqB,CAAC,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IAG1E,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,GAAoB,EAAE,GAAmB;YAC3E,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;YAC3B,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,qBAAqB;gBAAE,OAAO,KAAK,CAAC;YACpE,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,GAAG,KAAK,qBAAqB,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;gBAC7F,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,gBAAgB,EAAE,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC,CAAC;gBAAC,GAAG,CAAC,GAAG,EAAE,CAAC;gBAAC,OAAO,IAAI,CAAC;YACrG,CAAC;YACD,sGAAsG;YACtG,GAAG,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;YACpC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;YAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAC5E,CAAC,EAAE,CAAC,CAAC;AACP,CAAC"}
@@ -1,28 +0,0 @@
1
- import { type WebEffectManifest } from "./web-effect.js";
2
- export declare const WEB_EFFECT_MAX_BYTES: number;
3
- export declare const WEB_EFFECT_RAW_MAX_BYTES: number;
4
- export declare const WEB_EFFECT_ASSET_MAX = 16;
5
- export interface CheckedWebEffect {
6
- id: string;
7
- sha256: string;
8
- manifest: WebEffectManifest;
9
- bytes: number;
10
- files: ReadonlyMap<string, Uint8Array>;
11
- warnings: string[];
12
- }
13
- export type EffectEntryResult = ({
14
- ok: true;
15
- } & CheckedWebEffect) | {
16
- ok: false;
17
- problems: Array<{
18
- path: string;
19
- problem: string;
20
- }>;
21
- };
22
- export declare function checkEffectEntry(input: ReadonlyMap<string, Uint8Array>): EffectEntryResult;
23
- /** Already normalized files only: assets become decoded ImageBitmaps inside the trusted frame. */
24
- export declare function effectRasterAssets(entry: CheckedWebEffect): Array<{
25
- name: string;
26
- mime: string;
27
- bytes: Uint8Array;
28
- }>;
@@ -1,171 +0,0 @@
1
- /** CW1: synchronous validation and normalization. No I/O, JS execution, or image decoding. */
2
- import { Script } from "node:vm";
3
- import { imageSize, sniffMedia, stripMetadata, MEDIA_MIME } from "./web-image-meta.js";
4
- import { effectBundleIdentity, effectManifestJson } from "./web-effect-canonical.js";
5
- import { parseWebEffectManifest } from "./web-effect.js";
6
- export const WEB_EFFECT_MAX_BYTES = 1024 * 1024;
7
- export const WEB_EFFECT_RAW_MAX_BYTES = 8 * 1024 * 1024;
8
- export const WEB_EFFECT_ASSET_MAX = 16;
9
- const utf8 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
10
- const assetPath = /^assets\/[a-z0-9][a-z0-9_-]{0,63}\.(png|jpe?g|webp|gif)$/;
11
- const fail = (path, problem) => ({ ok: false, problems: [{ path, problem }] });
12
- /** Advisory text lint only, never validation or a security boundary. Keep quoted URLs while ignoring comments. */
13
- function workerLintText(code) {
14
- const parts = [];
15
- let copied = 0, at = 0;
16
- while (at < code.length) {
17
- const c = code[at];
18
- if (c === '"' || c === "'" || c === "`") {
19
- const quote = c;
20
- at++;
21
- while (at < code.length) {
22
- if (code[at] === "\\") {
23
- at += 2;
24
- continue;
25
- }
26
- if (code[at++] === quote)
27
- break;
28
- }
29
- continue;
30
- }
31
- // Escaped slashes in a regular-expression literal are not comment openers.
32
- if (c === "\\") {
33
- at += 2;
34
- continue;
35
- }
36
- if (c === "/" && (code[at + 1] === "/" || code[at + 1] === "*")) {
37
- parts.push(code.slice(copied, at), " ");
38
- if (code[at + 1] === "/") {
39
- at += 2;
40
- while (at < code.length && !/[\r\n\u2028\u2029]/.test(code[at]))
41
- at++;
42
- }
43
- else {
44
- at += 2;
45
- while (at < code.length && !(code[at] === "*" && code[at + 1] === "/"))
46
- at++;
47
- at = Math.min(code.length, at + 2);
48
- }
49
- copied = at;
50
- continue;
51
- }
52
- at++;
53
- }
54
- parts.push(code.slice(copied));
55
- return parts.join("");
56
- }
57
- export function checkEffectEntry(input) {
58
- try {
59
- if (!(input instanceof Map) || input.size < 2 || input.size > 20)
60
- return fail("<entry>", "invalid_files");
61
- let raw = 0, assets = 0, seen = 0;
62
- const snapshot = new Map();
63
- for (const [path, bytes] of input) {
64
- if (++seen > 20)
65
- return fail("<entry>", "invalid_files");
66
- if (typeof path !== "string" || !["effect.json", "worker.js", "poster.png", "cursor.png"].includes(path) && !assetPath.test(path))
67
- return fail("<entry>", "unsupported_path");
68
- if (!(bytes instanceof Uint8Array))
69
- return fail(path, "invalid_bytes");
70
- raw += bytes.byteLength;
71
- if (raw > WEB_EFFECT_RAW_MAX_BYTES)
72
- return fail("<entry>", "raw_entry_too_large");
73
- if (assetPath.test(path) && ++assets > WEB_EFFECT_ASSET_MAX)
74
- return fail("<entry>", "too_many_assets");
75
- if (snapshot.has(path))
76
- return fail("<entry>", "invalid_files");
77
- snapshot.set(path, new Uint8Array(bytes));
78
- }
79
- const manifestBytes = snapshot.get("effect.json"), script = snapshot.get("worker.js");
80
- if (!manifestBytes || !script)
81
- return fail("<entry>", "missing_entry");
82
- if (manifestBytes.byteLength > 64 * 1024)
83
- return fail("effect.json", "manifest_too_large");
84
- if (script.byteLength > WEB_EFFECT_MAX_BYTES)
85
- return fail("worker.js", "entry_too_large");
86
- let decoded, code;
87
- try {
88
- decoded = JSON.parse(utf8.decode(manifestBytes));
89
- }
90
- catch {
91
- return fail("effect.json", "invalid_manifest");
92
- }
93
- const parsed = parseWebEffectManifest(decoded);
94
- if (!parsed.ok)
95
- return fail("effect.json", "invalid_manifest");
96
- try {
97
- code = utf8.decode(script);
98
- }
99
- catch {
100
- return fail("worker.js", "invalid_utf8");
101
- }
102
- let manifest = parsed.manifest;
103
- if (manifest.poster && !snapshot.has("poster.png"))
104
- return fail("poster.png", "missing_poster");
105
- if (!!manifest.cursor !== snapshot.has("cursor.png"))
106
- return fail("cursor.png", "cursor_manifest_mismatch");
107
- if (snapshot.has("poster.png"))
108
- manifest = { ...manifest, poster: "poster.png" };
109
- let pixels = 0;
110
- const files = new Map();
111
- files.set("worker.js", Uint8Array.from(script));
112
- for (const [path, bytes] of snapshot) {
113
- if (path === "effect.json" || path === "worker.js")
114
- continue;
115
- const kind = sniffMedia(bytes);
116
- if (!kind || kind === "woff2")
117
- return fail(path, "invalid_raster");
118
- const extension = path.slice(path.lastIndexOf(".") + 1), expected = extension === "jpg" ? "jpeg" : extension;
119
- if (kind !== expected)
120
- return fail(path, "media_mismatch");
121
- const size = imageSize(bytes, kind);
122
- if (!size || size.width < 1 || size.height < 1 || size.width > 4096 || size.height > 4096 || size.width * size.height > 8 * 1024 * 1024)
123
- return fail(path, "image_dimensions");
124
- pixels += size.width * size.height;
125
- if (pixels > 8 * 1024 * 1024)
126
- return fail(path, "image_dimensions");
127
- const stripped = stripMetadata(bytes, kind);
128
- if (!stripped)
129
- return fail(path, "invalid_raster");
130
- if (path === "cursor.png") {
131
- if (kind !== "png" || stripped.byteLength > 32 * 1024 || size.width !== size.height || size.width > 64)
132
- return fail(path, "invalid_cursor");
133
- if (manifest.cursor.hotspot.some((point, index) => point >= (index === 0 ? size.width : size.height)))
134
- return fail(path, "invalid_hotspot");
135
- }
136
- files.set(path, Uint8Array.from(stripped));
137
- }
138
- files.set("effect.json", new TextEncoder().encode(effectManifestJson(manifest)));
139
- const bytes = [...files.values()].reduce((n, v) => n + v.byteLength, 0);
140
- if (bytes > WEB_EFFECT_MAX_BYTES)
141
- return fail("<entry>", "entry_too_large");
142
- // Compile classic syntax only. Never run the result or expose parser excerpts.
143
- try {
144
- new Script(code, { filename: "worker.js" });
145
- }
146
- catch {
147
- return fail("worker.js", "invalid_classic_script");
148
- }
149
- const identity = effectBundleIdentity(manifest, files);
150
- const warnings = [];
151
- if (/\b(?:fetch|XMLHttpRequest|WebSocket|RTCPeerConnection|importScripts)\b|https?:\/\/|["\'`]\/\/|\bimport\s*\(|\btop\.|\bparent\.location/.test(workerLintText(code)))
152
- warnings.push("network_or_import_api_unsupported");
153
- return { ok: true, id: identity.id, sha256: identity.sha256, manifest, files, bytes, warnings };
154
- }
155
- catch {
156
- return fail("<entry>", "invalid_entry");
157
- }
158
- }
159
- /** Already normalized files only: assets become decoded ImageBitmaps inside the trusted frame. */
160
- export function effectRasterAssets(entry) {
161
- const assets = [];
162
- for (const [name, bytes] of entry.files)
163
- if (assetPath.test(name)) {
164
- const kind = sniffMedia(bytes);
165
- if (!kind || kind === "woff2")
166
- throw Error("Invalid normalized raster");
167
- assets.push({ name, mime: MEDIA_MIME[kind], bytes: Uint8Array.from(bytes) });
168
- }
169
- return assets;
170
- }
171
- //# sourceMappingURL=web-effect-bundle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-effect-bundle.js","sourceRoot":"","sources":["../src/web-effect-bundle.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- import type { WebEffectManifest } from "./web-effect.js";
2
- export declare function effectBundleIdentity(manifest: WebEffectManifest, files: ReadonlyMap<string, Uint8Array>): {
3
- id: string;
4
- sha256: string;
5
- canonical: string;
6
- };
7
- /** Stable JSON for the validated manifest; array order is part of its value. */
8
- export declare function effectManifestJson(manifest: WebEffectManifest): string;
@@ -1,27 +0,0 @@
1
- /** #1629: identity of an already validated, normalized bundle, including every file.
2
- * This is not an upload validator. The bundle preparer owns paths, media stripping,
3
- * UTF-8, entry format and the normalized byte limit. */
4
- import { createHash } from "node:crypto";
5
- export function effectBundleIdentity(manifest, files) {
6
- const entries = [...files].map(([path, bytes]) => [path, createHash("sha256").update(bytes).digest("hex")]);
7
- entries.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
8
- const canonical = JSON.stringify({ manifest: JSON.parse(effectManifestJson(manifest)), files: entries });
9
- const sha256 = createHash("sha256").update(canonical, "utf8").digest("hex");
10
- return { id: sha256.slice(0, 32), sha256, canonical };
11
- }
12
- /** Stable JSON for the validated manifest; array order is part of its value. */
13
- export function effectManifestJson(manifest) {
14
- const normalized = (value) => {
15
- if (Array.isArray(value))
16
- return value.map(normalized);
17
- if (value !== null && typeof value === "object") {
18
- const object = Object.create(null);
19
- for (const key of Object.keys(value).sort())
20
- object[key] = normalized(value[key]);
21
- return object;
22
- }
23
- return value;
24
- };
25
- return JSON.stringify(normalized(manifest));
26
- }
27
- //# sourceMappingURL=web-effect-canonical.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-effect-canonical.js","sourceRoot":"","sources":["../src/web-effect-canonical.ts"],"names":[],"mappings":"AAAA;;uDAEuD;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,oBAAoB,CAAC,QAA2B,EAAE,KAAsC;IAKtG,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAU,CAAC,CAAC;IACrH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACzG,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5E,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACxD,CAAC;AACD,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,QAA2B;IAC5D,MAAM,UAAU,GAAG,CAAC,KAAc,EAAW,EAAE;QAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YACtB,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,MAAM,GAA4B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE;gBACzC,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;YACpE,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC9C,CAAC"}