@k2b/cloud 0.22.0 → 0.24.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 (117) hide show
  1. package/package.json +4 -3
  2. package/scripts/README.md +1 -1
  3. package/scripts/build-canvas-workers.ts +58 -0
  4. package/scripts/build.ts +4 -5
  5. package/src/_internal/canvas-worker.ts +24 -0
  6. package/src/_internal/capabilities.ts +230 -75
  7. package/src/_internal/define-app.ts +90 -7
  8. package/src/_internal/fixtures/filesv2-manifest-cloud-v0.29.0.json +887 -0
  9. package/src/_internal/page-responses.ts +20 -4
  10. package/src/_internal/registry-validation.ts +6 -0
  11. package/src/_internal/registry.ts +78 -3
  12. package/src/_internal/runtime-context.ts +1 -0
  13. package/src/_internal/static-assets.ts +18 -3
  14. package/src/access/ResourceApiKeys.tsx +30 -30
  15. package/src/ai/capability-execution.ts +5 -0
  16. package/src/ai/chat/blocks.tsx +2 -1
  17. package/src/ai/chat/messages.ts +6 -0
  18. package/src/ai/client/controller.ts +80 -21
  19. package/src/ai/client/transport.ts +47 -3
  20. package/src/ai/code-mode-skill.ts +2 -2
  21. package/src/ai/index.ts +0 -7
  22. package/src/ai/live-events.ts +1 -262
  23. package/src/ai/live.ts +31 -2
  24. package/src/ai/migrate.ts +35 -16
  25. package/src/ai/pdf-render.ts +2 -22
  26. package/src/ai/routes.ts +5 -4
  27. package/src/ai/runtime.ts +1 -6
  28. package/src/ai/solid.ts +0 -5
  29. package/src/ai/stream.ts +89 -65
  30. package/src/api/app-approval.ts +5 -1
  31. package/src/api/help.ts +2 -2
  32. package/src/api/index.ts +3 -0
  33. package/src/api/me.ts +19 -5
  34. package/src/api/pwa-phone.ts +168 -0
  35. package/src/api/pwa.ts +179 -0
  36. package/src/api/search/schemas.ts +34 -0
  37. package/src/api/search.ts +118 -50
  38. package/src/browser/CloudResourceSearch.browser-harness.tsx +11 -0
  39. package/src/browser/CloudResourceSearch.tsx +208 -80
  40. package/src/browser/app-session.ts +69 -0
  41. package/src/browser/live-connection.ts +211 -0
  42. package/src/browser/live-websocket.ts +31 -11
  43. package/src/browser/live.ts +2 -0
  44. package/src/browser/resource-search-messages.ts +15 -2
  45. package/src/browser/search-stream.ts +151 -0
  46. package/src/contracts/app.ts +10 -0
  47. package/src/contracts/capabilities.ts +89 -24
  48. package/src/contracts/capability-compatibility.ts +28 -14
  49. package/src/contracts/file-provider.ts +158 -0
  50. package/src/contracts/index.ts +2 -0
  51. package/src/contracts/pwa-paths.ts +6 -0
  52. package/src/contracts/pwa.ts +156 -0
  53. package/src/contracts/registry.ts +7 -0
  54. package/src/contracts/shared.ts +7 -1
  55. package/src/events/index.ts +2 -0
  56. package/src/events/live-engine.ts +830 -0
  57. package/src/events/live-protocol.ts +31 -0
  58. package/src/events/live.ts +298 -0
  59. package/src/server/actor.ts +7 -0
  60. package/src/server/api-client.ts +23 -2
  61. package/src/server/help.ts +3 -3
  62. package/src/server/index.ts +3 -1
  63. package/src/server/middleware/auth.ts +80 -8
  64. package/src/server/middleware/openapi.ts +2 -1
  65. package/src/server/services/access.ts +49 -0
  66. package/src/server/services/index.ts +1 -0
  67. package/src/services/app-approval.ts +6 -25
  68. package/src/services/audit/index.ts +2 -0
  69. package/src/services/branding/app-icon-source.ts +40 -0
  70. package/src/services/branding/app-icons.ts +112 -0
  71. package/src/services/branding/icon-render-worker.ts +69 -0
  72. package/src/services/branding/icon-svg.ts +22 -0
  73. package/src/services/identity/invocation-actor.ts +8 -5
  74. package/src/services/identity/invocation-authority.ts +1 -0
  75. package/src/services/identity/invocation-token.ts +6 -0
  76. package/src/services/index.ts +1 -0
  77. package/src/services/outbox.ts +114 -80
  78. package/src/services/pairing-secret.ts +16 -0
  79. package/src/services/pdf/markdown.ts +22 -2
  80. package/src/services/pwa-devices.ts +640 -0
  81. package/src/services/session/index.ts +212 -57
  82. package/src/services/session/recent.ts +42 -0
  83. package/src/services/session/user.ts +15 -5
  84. package/src/shared/index.ts +1 -0
  85. package/src/{browser → shared}/locale-preference.ts +1 -1
  86. package/src/shared/markdown/formula.ts +122 -26
  87. package/src/shared/markdown/index.ts +27 -23
  88. package/src/ssr/AppLaunchpad.island.tsx +8 -1
  89. package/src/ssr/AppLaunchpadPanel.tsx +1 -1
  90. package/src/ssr/GlobalAnnouncements.island.tsx +1 -1
  91. package/src/ssr/Layout.tsx +10 -12
  92. package/src/ssr/LayoutHeader.tsx +14 -2
  93. package/src/ssr/LayoutHelp.tsx +2 -4
  94. package/src/ssr/LayoutRail.tsx +13 -4
  95. package/src/ssr/MinimalLayoutPreferences.island.tsx +1 -1
  96. package/src/ssr/MobileProfileActions.tsx +19 -13
  97. package/src/ssr/PageError.tsx +23 -1
  98. package/src/ssr/ProfilePreferences.island.tsx +9 -1
  99. package/src/ssr/PwaLayout.tsx +70 -0
  100. package/src/ssr/PwaRuntime.island.tsx +105 -0
  101. package/src/ssr/TimezoneCookie.island.tsx +7 -1
  102. package/src/ssr/app-navigation.ts +25 -10
  103. package/src/ssr/index.ts +8 -1
  104. package/src/ssr/layout-context.ts +1 -1
  105. package/src/ssr/preference-controller.ts +2 -2
  106. package/src/ssr/profile-actions.ts +3 -1
  107. package/src/ssr/profile-preferences-messages.ts +2 -0
  108. package/src/ssr/pwa-messages.ts +24 -0
  109. package/src/styles/global.css +6 -0
  110. package/src/styles/resource-search.css +19 -0
  111. package/src/styles/utilities-feedback.css +2 -2
  112. package/scripts/build-pdf-renderer.ts +0 -39
  113. package/src/ai/client/live-connection.ts +0 -141
  114. package/src/ai/live-messages.ts +0 -45
  115. package/src/ai/live-outbox.ts +0 -102
  116. package/src/ai/live-routes.ts +0 -412
  117. package/src/shared/markdown/extensions/info-blocks.ts +0 -108
