@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.
Files changed (271) hide show
  1. package/dist/agent-cli.js +248 -2
  2. package/dist/agent-cli.js.map +1 -1
  3. package/dist/agent-endpoint.d.ts +2 -0
  4. package/dist/agent-endpoint.js +25 -0
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/agent-file-read.d.ts +30 -0
  7. package/dist/agent-file-read.js +129 -0
  8. package/dist/agent-file-read.js.map +1 -0
  9. package/dist/agent-whats-new.js +13 -0
  10. package/dist/agent-whats-new.js.map +1 -1
  11. package/dist/atomic-write.js +9 -1
  12. package/dist/atomic-write.js.map +1 -1
  13. package/dist/auth-api.js +17 -0
  14. package/dist/auth-api.js.map +1 -1
  15. package/dist/backend/antigravity.js +3 -3
  16. package/dist/backend/antigravity.js.map +1 -1
  17. package/dist/backend/launch-effort.js +1 -1
  18. package/dist/backend/launch-effort.js.map +1 -1
  19. package/dist/backend/muse.js +10 -2
  20. package/dist/backend/muse.js.map +1 -1
  21. package/dist/channel/adapters/discord.d.ts +2 -0
  22. package/dist/channel/adapters/discord.js +17 -2
  23. package/dist/channel/adapters/discord.js.map +1 -1
  24. package/dist/channel/adapters/telegram.d.ts +8 -1
  25. package/dist/channel/adapters/telegram.js +74 -4
  26. package/dist/channel/adapters/telegram.js.map +1 -1
  27. package/dist/channel/mcp-tools.js +34 -0
  28. package/dist/channel/mcp-tools.js.map +1 -1
  29. package/dist/channel/types.d.ts +15 -0
  30. package/dist/config-validator.js +17 -1
  31. package/dist/config-validator.js.map +1 -1
  32. package/dist/daemon.js +244 -20
  33. package/dist/daemon.js.map +1 -1
  34. package/dist/fleet-context.d.ts +5 -0
  35. package/dist/fleet-manager.d.ts +89 -0
  36. package/dist/fleet-manager.js +401 -25
  37. package/dist/fleet-manager.js.map +1 -1
  38. package/dist/general-knowledge/skills/web-appearance/SKILL.md +258 -0
  39. package/dist/instance-avatar.js +3 -0
  40. package/dist/instance-avatar.js.map +1 -1
  41. package/dist/instance-config-impact.js +3 -0
  42. package/dist/instance-config-impact.js.map +1 -1
  43. package/dist/instance-lifecycle.js +9 -4
  44. package/dist/instance-lifecycle.js.map +1 -1
  45. package/dist/needs-you-hub.d.ts +4 -0
  46. package/dist/needs-you-hub.js +31 -6
  47. package/dist/needs-you-hub.js.map +1 -1
  48. package/dist/needs-you.d.ts +1 -13
  49. package/dist/needs-you.js +3 -37
  50. package/dist/needs-you.js.map +1 -1
  51. package/dist/outbound-handlers.d.ts +5 -0
  52. package/dist/outbound-handlers.js +30 -9
  53. package/dist/outbound-handlers.js.map +1 -1
  54. package/dist/outbound-schemas.d.ts +64 -0
  55. package/dist/outbound-schemas.js +50 -0
  56. package/dist/outbound-schemas.js.map +1 -1
  57. package/dist/public-web-gateway.js +14 -0
  58. package/dist/public-web-gateway.js.map +1 -1
  59. package/dist/repo-worktree-guard.d.ts +36 -0
  60. package/dist/repo-worktree-guard.js +143 -0
  61. package/dist/repo-worktree-guard.js.map +1 -0
  62. package/dist/scheduler/scheduler.d.ts +58 -1
  63. package/dist/scheduler/scheduler.js +176 -10
  64. package/dist/scheduler/scheduler.js.map +1 -1
  65. package/dist/settings-api.js +74 -1
  66. package/dist/settings-api.js.map +1 -1
  67. package/dist/settings-change.js +8 -0
  68. package/dist/settings-change.js.map +1 -1
  69. package/dist/settings-effect.js +16 -2
  70. package/dist/settings-effect.js.map +1 -1
  71. package/dist/settings-http-confirmation.js +5 -0
  72. package/dist/settings-http-confirmation.js.map +1 -1
  73. package/dist/tool-permissions.js +50 -0
  74. package/dist/tool-permissions.js.map +1 -1
  75. package/dist/topic-commands.d.ts +10 -6
  76. package/dist/topic-commands.js +21 -17
  77. package/dist/topic-commands.js.map +1 -1
  78. package/dist/topic-link.d.ts +128 -0
  79. package/dist/topic-link.js +269 -0
  80. package/dist/topic-link.js.map +1 -0
  81. package/dist/types.d.ts +13 -0
  82. package/dist/ui/app-effects.js +187 -0
  83. package/dist/ui/chat-effect-posters.js +42 -0
  84. package/dist/ui/chat-effects.js +72 -0
  85. package/dist/ui/chat-live-replies.js +58 -0
  86. package/dist/ui/chat-render.js +4 -4
  87. package/dist/ui/chat-store.js +9 -3
  88. package/dist/ui/chat-strings.js +15 -0
  89. package/dist/ui/chat-thread.js +47 -21
  90. package/dist/ui/chat-tour.js +1 -1
  91. package/dist/ui/effect-trial-controller.js +119 -0
  92. package/dist/ui/effect-trial-offer.js +31 -0
  93. package/dist/ui/effect-trial-panel.js +37 -0
  94. package/dist/ui/image-lightbox.js +1 -1
  95. package/dist/ui/panel-chat.js +85 -17
  96. package/dist/ui/panel-details.js +18 -5
  97. package/dist/ui/panel-fleet.js +3 -3
  98. package/dist/ui/panel-log.js +6 -6
  99. package/dist/ui/panel-needs.js +3 -3
  100. package/dist/ui/panel-settings.js +8 -5
  101. package/dist/ui/preview-panel.js +25 -9
  102. package/dist/ui/settings-appearance.js +325 -0
  103. package/dist/ui/settings-effects.js +201 -0
  104. package/dist/ui/settings-mods.js +257 -0
  105. package/dist/ui/settings-owner-effects.js +80 -0
  106. package/dist/ui/settings-strings.js +245 -0
  107. package/dist/ui/shared/agend-auth.js +27 -3
  108. package/dist/ui/shared/agent-widget.js +248 -0
  109. package/dist/ui/shared/app-i18n.js +2 -0
  110. package/dist/ui/shared/app-prefs.js +30 -10
  111. package/dist/ui/shared/app-route.js +23 -1
  112. package/dist/ui/shared/app-session.js +1 -1
  113. package/dist/ui/shared/app-shell.js +29 -16
  114. package/dist/ui/shared/app-store.js +2 -0
  115. package/dist/ui/shared/app-stream.js +12 -7
  116. package/dist/ui/shared/app-themes.js +188 -0
  117. package/dist/ui/shared/app.css +214 -1
  118. package/dist/ui/shared/app.js +6 -0
  119. package/dist/ui/shared/card-strings.js +28 -0
  120. package/dist/ui/shared/effect-app-runtime.js +248 -0
  121. package/dist/ui/shared/effect-baseline.js +64 -0
  122. package/dist/ui/shared/effect-chat-runtime.js +154 -0
  123. package/dist/ui/shared/effect-cursor.js +125 -0
  124. package/dist/ui/shared/effect-frame.js +127 -0
  125. package/dist/ui/shared/effect-geometry.js +122 -0
  126. package/dist/ui/shared/effect-host-style.js +10 -0
  127. package/dist/ui/shared/effect-owner-regions.js +74 -0
  128. package/dist/ui/shared/effect-owner-source.js +115 -0
  129. package/dist/ui/shared/effect-policy.js +137 -0
  130. package/dist/ui/shared/effect-poster-reader.js +98 -0
  131. package/dist/ui/shared/effect-posters.js +117 -0
  132. package/dist/ui/shared/effect-profiler.js +162 -0
  133. package/dist/ui/shared/effect-profiles.js +65 -0
  134. package/dist/ui/shared/effect-registry.js +496 -0
  135. package/dist/ui/shared/effect-runtime-loader.js +234 -0
  136. package/dist/ui/shared/effect-safety.js +153 -0
  137. package/dist/ui/shared/effect-stock-snapshot.js +34 -0
  138. package/dist/ui/shared/effect-stock-trust.js +165 -0
  139. package/dist/ui/shared/effect-trial-source.js +103 -0
  140. package/dist/ui/shared/effect-trial-stage.js +147 -0
  141. package/dist/ui/shared/header-tools.js +1 -1
  142. package/dist/ui/shared/identity-card.js +202 -0
  143. package/dist/ui/shared/identity-color.js +261 -0
  144. package/dist/ui/shared/instance-nav.js +22 -14
  145. package/dist/ui/shared/owner-css.js +221 -0
  146. package/dist/ui/shared/owner-effect-prefs.js +117 -0
  147. package/dist/ui/shared/panel-view.js +81 -8
  148. package/dist/ui/shared/signin.js +2 -0
  149. package/dist/ui/shared/ui-dialog.js +1 -1
  150. package/dist/ui/shared/ui-icons.js +2 -0
  151. package/dist/ui/shared/ui-menu.js +1 -1
  152. package/dist/ui/shared/ui-toast.js +1 -1
  153. package/dist/ui/shared/view-strings.js +30 -0
  154. package/dist/ui/signin.html +1 -0
  155. package/dist/view-api.d.ts +29 -0
  156. package/dist/view-api.js +188 -8
  157. package/dist/view-api.js.map +1 -1
  158. package/dist/web-api.d.ts +42 -0
  159. package/dist/web-api.js +896 -36
  160. package/dist/web-api.js.map +1 -1
  161. package/dist/web-appearance-limits.d.ts +82 -0
  162. package/dist/web-appearance-limits.js +83 -0
  163. package/dist/web-appearance-limits.js.map +1 -0
  164. package/dist/web-appearance-policy.d.ts +66 -0
  165. package/dist/web-appearance-policy.js +94 -0
  166. package/dist/web-appearance-policy.js.map +1 -0
  167. package/dist/web-appearance-tools.d.ts +50 -0
  168. package/dist/web-appearance-tools.js +105 -0
  169. package/dist/web-appearance-tools.js.map +1 -0
  170. package/dist/web-appearance-view.d.ts +99 -0
  171. package/dist/web-appearance-view.js +163 -0
  172. package/dist/web-appearance-view.js.map +1 -0
  173. package/dist/web-appearance.d.ts +79 -0
  174. package/dist/web-appearance.js +298 -0
  175. package/dist/web-appearance.js.map +1 -0
  176. package/dist/web-asset-parts.d.ts +98 -0
  177. package/dist/web-asset-parts.js +133 -0
  178. package/dist/web-asset-parts.js.map +1 -0
  179. package/dist/web-auth.js +17 -1
  180. package/dist/web-auth.js.map +1 -1
  181. package/dist/web-card.d.ts +96 -0
  182. package/dist/web-card.js +232 -0
  183. package/dist/web-card.js.map +1 -0
  184. package/dist/web-chat-history.d.ts +13 -0
  185. package/dist/web-chat-history.js +23 -2
  186. package/dist/web-chat-history.js.map +1 -1
  187. package/dist/web-effect-bundle.d.ts +28 -0
  188. package/dist/web-effect-bundle.js +126 -0
  189. package/dist/web-effect-bundle.js.map +1 -0
  190. package/dist/web-effect-canonical.d.ts +8 -0
  191. package/dist/web-effect-canonical.js +27 -0
  192. package/dist/web-effect-canonical.js.map +1 -0
  193. package/dist/web-effect-library.d.ts +114 -0
  194. package/dist/web-effect-library.js +530 -0
  195. package/dist/web-effect-library.js.map +1 -0
  196. package/dist/web-effect-poster.d.ts +8 -0
  197. package/dist/web-effect-poster.js +52 -0
  198. package/dist/web-effect-poster.js.map +1 -0
  199. package/dist/web-effect-profiles.d.ts +118 -0
  200. package/dist/web-effect-profiles.js +180 -0
  201. package/dist/web-effect-profiles.js.map +1 -0
  202. package/dist/web-effect-service.d.ts +86 -0
  203. package/dist/web-effect-service.js +312 -0
  204. package/dist/web-effect-service.js.map +1 -0
  205. package/dist/web-effect-tools.d.ts +47 -0
  206. package/dist/web-effect-tools.js +126 -0
  207. package/dist/web-effect-tools.js.map +1 -0
  208. package/dist/web-effect-trials.d.ts +86 -0
  209. package/dist/web-effect-trials.js +204 -0
  210. package/dist/web-effect-trials.js.map +1 -0
  211. package/dist/web-effect-upload.d.ts +29 -0
  212. package/dist/web-effect-upload.js +190 -0
  213. package/dist/web-effect-upload.js.map +1 -0
  214. package/dist/web-effect-worker.d.ts +8 -0
  215. package/dist/web-effect-worker.js +170 -0
  216. package/dist/web-effect-worker.js.map +1 -0
  217. package/dist/web-effect.d.ts +89 -0
  218. package/dist/web-effect.js +132 -0
  219. package/dist/web-effect.js.map +1 -0
  220. package/dist/web-identity-color.d.ts +87 -0
  221. package/dist/web-identity-color.js +209 -0
  222. package/dist/web-identity-color.js.map +1 -0
  223. package/dist/web-identity-palette.d.ts +113 -0
  224. package/dist/web-identity-palette.js +84 -0
  225. package/dist/web-identity-palette.js.map +1 -0
  226. package/dist/web-image-meta.d.ts +25 -0
  227. package/dist/web-image-meta.js +200 -0
  228. package/dist/web-image-meta.js.map +1 -0
  229. package/dist/web-mod-agent.d.ts +50 -0
  230. package/dist/web-mod-agent.js +203 -0
  231. package/dist/web-mod-agent.js.map +1 -0
  232. package/dist/web-mod-bundle.d.ts +144 -0
  233. package/dist/web-mod-bundle.js +464 -0
  234. package/dist/web-mod-bundle.js.map +1 -0
  235. package/dist/web-mod-export.d.ts +59 -0
  236. package/dist/web-mod-export.js +79 -0
  237. package/dist/web-mod-export.js.map +1 -0
  238. package/dist/web-mod-store.d.ts +283 -0
  239. package/dist/web-mod-store.js +624 -0
  240. package/dist/web-mod-store.js.map +1 -0
  241. package/dist/web-org.d.ts +3 -3
  242. package/dist/web-org.js +11 -17
  243. package/dist/web-org.js.map +1 -1
  244. package/dist/web-owner-css-store.d.ts +180 -0
  245. package/dist/web-owner-css-store.js +384 -0
  246. package/dist/web-owner-css-store.js.map +1 -0
  247. package/dist/web-owner-css.d.ts +58 -0
  248. package/dist/web-owner-css.js +552 -0
  249. package/dist/web-owner-css.js.map +1 -0
  250. package/dist/web-prefs.d.ts +48 -0
  251. package/dist/web-prefs.js +209 -33
  252. package/dist/web-prefs.js.map +1 -1
  253. package/dist/web-preview.d.ts +9 -1
  254. package/dist/web-preview.js +24 -7
  255. package/dist/web-preview.js.map +1 -1
  256. package/dist/web-settings-patch.d.ts +18 -0
  257. package/dist/web-settings-patch.js +51 -0
  258. package/dist/web-settings-patch.js.map +1 -1
  259. package/dist/web-shell-routes.d.ts +1 -1
  260. package/dist/web-shell-routes.js +1 -1
  261. package/dist/web-shell-routes.js.map +1 -1
  262. package/dist/web-theme-store.d.ts +218 -0
  263. package/dist/web-theme-store.js +516 -0
  264. package/dist/web-theme-store.js.map +1 -0
  265. package/dist/web-theme.d.ts +121 -0
  266. package/dist/web-theme.js +407 -0
  267. package/dist/web-theme.js.map +1 -0
  268. package/dist/web-widget.d.ts +72 -0
  269. package/dist/web-widget.js +245 -0
  270. package/dist/web-widget.js.map +1 -0
  271. package/package.json +1 -1
