@hachej/boring-core 0.1.84 → 0.1.85

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.
@@ -1,5 +1,5 @@
1
1
  import postgres from 'postgres';
2
- import { C as CoreConfig } from './types-DKCtYltp.js';
2
+ import { C as CoreConfig } from './types-BIjRgbMV.js';
3
3
  import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
4
4
 
5
5
  type CoreMigrationSql = postgres.Sql;
@@ -9,12 +9,12 @@ import {
9
9
  useSignIn,
10
10
  useSignUp,
11
11
  useWorkspaceRouteStatus
12
- } from "../../chunk-6G6Z52VQ.js";
12
+ } from "../../chunk-JLBUXSC5.js";
13
13
  import "../../chunk-HYNKZSTF.js";
14
14
  import {
15
15
  isRuntimeEmailVerificationEnabled
16
16
  } from "../../chunk-I4PGL4ZD.js";
17
- import "../../chunk-VWE46RW4.js";
17
+ import "../../chunk-RTLBMHOB.js";
18
18
  import "../../chunk-MLKGABMK.js";
19
19
 
20
20
  // src/app/front/CoreWorkspaceAgentFront.tsx
@@ -0,0 +1,288 @@
1
+ /*
2
+ * Styling for `PublicLaunchPages` — the tab strip + preview pane apps use to
3
+ * showcase artifact/calendly/HTML demo pages on the public (no-auth) launch
4
+ * screen. Brand-agnostic and token-driven so every consumer inherits it
5
+ * without re-copying the sheet. Imported via the package's `styles.css`
6
+ * entry.
7
+ */
8
+
9
+ .public-pages-pane {
10
+ display: flex;
11
+ height: 100%;
12
+ min-height: 0;
13
+ flex-direction: column;
14
+ gap: 8px;
15
+ padding: 10px;
16
+ color: var(--foreground);
17
+ }
18
+
19
+ .public-pages-pane-header {
20
+ margin-bottom: 8px;
21
+ }
22
+
23
+ .public-pages-pane-header p {
24
+ margin: 0 0 6px;
25
+ color: var(--muted-foreground);
26
+ font-size: 10px;
27
+ font-weight: 800;
28
+ letter-spacing: 0.14em;
29
+ text-transform: uppercase;
30
+ }
31
+
32
+ .public-pages-pane-header h2 {
33
+ margin: 0;
34
+ font-size: 18px;
35
+ letter-spacing: -0.03em;
36
+ }
37
+
38
+ .public-pages-pane-header span,
39
+ .public-pages-pane-note span {
40
+ display: block;
41
+ margin-top: 6px;
42
+ color: var(--muted-foreground);
43
+ font-size: 12px;
44
+ line-height: 1.45;
45
+ }
46
+
47
+ .public-pages-pane button {
48
+ display: flex;
49
+ width: 100%;
50
+ flex-direction: column;
51
+ align-items: flex-start;
52
+ gap: 4px;
53
+ border: 1px solid transparent;
54
+ border-radius: 10px;
55
+ background: transparent;
56
+ color: var(--foreground);
57
+ cursor: pointer;
58
+ padding: 9px 11px;
59
+ text-align: left;
60
+ transition: background 0.15s ease, border-color 0.15s ease;
61
+ }
62
+
63
+ .public-pages-pane button strong {
64
+ font-size: 13px;
65
+ font-weight: 600;
66
+ letter-spacing: -0.01em;
67
+ }
68
+
69
+ .public-pages-pane button:hover {
70
+ border-color: var(--border);
71
+ background: var(--muted);
72
+ }
73
+
74
+ .public-pages-pane button span {
75
+ color: var(--muted-foreground);
76
+ font: 600 11.5px/1.3 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
77
+ }
78
+
79
+ .public-pages-pane-note {
80
+ margin-top: auto;
81
+ border: 1px solid var(--border);
82
+ border-radius: 16px;
83
+ background: color-mix(in oklch, var(--card) 80%, var(--background));
84
+ padding: 12px;
85
+ }
86
+
87
+ .public-html-preview {
88
+ display: block;
89
+ width: 100%;
90
+ height: 100%;
91
+ min-height: 0;
92
+ border: 0;
93
+ background: var(--background);
94
+ }
95
+
96
+ .public-workspace-tab {
97
+ min-height: 100%;
98
+ overflow: auto;
99
+ padding: 24px;
100
+ background:
101
+ radial-gradient(circle at 70% 0%, color-mix(in oklch, var(--primary) 12%, transparent), transparent 34rem),
102
+ var(--background);
103
+ }
104
+
105
+ .artifact-header {
106
+ display: flex;
107
+ align-items: flex-start;
108
+ justify-content: space-between;
109
+ gap: 20px;
110
+ margin: 0 auto 22px;
111
+ max-width: 980px;
112
+ }
113
+
114
+ .artifact-header p {
115
+ margin: 0 0 8px;
116
+ color: var(--muted-foreground);
117
+ font-size: 11px;
118
+ font-weight: 800;
119
+ letter-spacing: 0.14em;
120
+ text-transform: uppercase;
121
+ }
122
+
123
+ .artifact-header h1 {
124
+ margin: 0;
125
+ font-size: clamp(32px, 5vw, 56px);
126
+ line-height: 0.95;
127
+ letter-spacing: -0.055em;
128
+ }
129
+
130
+ .artifact-header span {
131
+ display: block;
132
+ margin-top: 12px;
133
+ max-width: 560px;
134
+ color: var(--muted-foreground);
135
+ font-size: 15px;
136
+ line-height: 1.6;
137
+ }
138
+
139
+ .artifact-header button {
140
+ border: 1px solid var(--foreground);
141
+ border-radius: 999px;
142
+ background: var(--foreground);
143
+ color: var(--background);
144
+ cursor: pointer;
145
+ padding: 11px 16px;
146
+ font-size: 13px;
147
+ font-weight: 700;
148
+ }
149
+
150
+ .artifact-card {
151
+ margin: 0 auto;
152
+ max-width: 980px;
153
+ border: 1px solid var(--border);
154
+ border-radius: 28px;
155
+ background: color-mix(in oklch, var(--card) 88%, transparent);
156
+ box-shadow: 0 24px 80px color-mix(in oklch, var(--foreground) 10%, transparent);
157
+ padding: clamp(24px, 5vw, 48px);
158
+ }
159
+
160
+ .artifact-kicker {
161
+ margin: 0 0 16px;
162
+ color: var(--muted-foreground);
163
+ font-size: 12px;
164
+ font-weight: 800;
165
+ letter-spacing: 0.16em;
166
+ text-transform: uppercase;
167
+ }
168
+
169
+ .artifact-card h2 {
170
+ margin: 0;
171
+ max-width: 760px;
172
+ font-size: clamp(36px, 7vw, 76px);
173
+ line-height: 0.92;
174
+ letter-spacing: -0.07em;
175
+ }
176
+
177
+ .artifact-card p {
178
+ max-width: 680px;
179
+ color: var(--muted-foreground);
180
+ font-size: 17px;
181
+ line-height: 1.65;
182
+ }
183
+
184
+ .artifact-actions {
185
+ display: flex;
186
+ flex-wrap: wrap;
187
+ gap: 12px;
188
+ margin: 28px 0;
189
+ }
190
+
191
+ .artifact-actions a {
192
+ border: 1px solid var(--border);
193
+ border-radius: 999px;
194
+ padding: 11px 15px;
195
+ color: var(--foreground);
196
+ font-size: 13px;
197
+ font-weight: 700;
198
+ text-decoration: none;
199
+ }
200
+
201
+ .artifact-feature-grid {
202
+ display: grid;
203
+ grid-template-columns: repeat(3, minmax(0, 1fr));
204
+ gap: 12px;
205
+ margin-top: 30px;
206
+ }
207
+
208
+ .artifact-feature-grid div {
209
+ border: 1px solid var(--border);
210
+ border-radius: 18px;
211
+ background: var(--background);
212
+ padding: 16px;
213
+ }
214
+
215
+ .artifact-feature-grid strong,
216
+ .artifact-feature-grid span {
217
+ display: block;
218
+ }
219
+
220
+ .artifact-feature-grid span {
221
+ margin-top: 8px;
222
+ color: var(--muted-foreground);
223
+ font-size: 13px;
224
+ line-height: 1.45;
225
+ }
226
+
227
+ .chat-artifact {
228
+ display: grid;
229
+ grid-template-columns: minmax(0, 0.85fr) minmax(320px, 1.15fr);
230
+ gap: 24px;
231
+ align-items: stretch;
232
+ }
233
+
234
+ .chat-artifact h2 {
235
+ font-size: clamp(34px, 5vw, 58px);
236
+ }
237
+
238
+ .calendly-frame-wrap {
239
+ min-height: 620px;
240
+ overflow: hidden;
241
+ border: 1px solid var(--border);
242
+ border-radius: 22px;
243
+ background: var(--background);
244
+ }
245
+
246
+ .calendly-frame {
247
+ width: 100%;
248
+ height: 720px;
249
+ border: 0;
250
+ }
251
+
252
+ .calendly-frame-full {
253
+ display: block;
254
+ height: 100%;
255
+ min-height: 760px;
256
+ background: var(--background);
257
+ }
258
+
259
+ .calendly-placeholder {
260
+ display: flex;
261
+ height: 100%;
262
+ min-height: 520px;
263
+ flex-direction: column;
264
+ align-items: center;
265
+ justify-content: center;
266
+ gap: 10px;
267
+ padding: 28px;
268
+ text-align: center;
269
+ }
270
+
271
+ .calendly-placeholder span {
272
+ max-width: 360px;
273
+ color: var(--muted-foreground);
274
+ font-size: 14px;
275
+ line-height: 1.5;
276
+ }
277
+
278
+ @media (max-width: 860px) {
279
+ .artifact-header,
280
+ .chat-artifact,
281
+ .artifact-feature-grid {
282
+ grid-template-columns: 1fr;
283
+ }
284
+
285
+ .artifact-header {
286
+ flex-direction: column;
287
+ }
288
+ }
@@ -9,6 +9,23 @@
9
9
  its plain rules sit after Tailwind's utilities in the cascade. */
