@k2b/cloud 0.6.0-rc.0

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 (540) hide show
  1. package/README.md +98 -0
  2. package/package.json +128 -0
  3. package/public/logo.svg +1 -0
  4. package/scripts/app-favicon.test.ts +49 -0
  5. package/scripts/app-favicon.ts +51 -0
  6. package/scripts/build.ts +205 -0
  7. package/scripts/preload.ts +164 -0
  8. package/scripts/sync-recovery-smoke.ts +200 -0
  9. package/src/_internal/app-favicon.ts +2 -0
  10. package/src/_internal/app-presentation.ts +61 -0
  11. package/src/_internal/app-workspace-state.ts +24 -0
  12. package/src/_internal/bounded-json.ts +47 -0
  13. package/src/_internal/build-metadata.ts +9 -0
  14. package/src/_internal/capabilities.ts +1118 -0
  15. package/src/_internal/define-app.ts +801 -0
  16. package/src/_internal/heartbeat.ts +167 -0
  17. package/src/_internal/help-catalog.ts +241 -0
  18. package/src/_internal/help.ts +95 -0
  19. package/src/_internal/nats-connection.ts +34 -0
  20. package/src/_internal/page-responses.ts +40 -0
  21. package/src/_internal/process-sync.ts +117 -0
  22. package/src/_internal/readiness.ts +3 -0
  23. package/src/_internal/registry-validation.ts +136 -0
  24. package/src/_internal/registry-watch.ts +52 -0
  25. package/src/_internal/registry.ts +338 -0
  26. package/src/_internal/runtime-compatibility.ts +64 -0
  27. package/src/_internal/runtime-context.ts +84 -0
  28. package/src/_internal/runtime-watcher.ts +78 -0
  29. package/src/_internal/static-assets.ts +86 -0
  30. package/src/_internal/status-preserving-ssr.ts +49 -0
  31. package/src/access/PermissionEditor.tsx +486 -0
  32. package/src/access/ResourceApiKeys.tsx +271 -0
  33. package/src/access/messages.ts +121 -0
  34. package/src/access/ui.ts +16 -0
  35. package/src/account/Avatar.tsx +28 -0
  36. package/src/account/EntitySearch.tsx +363 -0
  37. package/src/account/avatar-upload-dialog.tsx +197 -0
  38. package/src/account/avatar-upload.ts +149 -0
  39. package/src/account/ui.ts +3 -0
  40. package/src/ai/admin.ts +47 -0
  41. package/src/ai/approval-routes.ts +130 -0
  42. package/src/ai/approvals.ts +139 -0
  43. package/src/ai/assistant-models.ts +61 -0
  44. package/src/ai/attachments.ts +40 -0
  45. package/src/ai/browser.ts +92 -0
  46. package/src/ai/capabilities.ts +714 -0
  47. package/src/ai/capability-execution.ts +151 -0
  48. package/src/ai/chat/blocks.render.test.tsx +1108 -0
  49. package/src/ai/chat/blocks.tsx +730 -0
  50. package/src/ai/chat/builtin-tools.tsx +428 -0
  51. package/src/ai/chat/capability-table.tsx +87 -0
  52. package/src/ai/chat/composer-adapter.ts +169 -0
  53. package/src/ai/chat/file-tools.tsx +81 -0
  54. package/src/ai/chat/message-actions.tsx +370 -0
  55. package/src/ai/chat/message-utils.ts +479 -0
  56. package/src/ai/chat/messages.ts +43 -0
  57. package/src/ai/chat/presentation.tsx +395 -0
  58. package/src/ai/chat/primitives.tsx +3 -0
  59. package/src/ai/chat/tool-disclosure.tsx +41 -0
  60. package/src/ai/chat/turn-navigator-utils.ts +28 -0
  61. package/src/ai/chat/turn-navigator.tsx +164 -0
  62. package/src/ai/chat/user-message.tsx +149 -0
  63. package/src/ai/chat/visual-tools.tsx +435 -0
  64. package/src/ai/chat/web-tools.tsx +202 -0
  65. package/src/ai/chat-task-contracts.ts +113 -0
  66. package/src/ai/chat-tasks.ts +952 -0
  67. package/src/ai/client/controller.ts +1211 -0
  68. package/src/ai/client/file-source.ts +95 -0
  69. package/src/ai/client/live-connection.ts +140 -0
  70. package/src/ai/client/projection.ts +178 -0
  71. package/src/ai/client/transport.ts +111 -0
  72. package/src/ai/compaction.ts +182 -0
  73. package/src/ai/credentials.ts +124 -0
  74. package/src/ai/default-tool-contracts.ts +108 -0
  75. package/src/ai/default-tools.ts +127 -0
  76. package/src/ai/enrich.ts +280 -0
  77. package/src/ai/executor.ts +1624 -0
  78. package/src/ai/fetch-file-tool.ts +313 -0
  79. package/src/ai/file-context.ts +92 -0
  80. package/src/ai/file-media-type.ts +28 -0
  81. package/src/ai/file-mount.ts +16 -0
  82. package/src/ai/file-tools.ts +566 -0
  83. package/src/ai/files-store.ts +390 -0
  84. package/src/ai/firecrawl-tools.ts +305 -0
  85. package/src/ai/grids-skill.ts +126 -0
  86. package/src/ai/http.ts +265 -0
  87. package/src/ai/index.ts +337 -0
  88. package/src/ai/kit-skill.ts +22 -0
  89. package/src/ai/limits.ts +5 -0
  90. package/src/ai/live-events.ts +289 -0
  91. package/src/ai/live-messages.ts +45 -0
  92. package/src/ai/live-outbox.ts +102 -0
  93. package/src/ai/live-routes.ts +412 -0
  94. package/src/ai/live.ts +2 -0
  95. package/src/ai/maintenance.ts +302 -0
  96. package/src/ai/markdown-pdf-tool.ts +95 -0
  97. package/src/ai/memories.ts +605 -0
  98. package/src/ai/memory-learning-runs.ts +222 -0
  99. package/src/ai/memory-learning.ts +619 -0
  100. package/src/ai/memory-tool.ts +120 -0
  101. package/src/ai/memory-workflow-evidence.ts +158 -0
  102. package/src/ai/migrate.ts +2082 -0
  103. package/src/ai/model-access-migrate.ts +30 -0
  104. package/src/ai/model-access.ts +191 -0
  105. package/src/ai/personal-agent.ts +6 -0
  106. package/src/ai/prefs.ts +72 -0
  107. package/src/ai/project-tool.ts +94 -0
  108. package/src/ai/projects-routes.ts +277 -0
  109. package/src/ai/projects.ts +902 -0
  110. package/src/ai/protocol.ts +279 -0
  111. package/src/ai/provider.ts +73 -0
  112. package/src/ai/public-projection.ts +25 -0
  113. package/src/ai/resource-markers.ts +31 -0
  114. package/src/ai/resource-refs.ts +70 -0
  115. package/src/ai/routes.ts +1131 -0
  116. package/src/ai/runtime-tools.ts +39 -0
  117. package/src/ai/runtime.ts +544 -0
  118. package/src/ai/settings.ts +529 -0
  119. package/src/ai/short-id.ts +45 -0
  120. package/src/ai/skill-catalog.ts +73 -0
  121. package/src/ai/skill-format.ts +145 -0
  122. package/src/ai/skill-seeds.ts +430 -0
  123. package/src/ai/skill-tool.ts +81 -0
  124. package/src/ai/skills-routes.ts +143 -0
  125. package/src/ai/skills.ts +934 -0
  126. package/src/ai/solid.ts +27 -0
  127. package/src/ai/store.ts +3113 -0
  128. package/src/ai/stream.ts +308 -0
  129. package/src/ai/structured-runs.ts +66 -0
  130. package/src/ai/structured.ts +186 -0
  131. package/src/ai/system-prompt.ts +170 -0
  132. package/src/ai/task-prompt.ts +22 -0
  133. package/src/ai/timeline.ts +148 -0
  134. package/src/ai/tool-audit.ts +177 -0
  135. package/src/ai/tool-result-budget.ts +16 -0
  136. package/src/ai/tools.ts +155 -0
  137. package/src/ai/types.ts +967 -0
  138. package/src/ai/ui.tsx +39 -0
  139. package/src/ai/usage-migrate.ts +81 -0
  140. package/src/ai/usage.ts +315 -0
  141. package/src/ai/validate.ts +54 -0
  142. package/src/ai/vision-tool.ts +79 -0
  143. package/src/api/accounts-entities.ts +174 -0
  144. package/src/api/admin-ai-projects.ts +74 -0
  145. package/src/api/admin-ai-skills.ts +76 -0
  146. package/src/api/admin-ai-usage.ts +42 -0
  147. package/src/api/admin-core-settings.ts +508 -0
  148. package/src/api/admin-identity.ts +148 -0
  149. package/src/api/admin-lifecycle.ts +206 -0
  150. package/src/api/admin-linux-identities.ts +66 -0
  151. package/src/api/announcements.ts +131 -0
  152. package/src/api/app-approval.ts +129 -0
  153. package/src/api/apps.ts +51 -0
  154. package/src/api/auth/schemas.ts +54 -0
  155. package/src/api/auth.ts +370 -0
  156. package/src/api/capabilities.ts +658 -0
  157. package/src/api/help-messages.ts +19 -0
  158. package/src/api/help.ts +78 -0
  159. package/src/api/index.ts +108 -0
  160. package/src/api/mcp.ts +744 -0
  161. package/src/api/me-rail.ts +45 -0
  162. package/src/api/me.ts +753 -0
  163. package/src/api/search/schemas.ts +79 -0
  164. package/src/api/search.bench.ts +185 -0
  165. package/src/api/search.ts +407 -0
  166. package/src/api/sync-ops.ts +79 -0
  167. package/src/api/widgets.ts +143 -0
  168. package/src/browser/CloudResourceSearch.behavior.test.tsx +74 -0
  169. package/src/browser/CloudResourceSearch.tsx +791 -0
  170. package/src/browser/app-approval-vault.ts +305 -0
  171. package/src/browser/app-approval.ts +234 -0
  172. package/src/browser/live-websocket.ts +268 -0
  173. package/src/browser/locale-preference.ts +25 -0
  174. package/src/browser/notification-target.ts +27 -0
  175. package/src/browser/notification-timeout.ts +14 -0
  176. package/src/browser/notifications.ts +181 -0
  177. package/src/browser/resource-clipboard.ts +70 -0
  178. package/src/browser/resource-picker.tsx +39 -0
  179. package/src/browser/resource-search-messages.ts +55 -0
  180. package/src/browser/resource-search.ts +27 -0
  181. package/src/capabilities/client.ts +149 -0
  182. package/src/capabilities/response.ts +39 -0
  183. package/src/capabilities/server.ts +215 -0
  184. package/src/capabilities/signals.ts +4 -0
  185. package/src/capabilities/testing.ts +12 -0
  186. package/src/capabilities/types.ts +32 -0
  187. package/src/cli/access.ts +499 -0
  188. package/src/cli/account.ts +382 -0
  189. package/src/cli/admin/account-administration.ts +45 -0
  190. package/src/cli/admin/account-categories.ts +49 -0
  191. package/src/cli/admin/ai-usage.ts +118 -0
  192. package/src/cli/admin/app-sign-in.ts +49 -0
  193. package/src/cli/admin/data.ts +343 -0
  194. package/src/cli/admin/documentation.ts +34 -0
  195. package/src/cli/admin/gateway.ts +155 -0
  196. package/src/cli/admin/index.ts +61 -0
  197. package/src/cli/admin/instance.ts +250 -0
  198. package/src/cli/admin/jobs.ts +223 -0
  199. package/src/cli/admin/legal.ts +122 -0
  200. package/src/cli/admin/linux.ts +53 -0
  201. package/src/cli/admin/logs.ts +324 -0
  202. package/src/cli/admin/metrics.ts +142 -0
  203. package/src/cli/admin/nats.ts +167 -0
  204. package/src/cli/admin/notifications.ts +516 -0
  205. package/src/cli/admin/shared.ts +113 -0
  206. package/src/cli/admin/sync.ts +188 -0
  207. package/src/cli/admin/telemetry.ts +314 -0
  208. package/src/cli/admin/webhooks.ts +222 -0
  209. package/src/cli/admin/workflows.ts +367 -0
  210. package/src/cli/apps.ts +40 -0
  211. package/src/cli/capabilities.ts +239 -0
  212. package/src/cli/commands.ts +604 -0
  213. package/src/cli/index.ts +61 -0
  214. package/src/cli/locale.ts +31 -0
  215. package/src/cli/output.ts +58 -0
  216. package/src/clients/core.ts +20 -0
  217. package/src/config/env.ts +54 -0
  218. package/src/config/index.ts +6 -0
  219. package/src/contracts/account-categories.ts +62 -0
  220. package/src/contracts/announcements.ts +121 -0
  221. package/src/contracts/app-approval.ts +197 -0
  222. package/src/contracts/app.ts +162 -0
  223. package/src/contracts/capabilities.ts +484 -0
  224. package/src/contracts/index.ts +14 -0
  225. package/src/contracts/notification-live.ts +66 -0
  226. package/src/contracts/notification-types.ts +235 -0
  227. package/src/contracts/posix.ts +69 -0
  228. package/src/contracts/profile.ts +85 -0
  229. package/src/contracts/rail-preferences.ts +53 -0
  230. package/src/contracts/registry.ts +110 -0
  231. package/src/contracts/resource-clipboard.ts +33 -0
  232. package/src/contracts/settings-types.ts +98 -0
  233. package/src/contracts/shared.ts +408 -0
  234. package/src/contracts/user-notifications.ts +101 -0
  235. package/src/contracts/widgets.ts +183 -0
  236. package/src/desktop/index.ts +704 -0
  237. package/src/desktop/solid.tsx +938 -0
  238. package/src/index.ts +58 -0
  239. package/src/server/actor.ts +41 -0
  240. package/src/server/api/index.ts +2 -0
  241. package/src/server/api/respond.ts +96 -0
  242. package/src/server/api-client.ts +54 -0
  243. package/src/server/app-context.ts +39 -0
  244. package/src/server/help.ts +187 -0
  245. package/src/server/index.ts +89 -0
  246. package/src/server/locale.ts +55 -0
  247. package/src/server/middleware/auth.ts +386 -0
  248. package/src/server/middleware/index.ts +28 -0
  249. package/src/server/middleware/invocation.ts +55 -0
  250. package/src/server/middleware/middleware.ts +65 -0
  251. package/src/server/middleware/openapi.ts +126 -0
  252. package/src/server/middleware/rate-limit.ts +125 -0
  253. package/src/server/middleware/request-logger.ts +41 -0
  254. package/src/server/middleware/route-template.ts +46 -0
  255. package/src/server/middleware/runtime.ts +22 -0
  256. package/src/server/middleware/settings.ts +55 -0
  257. package/src/server/middleware/validator.ts +49 -0
  258. package/src/server/middleware/workload.ts +22 -0
  259. package/src/server/ratelimit.ts +151 -0
  260. package/src/server/request-cookies.ts +18 -0
  261. package/src/server/services/access.ts +644 -0
  262. package/src/server/services/freeipa/client.ts +137 -0
  263. package/src/server/services/freeipa/index.ts +9 -0
  264. package/src/server/services/freeipa/session.ts +123 -0
  265. package/src/server/services/freeipa/test-certificates.ts +44 -0
  266. package/src/server/services/freeipa/tls.ts +44 -0
  267. package/src/server/services/freeipa/transport.ts +116 -0
  268. package/src/server/services/freeipa/util.ts +59 -0
  269. package/src/server/services/geo.ts +198 -0
  270. package/src/server/services/index.ts +48 -0
  271. package/src/server/services/pagination.ts +22 -0
  272. package/src/server/services/services.ts +13 -0
  273. package/src/server/time.ts +33 -0
  274. package/src/services/account-category-policy.ts +51 -0
  275. package/src/services/account-lifecycle/audit.ts +41 -0
  276. package/src/services/account-lifecycle/index.ts +940 -0
  277. package/src/services/account-lifecycle/ipa-backfill.ts +152 -0
  278. package/src/services/account-lifecycle/notification-sender.ts +13 -0
  279. package/src/services/account-lifecycle/scheduler.ts +506 -0
  280. package/src/services/account-model.ts +22 -0
  281. package/src/services/accounts/app.ts +1671 -0
  282. package/src/services/accounts/authz.ts +44 -0
  283. package/src/services/accounts/avatar.ts +120 -0
  284. package/src/services/accounts/base-group.ts +11 -0
  285. package/src/services/accounts/base-user.ts +46 -0
  286. package/src/services/accounts/duplicate-emails.ts +82 -0
  287. package/src/services/accounts/entities.ts +622 -0
  288. package/src/services/accounts/group-sql.ts +106 -0
  289. package/src/services/accounts/groups.ts +272 -0
  290. package/src/services/accounts/index.ts +14 -0
  291. package/src/services/accounts/ipa-data.ts +66 -0
  292. package/src/services/accounts/lifecycle.ts +2 -0
  293. package/src/services/accounts/local-groups.ts +499 -0
  294. package/src/services/accounts/model.ts +129 -0
  295. package/src/services/accounts/notification-sender.ts +31 -0
  296. package/src/services/accounts/posix.ts +386 -0
  297. package/src/services/accounts/request-policy.ts +11 -0
  298. package/src/services/accounts/switching.ts +126 -0
  299. package/src/services/accounts/users.ts +745 -0
  300. package/src/services/announcements/index.ts +224 -0
  301. package/src/services/app-approval.ts +498 -0
  302. package/src/services/audit/index.ts +438 -0
  303. package/src/services/auth-flows/index.ts +15 -0
  304. package/src/services/auth-flows/ipa.ts +197 -0
  305. package/src/services/auth-flows/magic-link.ts +185 -0
  306. package/src/services/auth-flows/notification-sender.ts +10 -0
  307. package/src/services/auth-flows/password-reset.ts +268 -0
  308. package/src/services/auth-flows/proxy-return.ts +49 -0
  309. package/src/services/document-extraction.ts +148 -0
  310. package/src/services/freeipa-config.ts +179 -0
  311. package/src/services/gateway.ts +186 -0
  312. package/src/services/identity/constants.ts +18 -0
  313. package/src/services/identity/index.ts +52 -0
  314. package/src/services/identity/invocation-actor.ts +120 -0
  315. package/src/services/identity/invocation-authority.ts +53 -0
  316. package/src/services/identity/invocation-operations.ts +15 -0
  317. package/src/services/identity/invocation-token.ts +276 -0
  318. package/src/services/identity/key-config.ts +41 -0
  319. package/src/services/identity/key-ring.ts +530 -0
  320. package/src/services/identity/metrics.ts +29 -0
  321. package/src/services/identity/routes.ts +18 -0
  322. package/src/services/identity/runtime-config.ts +88 -0
  323. package/src/services/identity/session-token.ts +152 -0
  324. package/src/services/identity/signer-refresh.ts +44 -0
  325. package/src/services/identity/workload-auth.ts +64 -0
  326. package/src/services/index.ts +187 -0
  327. package/src/services/ipa/auth.ts +216 -0
  328. package/src/services/ipa/connection.ts +57 -0
  329. package/src/services/ipa/effective-groups.ts +70 -0
  330. package/src/services/ipa/groups.ts +722 -0
  331. package/src/services/ipa/guard.ts +17 -0
  332. package/src/services/ipa/index.ts +17 -0
  333. package/src/services/ipa/posix.ts +19 -0
  334. package/src/services/ipa/profile.ts +132 -0
  335. package/src/services/ipa/runtime.ts +28 -0
  336. package/src/services/ipa/search.ts +154 -0
  337. package/src/services/ipa/service-account.ts +15 -0
  338. package/src/services/ipa/sync-planning.ts +100 -0
  339. package/src/services/ipa/sync.ts +862 -0
  340. package/src/services/ipa/users.ts +806 -0
  341. package/src/services/legal-consent.ts +76 -0
  342. package/src/services/logging/index.ts +477 -0
  343. package/src/services/logging/redaction.ts +20 -0
  344. package/src/services/logging/trace.ts +1231 -0
  345. package/src/services/mandates/index.ts +855 -0
  346. package/src/services/mandates/policy.ts +85 -0
  347. package/src/services/network-security.ts +31 -0
  348. package/src/services/notifications/batches.ts +722 -0
  349. package/src/services/notifications/browser.ts +252 -0
  350. package/src/services/notifications/catalog.ts +113 -0
  351. package/src/services/notifications/channels.ts +104 -0
  352. package/src/services/notifications/dispatcher.ts +139 -0
  353. package/src/services/notifications/email.ts +118 -0
  354. package/src/services/notifications/index.ts +633 -0
  355. package/src/services/notifications/live.ts +50 -0
  356. package/src/services/notifications/observability.ts +407 -0
  357. package/src/services/notifications/platform.ts +421 -0
  358. package/src/services/notifications/runtime.ts +120 -0
  359. package/src/services/notifications/user.ts +248 -0
  360. package/src/services/notifications/web-push-transport.ts +135 -0
  361. package/src/services/oauth-tokens.ts +209 -0
  362. package/src/services/outbox.ts +187 -0
  363. package/src/services/pdf/gotenberg.ts +290 -0
  364. package/src/services/pdf/index.ts +43 -0
  365. package/src/services/pdf/markdown.ts +209 -0
  366. package/src/services/pdf/template-preview.ts +122 -0
  367. package/src/services/postgres.ts +76 -0
  368. package/src/services/providers/index.ts +27 -0
  369. package/src/services/providers/local/auth.ts +51 -0
  370. package/src/services/providers/local/index.ts +4 -0
  371. package/src/services/providers/local/users.ts +263 -0
  372. package/src/services/rail-preferences.ts +27 -0
  373. package/src/services/runtime-lifecycle.ts +191 -0
  374. package/src/services/secrets.ts +10 -0
  375. package/src/services/service-account-credentials.ts +891 -0
  376. package/src/services/service-accounts.ts +184 -0
  377. package/src/services/session/index.ts +236 -0
  378. package/src/services/session/test-fixture.ts +18 -0
  379. package/src/services/session/user.ts +144 -0
  380. package/src/services/settings/api.ts +61 -0
  381. package/src/services/settings/app.ts +86 -0
  382. package/src/services/settings/core-settings.ts +796 -0
  383. package/src/services/settings/crypto.ts +69 -0
  384. package/src/services/settings/defaults.ts +374 -0
  385. package/src/services/settings/index.ts +215 -0
  386. package/src/services/settings/namespace.ts +9 -0
  387. package/src/services/settings/snapshot.ts +49 -0
  388. package/src/services/settings/store.ts +241 -0
  389. package/src/services/settings/templates.ts +4 -0
  390. package/src/services/sync-ops.ts +403 -0
  391. package/src/services/topic-cursor.ts +22 -0
  392. package/src/services/weather/forecast.ts +323 -0
  393. package/src/services/weather/geo.ts +119 -0
  394. package/src/services/weather/index.ts +67 -0
  395. package/src/services/weather/location.ts +24 -0
  396. package/src/services/weather/locations.ts +133 -0
  397. package/src/services/weather/migrate.ts +45 -0
  398. package/src/services/weather/settings.ts +66 -0
  399. package/src/services/weather/short-id.ts +57 -0
  400. package/src/services/weather/types.ts +61 -0
  401. package/src/services/weather/ui.ts +50 -0
  402. package/src/services/webauthn.ts +385 -0
  403. package/src/shared/account-action-notice.ts +70 -0
  404. package/src/shared/account-display.ts +15 -0
  405. package/src/shared/account-session.ts +15 -0
  406. package/src/shared/ai-platform-prompt.ts +134 -0
  407. package/src/shared/ai-usage.ts +49 -0
  408. package/src/shared/app-presentation.ts +48 -0
  409. package/src/shared/app-url.ts +12 -0
  410. package/src/shared/branding.ts +14 -0
  411. package/src/shared/capability-messages.ts +70 -0
  412. package/src/shared/email-html.ts +54 -0
  413. package/src/shared/format.ts +91 -0
  414. package/src/shared/help.ts +68 -0
  415. package/src/shared/icons.ts +400 -0
  416. package/src/shared/index.ts +54 -0
  417. package/src/shared/locale.ts +48 -0
  418. package/src/shared/login-method.ts +44 -0
  419. package/src/shared/markdown/client.ts +130 -0
  420. package/src/shared/markdown/extensions/code.ts +105 -0
  421. package/src/shared/markdown/extensions/guided-help.ts +100 -0
  422. package/src/shared/markdown/extensions/images.ts +79 -0
  423. package/src/shared/markdown/extensions/info-blocks.ts +97 -0
  424. package/src/shared/markdown/extensions/katex.ts +120 -0
  425. package/src/shared/markdown/extensions/links.ts +43 -0
  426. package/src/shared/markdown/extensions/mark.ts +48 -0
  427. package/src/shared/markdown/extensions/sub-sup.ts +60 -0
  428. package/src/shared/markdown/extensions/tables.ts +109 -0
  429. package/src/shared/markdown/extensions/task-list.ts +53 -0
  430. package/src/shared/markdown/formula.ts +1187 -0
  431. package/src/shared/markdown/index.ts +193 -0
  432. package/src/shared/markdown/shared.ts +36 -0
  433. package/src/shared/mock-cover.ts +130 -0
  434. package/src/shared/network-address.ts +106 -0
  435. package/src/shared/redirect.ts +56 -0
  436. package/src/shared/template-rendering.ts +140 -0
  437. package/src/shared/theme.ts +68 -0
  438. package/src/shared/time.ts +13 -0
  439. package/src/ssr/AdminLayout.tsx +53 -0
  440. package/src/ssr/AdminSidebar.tsx +50 -0
  441. package/src/ssr/AppLaunchpad.island.tsx +236 -0
  442. package/src/ssr/AppWorkspaceController.island.tsx +21 -0
  443. package/src/ssr/BrowserNotifications.island.tsx +135 -0
  444. package/src/ssr/GlobalAnnouncements.island.tsx +142 -0
  445. package/src/ssr/GlobalSearchDialog.behavior.test.tsx +96 -0
  446. package/src/ssr/GlobalSearchDialog.tsx +35 -0
  447. package/src/ssr/GlobalSearchHelpDialog.tsx +104 -0
  448. package/src/ssr/GlobalSearchTrigger.island.tsx +55 -0
  449. package/src/ssr/HotkeysHelpRail.island.tsx +55 -0
  450. package/src/ssr/Layout.render.test.tsx +148 -0
  451. package/src/ssr/Layout.tsx +292 -0
  452. package/src/ssr/LayoutBreadcrumbs.island.tsx +44 -0
  453. package/src/ssr/LayoutFooter.tsx +22 -0
  454. package/src/ssr/LayoutHeader.tsx +81 -0
  455. package/src/ssr/LayoutHelp.tsx +869 -0
  456. package/src/ssr/LayoutPreferences.island.tsx +36 -0
  457. package/src/ssr/LayoutRail.tsx +58 -0
  458. package/src/ssr/MinimalLayout.tsx +46 -0
  459. package/src/ssr/PageError.tsx +29 -0
  460. package/src/ssr/ProfilePreferences.island.tsx +92 -0
  461. package/src/ssr/RailApps.island.tsx +61 -0
  462. package/src/ssr/RailEditor.tsx +293 -0
  463. package/src/ssr/RegisteredHelpDocuments.island.tsx +3 -0
  464. package/src/ssr/TimezoneCookie.island.tsx +23 -0
  465. package/src/ssr/admin-active-link.ts +47 -0
  466. package/src/ssr/admin-navigation.ts +78 -0
  467. package/src/ssr/app-appearance.ts +23 -0
  468. package/src/ssr/app-navigation.ts +41 -0
  469. package/src/ssr/help-messages.ts +104 -0
  470. package/src/ssr/index.ts +14 -0
  471. package/src/ssr/islands/SearchBar.island.tsx +80 -0
  472. package/src/ssr/islands/index.ts +16 -0
  473. package/src/ssr/layout-context.ts +17 -0
  474. package/src/ssr/layout-help-markdown.ts +9 -0
  475. package/src/ssr/layout-help-navigation.ts +24 -0
  476. package/src/ssr/layout-help-url.ts +5 -0
  477. package/src/ssr/layout-runtime.ts +22 -0
  478. package/src/ssr/page-error-messages.ts +25 -0
  479. package/src/ssr/platform-messages.ts +135 -0
  480. package/src/ssr/preference-controller.ts +44 -0
  481. package/src/ssr/profile-preferences-messages.ts +29 -0
  482. package/src/ssr/rail-context.ts +21 -0
  483. package/src/ssr/rail-messages.ts +66 -0
  484. package/src/ssr/rail-navigation.ts +60 -0
  485. package/src/ssr/runtime.ts +31 -0
  486. package/src/ssr/url-filter.ts +127 -0
  487. package/src/styles/base-popover.css +36 -0
  488. package/src/styles/effects.css +851 -0
  489. package/src/styles/global.css +268 -0
  490. package/src/styles/input.css +58 -0
  491. package/src/styles/tokens.css +230 -0
  492. package/src/styles/utilities-buttons.css +405 -0
  493. package/src/styles/utilities-data.css +33 -0
  494. package/src/styles/utilities-feedback.css +232 -0
  495. package/src/styles/utilities-layout.css +603 -0
  496. package/src/styles/utilities-markdown-editor.css +525 -0
  497. package/src/styles/utilities-markdown-table.css +234 -0
  498. package/src/styles/utilities-navigation.css +1054 -0
  499. package/src/types/ambient.d.ts +24 -0
  500. package/src/workflows/ai/index.ts +17 -0
  501. package/src/workflows/ai/runtime.ts +286 -0
  502. package/src/workflows/ai/store.ts +314 -0
  503. package/src/workflows/ai/types.ts +111 -0
  504. package/src/workflows/ai-actions.ts +269 -0
  505. package/src/workflows/authoring.ts +88 -0
  506. package/src/workflows/builtins.ts +193 -0
  507. package/src/workflows/contracts.ts +280 -0
  508. package/src/workflows/definition.ts +334 -0
  509. package/src/workflows/editor.ts +113 -0
  510. package/src/workflows/index.ts +71 -0
  511. package/src/workflows/language/binder.ts +45 -0
  512. package/src/workflows/language/canonical.ts +29 -0
  513. package/src/workflows/language/compiler.ts +396 -0
  514. package/src/workflows/language/expressions.ts +34 -0
  515. package/src/workflows/language/index.ts +20 -0
  516. package/src/workflows/language/references.ts +55 -0
  517. package/src/workflows/language/schema.ts +134 -0
  518. package/src/workflows/language/strict-yaml.ts +131 -0
  519. package/src/workflows/manifest.ts +24 -0
  520. package/src/workflows/module.ts +12 -0
  521. package/src/workflows/runtime/coordinator.ts +115 -0
  522. package/src/workflows/runtime/executor.ts +1003 -0
  523. package/src/workflows/runtime/index.ts +60 -0
  524. package/src/workflows/runtime/instant.ts +8 -0
  525. package/src/workflows/runtime/ports.ts +213 -0
  526. package/src/workflows/runtime/schedule.ts +203 -0
  527. package/src/workflows/runtime/trigger.ts +37 -0
  528. package/src/workflows/runtime/wake.ts +13 -0
  529. package/src/workflows/store/actions.ts +438 -0
  530. package/src/workflows/store/budget.ts +145 -0
  531. package/src/workflows/store/definitions.ts +345 -0
  532. package/src/workflows/store/events.ts +383 -0
  533. package/src/workflows/store/index.ts +107 -0
  534. package/src/workflows/store/observability.ts +594 -0
  535. package/src/workflows/store/runs.ts +975 -0
  536. package/src/workflows/store/transaction.ts +23 -0
  537. package/src/workflows/store/worker.ts +439 -0
  538. package/src/workflows/testing/conformance.ts +72 -0
  539. package/src/workflows/testing/index.ts +11 -0
  540. package/src/workflows/testing/process-fixtures.ts +275 -0