@@ -0,0 +1,384 @@
1
+ /**
2
+ * #1629 r4 §3: where each person's owner CSS lives. Per person (their web-prefs key, web-profile.ts webPersonKey), in
3
+ * `<dataDir>/web-owner-css/<hash of the key>/`:
4
+ * <sha>.css each kept version, as uploaded (served only after checkOwnerCss + serializeOwnerCss, every time)
5
+ * assets/<id>.<ext> the pictures and fonts its CSS names as url("asset:<id>") — metadata stripped, id = sha of the kept bytes
6
+ * index.json { versions: [{ sha, at }] newest first, at most 5; assets: [{ id, kind, bytes }]; pending? }
7
+ * Which version is in force is the person's `css.active` (web-prefs.ts), so every device of theirs follows.
8
+ * Keep-or-revert: a saved version is in force on trial (`pending`) until the person keeps it. Unkept by its deadline,
9
+ * it is reverted here, at the next read — a closed tab, or CSS that hid the question, reverts too.
10
+ * Nothing here is reachable from an agent: no tool, CLI command or agent route names it.
11
+ */
12
+ import { createHash, randomBytes } from "node:crypto";
13
+ import { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
14
+ import { join } from "node:path";
15
+ import { atomicWriteFileSync } from "./atomic-write.js";
16
+ import { MEDIA_EXT, MEDIA_MIME, sniffMedia, stripMetadata } from "./web-image-meta.js";
17
+ import { checkOwnerCss, OWNER_CSS_ASSET_ID, ownerCssAssetRefs, serializeOwnerCss } from "./web-owner-css.js";
18
+ export const OWNER_CSS_VERSIONS = 5;
19
+ /** How long a saved version waits to be kept (the page asks for 15 s; the host allows a little more for the round trip). */
20
+ export const OWNER_CSS_KEEP_MS = 20_000;
21
+ export const OWNER_CSS_MAX_ASSETS = 16;
22
+ export const OWNER_CSS_MAX_ASSET_BYTES = 1024 * 1024; // all of a person's assets together
23
+ const ASSET_KINDS = new Set(["png", "webp", "jpeg", "gif", "woff2"]);
24
+ const SHA = /^[0-9a-f]{32}$/;
25
+ const hash32 = (data) => createHash("sha256").update(data).digest("hex").slice(0, 32);
26
+ /** Bytes to a file, whole or not at all (a temp file renamed over it), 0600. */
27
+ function writeBytesAtomic(path, bytes) {
28
+ const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
29
+ try {
30
+ writeFileSync(tmp, bytes, { mode: 0o600 });
31
+ renameSync(tmp, path);
32
+ }
33
+ catch (err) {
34
+ try {
35
+ unlinkSync(tmp);
36
+ }
37
+ catch { /* none */ }
38
+ throw err;
39
+ }
40
+ }
41
+ export class OwnerCssStore {
42
+ dataDir;
43
+ pointer;
44
+ now;
45
+ constructor(dataDir, pointer, now = () => Date.now()) {
46
+ this.dataDir = dataDir;
47
+ this.pointer = pointer;
48
+ this.now = now;
49
+ }
50
+ dir(person) { return join(this.dataDir, "web-owner-css", hash32(`person\0${person}`)); }
51
+ readIndex(person, evidence) {
52
+ if (evidence)
53
+ evidence.known = false;
54
+ try {
55
+ const raw = JSON.parse(readFileSync(join(this.dir(person), "index.json"), "utf8"));
56
+ const versions = Array.isArray(raw.versions) ? raw.versions.filter(v => v && SHA.test(String(v.sha)) && Number.isFinite(v.at)) : [];
57
+ const assets = Array.isArray(raw.assets) ? raw.assets.filter(a => a && SHA.test(String(a.id)) && ASSET_KINDS.has(a.kind) && Number.isSafeInteger(a.bytes)) : [];
58
+ const p = raw.pending;
59
+ const pending = p && SHA.test(String(p.id)) && SHA.test(String(p.sha)) && (p.previous === null || SHA.test(String(p.previous))) && Number.isFinite(p.at) && Number.isFinite(p.until) ? p : undefined;
60
+ if (evidence)
61
+ evidence.known = Array.isArray(raw.versions) && Array.isArray(raw.assets)
62
+ && versions.length === raw.versions.length && versions.every(v => typeof v.sha === "string")
63
+ && assets.length === raw.assets.length && assets.every(a => typeof a.id === "string" && a.bytes >= 0)
64
+ && (raw.pending === undefined || !!pending && typeof pending.id === "string" && typeof pending.sha === "string"
65
+ && (pending.previous === null || typeof pending.previous === "string"));
66
+ return { versions, assets, ...(pending ? { pending } : {}) };
67
+ }
68
+ catch (err) {
69
+ if (evidence)
70
+ evidence.known = err?.code === "ENOENT";
71
+ return { versions: [], assets: [] };
72
+ }
73
+ }
74
+ writeIndex(person, index) {
75
+ mkdirSync(this.dir(person), { recursive: true, mode: 0o700 });
76
+ atomicWriteFileSync(join(this.dir(person), "index.json"), JSON.stringify(index, null, 2) + "\n", { mode: 0o600 });
77
+ }
78
+ readText(person, sha) {
79
+ if (!SHA.test(sha))
80
+ return null;
81
+ try {
82
+ return readFileSync(join(this.dir(person), `${sha}.css`), "utf8");
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ assetIds(index) { return new Set(index.assets.map(a => a.id)); }
89
+ /**
90
+ * A trial nobody kept by its deadline is reverted now: the version before it is put back. A clock that went back
91
+ * past the save counts as expired too (the deadline cannot be trusted).
92
+ */
93
+ settle(person) {
94
+ const index = this.readIndex(person);
95
+ const p = index.pending;
96
+ if (!p)
97
+ return;
98
+ const now = this.now();
99
+ if (now <= p.until && now >= p.at)
100
+ return;
101
+ this.endTrial(person, index, "revert");
102
+ }
103
+ /**
104
+ * End the trial in `index`: "keep" leaves its version in force; "revert" puts back the one before it (if that one is
105
+ * still kept, else none). Either way `css.trial` is cleared in the same write, so every device hears of it.
106
+ */
107
+ endTrial(person, index, how) {
108
+ const p = index.pending;
109
+ if (!p)
110
+ return false;
111
+ const change = { trial: null };
112
+ if (how === "revert" && this.pointer.ownerCssActive(person) === p.sha) {
113
+ change.active = p.previous && index.versions.some(v => v.sha === p.previous) ? p.previous : null;
114
+ }
115
+ if (!this.pointer.setOwnerCss(person, change).ok)
116
+ return false; // the pointer cannot be written: try at the next read
117
+ const { pending: _done, ...rest } = index;
118
+ void _done;
119
+ this.writeIndex(person, rest);
120
+ return true;
121
+ }
122
+ /**
123
+ * r4-5: everything a mod import may change for this person, to put back exactly if the import fails later: the index
124
+ * (versions, assets, a trial), both pointers, and the text of every kept version (a save may drop the oldest's file).
125
+ */
126
+ snapshot(person) {
127
+ const index = this.readIndex(person);
128
+ const texts = new Map();
129
+ for (const v of index.versions) {
130
+ const t = this.readText(person, v.sha);
131
+ if (t !== null)
132
+ texts.set(v.sha, t);
133
+ }
134
+ return { index: JSON.parse(JSON.stringify(index)), active: this.pointer.ownerCssActive(person), trial: this.pointer.ownerCssTrial?.(person) ?? null, texts };
135
+ }
136
+ /** Put a snapshot back: texts, index, pointers; versions and assets added since are removed. */
137
+ restoreSnapshot(person, snap) {
138
+ const now = this.readIndex(person);
139
+ try {
140
+ for (const [sha, text] of snap.texts)
141
+ if (this.readText(person, sha) !== text) {
142
+ mkdirSync(this.dir(person), { recursive: true, mode: 0o700 });
143
+ atomicWriteFileSync(join(this.dir(person), `${sha}.css`), text, { mode: 0o600 });
144
+ }
145
+ this.writeIndex(person, snap.index);
146
+ }
147
+ catch (err) {
148
+ return { ok: false, status: 503, error: "owner_css_restore_failed", detail: err.message };
149
+ }
150
+ const set = this.pointer.setOwnerCss(person, { active: snap.active, trial: snap.trial });
151
+ if (!set.ok)
152
+ return set;
153
+ for (const v of now.versions)
154
+ if (!snap.texts.has(v.sha)) {
155
+ try {
156
+ unlinkSync(join(this.dir(person), `${v.sha}.css`));
157
+ }
158
+ catch { /* none */ }
159
+ }
160
+ const kept = new Set(snap.index.assets.map(a => a.id));
161
+ for (const a of now.assets)
162
+ if (!kept.has(a.id)) {
163
+ try {
164
+ unlinkSync(join(this.dir(person), "assets", `${a.id}.${MEDIA_EXT[a.kind]}`));
165
+ }
166
+ catch { /* none */ }
167
+ }
168
+ return { ok: true };
169
+ }
170
+ /** The version in force (a kept one), or null — what the page links at load. */
171
+ active(person) {
172
+ this.settle(person);
173
+ const active = this.pointer.ownerCssActive(person);
174
+ return active && this.readIndex(person).versions.some(v => v.sha === active) ? active : null;
175
+ }
176
+ /** Positive CSS evidence for the page; no identity fallback or change to legacy CSS save/serve behavior. */
177
+ effectState(person) {
178
+ try {
179
+ this.settle(person);
180
+ const selection = this.pointer.ownerCssSelection?.(person);
181
+ if (!selection?.known)
182
+ return "unknown";
183
+ const evidence = { known: false }, index = this.readIndex(person, evidence);
184
+ if (!evidence.known)
185
+ return "unknown";
186
+ if (selection.active === null)
187
+ return "off";
188
+ return index.versions.some(v => v.sha === selection.active) && this.served(person, selection.active) !== null ? "on" : "unknown";
189
+ }
190
+ catch {
191
+ return "unknown";
192
+ }
193
+ }
194
+ state(person) {
195
+ this.settle(person);
196
+ const index = this.readIndex(person);
197
+ const active = this.pointer.ownerCssActive(person);
198
+ const kept = active && index.versions.some(v => v.sha === active) ? active : null;
199
+ return {
200
+ effectState: this.effectState(person),
201
+ active: kept,
202
+ pending: index.pending && index.pending.sha === kept
203
+ ? { id: index.pending.id, sha: index.pending.sha, previous: index.pending.previous, remaining_ms: Math.max(0, Math.min(OWNER_CSS_KEEP_MS, index.pending.until - this.now())) }
204
+ : null,
205
+ text: kept ? this.readText(person, kept) : null,
206
+ versions: index.versions.map(v => ({ ...v, bytes: Buffer.byteLength(this.readText(person, v.sha) ?? "", "utf8") })),
207
+ assets: index.assets,
208
+ limits: { maxBytes: 64 * 1024, maxAssets: OWNER_CSS_MAX_ASSETS, maxAssetBytes: OWNER_CSS_MAX_ASSET_BYTES, versions: OWNER_CSS_VERSIONS },
209
+ };
210
+ }
211
+ /**
212
+ * Check, store and select a new version — on trial until kept (keep()). `previous`: the version in force before,
213
+ * which an unkept trial goes back to.
214
+ */
215
+ save(person, text) {
216
+ if (typeof text !== "string")
217
+ return { ok: false, status: 400, error: "css: text" };
218
+ const index = this.readIndex(person);
219
+ const checked = checkOwnerCss(text, this.assetIds(index));
220
+ if (!checked.ok)
221
+ return { ok: false, status: checked.error.problem === "too_large" ? 413 : 400, error: checked.error.problem, ...(checked.error.detail ? { detail: checked.error.detail } : {}) };
222
+ try {
223
+ serializeOwnerCss(checked.tokens);
224
+ }
225
+ catch {
226
+ return { ok: false, status: 400, error: "unserialisable" };
227
+ }
228
+ const sha = hash32(text);
229
+ const before = this.state(person);
230
+ // A trial on top of a trial goes back to what was in force before the first: never to an unkept version.
231
+ const previous = before.pending ? (this.readIndex(person).pending?.previous ?? null) : before.active;
232
+ mkdirSync(this.dir(person), { recursive: true, mode: 0o700 });
233
+ atomicWriteFileSync(join(this.dir(person), `${sha}.css`), text, { mode: 0o600 });
234
+ const versions = [{ sha, at: this.now() }, ...index.versions.filter(v => v.sha !== sha)];
235
+ // The version a trial would go back to is never dropped, even past five.
236
+ const keepList = versions.slice(0, OWNER_CSS_VERSIONS);
237
+ if (previous && !keepList.some(v => v.sha === previous)) {
238
+ const p = versions.find(v => v.sha === previous);
239
+ if (p)
240
+ keepList.push(p);
241
+ }
242
+ const dropped = versions.filter(v => !keepList.includes(v));
243
+ const at = this.now();
244
+ const trial = randomBytes(16).toString("hex");
245
+ this.writeIndex(person, { ...index, versions: keepList, pending: { id: trial, sha, previous, at, until: at + OWNER_CSS_KEEP_MS } });
246
+ const set = this.pointer.setOwnerCss(person, { active: sha, trial });
247
+ if (!set.ok)
248
+ return set;
249
+ for (const v of dropped) {
250
+ try {
251
+ unlinkSync(join(this.dir(person), `${v.sha}.css`));
252
+ }
253
+ catch { /* already gone */ }
254
+ }
255
+ return { ok: true, sha, previous, trial };
256
+ }
257
+ /** The trial `id` names, while it still is the one on trial and in force; else null. */
258
+ trialOf(person, id) {
259
+ if (typeof id !== "string" || !SHA.test(id))
260
+ return null;
261
+ this.settle(person);
262
+ const index = this.readIndex(person);
263
+ return index.pending && index.pending.id === id && this.pointer.ownerCssActive(person) === index.pending.sha ? index : null;
264
+ }
265
+ /** Keep this trial (the person answered "Keep"). Too late, or another trial (even of the same text): 409. */
266
+ keep(person, trial) {
267
+ if (typeof trial !== "string" || !SHA.test(trial))
268
+ return { ok: false, status: 400, error: "trial" };
269
+ const index = this.trialOf(person, trial);
270
+ if (!index)
271
+ return { ok: false, status: 409, error: "not_on_trial" };
272
+ if (!this.endTrial(person, index, "keep"))
273
+ return { ok: false, status: 503, error: "prefs_unwritable" };
274
+ return { ok: true, active: index.pending.sha };
275
+ }
276
+ /**
277
+ * Revert exactly this trial — the page's Revert, or its timer. Only while it still is the trial: one kept, reverted
278
+ * or replaced meanwhile (a new trial of the same text included), on any device, is left alone (409).
279
+ */
280
+ revertTrial(person, trial) {
281
+ if (typeof trial !== "string" || !SHA.test(trial))
282
+ return { ok: false, status: 400, error: "trial" };
283
+ const index = this.trialOf(person, trial);
284
+ if (!index)
285
+ return { ok: false, status: 409, error: "not_on_trial" };
286
+ if (!this.endTrial(person, index, "revert"))
287
+ return { ok: false, status: 503, error: "prefs_unwritable" };
288
+ return { ok: true, active: this.pointer.ownerCssActive(person) };
289
+ }
290
+ /** Put a kept version back in force, or (null) none: their screens go stock. Ends any trial. */
291
+ restore(person, sha) {
292
+ if (sha !== null && (typeof sha !== "string" || !SHA.test(sha)))
293
+ return { ok: false, status: 400, error: "sha" };
294
+ const index = this.readIndex(person);
295
+ if (sha !== null && !index.versions.some(v => v.sha === sha))
296
+ return { ok: false, status: 404, error: "no_such_version" };
297
+ const set = this.pointer.setOwnerCss(person, { active: sha, trial: null });
298
+ if (!set.ok)
299
+ return set;
300
+ if (index.pending) {
301
+ const { pending: _done, ...rest } = index;
302
+ void _done;
303
+ this.writeIndex(person, rest);
304
+ }
305
+ return { ok: true, active: sha };
306
+ }
307
+ /** A picture or font for this person's CSS: png, webp, jpeg, gif or woff2; metadata stripped; ≤ 16 files, ≤ 1 MiB together. */
308
+ addAsset(person, bytes) {
309
+ const kind = sniffMedia(bytes);
310
+ if (!kind || !ASSET_KINDS.has(kind))
311
+ return { ok: false, status: 400, error: "asset_type", detail: "png, webp, jpeg, gif or woff2" };
312
+ const kept = stripMetadata(bytes, kind);
313
+ if (!kept)
314
+ return { ok: false, status: 400, error: "asset_unreadable" };
315
+ const id = hash32(kept);
316
+ const index = this.readIndex(person);
317
+ const existing = index.assets.find(a => a.id === id);
318
+ if (existing)
319
+ return { ok: true, ...existing };
320
+ if (index.assets.length >= OWNER_CSS_MAX_ASSETS)
321
+ return { ok: false, status: 409, error: "asset_quota", detail: `at most ${OWNER_CSS_MAX_ASSETS} files` };
322
+ if (index.assets.reduce((n, a) => n + a.bytes, 0) + kept.length > OWNER_CSS_MAX_ASSET_BYTES)
323
+ return { ok: false, status: 413, error: "asset_quota", detail: "at most 1 MiB together" };
324
+ mkdirSync(join(this.dir(person), "assets"), { recursive: true, mode: 0o700 });
325
+ writeBytesAtomic(join(this.dir(person), "assets", `${id}.${MEDIA_EXT[kind]}`), kept);
326
+ const entry = { id, kind, bytes: kept.length };
327
+ this.writeIndex(person, { ...index, assets: [...index.assets, entry] });
328
+ return { ok: true, ...entry };
329
+ }
330
+ /** Remove an asset no kept version names (a kept version must always restore whole). */
331
+ removeAsset(person, id) {
332
+ const index = this.readIndex(person);
333
+ const entry = index.assets.find(a => a.id === id);
334
+ if (!entry)
335
+ return { ok: false, status: 404, error: "no_such_asset" };
336
+ // What a kept version names, read from its decoded tokens: url("\\61sset:<id>") names the asset as well.
337
+ const names = (text) => {
338
+ if (text === null)
339
+ return false;
340
+ const checked = checkOwnerCss(text, this.assetIds(index));
341
+ return checked.ok && ownerCssAssetRefs(checked.tokens).has(id);
342
+ };
343
+ if (index.versions.some(v => names(this.readText(person, v.sha))))
344
+ return { ok: false, status: 409, error: "asset_in_use" };
345
+ try {
346
+ unlinkSync(join(this.dir(person), "assets", `${id}.${MEDIA_EXT[entry.kind]}`));
347
+ }
348
+ catch { /* already gone */ }
349
+ this.writeIndex(person, { ...index, assets: index.assets.filter(a => a.id !== id) });
350
+ return { ok: true, removed: id };
351
+ }
352
+ /** The text to serve for one of this person's kept versions: checked again and re-serialised. null: none, or it fails. */
353
+ served(person, sha) {
354
+ const index = this.readIndex(person);
355
+ if (!index.versions.some(v => v.sha === sha))
356
+ return null;
357
+ const text = this.readText(person, sha);
358
+ if (text === null)
359
+ return null;
360
+ const checked = checkOwnerCss(text, this.assetIds(index));
361
+ if (!checked.ok)
362
+ return null;
363
+ try {
364
+ return serializeOwnerCss(checked.tokens);
365
+ }
366
+ catch {
367
+ return null;
368
+ }
369
+ }
370
+ asset(person, id) {
371
+ if (!OWNER_CSS_ASSET_ID.test(id))
372
+ return null;
373
+ const entry = this.readIndex(person).assets.find(a => a.id === id);
374
+ if (!entry)
375
+ return null;
376
+ try {
377
+ return { bytes: readFileSync(join(this.dir(person), "assets", `${id}.${MEDIA_EXT[entry.kind]}`)), mime: MEDIA_MIME[entry.kind] };
378
+ }
379
+ catch {
380
+ return null;
381
+ }
382
+ }
383
+ }
384
+ //# sourceMappingURL=web-owner-css-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-owner-css-store.js","sourceRoot":"","sources":["../src/web-owner-css-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * #1629 r4 §3: owner CSS — one raw CSS text per human, for that human's own screens. This module is its gate:
3
+ * a CSS Syntax Level 3 tokenizer (no dependency), the rules a stored text must pass, and the serialiser the route
4
+ * serves from. The server re-serialises from tokens, so the bytes served are never the bytes uploaded; the CSP
5
+ * (`style-src 'self'`, `img-src 'self' data: blob:`, `font-src 'self' data:`) is the first wall, this the second
6
+ * and the one that says why at save time.
7
+ *
8
+ * Refused: `@import` / `@namespace` / `@charset`; any `url(…)` or `src(…)` except `url("asset:<id>")` (or the
9
+ * unquoted `url(asset:<id>)`) naming an asset stored with this CSS; `image-set`, `-webkit-image-set`, `cross-fade`,
10
+ * `element`, `-moz-element`, `paint`, `expression`; the properties `behavior` and `-moz-binding`; `javascript:` and
11
+ * `vbscript:` anywhere. Escapes are decoded before any check (`\75 rl(` is `url(`).
12
+ */
13
+ export declare const OWNER_CSS_MAX_BYTES: number;
14
+ export declare const OWNER_CSS_ASSET_ID: RegExp;
15
+ /** What an `asset:` reference becomes when served. */
16
+ export declare const ownerCssAssetUrl: (id: string) => string;
17
+ export type CssTokenType = "ident" | "function" | "at" | "hash" | "string" | "bad-string" | "url" | "bad-url" | "delim" | "number" | "percentage" | "dimension" | "ws" | "cdo" | "cdc" | ":" | ";" | "," | "[" | "]" | "(" | ")" | "{" | "}";
18
+ export interface CssToken {
19
+ type: CssTokenType;
20
+ /** Decoded: an ident/function/at/hash name, a string's or url's contents, a delim's character, a number's text. */
21
+ value: string;
22
+ /** dimension: its unit, decoded. */
23
+ unit?: string;
24
+ /** hash: "id" when its name would start an identifier (Syntax §4.3.1) — what makes it an ID selector. */
25
+ hashType?: "id" | "unrestricted";
26
+ /** ws: whether it held a newline (kept so the served text keeps its lines). */
27
+ newline?: boolean;
28
+ }
29
+ /** CSS Syntax Level 3 §4 tokenizer. Comments are consumed (they are not tokens). */
30
+ export declare function tokenizeCss(text: string): CssToken[];
31
+ export interface OwnerCssProblem {
32
+ problem: string;
33
+ detail?: string;
34
+ }
35
+ /**
36
+ * The checks (§3). `assets`: the ids stored with this CSS. Returns the tokens to serve from, or the first problem.
37
+ * Run before storing and again before serving.
38
+ */
39
+ export declare function checkOwnerCss(text: string, assets: ReadonlySet<string>): {
40
+ ok: true;
41
+ tokens: CssToken[];
42
+ } | {
43
+ ok: false;
44
+ error: OwnerCssProblem;
45
+ };
46
+ /** The asset ids a checked text names (decoded: url("\\61sset:<id>") counts as asset:<id>). */
47
+ export declare function ownerCssAssetRefs(tokens: readonly CssToken[]): Set<string>;
48
+ /**
49
+ * The served text: re-serialised from the checked tokens, `asset:<id>` rewritten to `/ui/owner-css/asset/<id>`.
50
+ * Throws if the result does not tokenize back to the same tokens (it never should; the route then serves nothing).
51
+ */
52
+ export declare function serializeOwnerCss(tokens: readonly CssToken[]): string;
53
+ /**
54
+ * #1629: the generic serialiser (effects reuse it, B2): canonical text for these tokens, exactly as given (no asset
55
+ * rewriting), with a comment between pairs that would merge. Throws if the text does not tokenize back to the same
56
+ * tokens (type, value, unit, hash type; whitespace as whitespace).
57
+ */
58
+ export declare function serializeCssTokens(tokens: readonly CssToken[]): string;