@songsid/agend 2.1.12-beta.9 → 2.2.0-alpha.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 (358) hide show
  1. package/README.md +2 -2
  2. package/README.zh-TW.md +2 -2
  3. package/dist/auth/one-time-code.d.ts +19 -0
  4. package/dist/auth/one-time-code.js +49 -0
  5. package/dist/auth/one-time-code.js.map +1 -0
  6. package/dist/auth-api.d.ts +52 -0
  7. package/dist/auth-api.js +346 -0
  8. package/dist/auth-api.js.map +1 -0
  9. package/dist/backend/claude-code.d.ts +4 -0
  10. package/dist/backend/claude-code.js +97 -0
  11. package/dist/backend/claude-code.js.map +1 -1
  12. package/dist/backend/codex.js +59 -30
  13. package/dist/backend/codex.js.map +1 -1
  14. package/dist/backend/kiro-agent.d.ts +66 -0
  15. package/dist/backend/kiro-agent.js +302 -0
  16. package/dist/backend/kiro-agent.js.map +1 -0
  17. package/dist/backend/kiro-identity.d.ts +80 -0
  18. package/dist/backend/kiro-identity.js +537 -0
  19. package/dist/backend/kiro-identity.js.map +1 -0
  20. package/dist/backend/kiro-v2-store-worker.d.ts +1 -0
  21. package/dist/backend/kiro-v2-store-worker.js +87 -0
  22. package/dist/backend/kiro-v2-store-worker.js.map +1 -0
  23. package/dist/backend/kiro-v2-store.d.ts +54 -0
  24. package/dist/backend/kiro-v2-store.js +131 -0
  25. package/dist/backend/kiro-v2-store.js.map +1 -0
  26. package/dist/backend/kiro-v3-identity.d.ts +5 -0
  27. package/dist/backend/kiro-v3-identity.js +22 -0
  28. package/dist/backend/kiro-v3-identity.js.map +1 -1
  29. package/dist/backend/kiro.d.ts +83 -7
  30. package/dist/backend/kiro.js +418 -91
  31. package/dist/backend/kiro.js.map +1 -1
  32. package/dist/backend/types.d.ts +45 -3
  33. package/dist/backend/types.js.map +1 -1
  34. package/dist/channel/adapters/discord.d.ts +1 -0
  35. package/dist/channel/adapters/discord.js +29 -10
  36. package/dist/channel/adapters/discord.js.map +1 -1
  37. package/dist/channel/adapters/telegram.d.ts +1 -0
  38. package/dist/channel/adapters/telegram.js +13 -1
  39. package/dist/channel/adapters/telegram.js.map +1 -1
  40. package/dist/channel/types.d.ts +9 -1
  41. package/dist/classic-channel-manager.d.ts +18 -10
  42. package/dist/classic-channel-manager.js +45 -18
  43. package/dist/classic-channel-manager.js.map +1 -1
  44. package/dist/cli.js +225 -127
  45. package/dist/cli.js.map +1 -1
  46. package/dist/command-table.d.ts +5 -3
  47. package/dist/command-table.js +29 -27
  48. package/dist/command-table.js.map +1 -1
  49. package/dist/config-validator.js +46 -0
  50. package/dist/config-validator.js.map +1 -1
  51. package/dist/config.js +12 -0
  52. package/dist/config.js.map +1 -1
  53. package/dist/connection-secrets.d.ts +6 -0
  54. package/dist/connection-secrets.js +4 -0
  55. package/dist/connection-secrets.js.map +1 -1
  56. package/dist/daemon.d.ts +89 -4
  57. package/dist/daemon.js +661 -77
  58. package/dist/daemon.js.map +1 -1
  59. package/dist/darwin-memory.d.ts +6 -1
  60. package/dist/darwin-memory.js +17 -6
  61. package/dist/darwin-memory.js.map +1 -1
  62. package/dist/delivery-consumed-watch.d.ts +85 -0
  63. package/dist/delivery-consumed-watch.js +244 -0
  64. package/dist/delivery-consumed-watch.js.map +1 -0
  65. package/dist/delivery-outbox.d.ts +61 -0
  66. package/dist/delivery-outbox.js +120 -2
  67. package/dist/delivery-outbox.js.map +1 -1
  68. package/dist/delivery-reconciliation.d.ts +14 -5
  69. package/dist/delivery-reconciliation.js +27 -4
  70. package/dist/delivery-reconciliation.js.map +1 -1
  71. package/dist/delivery-reconciliation.test.js +35 -1
  72. package/dist/delivery-reconciliation.test.js.map +1 -1
  73. package/dist/event-loop-watch.d.ts +28 -0
  74. package/dist/event-loop-watch.js +75 -3
  75. package/dist/event-loop-watch.js.map +1 -1
  76. package/dist/fleet-context.d.ts +22 -2
  77. package/dist/fleet-level-config.d.ts +2 -2
  78. package/dist/fleet-level-config.js +6 -1
  79. package/dist/fleet-level-config.js.map +1 -1
  80. package/dist/fleet-manager.d.ts +293 -12
  81. package/dist/fleet-manager.js +2364 -449
  82. package/dist/fleet-manager.js.map +1 -1
  83. package/dist/host-memory.d.ts +4 -0
  84. package/dist/host-memory.js.map +1 -1
  85. package/dist/instance-config-impact.js +5 -0
  86. package/dist/instance-config-impact.js.map +1 -1
  87. package/dist/instance-lifecycle.d.ts +10 -5
  88. package/dist/instance-lifecycle.js +162 -53
  89. package/dist/instance-lifecycle.js.map +1 -1
  90. package/dist/locale.js +150 -16
  91. package/dist/locale.js.map +1 -1
  92. package/dist/login-controller.d.ts +2 -0
  93. package/dist/login-controller.js +17 -5
  94. package/dist/login-controller.js.map +1 -1
  95. package/dist/memory-pressure.d.ts +7 -8
  96. package/dist/memory-pressure.js +76 -15
  97. package/dist/memory-pressure.js.map +1 -1
  98. package/dist/monotonic-budget.d.ts +2 -0
  99. package/dist/monotonic-budget.js +28 -0
  100. package/dist/monotonic-budget.js.map +1 -0
  101. package/dist/needs-you-hub.d.ts +114 -0
  102. package/dist/needs-you-hub.js +370 -0
  103. package/dist/needs-you-hub.js.map +1 -0
  104. package/dist/needs-you-live.d.ts +116 -0
  105. package/dist/needs-you-live.js +228 -0
  106. package/dist/needs-you-live.js.map +1 -0
  107. package/dist/needs-you.d.ts +132 -0
  108. package/dist/needs-you.js +164 -0
  109. package/dist/needs-you.js.map +1 -0
  110. package/dist/node-version-guard.d.ts +30 -0
  111. package/dist/node-version-guard.js +50 -0
  112. package/dist/node-version-guard.js.map +1 -0
  113. package/dist/operator-control-paths.d.ts +4 -0
  114. package/dist/operator-control-paths.js +24 -0
  115. package/dist/operator-control-paths.js.map +1 -0
  116. package/dist/outbound-handlers.d.ts +2 -0
  117. package/dist/outbound-handlers.js +9 -2
  118. package/dist/outbound-handlers.js.map +1 -1
  119. package/dist/outbound-schemas.d.ts +5 -5
  120. package/dist/profile-control.js +4 -20
  121. package/dist/profile-control.js.map +1 -1
  122. package/dist/public-web-gateway.d.ts +18 -0
  123. package/dist/public-web-gateway.js +141 -0
  124. package/dist/public-web-gateway.js.map +1 -0
  125. package/dist/public-web-link.d.ts +53 -0
  126. package/dist/public-web-link.js +175 -0
  127. package/dist/public-web-link.js.map +1 -0
  128. package/dist/quickstart-api.d.ts +8 -1
  129. package/dist/quickstart-api.js +86 -48
  130. package/dist/quickstart-api.js.map +1 -1
  131. package/dist/quickstart.d.ts +1 -0
  132. package/dist/quickstart.js +6 -2
  133. package/dist/quickstart.js.map +1 -1
  134. package/dist/scheduler/db.d.ts +7 -1
  135. package/dist/scheduler/db.js +38 -0
  136. package/dist/scheduler/db.js.map +1 -1
  137. package/dist/scheduler/index.d.ts +1 -1
  138. package/dist/scheduler/retry-label.d.ts +11 -0
  139. package/dist/scheduler/retry-label.js +24 -0
  140. package/dist/scheduler/retry-label.js.map +1 -0
  141. package/dist/scheduler/scheduler.d.ts +55 -2
  142. package/dist/scheduler/scheduler.js +220 -8
  143. package/dist/scheduler/scheduler.js.map +1 -1
  144. package/dist/scheduler/types.d.ts +22 -0
  145. package/dist/scheduler/types.js.map +1 -1
  146. package/dist/secret-store.d.ts +5 -0
  147. package/dist/secret-store.js +20 -0
  148. package/dist/secret-store.js.map +1 -1
  149. package/dist/service-activation.d.ts +110 -0
  150. package/dist/service-activation.js +302 -0
  151. package/dist/service-activation.js.map +1 -0
  152. package/dist/service-installer.d.ts +7 -0
  153. package/dist/service-installer.js +7 -4
  154. package/dist/service-installer.js.map +1 -1
  155. package/dist/service-restart-selection.d.ts +6 -5
  156. package/dist/service-restart-selection.js +6 -5
  157. package/dist/service-restart-selection.js.map +1 -1
  158. package/dist/settings-api.d.ts +10 -2
  159. package/dist/settings-api.js +175 -72
  160. package/dist/settings-api.js.map +1 -1
  161. package/dist/settings-baseline.d.ts +20 -0
  162. package/dist/settings-baseline.js +104 -0
  163. package/dist/settings-baseline.js.map +1 -0
  164. package/dist/settings-change.d.ts +21 -0
  165. package/dist/settings-change.js +133 -0
  166. package/dist/settings-change.js.map +1 -0
  167. package/dist/settings-confirmation.d.ts +105 -0
  168. package/dist/settings-confirmation.js +232 -0
  169. package/dist/settings-confirmation.js.map +1 -0
  170. package/dist/settings-control.d.ts +41 -0
  171. package/dist/settings-control.js +294 -0
  172. package/dist/settings-control.js.map +1 -0
  173. package/dist/settings-effect.d.ts +24 -0
  174. package/dist/settings-effect.js +169 -0
  175. package/dist/settings-effect.js.map +1 -0
  176. package/dist/settings-http-confirmation.d.ts +29 -0
  177. package/dist/settings-http-confirmation.js +123 -0
  178. package/dist/settings-http-confirmation.js.map +1 -0
  179. package/dist/settings-instance-patch.d.ts +4 -0
  180. package/dist/settings-instance-patch.js +26 -0
  181. package/dist/settings-instance-patch.js.map +1 -0
  182. package/dist/settings-request-capability.d.ts +16 -0
  183. package/dist/settings-request-capability.js +32 -0
  184. package/dist/settings-request-capability.js.map +1 -0
  185. package/dist/settings-transaction.d.ts +65 -0
  186. package/dist/settings-transaction.js +223 -0
  187. package/dist/settings-transaction.js.map +1 -0
  188. package/dist/setup-auth.d.ts +10 -18
  189. package/dist/setup-auth.js +14 -38
  190. package/dist/setup-auth.js.map +1 -1
  191. package/dist/setup-form.d.ts +1 -1
  192. package/dist/setup-form.js +75 -18
  193. package/dist/setup-form.js.map +1 -1
  194. package/dist/setup-guide.d.ts +13 -0
  195. package/dist/setup-guide.js +25 -0
  196. package/dist/setup-guide.js.map +1 -0
  197. package/dist/setup-host.d.ts +16 -0
  198. package/dist/setup-host.js +197 -32
  199. package/dist/setup-host.js.map +1 -1
  200. package/dist/setup-wizard.js +3 -0
  201. package/dist/setup-wizard.js.map +1 -1
  202. package/dist/slash-authz.d.ts +17 -3
  203. package/dist/slash-authz.js +5 -0
  204. package/dist/slash-authz.js.map +1 -1
  205. package/dist/spawn-gate.js +3 -3
  206. package/dist/spawn-gate.js.map +1 -1
  207. package/dist/statusline-watcher.d.ts +5 -0
  208. package/dist/statusline-watcher.js +2 -0
  209. package/dist/statusline-watcher.js.map +1 -1
  210. package/dist/steer-capability.d.ts +6 -0
  211. package/dist/steer-capability.js +8 -0
  212. package/dist/steer-capability.js.map +1 -1
  213. package/dist/sync-work-attribution.d.ts +14 -0
  214. package/dist/sync-work-attribution.js +43 -8
  215. package/dist/sync-work-attribution.js.map +1 -1
  216. package/dist/tips.js +10 -5
  217. package/dist/tips.js.map +1 -1
  218. package/dist/tmux-control.d.ts +35 -5
  219. package/dist/tmux-control.js +291 -57
  220. package/dist/tmux-control.js.map +1 -1
  221. package/dist/tmux-manager.d.ts +20 -6
  222. package/dist/tmux-manager.js +90 -47
  223. package/dist/tmux-manager.js.map +1 -1
  224. package/dist/tmux-read.d.ts +59 -0
  225. package/dist/tmux-read.js +213 -0
  226. package/dist/tmux-read.js.map +1 -0
  227. package/dist/topic-commands.d.ts +21 -10
  228. package/dist/topic-commands.js +191 -58
  229. package/dist/topic-commands.js.map +1 -1
  230. package/dist/transcript-delta-reader.js +2 -1
  231. package/dist/transcript-delta-reader.js.map +1 -1
  232. package/dist/tunnel/cloudflared-install.d.ts +2 -0
  233. package/dist/tunnel/cloudflared-install.js +1 -1
  234. package/dist/tunnel/cloudflared-install.js.map +1 -1
  235. package/dist/tunnel/purpose-lane.d.ts +14 -0
  236. package/dist/tunnel/purpose-lane.js +43 -0
  237. package/dist/tunnel/purpose-lane.js.map +1 -0
  238. package/dist/turn-reply-guard.d.ts +2 -0
  239. package/dist/turn-reply-guard.js +10 -1
  240. package/dist/turn-reply-guard.js.map +1 -1
  241. package/dist/types.d.ts +33 -0
  242. package/dist/ui/app.html +18 -0
  243. package/dist/ui/chat-render.js +478 -0
  244. package/dist/ui/chat-store.js +289 -0
  245. package/dist/ui/chat-strings.js +69 -0
  246. package/dist/ui/chat-thread.js +209 -0
  247. package/dist/ui/chat-tour.js +116 -0
  248. package/dist/ui/fleet-org.js +142 -0
  249. package/dist/ui/panel-chat.js +418 -0
  250. package/dist/ui/panel-fleet.js +413 -0
  251. package/dist/ui/panel-needs.js +202 -0
  252. package/dist/ui/panel-settings.js +750 -0
  253. package/dist/ui/preview.js +266 -0
  254. package/dist/ui/settings-apply.js +239 -0
  255. package/dist/ui/settings-confirm.js +186 -0
  256. package/dist/ui/settings-dialogs.js +546 -0
  257. package/dist/ui/settings-model.js +277 -0
  258. package/dist/ui/settings-strings.js +652 -0
  259. package/dist/ui/settings-wizard.js +140 -0
  260. package/dist/ui/shared/agend-auth.js +93 -0
  261. package/dist/ui/shared/app-ctx.js +80 -0
  262. package/dist/ui/shared/app-html.js +9 -0
  263. package/dist/ui/shared/app-i18n.js +95 -0
  264. package/dist/ui/shared/app-nav.js +73 -0
  265. package/dist/ui/shared/app-needs.js +114 -0
  266. package/dist/ui/shared/app-route.js +73 -0
  267. package/dist/ui/shared/app-session.js +66 -0
  268. package/dist/ui/shared/app-shell.js +344 -0
  269. package/dist/ui/shared/app-store.js +51 -0
  270. package/dist/ui/shared/app-stream.js +201 -0
  271. package/dist/ui/shared/app.css +676 -0
  272. package/dist/ui/shared/app.js +88 -0
  273. package/dist/ui/shared/fonts/OFL.txt +92 -0
  274. package/dist/ui/shared/fonts/README.md +21 -0
  275. package/dist/ui/shared/fonts/inter.woff2 +0 -0
  276. package/dist/ui/shared/htm.module.js +1 -0
  277. package/dist/ui/shared/panel-view.js +655 -0
  278. package/dist/ui/shared/preact-hooks.module.js +2 -0
  279. package/dist/ui/shared/preact.module.js +2 -0
  280. package/dist/ui/shared/signin.js +130 -0
  281. package/dist/ui/shared/theme.js +29 -0
  282. package/dist/ui/shared/tokens.css +153 -0
  283. package/dist/ui/shared/ui-confirm.js +43 -0
  284. package/dist/ui/shared/ui-dialog.js +45 -0
  285. package/dist/ui/shared/ui-icons.js +61 -0
  286. package/dist/ui/shared/ui-menu.js +39 -0
  287. package/dist/ui/shared/ui-states.js +20 -0
  288. package/dist/ui/shared/ui-toast.js +18 -0
  289. package/dist/ui/shared/vendor/htm.LICENSE +202 -0
  290. package/dist/ui/shared/vendor/preact.LICENSE +21 -0
  291. package/dist/ui/shared/vendor/vendor.json +39 -0
  292. package/dist/ui/shared/view-strings.js +309 -0
  293. package/dist/ui/signin.html +51 -0
  294. package/dist/update-check.d.ts +6 -2
  295. package/dist/update-check.js +12 -3
  296. package/dist/update-check.js.map +1 -1
  297. package/dist/update-install.d.ts +71 -0
  298. package/dist/update-install.js +162 -0
  299. package/dist/update-install.js.map +1 -0
  300. package/dist/upgrade-notices.d.ts +17 -0
  301. package/dist/upgrade-notices.js +93 -0
  302. package/dist/upgrade-notices.js.map +1 -0
  303. package/dist/usage/statusline-usage.d.ts +2 -0
  304. package/dist/usage/statusline-usage.js +14 -10
  305. package/dist/usage/statusline-usage.js.map +1 -1
  306. package/dist/view-api.d.ts +6 -1
  307. package/dist/view-api.js +62 -51
  308. package/dist/view-api.js.map +1 -1
  309. package/dist/web-api.d.ts +71 -14
  310. package/dist/web-api.js +492 -77
  311. package/dist/web-api.js.map +1 -1
  312. package/dist/web-auth.d.ts +71 -27
  313. package/dist/web-auth.js +169 -69
  314. package/dist/web-auth.js.map +1 -1
  315. package/dist/web-body.d.ts +3 -0
  316. package/dist/web-body.js +55 -0
  317. package/dist/web-body.js.map +1 -0
  318. package/dist/web-channel-echo.d.ts +9 -0
  319. package/dist/web-channel-echo.js +55 -0
  320. package/dist/web-channel-echo.js.map +1 -0
  321. package/dist/web-chat-history.d.ts +125 -0
  322. package/dist/web-chat-history.js +184 -0
  323. package/dist/web-chat-history.js.map +1 -0
  324. package/dist/web-continuation.d.ts +7 -0
  325. package/dist/web-continuation.js +22 -0
  326. package/dist/web-continuation.js.map +1 -0
  327. package/dist/web-host-guard.d.ts +34 -0
  328. package/dist/web-host-guard.js +57 -1
  329. package/dist/web-host-guard.js.map +1 -1
  330. package/dist/web-login.d.ts +72 -0
  331. package/dist/web-login.js +132 -0
  332. package/dist/web-login.js.map +1 -0
  333. package/dist/web-org.d.ts +55 -0
  334. package/dist/web-org.js +67 -0
  335. package/dist/web-org.js.map +1 -0
  336. package/dist/web-preview.d.ts +77 -0
  337. package/dist/web-preview.js +240 -0
  338. package/dist/web-preview.js.map +1 -0
  339. package/dist/web-request-context.d.ts +10 -0
  340. package/dist/web-request-context.js +13 -0
  341. package/dist/web-request-context.js.map +1 -0
  342. package/dist/web-session.d.ts +167 -0
  343. package/dist/web-session.js +389 -0
  344. package/dist/web-session.js.map +1 -0
  345. package/dist/web-shell-routes.d.ts +59 -0
  346. package/dist/web-shell-routes.js +96 -0
  347. package/dist/web-shell-routes.js.map +1 -0
  348. package/dist/web-upload.d.ts +183 -0
  349. package/dist/web-upload.js +468 -0
  350. package/dist/web-upload.js.map +1 -0
  351. package/dist/website-tips-renderer.d.ts +2 -2
  352. package/dist/website-tips-renderer.js +3 -3
  353. package/dist/website-tips-renderer.js.map +1 -1
  354. package/package.json +8 -5
  355. package/scripts/preinstall-guard.cjs +36 -0
  356. package/dist/ui/dashboard.html +0 -774
  357. package/dist/ui/settings.html +0 -2165
  358. package/dist/ui/view.html +0 -1139