@@ -0,0 +1,302 @@
1
+ import type { Worker } from "@k2b/sync";
2
+ import { lazySync } from "../_internal/process-sync";
3
+ import { coreSettings } from "../services";
4
+ import { logger, trace } from "../services/logging";
5
+
6
+ import { enrichDirtyAiConversations } from "./enrich";
7
+ import { learnAiMemoriesFromPrivateChats } from "./memory-learning";
8
+
9
+ const log = logger("ai:maintenance");
10
+
11
+ export const AI_ENRICH_CRON_SETTING_KEY = "ai.enrich_cron";
12
+ export const AI_MEMORY_LEARNING_CRON_SETTING_KEY = "ai.memory_learning_cron";
13
+ const DEFAULT_ENRICH_CRON = "*/10 * * * *";
14
+
15
+ const getCronSetting = async (key: string, fallback: string): Promise<string> => {
16
+ const value = String((await coreSettings.get<string>(key)) || "").trim();
17
+ return value.length > 0 ? value : fallback;
18
+ };
19
+
20
+ const getTimezoneSetting = async (): Promise<string> => {
21
+ const value = String((await coreSettings.get<string>("app.timezone")) || "").trim();
22
+ return value.length > 0 ? value : "Europe/Berlin";
23
+ };
24
+
25
+ // ── Job ────────────────────────────────────────────────────────────────
26
+
27
+ const enrichJob = lazySync((sync) => {
28
+ const handle = sync.job<void>({
29
+ id: "ai:chat:enrich",
30
+ owner: "cloud",
31
+ delivery: { ackWaitMs: 900_000, maxAttempts: 3, backoffMs: [2_000, 4_000] },
32
+ });
33
+
34
+ return handle;
35
+ });
36
+ const reindexJob = lazySync((sync) => {
37
+ const handle = sync.job<{ conversationId: string }>({
38
+ id: "ai:chat:reindex",
39
+ owner: "cloud",
40
+ delivery: { ackWaitMs: 300_000, maxAttempts: 2, backoffMs: [2_000] },
41
+ });
42
+
43
+ return handle;
44
+ });
45
+ const memoryLearningJob = lazySync((sync) => {
46
+ const handle = sync.job<void>({
47
+ id: "ai:memory:learn",
48
+ owner: "cloud",
49
+ delivery: { ackWaitMs: 900_000, maxAttempts: 3, backoffMs: [2_000, 4_000] },
50
+ });
51
+
52
+ return handle;
53
+ });
54
+ const workers: Worker[] = [];
55
+
56
+ const startWorkers = async (): Promise<void> => {
57
+ workers.push(
58
+ await enrichJob().process({ concurrency: 1 }, async (context) => {
59
+ const summary = await trace.withSpan(
60
+ {
61
+ name: "AI chat enrichment",
62
+ source: "ai:chat:enrich",
63
+ appId: "ai",
64
+ category: "job",
65
+ kind: "consumer",
66
+ spanKey: trace.syncSpanKey("job", "ai:chat:enrich", context.jobId),
67
+ },
68
+ () => enrichDirtyAiConversations({ signal: context.signal, heartbeat: () => context.heartbeat() }),
69
+ { summarize: (summary) => summary },
70
+ );
71
+ if (summary.scanned > 0) log.info("Chat enrichment run complete", { ...summary });
72
+ }),
73
+ );
74
+ workers.push(
75
+ await reindexJob().process({ concurrency: 1 }, async (context) => {
76
+ await trace.withSpan(
77
+ {
78
+ name: "AI chat reindex (manual)",
79
+ source: "ai:chat:reindex",
80
+ appId: "ai",
81
+ category: "job",
82
+ kind: "consumer",
83
+ spanKey: trace.syncSpanKey("job", "ai:chat:reindex", context.jobId),
84
+ },
85
+ () =>
86
+ enrichDirtyAiConversations({
87
+ conversationId: context.input.conversationId,
88
+ signal: context.signal,
89
+ heartbeat: () => context.heartbeat(),
90
+ }),
91
+ { summarize: (summary) => summary },
92
+ );
93
+ }),
94
+ );
95
+ workers.push(
96
+ await memoryLearningJob().process({ concurrency: 1 }, async (context) => {
97
+ const summary = await trace.withSpan(
98
+ {
99
+ name: "AI memory learning",
100
+ source: "ai:memory:learn",
101
+ appId: "ai",
102
+ category: "job",
103
+ kind: "consumer",
104
+ spanKey: trace.syncSpanKey("job", "ai:memory:learn", context.jobId),
105
+ },
106
+ () => learnAiMemoriesFromPrivateChats({ signal: context.signal, heartbeat: () => context.heartbeat() }),
107
+ { summarize: (summary) => summary },
108
+ );
109
+ if (summary.scanned > 0) log.info("Memory learning run complete", { ...summary });
110
+ }),
111
+ );
112
+ };
113
+
114
+ // ── Schedule ───────────────────────────────────────────────────────────
115
+
116
+ const aiScheduler = lazySync((sync) => {
117
+ const handle = sync.scheduler({ id: "ai-maintenance", owner: "cloud", delivery: { maxAttempts: 1 } });
118
+
119
+ return handle;
120
+ });
121
+
122
+ let started = false;
123
+ let registered = false;
124
+ let registerPromise: Promise<void> | null = null;
125
+
126
+ const createSchedule = async (config: {
127
+ id: string;
128
+ cron: string;
129
+ tz: string;
130
+ submit: (key: string) => Promise<string>;
131
+ label: string;
132
+ family: string;
133
+ resourceKind: string;
134
+ resourceId: string;
135
+ }): Promise<void> => {
136
+ await aiScheduler().create({
137
+ id: config.id,
138
+ cron: config.cron,
139
+ timezone: config.tz,
140
+ meta: {
141
+ appId: "ai",
142
+ family: config.family,
143
+ label: config.label,
144
+ source: config.id,
145
+ resourceKind: config.resourceKind,
146
+ resourceId: config.resourceId,
147
+ resourceLabel: config.label,
148
+ detailHref: "/admin/settings?tab=ai",
149
+ },
150
+ process: async (context) => {
151
+ await config.submit(`slot:${context.slot.getTime()}`);
152
+ },
153
+ });
154
+ };
155
+
156
+ /**
157
+ * Coalescing submit for scheduled runs: one stable idempotency key means at
158
+ * most one scheduled run is queued or running at a time. On slow models a run
159
+ * can outlast the cron interval — extra slots must not pile up in the queue
160
+ * (they would also starve manual work); the dirty scan catches up next slot.
161
+ * The key is released on completion.
162
+ */
163
+ const submitScheduledRun = (): Promise<string> =>
164
+ enrichJob()
165
+ .submit({ key: "scheduled", input: undefined, coalesce: true })
166
+ .then((receipt) => receipt.jobId);
167
+ const submitMemoryLearning = (): Promise<string> =>
168
+ memoryLearningJob()
169
+ .submit({ key: "run", input: undefined, coalesce: true })
170
+ .then((receipt) => receipt.jobId);
171
+
172
+ const doRegister = async (): Promise<void> => {
173
+ const [tz, enrichCron, memoryLearningCron] = await Promise.all([
174
+ getTimezoneSetting(),
175
+ getCronSetting(AI_ENRICH_CRON_SETTING_KEY, DEFAULT_ENRICH_CRON),
176
+ getCronSetting(AI_MEMORY_LEARNING_CRON_SETTING_KEY, DEFAULT_ENRICH_CRON),
177
+ ]);
178
+ try {
179
+ await createSchedule({
180
+ id: "ai:chat:enrich",
181
+ cron: enrichCron,
182
+ tz,
183
+ submit: () => submitScheduledRun(),
184
+ label: "Chat enrichment",
185
+ family: "ai:chat",
186
+ resourceKind: "ai-enrichment",
187
+ resourceId: "chat-enrichment",
188
+ });
189
+ } catch (error) {
190
+ if (enrichCron === DEFAULT_ENRICH_CRON) throw error;
191
+ log.warn("Invalid configured enrichment cron, falling back to default", {
192
+ key: AI_ENRICH_CRON_SETTING_KEY,
193
+ configuredCron: enrichCron,
194
+ fallbackCron: DEFAULT_ENRICH_CRON,
195
+ error: error instanceof Error ? error.message : String(error),
196
+ });
197
+ await createSchedule({
198
+ id: "ai:chat:enrich",
199
+ cron: DEFAULT_ENRICH_CRON,
200
+ tz,
201
+ submit: () => submitScheduledRun(),
202
+ label: "Chat enrichment",
203
+ family: "ai:chat",
204
+ resourceKind: "ai-enrichment",
205
+ resourceId: "chat-enrichment",
206
+ });
207
+ }
208
+ try {
209
+ await createSchedule({
210
+ id: "ai:memory:learn",
211
+ cron: memoryLearningCron,
212
+ tz,
213
+ submit: () => submitMemoryLearning(),
214
+ label: "Personal memory learning",
215
+ family: "ai:memory",
216
+ resourceKind: "ai-memory-learning",
217
+ resourceId: "personal-memory-learning",
218
+ });
219
+ } catch (error) {
220
+ if (memoryLearningCron === DEFAULT_ENRICH_CRON) throw error;
221
+ log.warn("Invalid configured memory learning cron, falling back to default", {
222
+ key: AI_MEMORY_LEARNING_CRON_SETTING_KEY,
223
+ configuredCron: memoryLearningCron,
224
+ fallbackCron: DEFAULT_ENRICH_CRON,
225
+ error: error instanceof Error ? error.message : String(error),
226
+ });
227
+ await createSchedule({
228
+ id: "ai:memory:learn",
229
+ cron: DEFAULT_ENRICH_CRON,
230
+ tz,
231
+ submit: () => submitMemoryLearning(),
232
+ label: "Personal memory learning",
233
+ family: "ai:memory",
234
+ resourceKind: "ai-memory-learning",
235
+ resourceId: "personal-memory-learning",
236
+ });
237
+ }
238
+ registered = true;
239
+ };
240
+
241
+ const ensureRegistered = async (): Promise<void> => {
242
+ if (registered) return;
243
+ if (!registerPromise) {
244
+ registerPromise = doRegister().finally(() => {
245
+ registerPromise = null;
246
+ });
247
+ }
248
+ await registerPromise;
249
+ };
250
+
251
+ /** AI maintenance jobs (chat enrichment). Started next to the AI runtime; leases make this horizontally safe. */
252
+ export const aiMaintenanceJobs = {
253
+ start: async (): Promise<void> => {
254
+ if (started) return;
255
+ try {
256
+ await ensureRegistered();
257
+ await startWorkers();
258
+ workers.push(await aiScheduler().process());
259
+ started = true;
260
+ await submitScheduledRun();
261
+ await submitMemoryLearning();
262
+ } catch (error) {
263
+ await aiMaintenanceJobs.stop();
264
+ throw error;
265
+ }
266
+ },
267
+
268
+ stop: async (): Promise<void> => {
269
+ const active = workers.splice(0);
270
+ for (const worker of active) worker.stop();
271
+ await Promise.all(active.map((worker) => worker.drain()));
272
+ started = false;
273
+ registered = false;
274
+ registerPromise = null;
275
+ },
276
+
277
+ /** Manual full run (admin/testing). */
278
+ submitEnrichmentRun: (): Promise<string> =>
279
+ enrichJob()
280
+ .submit({ key: `manual:${crypto.randomUUID()}`, input: undefined })
281
+ .then((receipt) => receipt.jobId),
282
+
283
+ /** Manual full memory-learning run (admin/testing). */
284
+ submitMemoryLearningRun: (): Promise<string> => submitMemoryLearning(),
285
+
286
+ /**
287
+ * User-triggered reindex of one conversation on the dedicated reindex queue
288
+ * (never waits behind scheduled batch runs). The stable per-conversation key
289
+ * coalesces rapid clicks while a reindex is queued or running; it is
290
+ * released on completion, so the next click after that starts a fresh run.
291
+ * A click that joins a running reindex starts no second run; changes the
292
+ * running pass missed stay dirty and the scheduled enrichment picks them up.
293
+ */
294
+ submitConversationReindex: (conversationId: string): Promise<string> =>
295
+ reindexJob()
296
+ .submit({
297
+ key: `reindex:${conversationId}`,
298
+ coalesce: true,
299
+ input: { conversationId },
300
+ })
301
+ .then((receipt) => receipt.jobId),
302
+ };
@@ -0,0 +1,95 @@
1
+ import {
2
+ MARKDOWN_PDF_MAX_CUSTOM_CSS_BYTES,
3
+ MARKDOWN_PDF_MAX_MARKDOWN_BYTES,
4
+ MARKDOWN_PDF_TEMPLATE_IDS,
5
+ type RenderMarkdownToPdfInput,
6
+ renderMarkdownToPdf,
7
+ } from "../services/pdf";
8
+ import { z } from "zod";
9
+ import { aiProjectFilePathFromMount } from "./file-mount";
10
+ import { aiFileStore, normalizeAiFilePath, type AiFileContent } from "./files-store";
11
+ import { defineAiTool } from "./tools";
12
+
13
+ export const CloudAiMarkdownToPdfInputSchema = z
14
+ .object({
15
+ path: z.string().trim().min(1).describe("Absolute path to an assistant-created Markdown file in this conversation."),
16
+ template: z.enum(MARKDOWN_PDF_TEMPLATE_IDS).optional().describe("Optional A4 preset applied before custom CSS."),
17
+ customCss: z.string().max(MARKDOWN_PDF_MAX_CUSTOM_CSS_BYTES).optional().describe("Optional bounded print CSS."),
18
+ })
19
+ .strict();
20
+
21
+ export const CloudAiMarkdownToPdfOutputSchema = z.object({
22
+ sourcePath: z.string(),
23
+ path: z.string(),
24
+ size: z.number().int().nonnegative(),
25
+ mediaType: z.literal("application/pdf"),
26
+ });
27
+
28
+ type MarkdownPdfToolDependencies = {
29
+ read?: (input: { conversationId: string; path: string }) => Promise<AiFileContent | null>;
30
+ write?: (input: { conversationId: string; path: string; bytes: Uint8Array; mediaType: string; origin: "assistant" }) => Promise<void>;
31
+ render?: (input: RenderMarkdownToPdfInput) => Promise<{ pdf: Uint8Array; contentType: string }>;
32
+ };
33
+
34
+ const conversationPath = (value: string): string => {
35
+ const candidate = value.startsWith("/") ? value : `/${value}`;
36
+ const path = normalizeAiFilePath(candidate);
37
+ if (!path) throw new Error("Use an absolute conversation Markdown file path.");
38
+ if (aiProjectFilePathFromMount(path) !== null) {
39
+ throw new Error("Project files are read-only. Create a conversation Markdown file with write_file first.");
40
+ }
41
+ if (!path.toLowerCase().endsWith(".md")) throw new Error("markdown_to_pdf requires a .md file written with write_file.");
42
+ return path;
43
+ };
44
+
45
+ const pdfPath = (path: string): string => `${path.slice(0, -3)}.pdf`;
46
+
47
+ export const createCloudAiMarkdownToPdfTool = (dependencies: MarkdownPdfToolDependencies = {}) => {
48
+ const read = dependencies.read ?? aiFileStore.read;
49
+ const write = dependencies.write ?? aiFileStore.write;
50
+ const render = dependencies.render ?? renderMarkdownToPdf;
51
+
52
+ return defineAiTool({
53
+ name: "markdown_to_pdf",
54
+ description:
55
+ "Convert one assistant-created conversation Markdown file to a sibling PDF. Write or edit the .md source with write_file first. A named A4 template may be combined with custom CSS; custom CSS without a template is used as the complete stylesheet. The output path replaces .md with .pdf.",
56
+ inputSchema: CloudAiMarkdownToPdfInputSchema,
57
+ outputSchema: CloudAiMarkdownToPdfOutputSchema,
58
+ approval: "never",
59
+ timeoutMs: 125_000,
60
+ promptHint:
61
+ "write or edit an assistant-owned .md file with write_file before converting it with markdown_to_pdf; call present with the returned PDF path afterwards.",
62
+ }).server(async (input, ctx) => {
63
+ if (!ctx.conversationId) throw new Error("The markdown_to_pdf tool needs a conversation context.");
64
+ const sourcePath = conversationPath(input.path);
65
+ const source = await read({ conversationId: ctx.conversationId, path: sourcePath });
66
+ if (!source) throw new Error(`No such file: ${sourcePath}`);
67
+ if (source.origin !== "assistant") {
68
+ throw new Error(`Create an assistant-owned Markdown file with write_file before converting ${sourcePath}.`);
69
+ }
70
+ if (source.bytes.byteLength > MARKDOWN_PDF_MAX_MARKDOWN_BYTES) {
71
+ throw new Error(`Markdown exceeds the ${MARKDOWN_PDF_MAX_MARKDOWN_BYTES}-byte PDF rendering limit.`);
72
+ }
73
+
74
+ let markdown: string;
75
+ try {
76
+ markdown = new TextDecoder("utf-8", { fatal: true }).decode(source.bytes);
77
+ } catch {
78
+ throw new Error(`File ${sourcePath} is not valid UTF-8 Markdown.`);
79
+ }
80
+
81
+ const rendered = await render({ markdown, templateId: input.template, customCss: input.customCss });
82
+ if (ctx.signal.aborted) {
83
+ throw ctx.signal.reason instanceof Error ? ctx.signal.reason : new Error("PDF conversion was cancelled.");
84
+ }
85
+ const path = pdfPath(sourcePath);
86
+ await write({
87
+ conversationId: ctx.conversationId,
88
+ path,
89
+ bytes: rendered.pdf,
90
+ mediaType: "application/pdf",
91
+ origin: "assistant",
92
+ });
93
+ return { sourcePath, path, size: rendered.pdf.byteLength, mediaType: "application/pdf" as const };
94
+ });
95
+ };