@frockbot/cloudflare 0.0.0 → 0.7.291

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 (88) hide show
  1. package/build-artifact.ts +130 -0
  2. package/build-flutter-web.ts +508 -0
  3. package/deployment-config/README.md +414 -0
  4. package/deployment-config/cli.ts +228 -0
  5. package/deployment-config/generate.ts +689 -0
  6. package/deployment-config/jsonc.ts +18 -0
  7. package/deployment-config/profile-schema.generated.ts +391 -0
  8. package/deployment-config/profile.schema.json +358 -0
  9. package/deployment-config/profile.ts +124 -0
  10. package/migrations/0001_better_auth.sql +15 -0
  11. package/migrations/0002_drop_account_issuer.sql +8 -0
  12. package/package.json +61 -5
  13. package/release-version.ts +20 -0
  14. package/src/account-admission.ts +179 -0
  15. package/src/account-deletion.ts +274 -0
  16. package/src/admin-entrypoint.ts +194 -0
  17. package/src/admin-identities.ts +26 -0
  18. package/src/audit.ts +103 -0
  19. package/src/auth-package.access.ts +24 -0
  20. package/src/auth-package.ts +36 -0
  21. package/src/avatar-state-cleanup.ts +107 -0
  22. package/src/billing-computer.ts +267 -0
  23. package/src/billing-readiness.ts +21 -0
  24. package/src/billing.ts +461 -0
  25. package/src/bot-capabilities.ts +480 -0
  26. package/src/bot-recovery.ts +1 -0
  27. package/src/bot-state-channel.ts +702 -0
  28. package/src/bot-state.ts +3995 -0
  29. package/src/bot-template-cleanup.ts +98 -0
  30. package/src/bot-title-cleanup.ts +104 -0
  31. package/src/brand-icon.png +0 -0
  32. package/src/brand-logo.ts +2 -0
  33. package/src/brand.ts +36 -0
  34. package/src/client-compatibility.ts +51 -0
  35. package/src/compaction-announcement-cleanup.ts +113 -0
  36. package/src/computer-egress.ts +110 -0
  37. package/src/computer-host.ts +92 -0
  38. package/src/computer-screenshot-cleanup.ts +78 -0
  39. package/src/contracts.ts +832 -0
  40. package/src/debug.ts +272 -0
  41. package/src/default-packages-marker-cleanup.ts +39 -0
  42. package/src/deployment-policy-admin-host.ts +121 -0
  43. package/src/deployment-policy.ts +426 -0
  44. package/src/directory-profile-cleanup.ts +101 -0
  45. package/src/durable-rpc.ts +753 -0
  46. package/src/durable-session.ts +21 -0
  47. package/src/entry-boundary.ts +103 -0
  48. package/src/frock-ai.ts +338 -0
  49. package/src/gateway.ts +1392 -0
  50. package/src/group-chat.ts +736 -0
  51. package/src/hidden-bot-notifications-cleanup.ts +32 -0
  52. package/src/index.ts +2798 -0
  53. package/src/insights.ts +15 -0
  54. package/src/machine-messages-cleanup.ts +121 -0
  55. package/src/machine-socket.ts +164 -0
  56. package/src/memory-records.ts +181 -0
  57. package/src/memory.ts +145 -0
  58. package/src/model-rates.ts +252 -0
  59. package/src/native-auth.ts +1006 -0
  60. package/src/native-sessions.ts +121 -0
  61. package/src/notification-state-cleanup.ts +18 -0
  62. package/src/ollama-web-search-cleanup.ts +69 -0
  63. package/src/package-page-shapes-cleanup.ts +190 -0
  64. package/src/plugin-egress.ts +31 -0
  65. package/src/plugin-page-route.ts +72 -0
  66. package/src/plugin-panels-cleanup.ts +101 -0
  67. package/src/prepared-input-cleanup.ts +105 -0
  68. package/src/production-secrets.ts +484 -0
  69. package/src/project-cleanup.ts +123 -0
  70. package/src/project-events-cleanup.ts +152 -0
  71. package/src/publication-state-cleanup.ts +92 -0
  72. package/src/push.ts +498 -0
  73. package/src/request-body.ts +165 -0
  74. package/src/routine-state-cleanup.ts +57 -0
  75. package/src/search.ts +88 -0
  76. package/src/sidebar-label-cleanup.ts +165 -0
  77. package/src/skill-index-cleanup.ts +53 -0
  78. package/src/supersede-cleanup.ts +162 -0
  79. package/src/test-chat-cleanup.ts +93 -0
  80. package/src/uploads.ts +486 -0
  81. package/src/user-application.ts +1068 -0
  82. package/src/user-configuration.ts +4491 -0
  83. package/src/voice-assistant.ts +4999 -0
  84. package/src/voice-dictation.ts +743 -0
  85. package/src/working-context-cleanup.ts +96 -0
  86. package/src/workspace.ts +201 -0
  87. package/wrangler.jsonc +385 -0
  88. package/README.md +0 -3