@@ -0,0 +1,123 @@
1
+ import { ServerResponse as Response } from "node:http";
2
+ import { readBoundedWebBody } from "./web-body.js";
3
+ import { requestSessionBinding } from "./connection-secrets.js";
4
+ import { cacheSettingsBody, createSettingsReplay, settingsRequestExecution } from "./settings-request-capability.js";
5
+ import { prepareSettingsEffect, isSettingsMutation } from "./settings-effect.js";
6
+ import { SettingsConfirmationError } from "./settings-confirmation.js";
7
+ import { SettingsExecution, settingsFingerprint } from "./settings-transaction.js";
8
+ function json(res, status, body) {
9
+ if (res.destroyed || res.headersSent)
10
+ return;
11
+ res.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
12
+ res.end(JSON.stringify(body));
13
+ }
14
+ /** The same server-side gate serves a running fleet and the no-fleet SetupHost. */
15
+ export class SettingsHttpConfirmation {
16
+ store;
17
+ options;
18
+ passed = new WeakSet();
19
+ constructor(store, options) {
20
+ this.store = store;
21
+ this.options = options;
22
+ }
23
+ handle(req, res, url, next) {
24
+ if (settingsRequestExecution(req) || this.passed.has(req))
25
+ return false;
26
+ const path = url.pathname, method = req.method ?? "GET";
27
+ const pending = path.match(/^\/api\/settings\/pending(?:\/([0-9a-f]{32}))?$/);
28
+ if (pending && (method === "GET" || method === "DELETE" && pending[1])) {
29
+ const principal = this.options.principal(req);
30
+ if (!principal?.current()) {
31
+ json(res, 401, { error: "session_required" });
32
+ return true;
33
+ }
34
+ const result = pending[1] ? method === "DELETE" ? this.store.withdraw(pending[1], principal.id) : this.store.get(pending[1], principal.id) : this.store.list(principal.id);
35
+ json(res, result === null ? 404 : 200, result === null ? { error: "not_found" } : result);
36
+ return true;
37
+ }
38
+ if (!isSettingsMutation(method, path))
39
+ return false;
40
+ void this.prepare(req, res, url, next).catch(err => json(res, err instanceof SettingsConfirmationError ? err.status : 409, { error: err instanceof SettingsConfirmationError ? err.code : "settings_confirmation_unavailable" }));
41
+ return true;
42
+ }
43
+ async prepare(req, res, url, next) {
44
+ const method = req.method ?? "POST", raw = method === "DELETE" ? Buffer.from("{}") : await readBoundedWebBody(req, 512 * 1024);
45
+ if (res.destroyed || req.aborted)
46
+ return;
47
+ let body;
48
+ try {
49
+ body = JSON.parse(raw.toString("utf8") || "{}");
50
+ }
51
+ catch {
52
+ throw new SettingsConfirmationError(400, "invalid_json");
53
+ }
54
+ const principal = this.options.principal(req);
55
+ const key = typeof req.headers["idempotency-key"] === "string" ? req.headers["idempotency-key"]
56
+ : body && typeof body === "object" && typeof body.idempotency_key === "string" ? body.idempotency_key : undefined;
57
+ const requestFingerprint = settingsFingerprint([method, url.pathname, body]);
58
+ if (principal?.current() && key) {
59
+ const prior = this.store.findRequest(principal.id, key, requestFingerprint);
60
+ if (prior) {
61
+ json(res, 202, { ok: true, result: "pending_confirmation", pending_change: prior });
62
+ return;
63
+ }
64
+ }
65
+ const baseline = await this.options.baseline();
66
+ if (res.destroyed || req.aborted)
67
+ return;
68
+ const classifiedSnapshot = settingsFingerprint(this.options.snapshot());
69
+ const effect = prepareSettingsEffect(method, url.pathname, body, baseline, requestSessionBinding(req), key);
70
+ if (!effect.diff) {
71
+ const execution = new SettingsExecution({ current: () => principal ? principal.current() : true,
72
+ snapshot: () => this.options.snapshot(), expectedFingerprint: classifiedSnapshot });
73
+ res.once?.("finish", () => execution.close());
74
+ res.once?.("close", () => execution.cancel());
75
+ this.passed.add(req);
76
+ cacheSettingsBody(req, raw, execution, requestSessionBinding(req));
77
+ next(req, res, url);
78
+ return;
79
+ }
80
+ if (!principal?.current())
81
+ throw new SettingsConfirmationError(401, "session_required");
82
+ const binding = requestSessionBinding(req), snapshot = settingsFingerprint(this.options.snapshot());
83
+ const payload = { method, url: url.pathname + url.search, key, body: Buffer.from(raw), binding };
84
+ const result = this.store.propose({ session: principal.id, key: key ?? `operation:${requestFingerprint}`,
85
+ requestFingerprint, fingerprint: effect.diff.fingerprint, section: effect.diff.section, requestedBy: principal.label,
86
+ source: principal.source, summary: effect.diff.summary, affectedConnections: effect.diff.affectedConnections,
87
+ bytes: raw.length, remainingMs: effect.proof?.remainingMs,
88
+ current: () => principal.current(), snapshot: () => this.options.snapshot(),
89
+ unchanged: async () => (await this.options.baseline()).fingerprint === baseline.fingerprint && settingsFingerprint(this.options.snapshot()) === snapshot,
90
+ apply: async (_current, execution) => {
91
+ // Recheck after replay/body/queue awaits in the real handler and actual job.
92
+ execution.assert();
93
+ const replay = createSettingsReplay(payload, execution);
94
+ const response = await new Promise((yes, no) => {
95
+ const collector = new Response(replay);
96
+ collector.end = ((chunk) => {
97
+ try {
98
+ yes({ status: collector.statusCode, body: JSON.parse(String(chunk ?? "{}")) });
99
+ }
100
+ catch {
101
+ no(new Error("invalid_apply_response"));
102
+ }
103
+ return collector;
104
+ });
105
+ try {
106
+ if (!next(replay, collector, new URL(payload.url, "http://localhost")))
107
+ no(new Error("unsupported_apply"));
108
+ }
109
+ catch (err) {
110
+ no(err);
111
+ }
112
+ });
113
+ if (response.status >= 400)
114
+ throw new Error("apply_rejected");
115
+ if (response.body.job_id && (!this.options.job || !await this.options.job(response.body.job_id)))
116
+ throw new Error("apply_job_failed");
117
+ await this.options.applied?.(url.pathname, response.body, execution);
118
+ return response.body;
119
+ }, discard: () => { payload.body.fill(0); effect.proof?.discard(); }, });
120
+ json(res, 202, { ok: true, result: "pending_confirmation", pending_change: result.view });
121
+ }
122
+ }
123
+ //# sourceMappingURL=settings-http-confirmation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-http-confirmation.js","sourceRoot":"","sources":["../src/settings-http-confirmation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const NULLABLE_INSTANCE_OVERRIDES: Set<string>;
2
+ export declare function removesInstanceOverride(key: string, value: unknown): boolean;
3
+ /** Projection and persistence share exactly the same null/inheritance rules. */
4
+ export declare function normalizeSettingsInstancePatch(base: Record<string, any>, patch: Record<string, any>): Record<string, any>;
@@ -0,0 +1,26 @@
1
+ import { SettingsConfirmationError } from "./settings-confirmation.js";
2
+ export const NULLABLE_INSTANCE_OVERRIDES = new Set(["model", "auto_pause_after", "hang_detector", "agent_mode", "tool_set", "tool_progress", "reply_completion_guard", "log_level", "lightweight", "model_failover", "display_name", "status_emojis", "cross_instance_visibility"]);
3
+ export function removesInstanceOverride(key, value) {
4
+ return NULLABLE_INSTANCE_OVERRIDES.has(key) && (value === null || key === "model" && typeof value === "string" && value.trim() === "");
5
+ }
6
+ /** Projection and persistence share exactly the same null/inheritance rules. */
7
+ export function normalizeSettingsInstancePatch(base, patch) {
8
+ for (const [key, value] of Object.entries(patch))
9
+ if (value === null && !NULLABLE_INSTANCE_OVERRIDES.has(key))
10
+ throw new SettingsConfirmationError(400, "unsupported_instance_null");
11
+ const next = { ...base, ...patch };
12
+ if (patch.hang_detector && typeof patch.hang_detector === "object" && !Array.isArray(patch.hang_detector)) {
13
+ const hang = { ...base.hang_detector, ...patch.hang_detector };
14
+ if (patch.hang_detector.timeout_minutes === null)
15
+ delete hang.timeout_minutes;
16
+ if (Object.keys(hang).length)
17
+ next.hang_detector = hang;
18
+ else
19
+ delete next.hang_detector;
20
+ }
21
+ for (const key of NULLABLE_INSTANCE_OVERRIDES)
22
+ if (removesInstanceOverride(key, patch[key]))
23
+ delete next[key];
24
+ return next;
25
+ }
26
+ //# sourceMappingURL=settings-instance-patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-instance-patch.js","sourceRoot":"","sources":["../src/settings-instance-patch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,wBAAwB,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,2BAA2B,CAAC,CAAC,CAAC;AACpR,MAAM,UAAU,uBAAuB,CAAC,GAAW,EAAE,KAAc;IACjE,OAAO,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,GAAG,KAAK,OAAO,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACzI,CAAC;AACD,gFAAgF;AAChF,MAAM,UAAU,8BAA8B,CAAC,IAAyB,EAAE,KAA0B;IAClG,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,yBAAyB,CAAC,GAAG,EAAE,2BAA2B,CAAC,CAAC;IACrL,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,aAAa,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1G,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;QAC/D,IAAI,KAAK,CAAC,aAAa,CAAC,eAAe,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9E,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM;YAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;;YAAM,OAAO,IAAI,CAAC,aAAa,CAAC;IAC1F,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,2BAA2B;QAAE,IAAI,uBAAuB,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9G,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { IncomingMessage } from "node:http";
2
+ import type { SettingsExecution } from "./settings-transaction.js";
3
+ export declare function isSettingsReplay(req: object): boolean;
4
+ /** Only server code creates a replay; bearer cookies/tokens are never replayed. */
5
+ export declare function createSettingsReplay(input: {
6
+ method: string;
7
+ url: string;
8
+ key?: string;
9
+ body: Buffer;
10
+ binding: string;
11
+ }, execution: SettingsExecution): IncomingMessage;
12
+ export declare function settingsRequestExecution(req: object): SettingsExecution | undefined;
13
+ export declare function settingsRequestBinding(req: object): string | undefined;
14
+ export declare function cacheSettingsBody(req: object, body: Buffer, execution?: SettingsExecution, binding?: string): void;
15
+ export declare function cachedSettingsBody(req: object): Buffer | undefined;
16
+ export declare function settingsWrite<T>(req: object, effect: () => T, final?: boolean): T;
@@ -0,0 +1,32 @@
1
+ import { Readable } from "node:stream";
2
+ const continuations = new WeakMap();
3
+ const bodies = new WeakMap();
4
+ const replays = new WeakSet();
5
+ export function isSettingsReplay(req) { return replays.has(req); }
6
+ /** Only server code creates a replay; bearer cookies/tokens are never replayed. */
7
+ export function createSettingsReplay(input, execution) {
8
+ const req = Readable.from([]);
9
+ req.method = input.method;
10
+ req.url = input.url;
11
+ replays.add(req);
12
+ req.headers = input.key ? { "idempotency-key": input.key } : {};
13
+ continuations.set(req, { body: Buffer.from(input.body), execution, binding: input.binding });
14
+ return req;
15
+ }
16
+ export function settingsRequestExecution(req) { return continuations.get(req)?.execution; }
17
+ export function settingsRequestBinding(req) { return continuations.get(req)?.binding; }
18
+ export function cacheSettingsBody(req, body, execution, binding = "") {
19
+ if (execution)
20
+ continuations.set(req, { body: Buffer.from(body), execution, binding });
21
+ else
22
+ bodies.set(req, Buffer.from(body));
23
+ }
24
+ export function cachedSettingsBody(req) {
25
+ const body = continuations.get(req)?.body ?? bodies.get(req);
26
+ return body ? Buffer.from(body) : undefined;
27
+ }
28
+ export function settingsWrite(req, effect, final = true) {
29
+ const execution = settingsRequestExecution(req);
30
+ return execution ? final ? execution.commit(effect) : execution.mutate(effect) : effect();
31
+ }
32
+ //# sourceMappingURL=settings-request-capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-request-capability.js","sourceRoot":"","sources":["../src/settings-request-capability.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,MAAM,aAAa,GAAG,IAAI,OAAO,EAAwB,CAAC;AAC1D,MAAM,MAAM,GAAG,IAAI,OAAO,EAAkB,CAAC;AAC7C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAU,CAAC;AACtC,MAAM,UAAU,gBAAgB,CAAC,GAAW,IAAa,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACnF,mFAAmF;AACnF,MAAM,UAAU,oBAAoB,CAAC,KAAmF,EAAE,SAA4B;IACpJ,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAA+B,CAAC;IAC5D,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAAC,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjE,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7F,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,UAAU,wBAAwB,CAAC,GAAW,IAAmC,OAAO,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AAClI,MAAM,UAAU,sBAAsB,CAAC,GAAW,IAAwB,OAAO,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AACnH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,IAAY,EAAE,SAA6B,EAAE,OAAO,GAAG,EAAE;IACtG,IAAI,SAAS;QAAE,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;;QAClF,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5G,CAAC;AACD,MAAM,UAAU,aAAa,CAAI,GAAW,EAAE,MAAe,EAAE,KAAK,GAAG,IAAI;IACzE,MAAM,SAAS,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAChD,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AAC5F,CAAC"}
@@ -0,0 +1,65 @@
1
+ export declare const SETTINGS_OPERATION_MS = 60000;
2
+ export declare class SettingsExecutionError extends Error {
3
+ readonly code: string;
4
+ constructor(code: string);
5
+ }
6
+ export declare function settingsFingerprint(value: unknown): string;
7
+ export declare function settingsRevision(path: string): number;
8
+ /** All in-process writers, including ordinary edits, record before replacement. */
9
+ export declare function noteSettingsWrite(path: string, before: unknown, after: unknown): void;
10
+ export interface SettingsUndo {
11
+ path: readonly string[];
12
+ before: unknown;
13
+ written: unknown;
14
+ revision: number;
15
+ }
16
+ export declare function settingsUndo(path: string, before: unknown, written: unknown, fields: readonly (readonly string[])[]): SettingsUndo[];
17
+ /** Preserve concurrent edits and ABA writes; never restore a whole stale document. */
18
+ export declare function undoSettingsPaths(path: string, current: unknown, undo: readonly SettingsUndo[]): {
19
+ value: any;
20
+ conflicts: boolean;
21
+ };
22
+ export interface SettingsLease {
23
+ readonly owner: symbol;
24
+ readonly keys: readonly string[];
25
+ release(): void;
26
+ }
27
+ export declare function settingsFileResource(path: string): string;
28
+ export declare function settingsLeaseBusy(key: string): boolean;
29
+ export declare function assertSettingsLease(key: string, owner?: symbol): void;
30
+ /** Atomic reservation of the complete resource set; helpers reuse the same owner. */
31
+ export declare function trySettingsLease(keys: readonly string[], owner?: symbol): SettingsLease | null;
32
+ /** A server-created continuation; never reconstructed from headers or payload. */
33
+ export declare class SettingsExecution {
34
+ private readonly options;
35
+ readonly owner: symbol;
36
+ private expected;
37
+ private deadline;
38
+ private cancelled;
39
+ private committed;
40
+ private timer;
41
+ constructor(options: {
42
+ current(): boolean;
43
+ snapshot(): unknown;
44
+ now?: () => number;
45
+ expectedFingerprint?: string;
46
+ progress?(phase: "queued" | "running" | "cleanup", reason?: string): void;
47
+ });
48
+ private now;
49
+ current(): boolean;
50
+ assert(): void;
51
+ /** No await is permitted between the check, mutation, and expected-state update. */
52
+ mutate<T>(effect: () => T): T;
53
+ /** Place a self-revoking effect last; its receipt authorizes settlement only. */
54
+ commit<T>(effect: () => T): T;
55
+ complete(): void;
56
+ get deadlineAt(): number;
57
+ get remainingMs(): number;
58
+ get completed(): boolean;
59
+ cancel(): void;
60
+ close(): void;
61
+ }
62
+ /** Wait for physical cleanup, with a bounded admission deadline and no polling. */
63
+ export declare function waitSettingsLease(keys: readonly string[], current: () => boolean, deadline: number, owner?: symbol): Promise<SettingsLease>;
64
+ /** Apply only this writer's delta to the latest document, retaining unrelated fields. */
65
+ export declare function mergeSettingsDelta(before: any, after: any, current: any): any;
@@ -0,0 +1,223 @@
1
+ import { createHash } from "node:crypto";
2
+ import { dirname, resolve, basename } from "node:path";
3
+ import { realpathSync } from "node:fs";
4
+ import { performance } from "node:perf_hooks";
5
+ export const SETTINGS_OPERATION_MS = 60_000;
6
+ export class SettingsExecutionError extends Error {
7
+ code;
8
+ constructor(code) {
9
+ super(code);
10
+ this.code = code;
11
+ }
12
+ }
13
+ export function settingsFingerprint(value) {
14
+ return createHash("sha256").update((JSON.stringify(value, (_key, item) => item && typeof item === "object" && !Array.isArray(item)
15
+ ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b))) : item) ?? "undefined")).digest("hex");
16
+ }
17
+ function canonicalPath(path) {
18
+ const full = resolve(path);
19
+ try {
20
+ return realpathSync(full);
21
+ }
22
+ catch { /* a future file still has one identity */ }
23
+ try {
24
+ return resolve(realpathSync(dirname(full)), basename(full));
25
+ }
26
+ catch {
27
+ return full;
28
+ }
29
+ }
30
+ // Process-wide: stop/start never revives an old lease or revision ticket.
31
+ const journals = new Map();
32
+ function journal(path) {
33
+ const key = canonicalPath(path);
34
+ let value = journals.get(key);
35
+ if (!value) {
36
+ value = { epoch: 0, next: 0, revisions: new Map() };
37
+ journals.set(key, value);
38
+ }
39
+ return value;
40
+ }
41
+ export function settingsRevision(path) { return journal(path).epoch; }
42
+ function leaves(value, path = [], result = new Map()) {
43
+ if (value && typeof value === "object" && Object.keys(value).length) {
44
+ for (const [key, child] of Object.entries(value))
45
+ leaves(child, [...path, key], result);
46
+ }
47
+ else
48
+ result.set(JSON.stringify(path), value);
49
+ return result;
50
+ }
51
+ /** All in-process writers, including ordinary edits, record before replacement. */
52
+ export function noteSettingsWrite(path, before, after) {
53
+ const state = journal(path), old = leaves(before), next = leaves(after);
54
+ state.epoch++;
55
+ for (const key of new Set([...old.keys(), ...next.keys()])) {
56
+ if (settingsFingerprint(old.get(key)) !== settingsFingerprint(next.get(key))) {
57
+ const parts = JSON.parse(key);
58
+ for (let depth = 0; depth <= parts.length; depth++)
59
+ state.revisions.set(JSON.stringify(parts.slice(0, depth)), ++state.next);
60
+ }
61
+ }
62
+ }
63
+ function getPath(value, path) {
64
+ for (const key of path)
65
+ value = value != null && Object.hasOwn(value, key) ? value[key] : undefined;
66
+ return value;
67
+ }
68
+ function setPath(value, path, next) {
69
+ for (const key of path.slice(0, -1)) {
70
+ if (!Object.hasOwn(value, key) || !value[key] || typeof value[key] !== "object")
71
+ Object.defineProperty(value, key, { value: {}, writable: true, enumerable: true, configurable: true });
72
+ value = value[key];
73
+ }
74
+ if (next === undefined)
75
+ delete value[path.at(-1)];
76
+ else
77
+ Object.defineProperty(value, path.at(-1), { value: structuredClone(next), writable: true, enumerable: true, configurable: true });
78
+ }
79
+ export function settingsUndo(path, before, written, fields) {
80
+ return fields.map(field => ({ path: [...field], before: structuredClone(getPath(before, field)),
81
+ written: structuredClone(getPath(written, field)), revision: journal(path).revisions.get(JSON.stringify(field)) ?? 0 }));
82
+ }
83
+ /** Preserve concurrent edits and ABA writes; never restore a whole stale document. */
84
+ export function undoSettingsPaths(path, current, undo) {
85
+ const value = structuredClone(current), state = journal(path);
86
+ let conflicts = false;
87
+ for (const item of undo) {
88
+ if ((state.revisions.get(JSON.stringify(item.path)) ?? 0) !== item.revision
89
+ || settingsFingerprint(getPath(current, item.path)) !== settingsFingerprint(item.written)) {
90
+ conflicts = true;
91
+ continue;
92
+ }
93
+ setPath(value, item.path, item.before);
94
+ }
95
+ return { value, conflicts };
96
+ }
97
+ const leases = new Map();
98
+ const leaseWaiters = new Set();
99
+ export function settingsFileResource(path) { return `file:${canonicalPath(path)}`; }
100
+ export function settingsLeaseBusy(key) { return leases.has(key); }
101
+ export function assertSettingsLease(key, owner) {
102
+ const held = leases.get(key);
103
+ if (held && held.owner !== owner)
104
+ throw new SettingsExecutionError("settings_resource_busy");
105
+ }
106
+ /** Atomic reservation of the complete resource set; helpers reuse the same owner. */
107
+ export function trySettingsLease(keys, owner = Symbol("settings-operation")) {
108
+ const ordered = [...new Set(keys)].sort();
109
+ if (ordered.some(key => leases.has(key) && leases.get(key)?.owner !== owner))
110
+ return null;
111
+ for (const key of ordered) {
112
+ const held = leases.get(key);
113
+ leases.set(key, { owner, count: (held?.count ?? 0) + 1 });
114
+ }
115
+ let released = false;
116
+ return { owner, keys: ordered, release() {
117
+ if (released)
118
+ return;
119
+ released = true;
120
+ for (const key of ordered) {
121
+ const held = leases.get(key);
122
+ if (held?.owner !== owner)
123
+ continue;
124
+ if (--held.count === 0)
125
+ leases.delete(key);
126
+ }
127
+ for (const notify of [...leaseWaiters])
128
+ notify();
129
+ } };
130
+ }
131
+ /** A server-created continuation; never reconstructed from headers or payload. */
132
+ export class SettingsExecution {
133
+ options;
134
+ owner = Symbol("settings-execution");
135
+ expected;
136
+ deadline;
137
+ cancelled = false;
138
+ committed = false;
139
+ timer;
140
+ constructor(options) {
141
+ this.options = options;
142
+ this.expected = options.expectedFingerprint ?? settingsFingerprint(options.snapshot());
143
+ this.deadline = this.now() + SETTINGS_OPERATION_MS;
144
+ this.timer = setTimeout(() => { this.cancelled = true; options.progress?.("cleanup", "operation_timed_out"); }, SETTINGS_OPERATION_MS);
145
+ this.timer.unref?.();
146
+ options.progress?.("queued");
147
+ }
148
+ now() { return this.options.now?.() ?? performance.now(); }
149
+ current() {
150
+ return !this.cancelled && !this.committed && this.now() < this.deadline && this.options.current()
151
+ && this.expected === settingsFingerprint(this.options.snapshot());
152
+ }
153
+ assert() { if (!this.current())
154
+ throw new SettingsExecutionError("settings_execution_stale"); }
155
+ /** No await is permitted between the check, mutation, and expected-state update. */
156
+ mutate(effect) {
157
+ this.assert();
158
+ this.options.progress?.("running");
159
+ try {
160
+ return effect();
161
+ }
162
+ finally {
163
+ this.expected = settingsFingerprint(this.options.snapshot());
164
+ }
165
+ }
166
+ /** Place a self-revoking effect last; its receipt authorizes settlement only. */
167
+ commit(effect) {
168
+ const result = this.mutate(effect);
169
+ this.committed = true;
170
+ clearTimeout(this.timer);
171
+ return result;
172
+ }
173
+ complete() { this.commit(() => undefined); }
174
+ get deadlineAt() { return this.deadline; }
175
+ get remainingMs() { return Math.max(0, this.deadline - this.now()); }
176
+ get completed() { return this.committed; }
177
+ cancel() { this.cancelled = true; this.options.progress?.("cleanup", "execution_cancelled"); }
178
+ close() { clearTimeout(this.timer); }
179
+ }
180
+ /** Wait for physical cleanup, with a bounded admission deadline and no polling. */
181
+ export function waitSettingsLease(keys, current, deadline, owner) {
182
+ return new Promise((resolve, reject) => {
183
+ let timer;
184
+ const check = () => {
185
+ if (!current() || performance.now() >= deadline) {
186
+ clearTimeout(timer);
187
+ leaseWaiters.delete(check);
188
+ reject(new SettingsExecutionError("settings_resource_unavailable"));
189
+ return;
190
+ }
191
+ const lease = trySettingsLease(keys, owner);
192
+ if (lease) {
193
+ clearTimeout(timer);
194
+ leaseWaiters.delete(check);
195
+ resolve(lease);
196
+ }
197
+ };
198
+ leaseWaiters.add(check);
199
+ timer = setTimeout(check, Math.max(1, Math.ceil(deadline - performance.now())));
200
+ check();
201
+ });
202
+ }
203
+ /** Apply only this writer's delta to the latest document, retaining unrelated fields. */
204
+ export function mergeSettingsDelta(before, after, current) {
205
+ if (settingsFingerprint(before) === settingsFingerprint(after))
206
+ return structuredClone(current);
207
+ const object = (v) => !!v && typeof v === "object" && !Array.isArray(v);
208
+ if (!object(before) || !object(after))
209
+ return structuredClone(after);
210
+ const next = object(current) ? structuredClone(current) : {};
211
+ for (const key of new Set([...Object.keys(before), ...Object.keys(after)])) {
212
+ const old = Object.hasOwn(before, key) ? before[key] : undefined, written = Object.hasOwn(after, key) ? after[key] : undefined;
213
+ if (settingsFingerprint(old) === settingsFingerprint(written))
214
+ continue;
215
+ if (!Object.hasOwn(after, key))
216
+ delete next[key];
217
+ else
218
+ Object.defineProperty(next, key, { value: mergeSettingsDelta(old, written, Object.hasOwn(next, key) ? next[key] : undefined),
219
+ writable: true, enumerable: true, configurable: true });
220
+ }
221
+ return next;
222
+ }
223
+ //# sourceMappingURL=settings-transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-transaction.js","sourceRoot":"","sources":["../src/settings-transaction.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { constantTimeMatches, formatOneTimeCode, generateOneTimeCode, normalizeOneTimeCode } from "./auth/one-time-code.js";
1
2
  export declare const SETUP_CODE_LENGTH = 8;