10
10
  @import "./chatFirst/chatFirstPublicShell.css";
11
11
 
12
+ /* Styling for PublicLaunchPages (artifact/calendly/HTML demo tabs on the
13
+ public launch screen). Imported last for the same cascade-ordering reason
14
+ as chatFirstPublicShell.css above. */
15
+ @import "./publicLaunchPages.css";
16
+
17
+ /* Full-bleed app shell: the React root fills the viewport with no scroll
18
+ chrome of its own (panes manage their own overflow). Every app-shell
19
+ consumer needs this, so it ships from the package instead of being
20
+ copy-pasted per app. */
21
+ html,
22
+ body,
23
+ #root {
24
+ height: 100%;
25
+ margin: 0;
26
+ overflow: hidden;
27
+ }
28
+
12
29
  /* Credit notice CTA renders inside the agent subtree. Keep this selector after
13
30
  Tailwind + agent globals so it beats both the Button variant colors and
14
31
  [data-boring-agent] button color reset. */
@@ -2,11 +2,11 @@ import { RuntimeProvisioningContribution, RegisterAgentRoutesOptions } from '@ha
2
2
  import { DirPluginEntry, CreateWorkspaceAgentServerOptions, WorkspaceAgentServerPluginContext } from '@hachej/boring-workspace/app/server';
3
3
  import { WorkspaceServerPlugin, WorkspaceBridgeOperationDefinition, WorkspaceBridgeHandler, WorkspaceBridgeRuntimeEnvOptions, WorkspaceBridgeCallRequest, WorkspaceBridgeCallResponse } from '@hachej/boring-workspace/server';
4
4
  import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify';
5
- import { C as CoreConfig } from '../../types-DKCtYltp.js';
5
+ import { C as CoreConfig } from '../../types-BIjRgbMV.js';
6
6
  import { T as TelemetrySink } from '../../telemetry-DR18MeI0.js';
7
- import { B as BetterAuthInstance, L as LoadConfigOptions } from '../../loadConfig-DEG0Tu5n.js';
8
- import { D as Database, U as UserStore, W as WorkspaceStore, C as CoreRequestScopeResolver } from '../../types-uK6CFlxr.js';
9
- export { a as CoreRequestScope } from '../../types-uK6CFlxr.js';
7
+ import { B as BetterAuthInstance, L as LoadConfigOptions } from '../../loadConfig-Bw6jtipE.js';
8
+ import { D as Database, U as UserStore, W as WorkspaceStore, C as CoreRequestScopeResolver } from '../../types-C5xuRqmA.js';
9
+ export { a as CoreRequestScope } from '../../types-C5xuRqmA.js';
10
10
  import { IncomingMessage, ServerResponse } from 'node:http';