@@ -0,0 +1,391 @@
1
+ import type { FromSchema } from "json-schema-to-ts";
2
+
3
+ export const DEPLOYMENT_PROFILE_SCHEMA_V1 = {
4
+ $schema: "http://json-schema.org/draft-07/schema#",
5
+ $id: "https://frockbot.com/schemas/deployment-profile-v1.json",
6
+ title: "FrockBot deployment profile",
7
+ description:
8
+ "Who a deployment is: the Cloudflare account, the Worker names, the hostnames, the auth Package and the resources that carry identity. `frockbot-deployment-config` (`bun run deployment:config` in the FrockBot repository) reads one of these and writes the deployable wrangler configs from the tracked ones, which hold bindings and migrations and no identity at all.",
9
+ type: "object",
10
+ additionalProperties: false,
11
+ required: ["schemaVersion", "name", "accountId", "prefix", "authPackage"],
12
+ properties: {
13
+ schemaVersion: {
14
+ const: 1,
15
+ },
16
+ name: {
17
+ description:
18
+ "The profile's own name. Must match the file name, and names the directory under `.deployment/`.",
19
+ type: "string",
20
+ pattern: "^[a-z0-9][a-z0-9-]*$",
21
+ },
22
+ accountId: {
23
+ description:
24
+ "The Cloudflare account every Worker in this deployment belongs to.",
25
+ type: "string",
26
+ pattern: "^[0-9a-f]{32}$",
27
+ },
28
+ region: {
29
+ description:
30
+ "Where a fresh deployment's R2 buckets and Vectorize index are created. The installer passes it; no wrangler config carries it, so changing it never moves an existing resource.",
31
+ type: "string",
32
+ enum: ["wnam", "enam", "weur", "eeur", "apac", "oc"],
33
+ },
34
+ prefix: {
35
+ description:
36
+ "What every unnamed Worker and resource below is named from.",
37
+ type: "string",
38
+ pattern: "^[a-z0-9][a-z0-9-]*$",
39
+ },
40
+ workers: {
41
+ description:
42
+ "One entry per deployable. An entry that is absent is not generated and not deployed, which is how a profile leaves out the hosted-only marketing site and admin portal.",
43
+ type: "object",
44
+ additionalProperties: false,
45
+ properties: {
46
+ app: {
47
+ $ref: "#/$defs/worker",
48
+ },
49
+ computerHost: {
50
+ $ref: "#/$defs/worker",
51
+ },
52
+ appletBuild: {
53
+ $ref: "#/$defs/worker",
54
+ },
55
+ marketing: {
56
+ $ref: "#/$defs/worker",
57
+ },
58
+ adminPortal: {
59
+ $ref: "#/$defs/worker",
60
+ },
61
+ },
62
+ },
63
+ images: {
64
+ description:
65
+ "Where the two container Workers get their image. Absent is `dockerfile`: wrangler builds it on the deploying machine, which needs Docker. `registry` pulls the image `release.yml` published for one tag, which is what an installer with no Docker deploys.",
66
+ type: "object",
67
+ additionalProperties: false,
68
+ required: ["source"],
69
+ properties: {
70
+ source: {
71
+ enum: ["dockerfile", "registry"],
72
+ },
73
+ registry: {
74
+ description:
75
+ "The registry and namespace the images were published under, without the image name. It must be one Cloudflare Containers pull from: the managed registry, Docker Hub, Amazon ECR or Google Artifact Registry (see the README).",
76
+ type: "string",
77
+ pattern: "^[a-z0-9][a-z0-9.-]*(:[0-9]+)?(/[a-z0-9][a-z0-9._-]*)*$",
78
+ },
79
+ tag: {
80
+ description:
81
+ "The image tag, which is the release version the deployment is running.",
82
+ type: "string",
83
+ pattern: "^[A-Za-z0-9_][A-Za-z0-9._-]{0,127}$",
84
+ },
85
+ },
86
+ allOf: [
87
+ {
88
+ if: {
89
+ properties: {
90
+ source: {
91
+ const: "registry",
92
+ },
93
+ },
94
+ required: ["source"],
95
+ },
96
+ then: {
97
+ properties: {
98
+ registry: true,
99
+ tag: true,
100
+ },
101
+ required: ["registry", "tag"],
102
+ },
103
+ },
104
+ ],
105
+ },
106
+ authPackage: {
107
+ description:
108
+ "Which sign-in Package this deployment builds: one of the two `@frockbot/cloudflare` ships, or a path, relative to this profile file, to a chooser module a white-label wrote — a module exporting `AUTH_PACKAGE_V1: AuthPackageBuildV1` and the `AuthPackageEnvironmentV1` type, as `apps/cloudflare/src/auth-package.ts` does (ADR 0038 §3). Written as a wrangler `alias` for `#auth-package` unless it is `better-auth`, which the tracked source already resolves.",
109
+ anyOf: [
110
+ {
111
+ enum: ["better-auth", "access"],
112
+ },
113
+ {
114
+ type: "string",
115
+ pattern: "^\\.{1,2}/\\S+\\.(ts|mts|js|mjs)$",
116
+ },
117
+ ],
118
+ },
119
+ authEnvironment: {
120
+ description:
121
+ "What a white-label's own auth Package reads off `env`, which this repository cannot know: `secrets` are required by the production-secrets check and carried by the deploy's secrets file, and `vars` are written into the app Worker's `vars`. Together they must name exactly the settings the chooser's `AUTH_PACKAGE_V1.required` lists. Only for an auth Package named by path.",
122
+ type: "object",
123
+ additionalProperties: false,
124
+ properties: {
125
+ secrets: {
126
+ type: "array",
127
+ uniqueItems: true,
128
+ items: {
129
+ type: "object",
130
+ additionalProperties: false,
131
+ required: ["name", "why"],
132
+ properties: {
133
+ name: {
134
+ $ref: "#/$defs/envName",
135
+ },
136
+ why: {
137
+ type: "string",
138
+ minLength: 1,
139
+ },
140
+ },
141
+ },
142
+ },
143
+ vars: {
144
+ type: "object",
145
+ propertyNames: {
146
+ $ref: "#/$defs/envName",
147
+ },
148
+ additionalProperties: {
149
+ type: "string",
150
+ },
151
+ },
152
+ },
153
+ },
154
+ brand: {
155
+ description:
156
+ "The brand module this deployment builds, relative to this profile file: a TypeScript module exporting `BRAND_V1: BrandV1` (`core/contracts/brand.ts`). Written as a wrangler `alias` for `#brand`. Absent, the Worker resolves `#brand` to FrockBot's own, `apps/cloudflare/src/brand.ts`.",
157
+ type: "string",
158
+ pattern: "^\\S+\\.ts$",
159
+ },
160
+ webClient: {
161
+ description:
162
+ "The directory the app Worker's static assets are uploaded from, relative to this profile file: the web client `build-flutter-web.ts` staged for this deployment's own application. Absent, the package's own `dist/web`, which is where FrockBot's build stages FrockBot's client.",
163
+ type: "string",
164
+ minLength: 1,
165
+ },
166
+ access: {
167
+ description:
168
+ "The Cloudflare Access application the `access` Package verifies against. Written as the `ACCESS_TEAM_DOMAIN` and `ACCESS_AUD` vars.",
169
+ type: "object",
170
+ additionalProperties: false,
171
+ required: ["teamDomain", "aud"],
172
+ properties: {
173
+ teamDomain: {
174
+ $ref: "#/$defs/hostname",
175
+ },
176
+ aud: {
177
+ type: "string",
178
+ pattern: "^[0-9a-f]{64}$",
179
+ },
180
+ },
181
+ },
182
+ adminEmails: {
183
+ description:
184
+ "The deployment's admins: they bypass admission, and a debug Turn may act as one of them. The debug surface itself is gated on `DEBUG_TOKEN`. The installer sets it as the Worker secret `FROCKBOT_ADMIN_EMAILS`; no generated config carries it, which is why the hosted profile leaves it to the repository secret it already has.",
185
+ type: "array",
186
+ minItems: 1,
187
+ items: {
188
+ $ref: "#/$defs/email",
189
+ },
190
+ },
191
+ d1DatabaseId: {
192
+ description:
193
+ "The `AUTH_DB` database. Required by the `better-auth` Package unless the deploy supplies it with `--d1-database-id`, which is how a disposable stage names a database it creates in the same job.",
194
+ type: "string",
195
+ pattern: "^[0-9a-fA-F-]{36}$",
196
+ },
197
+ aiGateway: {
198
+ description:
199
+ "The AI Gateway that serves the platform model. Absent, the Worker takes the `AI` binding and Auto resolves to a concrete Workers AI model.",
200
+ type: "object",
201
+ additionalProperties: false,
202
+ required: ["accountId"],
203
+ properties: {
204
+ accountId: {
205
+ description:
206
+ "The account owning the Gateway. Present with the `FROCK_AI_GATEWAY_TOKEN` secret, requests take the compat HTTP transport — the only one that accepts a dynamic route.",
207
+ type: "string",
208
+ pattern: "^[0-9a-f]{32}$",
209
+ },
210
+ id: {
211
+ type: "string",
212
+ pattern: "^[A-Za-z0-9-]+$",
213
+ },
214
+ autoRoute: {
215
+ type: "string",
216
+ pattern: "^[A-Za-z0-9-]+$",
217
+ },
218
+ },
219
+ },
220
+ nativeAuth: {
221
+ description:
222
+ "The native returns this deployment serves: `android`, the released Mac and iPhone apps (`macos`, `ios`), and the FrockBot Dev builds (`macos-dev`, `ios-dev`), each named only where such a build signs in. Nothing is implied by another entry. Absent, the deployment offers no native sign-in at all.",
223
+ type: "array",
224
+ minItems: 1,
225
+ uniqueItems: true,
226
+ items: {
227
+ type: "string",
228
+ enum: ["android", "macos", "macos-dev", "ios", "ios-dev"],
229
+ },
230
+ },
231
+ nativeApps: {
232
+ description:
233
+ "The signed native apps this deployment's App Links and Universal Links name, in `/.well-known/assetlinks.json` and `/.well-known/apple-app-site-association`. Written as the `NATIVE_APPS` var. Absent, the deployment serves neither file.",
234
+ type: "object",
235
+ additionalProperties: false,
236
+ properties: {
237
+ android: {
238
+ description:
239
+ "Each Android app by package name, with the SHA-256 fingerprints of the certificates that sign it.",
240
+ type: "array",
241
+ minItems: 1,
242
+ items: {
243
+ type: "object",
244
+ additionalProperties: false,
245
+ required: ["packageName", "sha256CertFingerprints"],
246
+ properties: {
247
+ packageName: {
248
+ type: "string",
249
+ pattern: "^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$",
250
+ },
251
+ sha256CertFingerprints: {
252
+ type: "array",
253
+ minItems: 1,
254
+ uniqueItems: true,
255
+ items: {
256
+ type: "string",
257
+ pattern: "^[0-9A-F]{2}(:[0-9A-F]{2}){31}$",
258
+ },
259
+ },
260
+ },
261
+ },
262
+ },
263
+ apple: {
264
+ description:
265
+ "The Apple app ids (`<team id>.<bundle id>`) the association names for the released Mac and iPhone returns.",
266
+ type: "array",
267
+ minItems: 1,
268
+ uniqueItems: true,
269
+ items: {
270
+ type: "string",
271
+ pattern: "^[A-Z0-9]{10}\\.[A-Za-z0-9.-]+$",
272
+ },
273
+ },
274
+ },
275
+ },
276
+ email: {
277
+ description:
278
+ "Email to and from Bots, both directions on one domain. Each Bot's address is `<bot-slug>.<username>@<domain>`. The domain becomes the app Worker's `EMAIL_DOMAIN` var, which the `email()` handler receives mail for, and the app Worker gains a `send_email` binding named `SEND_EMAIL`, through which each Bot sends from its own address on that domain and no other. Absent, no Bot has an address, every message is refused and nothing is sent. The domain's Email Routing catch-all and its onboarding for Email Sending are set up in Cloudflare by hand: see `apps/cloudflare/deployment-config/README.md`.",
279
+ type: "object",
280
+ additionalProperties: false,
281
+ required: ["domain"],
282
+ properties: {
283
+ domain: {
284
+ $ref: "#/$defs/hostname",
285
+ },
286
+ },
287
+ },
288
+ resources: {
289
+ description:
290
+ "Names that carry identity. Each is derived from `prefix` when absent.",
291
+ type: "object",
292
+ additionalProperties: false,
293
+ properties: {
294
+ applicationArtifactsBucket: {
295
+ $ref: "#/$defs/resourceName",
296
+ },
297
+ memoryFilesBucket: {
298
+ $ref: "#/$defs/resourceName",
299
+ },
300
+ memoryIndex: {
301
+ $ref: "#/$defs/resourceName",
302
+ },
303
+ authDatabaseName: {
304
+ $ref: "#/$defs/resourceName",
305
+ },
306
+ },
307
+ },
308
+ },
309
+ allOf: [
310
+ {
311
+ if: {
312
+ properties: {
313
+ authPackage: {
314
+ const: "access",
315
+ },
316
+ },
317
+ required: ["authPackage"],
318
+ },
319
+ then: {
320
+ properties: {
321
+ access: true,
322
+ },
323
+ required: ["access"],
324
+ },
325
+ },
326
+ {
327
+ if: {
328
+ properties: {
329
+ authPackage: {
330
+ enum: ["better-auth", "access"],
331
+ },
332
+ },
333
+ required: ["authPackage"],
334
+ },
335
+ then: {
336
+ properties: {
337
+ authEnvironment: false,
338
+ },
339
+ },
340
+ else: {
341
+ properties: {
342
+ authEnvironment: true,
343
+ },
344
+ required: ["authEnvironment"],
345
+ },
346
+ },
347
+ ],
348
+ $defs: {
349
+ worker: {
350
+ type: "object",
351
+ additionalProperties: false,
352
+ properties: {
353
+ name: {
354
+ $ref: "#/$defs/resourceName",
355
+ },
356
+ hostnames: {
357
+ description:
358
+ "Custom domains this Worker answers on. Absent, the Worker takes its `workers.dev` hostname, which is what a deployment with no zone has.",
359
+ type: "array",
360
+ minItems: 1,
361
+ items: {
362
+ $ref: "#/$defs/hostname",
363
+ },
364
+ },
365
+ },
366
+ },
367
+ hostname: {
368
+ type: "string",
369
+ pattern:
370
+ "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$",
371
+ },
372
+ email: {
373
+ type: "string",
374
+ pattern: "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
375
+ },
376
+ resourceName: {
377
+ type: "string",
378
+ pattern: "^[a-z0-9][a-z0-9-]*$",
379
+ maxLength: 63,
380
+ },
381
+ envName: {
382
+ type: "string",
383
+ pattern: "^[A-Z][A-Z0-9_]*$",
384
+ },
385
+ },
386
+ } as const;
387
+
388
+ export type DeploymentProfileV1 = FromSchema<
389
+ typeof DEPLOYMENT_PROFILE_SCHEMA_V1,
390
+ { parseIfThenElseKeywords: true }
391
+ >;