@@ -0,0 +1,16 @@
1
+ import { createHash, randomBytes, randomInt, timingSafeEqual } from "node:crypto";
2
+
3
+ /** Shared by Cloud Login and mobile app pairing: secrets are stored only as SHA-256 hex. */
4
+ export const pairingSecret = {
5
+ /** 32 random bytes, base64url without padding (43 characters). */
6
+ create: (): string => randomBytes(32).toString("base64url"),
7
+ hash: (value: string): string => createHash("sha256").update(value).digest("hex"),
8
+ /** Timing-safe comparison of a presented secret with a stored hash. */
9
+ matches: (value: string, expectedHash: string): boolean => {
10
+ const expected = Buffer.from(expectedHash, "hex");
11
+ const actual = Buffer.from(pairingSecret.hash(value), "hex");
12
+ return expected.length === actual.length && timingSafeEqual(actual, expected);
13
+ },
14
+ /** A six-digit code with leading zeros. */
15
+ code: (): string => String(randomInt(0, 1_000_000)).padStart(6, "0"),
16
+ };
@@ -1,3 +1,4 @@
1
+ import { markdownInfoBlocks } from "@k2b/ui";
1
2
  import { Marked, Renderer, type Tokens } from "marked";
2
3
  import postcss from "postcss";
3
4
  import {
@@ -122,6 +123,25 @@ hr { border: 0; border-top: 1px solid #d1d5db; margin: .9em 0; }
122
123
  `,
123
124
  };
124
125
 
126
+ /**
127
+ * Markdown info blocks print as the calm NoticeCard: a light tint per tone, no
128
+ * border, and the preset's own text colour, so they stay readable on paper.
129
+ * The tints are a step stronger than on screen because paper and printers wash
130
+ * them out. Every preset and application document shares them.
131
+ */
132
+ const INFO_BLOCK_PRINT_CSS = `
133
+ .k2b-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
134
+ .k2b-notice-card { margin: 0 0 1em; padding: .85em 1.05em; border-radius: .8em; background: var(--notice-tint); break-inside: avoid; print-color-adjust: exact; -webkit-print-color-adjust: exact; }
135
+ .k2b-notice-card[data-tone="neutral"] { --notice-tint: #f1f2f4; }
136
+ .k2b-notice-card[data-tone="info"] { --notice-tint: #e9f1fe; }
137
+ .k2b-notice-card[data-tone="success"] { --notice-tint: #e6f6ee; }
138
+ .k2b-notice-card[data-tone="warning"] { --notice-tint: #fcf2da; }
139
+ .k2b-notice-card[data-tone="danger"] { --notice-tint: #fcebeb; }
140
+ .k2b-notice-card__title { margin: 0 0 .25em; font-weight: 600; }
141
+ .k2b-notice-card__body > :first-child { margin-top: 0; }
142
+ .k2b-notice-card__body > :last-child { margin-bottom: 0; }
143
+ `;
144
+
125
145
  const byteLength = (value: string): number => new TextEncoder().encode(value).byteLength;
126
146
 
127
147
  const escapeHtml = (value: string): string =>
@@ -156,7 +176,7 @@ const renderMarkdown = (source: string): string => {
156
176
  return `<a href="${escapeHtml(safeHref)}"${titleAttribute}>${body}</a>`;
157
177
  };
158
178
 
159
- const parser = new Marked({ breaks: true, gfm: true, renderer });
179
+ const parser = new Marked({ breaks: true, gfm: true, renderer }, markdownInfoBlocks());
160
180
  try {
161
181
  return parser.parse(source, { async: false }) as string;
162
182
  } catch (cause) {
@@ -216,7 +236,7 @@ export const buildPresetPdfHtml = (input: BuildPresetPdfHtmlInput): string => {
216
236
  const suppliedCustomCss = input.customCss?.trim() ?? "";
217
237
  const customCss = suppliedCustomCss ? validateCustomCss(input.customCss ?? "") : "";
218
238
  const presetCss = templateId ? TEMPLATE_CSS[templateId] : customCss ? "" : TEMPLATE_CSS.document;
219
- const baseCss = [presetCss, input.css ? styleText(input.css) : ""].filter(Boolean).join("\n");
239
+ const baseCss = [presetCss, INFO_BLOCK_PRINT_CSS, input.css ? styleText(input.css) : ""].filter(Boolean).join("\n");
220
240
  const stylesheet = `${baseCss}${baseCss && customCss ? `\n/* Custom CSS overrides */\n` : ""}${customCss}`;
221
241
  return `<!doctype html>
222
242
  <html lang="en">