11
11
  import 'better-auth';
12
12
  import 'drizzle-orm/postgres-js';
@@ -10,13 +10,13 @@ import {
10
10
  registerRoutes,
11
11
  registerSettingsRoutes,
12
12
  registerWorkspaceRoutes
13
- } from "../../chunk-MWOZRTRG.js";
13
+ } from "../../chunk-ONZ6UPYK.js";
14
14
  import {
15
15
  PostgresUserStore,
16
16
  PostgresWorkspaceStore,
17
17
  createDatabase,
18
18
  telemetryEvents
19
- } from "../../chunk-C4YTZAZC.js";
19
+ } from "../../chunk-WRFEUAG7.js";
20
20
  import {
21
21
  noopTelemetry,
22
22
  safeCapture
@@ -25,7 +25,7 @@ import "../../chunk-I4PGL4ZD.js";
25
25
  import {
26
26
  ERROR_CODES,
27
27
  HttpError
28
- } from "../../chunk-VWE46RW4.js";
28
+ } from "../../chunk-RTLBMHOB.js";
29
29
  import "../../chunk-MLKGABMK.js";
30
30
 
31
31
  // src/app/server/createCoreWorkspaceAgentServer.ts
@@ -939,11 +939,12 @@ async function createCoreWorkspaceAgentServer(options = {}) {
939
939
  admitRuntimeOperation: options.admitEffect ? async (workspaceId) => {
940
940
  try {
941
941
  await options.admitEffect({ workspaceId, requestId: "workspace-bridge-runtime" });
942
- } catch {
942
+ } catch (error) {
943
+ const code = typeof error === "object" && error !== null && "code" in error && error.code === ERROR_CODES.D1_ADMISSION_IDENTITY_MISMATCH ? ERROR_CODES.D1_ADMISSION_IDENTITY_MISMATCH : ERROR_CODES.D1_ADMISSION_RECORD_FAILED;
943
944
  throw new HttpError({
944
945
  status: 500,
945
- code: ERROR_CODES.D1_ADMISSION_RECORD_FAILED,
946
- message: ERROR_CODES.D1_ADMISSION_RECORD_FAILED
946
+ code,
947
+ message: code
947
948
  });
948
949
  }
949
950
  } : void 0
@@ -9,7 +9,7 @@ import {
9
9
  ConfigFetchError,
10
10
  ERROR_CODES,
11
11
  HttpError
12
- } from "./chunk-VWE46RW4.js";
12
+ } from "./chunk-RTLBMHOB.js";
13
13
 
14
14
  // src/front/AppErrorBoundary.tsx
15
15
  import { Component } from "react";
@@ -13,7 +13,7 @@ import {
13
13
  workspaceRuntimes,
14
14
  workspaceSettings,
15
15
  workspaces
16
- } from "./chunk-C4YTZAZC.js";
16
+ } from "./chunk-WRFEUAG7.js";
17
17
  import {
18
18
  noopTelemetry,
19
19
  safeCapture
@@ -25,7 +25,7 @@ import {
25
25
  ConfigValidationError,
26
26
  ERROR_CODES,
27
27
  HttpError
28
- } from "./chunk-VWE46RW4.js";
28
+ } from "./chunk-RTLBMHOB.js";
29
29
 
30
30
  // src/server/config/schema.ts
31
31
  import { z } from "zod";
@@ -259,10 +259,31 @@ function parseTrustedProxyPolicy(env) {
259
259
  }
260
260
  return void 0;
261
261
  }
262
- return {
263
- cidrs: (cidrs ?? "").split(",").map((value) => value.trim()),
262
+ return Object.freeze({
263
+ cidrs: Object.freeze(
264
+ (cidrs ?? "").split(",").map((value) => value.trim())
265
+ ),
264
266
  hops: hops !== void 0 && /^[1-8]$/.test(hops) ? Number(hops) : Number.NaN
265
- };
267
+ });
268
+ }
269
+ function readCoreSecurityConfigProjection(env) {
270
+ const betterAuthUrl = env.BETTER_AUTH_URL ?? `http://localhost:${env.PORT ?? "3000"}`;
271
+ const corsOriginsRaw = env.CORS_ORIGINS ?? "";
272
+ const corsOrigins = Object.freeze(
273
+ corsOriginsRaw ? corsOriginsRaw.split(",").map((origin) => origin.trim()).filter(Boolean) : ["http://localhost:3000", "http://localhost:5173"]
274
+ );
275
+ const cspUpgradeInsecureRequests = env.CSP_UPGRADE_INSECURE_REQUESTS !== void 0 ? env.CSP_UPGRADE_INSECURE_REQUESTS === "true" : betterAuthUrl.startsWith("https://");
276
+ const sessionCookieSecure = env.SESSION_COOKIE_SECURE !== void 0 ? env.SESSION_COOKIE_SECURE === "true" : betterAuthUrl.startsWith("https://");
277
+ return Object.freeze({
278
+ host: env.HOST ?? "0.0.0.0",
279
+ port: parseInt(env.PORT ?? "3000", 10),
280
+ betterAuthUrl,
281
+ corsOrigins,
282
+ cspEnabled: env.CSP_ENABLED !== "false",
283
+ cspUpgradeInsecureRequests,
284
+ sessionCookieSecure,
285
+ trustedProxy: parseTrustedProxyPolicy(env)
286
+ });
266
287
  }
267
288
  async function loadConfig(options) {
268
289
  const env = options?.env ?? process.env;
@@ -310,13 +331,6 @@ async function loadConfig(options) {
310
331
  `[config:insecure-defaults] Using placeholder values for: ${insecureDefaults.join(", ")}. Do NOT use in production.`
311
332
  );
312
333
  }
313
- const authUrl = env.BETTER_AUTH_URL ?? `http://localhost:${env.PORT ?? "3000"}`;
314
- const corsOriginsRaw = env.CORS_ORIGINS ?? "";
315
- const corsOrigins = corsOriginsRaw ? corsOriginsRaw.split(",").map((s) => s.trim()).filter(Boolean) : ["http://localhost:3000", "http://localhost:5173"];
316
- const cspEnabled = env.CSP_ENABLED !== "false";
317
- const cspUpgradeInsecureRequests = env.CSP_UPGRADE_INSECURE_REQUESTS !== void 0 ? env.CSP_UPGRADE_INSECURE_REQUESTS === "true" : authUrl.startsWith("https://");
318
- const sessionCookieSecureOverride = env.SESSION_COOKIE_SECURE;
319
- const sessionCookieSecure = sessionCookieSecureOverride !== void 0 ? sessionCookieSecureOverride === "true" : authUrl.startsWith("https://");
320
334
  const githubOauth = toml.features?.github_oauth ?? env.GITHUB_OAUTH === "true";