2
3
  /**
3
4
  * Five, not three.
@@ -8,24 +9,10 @@ export declare const SETUP_CODE_LENGTH = 8;
8
9
  */
9
10
  export declare const MAX_SETUP_ATTEMPTS = 5;
10
11
  export declare const SETUP_COOKIE_NAME = "agend_setup";
11
- export declare function generateSetupCode(): string;
12
- /** `ABCD-EFGH` — a shape that survives being read aloud and retyped. */
13
- export declare function formatSetupCode(code: string): string;
14
- /**
15
- * What the person typed, as the code it was meant to be.
16
- *
17
- * Case and the dash are presentation. Rejecting `abcd efgh` would be rejecting
18
- * a correct answer, and the person retyping it has no idea which detail was
19
- * wrong — so they spend attempts on formatting.
20
- */
21
- export declare function normalizeSetupCode(input: string): string;
22
- /**
23
- * Fixed-length constant-time compare.
24
- *
25
- * Both sides are padded to the same length first: `timingSafeEqual` throws on a
26
- * mismatch, and returning early on one leaks the length through timing.
27
- */
28
- export declare function constantTimeMatches(provided: string, expected: string): boolean;
12
+ export declare const generateSetupCode: typeof generateOneTimeCode;
13
+ export declare const formatSetupCode: typeof formatOneTimeCode;
14
+ export declare const normalizeSetupCode: typeof normalizeOneTimeCode;
15
+ export { constantTimeMatches };
29
16
  /** The cookie carries a hash of the secret, never the secret itself. */
30
17
  export declare function setupCookieValue(secret: string): string;
31
18
  export declare function buildSetupCookie(secret: string, opts: {
@@ -62,6 +49,11 @@ export declare class SetupCredentials {
62
49
  readonly sid: string;
63
50
  readonly code: string;
64
51
  private secret;
52
+ private sessionOwner;
53
+ get sessionIdentity(): {
54
+ readonly id: string;
55
+ } | null;
56
+ isSessionCurrent(owner: object): boolean;
65
57
  private failures;
66
58
  constructor(opts?: {
67
59
  sid?: string;