321
335
  const github = env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET ? {
322
336
  clientId: env.GITHUB_CLIENT_ID,
@@ -330,35 +344,37 @@ async function loadConfig(options) {
330
344
  const mailFrom = env.MAIL_FROM;
331
345
  const mailTransportUrl = env.MAIL_TRANSPORT_URL;
332
346
  const mail = mailFrom && mailTransportUrl ? { from: mailFrom, transportUrl: mailTransportUrl } : void 0;
347
+ const rateLimit2 = parseRateLimitOverrides(env.RATE_LIMIT_OVERRIDES_JSON);
348
+ const securityConfig = readCoreSecurityConfigProjection(env);
333
349
  const raw = {
334
350
  appId,
335
351
  appName,
336
352
  appLogo,
337
- port: parseInt(env.PORT ?? "3000", 10),
338
- host: env.HOST ?? "0.0.0.0",
353
+ port: securityConfig.port,
354
+ host: securityConfig.host,
339
355
  staticDir: env.STATIC_DIR ?? null,
340
356
  databaseUrl,
341
357
  stores,
342
358
  cors: {
343
- origins: corsOrigins,
359
+ origins: securityConfig.corsOrigins,
344
360
  credentials: true
345
361
  },
346
362
  bodyLimit: parseInt(env.BODY_LIMIT_BYTES ?? String(SIXTEEN_MB), 10),
347
363
  logLevel: env.LOG_LEVEL ?? "info",
348
- rateLimit: parseRateLimitOverrides(env.RATE_LIMIT_OVERRIDES_JSON),
364
+ rateLimit: rateLimit2,
349
365
  security: {
350
366
  csp: {
351
- enabled: cspEnabled,
352
- upgradeInsecureRequests: cspUpgradeInsecureRequests
367
+ enabled: securityConfig.cspEnabled,
368
+ upgradeInsecureRequests: securityConfig.cspUpgradeInsecureRequests
353
369
  },
354
- trustedProxy: parseTrustedProxyPolicy(env)
370
+ trustedProxy: securityConfig.trustedProxy
355
371
  },
356
372
  encryption: {
357
373
  workspaceSettingsKey: encryptionKey
358
374
  },
359
375
  auth: {
360
376
  secret: authSecret,
361
- url: authUrl,
377
+ url: securityConfig.betterAuthUrl,
362
378
  github,
363
379
  google,
364
380
  mail,
@@ -366,7 +382,7 @@ async function loadConfig(options) {
366
382
  env.SESSION_TTL_SECONDS ?? String(THIRTY_DAYS_SECONDS),
367
383
  10
368
384
  ),
369
- sessionCookieSecure
385
+ sessionCookieSecure: securityConfig.sessionCookieSecure
370
386
  },
371
387
  features: {
372
388
  githubOauth: githubOauth && github !== void 0,
@@ -3308,6 +3324,7 @@ function resourceToHandle(resource) {
3308
3324
 
3309
3325
  export {
3310
3326
  coreConfigSchema,
3327
+ readCoreSecurityConfigProjection,
3311
3328
  loadConfig,
3312
3329
  validateConfig,
3313
3330
  buildRuntimeConfigPayload,
@@ -30,6 +30,7 @@ var ERROR_CODES = {
30
30
  DB_UNAVAILABLE: "db_unavailable",
31
31
  INTERNAL_ERROR: "internal_error",
32
32
  D1_HOST_SCOPE_VIOLATION: "D1_HOST_SCOPE_VIOLATION",
33
+ D1_ADMISSION_IDENTITY_MISMATCH: "D1_ADMISSION_IDENTITY_MISMATCH",
33
34
  D1_ADMISSION_RECORD_FAILED: "D1_ADMISSION_RECORD_FAILED",
34
35
  D1_MANAGED_WORKSPACE_MUTATION_FORBIDDEN: "D1_MANAGED_WORKSPACE_MUTATION_FORBIDDEN",
35
36
  // Credits + purchases
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ERROR_CODES,
3
3
  HttpError
4
- } from "./chunk-VWE46RW4.js";
4
+ } from "./chunk-RTLBMHOB.js";
5
5
  import {
6
6
  __export
7
7
  } from "./chunk-MLKGABMK.js";
@@ -566,6 +566,7 @@ __export(schema_exports, {
566
566
  creditGrants: () => creditGrants,
567
567
  creditPurchases: () => creditPurchases,
568
568
  d1BindingAdmissions: () => d1BindingAdmissions,
569
+ d1DestructivePublicationEvents: () => d1DestructivePublicationEvents,
569
570
  idempotencyKeys: () => idempotencyKeys,
570
571
  modelBudgetReservations: () => modelBudgetReservations,
571
572
  sessions: () => sessions,
@@ -1068,13 +1069,43 @@ var d1BindingAdmissions = pgTable2(
1068
1069
  sequence: bigint("sequence", { mode: "bigint" }).generatedAlwaysAsIdentity(),
1069
1070
  hostId: text2("host_id").notNull(),
1070
1071
  bindingId: text2("binding_id").notNull(),
1071
- activeRevision: text2("active_revision").notNull(),
1072
+ firstRevisionId: text2("active_revision").notNull(),
1073
+ // Nullable only for immutable rows created before migration 0020; runtime admission rejects those rows as mismatches.
1074
+ executionIdentityDigest: text2("execution_identity_digest"),
1075
+ firstDesiredStateDigest: text2("first_desired_state_digest"),
1072
1076
  admittedAt: timestamp2("admitted_at", { withTimezone: true }).defaultNow().notNull()
1073
1077
  },
1074
1078
  (table) => [
1075
1079
  primaryKey({ name: "d1_binding_admissions_pk", columns: [table.hostId, table.bindingId] }),
1076
1080
  uniqueIndex("d1_binding_admissions_sequence_unique").on(table.sequence),
1077
- check("d1_binding_admissions_revision_check", sql3`${table.activeRevision} ~ '^r[0-9]{10}$'`)
1081
+ check("d1_binding_admissions_revision_check", sql3`${table.firstRevisionId} ~ '^r[0-9]{10}$'`),
1082
+ check("d1_binding_admissions_execution_digest_check", sql3`${table.executionIdentityDigest} ~ '^sha256:[a-f0-9]{64}$'`),
1083
+ check("d1_binding_admissions_desired_digest_check", sql3`${table.firstDesiredStateDigest} ~ '^sha256:[a-f0-9]{64}$'`)
1084
+ ]
1085
+ );
1086
+ var d1DestructivePublicationEvents = pgTable2(
1087
+ "d1_destructive_publication_events",
1088
+ {
1089
+ sequence: bigint("sequence", { mode: "bigint" }).generatedAlwaysAsIdentity().primaryKey(),
1090
+ operationId: text2("operation_id").notNull(),
1091
+ state: text2("state").notNull(),
1092
+ hostId: text2("host_id").notNull(),
1093
+ expectedRevision: text2("expected_revision").notNull(),
1094
+ expectedDigest: text2("expected_digest").notNull(),
1095
+ targetRevision: text2("target_revision").notNull(),
1096
+ targetDigest: text2("target_digest").notNull(),
1097
+ removalBindingIds: text2("removal_binding_ids").array().notNull(),
1098
+ recordedAt: timestamp2("recorded_at", { withTimezone: true }).defaultNow().notNull()
1099
+ },
1100
+ (table) => [
1101
+ uniqueIndex("d1_destructive_publication_prepared_unique").on(table.operationId).where(sql3`${table.state} = 'prepared'`),
1102
+ uniqueIndex("d1_destructive_publication_terminal_unique").on(table.operationId).where(sql3`${table.state} IN ('committed', 'aborted')`),
1103
+ check("d1_destructive_publication_state_check", sql3`${table.state} IN ('prepared', 'committed', 'aborted')`),
1104
+ check("d1_destructive_publication_expected_revision_check", sql3`${table.expectedRevision} ~ '^r[0-9]{10}$'`),
1105
+ check("d1_destructive_publication_target_revision_check", sql3`${table.targetRevision} ~ '^r[0-9]{10}$'`),
1106
+ check("d1_destructive_publication_expected_digest_check", sql3`${table.expectedDigest} ~ '^sha256:[a-f0-9]{64}$'`),
1107
+ check("d1_destructive_publication_target_digest_check", sql3`${table.targetDigest} ~ '^sha256:[a-f0-9]{64}$'`),
1108
+ check("d1_destructive_publication_removals_check", sql3`cardinality(${table.removalBindingIds}) > 0`)
1078
1109
  ]
1079
1110
  );
1080
1111
 
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { Component, ReactNode, ErrorInfo } from 'react';
3
- import { R as RuntimeConfig, a as CapabilitiesResponse, W as WorkspaceMember, U as User, b as Workspace, M as MemberRole, S as SessionState } from '../types-DKCtYltp.js';
3
+ import { R as RuntimeConfig, a as CapabilitiesResponse, W as WorkspaceMember, U as User, b as Workspace, M as MemberRole, S as SessionState } from '../types-BIjRgbMV.js';
4
4
  export { b as CompanyAdminLabels, c as CompanyAdminProvider, d as CompanyAdminProviderProps, e as CompanyAdminStatus, f as CoreFront, C as CoreFrontAuthPagesOverride, a as CoreFrontCompanyAdminOptions, g as CoreFrontProps, L as LoadCompanyAdminStatus, R as RenderCompanyAdminContent, u as useCompanyAdminStatus } from '../CoreFront-DB1OfNJU.js';
5
5
  import * as _tanstack_react_query from '@tanstack/react-query';
6
6
  import * as better_auth_react from 'better-auth/react';
@@ -62,13 +62,13 @@ import {
62
62
  useWorkspaceMembers,
63
63
  useWorkspaceRole,
64
64
  useWorkspaceRouteStatus
65
- } from "../chunk-6G6Z52VQ.js";
65
+ } from "../chunk-JLBUXSC5.js";
66
66
  import {
67
67
  TopBarSlotProvider,
68
68
  useTopBarSlot
69
69
  } from "../chunk-HYNKZSTF.js";
70
70
  import "../chunk-I4PGL4ZD.js";
71
- import "../chunk-VWE46RW4.js";
71
+ import "../chunk-RTLBMHOB.js";
72
72
  import "../chunk-MLKGABMK.js";
73
73
  export {
74
74
  AppErrorBoundary,
@@ -1,7 +1,7 @@
1
1
  import { FastifyPluginAsync } from 'fastify';
2
2
  import { Auth } from 'better-auth';
3
- import { C as CoreConfig, R as RuntimeConfig } from './types-DKCtYltp.js';
4
- import { W as WorkspaceStore, D as Database } from './types-uK6CFlxr.js';
3
+ import { C as CoreConfig, R as RuntimeConfig } from './types-BIjRgbMV.js';
4
+ import { W as WorkspaceStore, D as Database } from './types-C5xuRqmA.js';
5
5
  import { T as TelemetrySink } from './telemetry-DR18MeI0.js';
6
6
 
7
7
  declare function validatePasswordStrength(password: string): {
@@ -35,8 +35,24 @@ interface LoadConfigOptions {
35
35
  env?: Record<string, string | undefined>;
36
36
  allowMissingSecrets?: boolean;
37
37
  }
38
+ type CoreTrustedProxyPolicyInput = undefined | 'legacy-unsafe' | Readonly<{
39
+ cidrs: readonly string[];
40
+ hops: number;
41
+ }>;
42
+ interface CoreSecurityConfigProjection {
43
+ readonly host: string;
44
+ readonly port: number;
45
+ readonly betterAuthUrl: string;
46
+ readonly corsOrigins: readonly string[];
47
+ readonly cspEnabled: boolean;
48
+ readonly cspUpgradeInsecureRequests: boolean;
49
+ readonly sessionCookieSecure: boolean;
50
+ /** Parsed input only; whole-config schema validation still establishes validity. */
51
+ readonly trustedProxy: CoreTrustedProxyPolicyInput;
52
+ }
53
+ declare function readCoreSecurityConfigProjection(env: Readonly<Record<string, string | undefined>>): CoreSecurityConfigProjection;
38
54
  declare function loadConfig(options?: LoadConfigOptions): Promise<CoreConfig>;
39
55
  declare function validateConfig(raw: unknown): CoreConfig;
40
56
  declare function buildRuntimeConfigPayload(config: CoreConfig): RuntimeConfig;
41
57
 
42
- export { type AuthHookOptions as A, type BetterAuthInstance as B, type CreateAuthOptions as C, type LoadConfigOptions as L, authHook as a, buildRuntimeConfigPayload as b, createAuth as c, validatePasswordStrength as d, loadConfig as l, validateConfig as v };
58
+ export { type AuthHookOptions as A, type BetterAuthInstance as B, type CoreSecurityConfigProjection as C, type LoadConfigOptions as L, type CoreTrustedProxyPolicyInput as a, type CreateAuthOptions as b, authHook as c, buildRuntimeConfigPayload as d, createAuth as e, validatePasswordStrength as f, loadConfig as l, readCoreSecurityConfigProjection as r, validateConfig as v };
@@ -1,7 +1,7 @@
1
- import { U as UserStore, W as WorkspaceStore } from '../../types-uK6CFlxr.js';
2
- export { D as Database, c as createDatabase } from '../../types-uK6CFlxr.js';
3
- export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, c as BudgetSpendQuery, d as BudgetSpendSnapshot, F as FinishBudgetReservationInput, e as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, f as ModelBudgetExceededError, P as PostgresBudgetReservationStore, g as PostgresMeteringStore, h as PostgresModelBudgetStore, R as RecordUsageInput, i as RecordUsageResult, j as ReservationFinalStatus, k as ReserveBudgetInput, l as ReserveBudgetResult, m as ReserveInput, n as ReserveResult, o as RunMigrationsOptions, U as UserBudgetExceededError, r as runMigrations } from '../../PostgresModelBudgetStore-CViAvfFy.js';
4
- import { U as User, b as Workspace, E as ERROR_CODES, M as MemberRole, W as WorkspaceMember, c as WorkspaceInvite, d as WorkspaceRuntime, e as WorkspaceRuntimeResourceSelector, f as WorkspaceRuntimeResource, g as WorkspaceRuntimeResourceInput } from '../../types-DKCtYltp.js';
1
+ import { U as UserStore, W as WorkspaceStore } from '../../types-C5xuRqmA.js';
2
+ export { D as Database, c as createDatabase } from '../../types-C5xuRqmA.js';
3
+ export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, c as BudgetSpendQuery, d as BudgetSpendSnapshot, F as FinishBudgetReservationInput, e as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, f as ModelBudgetExceededError, P as PostgresBudgetReservationStore, g as PostgresMeteringStore, h as PostgresModelBudgetStore, R as RecordUsageInput, i as RecordUsageResult, j as ReservationFinalStatus, k as ReserveBudgetInput, l as ReserveBudgetResult, m as ReserveInput, n as ReserveResult, o as RunMigrationsOptions, U as UserBudgetExceededError, r as runMigrations } from '../../PostgresModelBudgetStore-vDTn1QkE.js';
4
+ import { U as User, b as Workspace, E as ERROR_CODES, M as MemberRole, W as WorkspaceMember, c as WorkspaceInvite, d as WorkspaceRuntime, e as WorkspaceRuntimeResourceSelector, f as WorkspaceRuntimeResource, g as WorkspaceRuntimeResourceInput } from '../../types-BIjRgbMV.js';
5
5
  import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
6
6
  import 'postgres';
7
7
  import 'fastify';
@@ -11,8 +11,8 @@ import {
11
11
  UserBudgetExceededError,
12
12
  createDatabase,
13
13
  runMigrations
14
- } from "../../chunk-C4YTZAZC.js";
15
- import "../../chunk-VWE46RW4.js";
14
+ } from "../../chunk-WRFEUAG7.js";
15
+ import "../../chunk-RTLBMHOB.js";
16
16
  import "../../chunk-MLKGABMK.js";
17
17
  export {
18
18
  InsufficientCreditError,
@@ -1,16 +1,16 @@
1
- import { L as LoadConfigOptions } from '../loadConfig-DEG0Tu5n.js';
2
- export { A as AuthHookOptions, B as BetterAuthInstance, C as CreateAuthOptions, a as authHook, b as buildRuntimeConfigPayload, c as createAuth, l as loadConfig, v as validateConfig, d as validatePasswordStrength } from '../loadConfig-DEG0Tu5n.js';
1
+ import { L as LoadConfigOptions } from '../loadConfig-Bw6jtipE.js';
2
+ export { A as AuthHookOptions, B as BetterAuthInstance, C as CoreSecurityConfigProjection, a as CoreTrustedProxyPolicyInput, b as CreateAuthOptions, c as authHook, d as buildRuntimeConfigPayload, e as createAuth, l as loadConfig, r as readCoreSecurityConfigProjection, v as validateConfig, f as validatePasswordStrength } from '../loadConfig-Bw6jtipE.js';
3
3
  import { z } from 'zod';
4
- import { C as CoreConfig, M as MemberRole, e as WorkspaceRuntimeResourceSelector, f as WorkspaceRuntimeResource, g as WorkspaceRuntimeResourceInput } from '../types-DKCtYltp.js';
4
+ import { C as CoreConfig, M as MemberRole, e as WorkspaceRuntimeResourceSelector, f as WorkspaceRuntimeResource, g as WorkspaceRuntimeResourceInput } from '../types-BIjRgbMV.js';
5
5
  import * as fastify from 'fastify';
6
6
  import { preHandlerHookHandler, FastifyInstance, FastifyPluginAsync, FastifyRequest, FastifyReply } from 'fastify';
7
7
  import * as http from 'http';
8
8
  import { IncomingMessage } from 'node:http';
9
- import { W as WorkspaceStore, b as CreateCoreAppOptions, D as Database, U as UserStore, d as WorkspaceProvisioner } from '../types-uK6CFlxr.js';
10
- export { A as AuthProvider, e as CapabilitiesContributor, a as CoreRequestScope, C as CoreRequestScopeResolver, P as ProvisionContext, f as ProvisionResult, c as createDatabase } from '../types-uK6CFlxr.js';
9
+ import { W as WorkspaceStore, b as CreateCoreAppOptions, D as Database, U as UserStore, d as WorkspaceProvisioner } from '../types-C5xuRqmA.js';
10
+ export { A as AuthProvider, e as CapabilitiesContributor, a as CoreRequestScope, C as CoreRequestScopeResolver, P as ProvisionContext, f as ProvisionResult, c as createDatabase } from '../types-C5xuRqmA.js';
11
11
  import postgres from 'postgres';
12
- import { o as RunMigrationsOptions, g as PostgresMeteringStore, C as CreditLedgerEntry } from '../PostgresModelBudgetStore-CViAvfFy.js';
13
- export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, c as BudgetSpendQuery, d as BudgetSpendSnapshot, F as FinishBudgetReservationInput, e as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, f as ModelBudgetExceededError, P as PostgresBudgetReservationStore, h as PostgresModelBudgetStore, R as RecordUsageInput, i as RecordUsageResult, j as ReservationFinalStatus, k as ReserveBudgetInput, l as ReserveBudgetResult, m as ReserveInput, n as ReserveResult, U as UserBudgetExceededError, r as runMigrations } from '../PostgresModelBudgetStore-CViAvfFy.js';
12
+ import { o as RunMigrationsOptions, g as PostgresMeteringStore, C as CreditLedgerEntry } from '../PostgresModelBudgetStore-vDTn1QkE.js';
13
+ export { B as BudgetReservationAdmission, a as BudgetReservationAdmissionInput, b as BudgetReservationScope, c as BudgetSpendQuery, d as BudgetSpendSnapshot, F as FinishBudgetReservationInput, e as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, f as ModelBudgetExceededError, P as PostgresBudgetReservationStore, h as PostgresModelBudgetStore, R as RecordUsageInput, i as RecordUsageResult, j as ReservationFinalStatus, k as ReserveBudgetInput, l as ReserveBudgetResult, m as ReserveInput, n as ReserveResult, U as UserBudgetExceededError, r as runMigrations } from '../PostgresModelBudgetStore-vDTn1QkE.js';
14
14
  import { T as TelemetrySink } from '../telemetry-DR18MeI0.js';
15
15
  import { AgentMeteringSink } from '@hachej/boring-agent/server';
16
16
  import 'better-auth';
@@ -11,6 +11,7 @@ import {
11
11
  createMailTransport,
12
12
  createPostSignupHook,
13
13
  loadConfig,
14
+ readCoreSecurityConfigProjection,
14
15
  registerInviteRoutes,
15
16
  registerMemberRoutes,
16
17
  registerRoutes,
@@ -25,7 +26,7 @@ import {
25
26
  validateConfig,
26
27
  validatePasswordStrength,
27
28
  withUserSettingsWriteLock
28
- } from "../chunk-MWOZRTRG.js";
29
+ } from "../chunk-ONZ6UPYK.js";
29
30
  import {
30
31
  InsufficientCreditError,
31
32
  ModelBudgetExceededError,
@@ -35,7 +36,7 @@ import {
35
36
  UserBudgetExceededError,
36
37
  createDatabase,
37
38
  runMigrations
38
- } from "../chunk-C4YTZAZC.js";
39
+ } from "../chunk-WRFEUAG7.js";
39
40
  import {
40
41
  noopTelemetry,
41
42
  safeCapture
@@ -43,7 +44,7 @@ import {
43
44
  import "../chunk-I4PGL4ZD.js";
44
45
  import {
45
46
  ERROR_CODES
46
- } from "../chunk-VWE46RW4.js";
47
+ } from "../chunk-RTLBMHOB.js";
47
48
  import "../chunk-MLKGABMK.js";
48
49
 
49
50
  // src/server/security/safeRedirect.ts
@@ -1626,6 +1627,7 @@ export {
1626
1627
  maxEffectiveRate,
1627
1628
  maxServedRate,
1628
1629
  parseLemonSqueezyOrder,
1630
+ readCoreSecurityConfigProjection,
1629
1631
  registerCreditsRoutes,
1630
1632
  registerInviteRoutes,
1631
1633
  registerMemberRoutes,
@@ -1,5 +1,5 @@
1
- import { U as User, C as CoreConfig, R as RuntimeConfig } from '../types-DKCtYltp.js';
2
- export { a as CapabilitiesResponse, h as ConfigFetchError, i as ConfigValidationError, j as CoreCapabilities, E as ERROR_CODES, k as ErrorCode, H as HttpError, J as JsonValue, M as MemberRole, l as RateLimitEndpointOverride, m as SessionPayload, S as SessionState, T as TrustedProxyPolicy, b as Workspace, c as WorkspaceInvite, W as WorkspaceMember, d as WorkspaceRuntime } from '../types-DKCtYltp.js';
1
+ import { U as User, C as CoreConfig, R as RuntimeConfig } from '../types-BIjRgbMV.js';
2
+ export { a as CapabilitiesResponse, h as ConfigFetchError, i as ConfigValidationError, j as CoreCapabilities, E as ERROR_CODES, k as ErrorCode, H as HttpError, J as JsonValue, M as MemberRole, l as RateLimitEndpointOverride, m as SessionPayload, S as SessionState, T as TrustedProxyPolicy, b as Workspace, c as WorkspaceInvite, W as WorkspaceMember, d as WorkspaceRuntime } from '../types-BIjRgbMV.js';
3
3
  export { a as TelemetryEvent, T as TelemetrySink, n as noopTelemetry, s as safeCapture } from '../telemetry-DR18MeI0.js';
4
4
 
5
5
  declare function isCoreEmailVerificationEnabled(config: Pick<CoreConfig, 'auth'>): boolean;
@@ -12,7 +12,7 @@ import {
12
12
  ConfigValidationError,
13
13
  ERROR_CODES,
14
14
  HttpError
15
- } from "../chunk-VWE46RW4.js";
15
+ } from "../chunk-RTLBMHOB.js";
16
16
  import "../chunk-MLKGABMK.js";
17
17
  export {
18
18
  ConfigFetchError,
@@ -24,6 +24,7 @@ declare const ERROR_CODES: {
24
24
  readonly DB_UNAVAILABLE: "db_unavailable";
25
25
  readonly INTERNAL_ERROR: "internal_error";
26
26
  readonly D1_HOST_SCOPE_VIOLATION: "D1_HOST_SCOPE_VIOLATION";
27
+ readonly D1_ADMISSION_IDENTITY_MISMATCH: "D1_ADMISSION_IDENTITY_MISMATCH";
27
28
  readonly D1_ADMISSION_RECORD_FAILED: "D1_ADMISSION_RECORD_FAILED";
28
29
  readonly D1_MANAGED_WORKSPACE_MUTATION_FORBIDDEN: "D1_MANAGED_WORKSPACE_MUTATION_FORBIDDEN";
29
30
  readonly PAYMENT_REQUIRED: "payment_required";
@@ -1,6 +1,6 @@
1
1
  import { drizzle } from 'drizzle-orm/postgres-js';
2
2
  import postgres from 'postgres';
3
- import { C as CoreConfig, b as Workspace, E as ERROR_CODES, M as MemberRole, W as WorkspaceMember, U as User, c as WorkspaceInvite, d as WorkspaceRuntime, e as WorkspaceRuntimeResourceSelector, f as WorkspaceRuntimeResource, g as WorkspaceRuntimeResourceInput, a as CapabilitiesResponse } from './types-DKCtYltp.js';
3
+ import { C as CoreConfig, b as Workspace, E as ERROR_CODES, M as MemberRole, W as WorkspaceMember, U as User, c as WorkspaceInvite, d as WorkspaceRuntime, e as WorkspaceRuntimeResourceSelector, f as WorkspaceRuntimeResource, g as WorkspaceRuntimeResourceInput, a as CapabilitiesResponse } from './types-BIjRgbMV.js';
4
4
  import { FastifyRequest } from 'fastify';
5
5
 
6
6
  type Database = ReturnType<typeof drizzle>;
@@ -0,0 +1,36 @@
1
+ CREATE TABLE "d1_destructive_publication_events" (
2
+ "sequence" bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
3
+ "operation_id" text NOT NULL,
4
+ "state" text NOT NULL,
5
+ "host_id" text NOT NULL,
6
+ "expected_revision" text NOT NULL,
7
+ "expected_digest" text NOT NULL,
8
+ "target_revision" text NOT NULL,
9
+ "target_digest" text NOT NULL,
10
+ "removal_binding_ids" text[] NOT NULL,
11
+ "recorded_at" timestamp with time zone DEFAULT now() NOT NULL,
12
+ CONSTRAINT "d1_destructive_publication_state_check" CHECK ("state" IN ('prepared', 'committed', 'aborted')),
13
+ CONSTRAINT "d1_destructive_publication_expected_revision_check" CHECK ("expected_revision" ~ '^r[0-9]{10}$'),
14
+ CONSTRAINT "d1_destructive_publication_target_revision_check" CHECK ("target_revision" ~ '^r[0-9]{10}$'),
15
+ CONSTRAINT "d1_destructive_publication_expected_digest_check" CHECK ("expected_digest" ~ '^sha256:[a-f0-9]{64}$'),
16
+ CONSTRAINT "d1_destructive_publication_target_digest_check" CHECK ("target_digest" ~ '^sha256:[a-f0-9]{64}$'),
17
+ CONSTRAINT "d1_destructive_publication_removals_check" CHECK (cardinality("removal_binding_ids") > 0)
18
+ );
19
+ --> statement-breakpoint
20
+ CREATE UNIQUE INDEX "d1_destructive_publication_prepared_unique" ON "d1_destructive_publication_events" ("operation_id") WHERE "state" = 'prepared';
21
+ --> statement-breakpoint
22
+ CREATE UNIQUE INDEX "d1_destructive_publication_terminal_unique" ON "d1_destructive_publication_events" ("operation_id") WHERE "state" IN ('committed', 'aborted');
23
+ --> statement-breakpoint
24
+ CREATE OR REPLACE FUNCTION d1_reject_destructive_publication_event_mutation() RETURNS trigger AS $$
25
+ BEGIN
26
+ RAISE EXCEPTION 'd1 destructive publication events are immutable';
27
+ END;
28
+ $$ LANGUAGE plpgsql;
29
+ --> statement-breakpoint
30
+ CREATE TRIGGER d1_destructive_publication_events_immutable
31
+ BEFORE UPDATE OR DELETE ON "d1_destructive_publication_events"
32
+ FOR EACH ROW EXECUTE FUNCTION d1_reject_destructive_publication_event_mutation();
33
+ --> statement-breakpoint
34
+ CREATE TRIGGER d1_destructive_publication_events_truncate_immutable
35
+ BEFORE TRUNCATE ON "d1_destructive_publication_events"
36
+ FOR EACH STATEMENT EXECUTE FUNCTION d1_reject_destructive_publication_event_mutation();
@@ -0,0 +1,5 @@
1
+ ALTER TABLE "d1_binding_admissions"
2
+ ADD COLUMN "execution_identity_digest" text,
3
+ ADD COLUMN "first_desired_state_digest" text,
4
+ ADD CONSTRAINT "d1_binding_admissions_execution_digest_check" CHECK ("execution_identity_digest" ~ '^sha256:[a-f0-9]{64}$'),
5
+ ADD CONSTRAINT "d1_binding_admissions_desired_digest_check" CHECK ("first_desired_state_digest" ~ '^sha256:[a-f0-9]{64}$');
@@ -134,6 +134,20 @@
134
134
  "when": 1783900800000,
135
135
  "tag": "0018_d1_binding_admissions",
136
136
  "breakpoints": true
137
+ },
138
+ {
139
+ "idx": 19,
140
+ "version": "7",
141
+ "when": 1783987200000,
142
+ "tag": "0019_d1_destructive_publication_events",
143
+ "breakpoints": true
144
+ },
145
+ {
146
+ "idx": 20,
147
+ "version": "7",
148
+ "when": 1784073600000,
149
+ "tag": "0020_d1_admission_execution_identity",
150
+ "breakpoints": true
137
151
  }
138
152
  ]
139
153
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-core",
3
- "version": "0.1.84",
3
+ "version": "0.1.85",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Foundation package for boring-ui-v2 apps: DB, auth, config, HTTP app factory, and frontend app shell.",
@@ -80,9 +80,9 @@
80
80
  "react-router-dom": "^7.18.0",
81
81
  "smol-toml": "^1.7.0",
82
82
  "zod": "^3.25.76",
83
- "@hachej/boring-agent": "0.1.84",
84
- "@hachej/boring-ui-kit": "0.1.84",
85
- "@hachej/boring-workspace": "0.1.84"
83
+ "@hachej/boring-agent": "0.1.85",
84
+ "@hachej/boring-ui-kit": "0.1.85",
85
+ "@hachej/boring-workspace": "0.1.85"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@testing-library/jest-dom": "^6.9.1",