@cosmicdrift/kumiko-bundled-features 0.365.1 → 0.366.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.
- package/dist/admin-shell/feature.js +9 -9
- package/dist/agent-tools/tool-dispatch.d.ts +9 -1
- package/dist/agent-tools/tool-dispatch.js +55 -5
- package/dist/audit/feature.js +1 -1
- package/dist/auth-email-password/constants.d.ts +0 -1
- package/dist/auth-email-password/constants.js +0 -2
- package/dist/auth-email-password/feature.js +3 -3
- package/dist/auth-email-password/handlers/invite-create.write.js +1 -0
- package/dist/auth-mfa/feature.js +4 -4
- package/dist/auth-mfa-user-data/index.js +1 -1
- package/dist/billing-foundation/consumer-protection/register-consent.js +1 -1
- package/dist/billing-foundation/feature.js +1 -1
- package/dist/cap-counter/cap-reservation.js +73 -25
- package/dist/cap-counter/constants.d.ts +1 -0
- package/dist/cap-counter/constants.js +2 -0
- package/dist/cap-counter/feature.js +2 -2
- package/dist/cap-counter/tables.js +5 -2
- package/dist/cap-overview/feature.js +3 -3
- package/dist/channel-discord/feature.js +2 -2
- package/dist/channel-email/feature.js +1 -1
- package/dist/channel-in-app/feature.js +1 -1
- package/dist/channel-push/feature.js +1 -1
- package/dist/channel-slack/feature.js +2 -2
- package/dist/channel-teams/feature.js +2 -2
- package/dist/channel-telegram/feature.js +2 -2
- package/dist/compliance-profiles/feature.js +1 -1
- package/dist/compliance-profiles-ops/index.js +3 -3
- package/dist/config/feature.js +1 -1
- package/dist/custom-fields/feature.js +2 -2
- package/dist/custom-fields/wire-for-entity.js +17 -13
- package/dist/data-retention/feature.js +1 -1
- package/dist/data-retention/presets.d.ts +4 -4
- package/dist/delivery/db/queries/address-opt-outs.d.ts +1 -1
- package/dist/delivery/db/queries/address-opt-outs.js +6 -2
- package/dist/delivery/db/queries/preferences.d.ts +1 -1
- package/dist/delivery/db/queries/preferences.js +4 -4
- package/dist/delivery/delivery-service.js +9 -2
- package/dist/delivery/feature.js +9 -5
- package/dist/delivery/handlers/resubscribe-address.write.js +13 -9
- package/dist/delivery/handlers/resubscribe-user.write.js +3 -1
- package/dist/delivery/handlers/set-preference.write.js +3 -1
- package/dist/delivery/handlers/unsubscribe-address.write.js +3 -1
- package/dist/delivery/handlers/unsubscribe-user.write.js +3 -1
- package/dist/delivery/notification-type-aliases.d.ts +3 -0
- package/dist/delivery/notification-type-aliases.js +11 -0
- package/dist/derivatives-sharp/feature.js +1 -1
- package/dist/document-ingest-foundation/feature.js +2 -2
- package/dist/file-derivatives/feature.js +3 -3
- package/dist/file-foundation/feature.js +1 -1
- package/dist/file-provider-inmemory/feature.js +2 -2
- package/dist/file-provider-s3/feature.js +3 -3
- package/dist/file-provider-s3-env/feature.js +2 -2
- package/dist/files-tenant-data/index.js +1 -1
- package/dist/folders/feature.js +2 -2
- package/dist/folders-user-data/index.js +1 -1
- package/dist/form-draft/feature.js +2 -2
- package/dist/form-draft-user-data/index.js +1 -1
- package/dist/inbound-mail-foundation/connect-routes.d.ts +3 -0
- package/dist/inbound-mail-foundation/connect-routes.js +6 -1
- package/dist/inbound-mail-foundation/feature.js +1 -1
- package/dist/inbound-mail-foundation/types.d.ts +17 -7
- package/dist/inbound-mail-foundation/watch-supervisor.js +16 -2
- package/dist/inbound-provider-imap/feature.js +2 -2
- package/dist/inbound-provider-inmemory/feature.js +1 -1
- package/dist/ledger/feature.js +5 -5
- package/dist/legal-pages/feature.js +1 -1
- package/dist/mail-foundation/feature.js +1 -1
- package/dist/mail-transport-inmemory/feature.js +2 -2
- package/dist/mail-transport-smtp/feature.js +3 -3
- package/dist/managed-pages/css-gate.js +1 -1
- package/dist/managed-pages/feature.js +2 -2
- package/dist/metrics/feature.js +2 -2
- package/dist/notes-history/feature.js +2 -2
- package/dist/notes-history-user-data/index.js +1 -1
- package/dist/personal-access-tokens/feature.js +17 -13
- package/dist/readiness/feature.js +2 -2
- package/dist/renderer-foundation/feature.js +1 -1
- package/dist/renderer-pdf/feature.js +1 -1
- package/dist/secrets/feature.js +1 -1
- package/dist/seo/feature.js +1 -1
- package/dist/sessions/feature.js +20 -16
- package/dist/step-dispatcher/feature.js +1 -1
- package/dist/subscription-mollie/feature.js +1 -1
- package/dist/subscription-stripe/feature.js +3 -3
- package/dist/tags/feature.js +2 -2
- package/dist/template-resolver/feature.js +2 -2
- package/dist/template-resolver-user-data/index.js +1 -1
- package/dist/tenant/feature.js +4 -4
- package/dist/tenant/seeding.js +1 -1
- package/dist/tenant-lifecycle/feature.js +2 -3
- package/dist/tenant-settings/feature.js +1 -1
- package/dist/tier-engine/feature.js +86 -72
- package/dist/user/feature.js +1 -1
- package/dist/user-data-rights/feature.js +4 -4
- package/dist/user-data-rights-defaults/feature.js +2 -2
- package/dist/user-profile/feature.js +4 -4
- package/dist/waitlist/feature.js +2 -2
- package/package.json +10 -10
- package/src/agent-tools/changes.json +6 -0
- package/src/auth-email-password/changes.json +13 -0
- package/src/cap-counter/changes.json +7 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/delivery/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +13 -0
|
@@ -126,9 +126,9 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
126
126
|
category: "billing",
|
|
127
127
|
recommended: false,
|
|
128
128
|
});
|
|
129
|
-
r.requires("config");
|
|
130
|
-
r.requires("tenant");
|
|
131
|
-
r.entity("tier-assignment", tierAssignmentEntity);
|
|
129
|
+
r.requires({ features: ["config"] });
|
|
130
|
+
r.requires({ features: ["tenant"] });
|
|
131
|
+
r.entity({ name: "tier-assignment", ...tierAssignmentEntity });
|
|
132
132
|
// Standard-CRUD via Helper.
|
|
133
133
|
r.writeHandler(defineEntityCreateHandler("tier-assignment", tierAssignmentEntity, {
|
|
134
134
|
...writeAccess,
|
|
@@ -265,27 +265,35 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
265
265
|
};
|
|
266
266
|
onTierAssigned.fn = applyAssignment;
|
|
267
267
|
// Invalidation: tier-assignment CRUD events (e.g. the billing webhook) update the cache.
|
|
268
|
-
r.hook(
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
268
|
+
r.hook({
|
|
269
|
+
type: "postSave",
|
|
270
|
+
target: { allOf: "tier-assignment" },
|
|
271
|
+
handler: async (result) => {
|
|
272
|
+
// result.data has tenantId + tier (after entity-update merge)
|
|
273
|
+
const data = result.data; // @cast-boundary engine-payload
|
|
274
|
+
// skip: defensive guard on the payload shape. Correct entity events
|
|
275
|
+
// always carry both fields as strings; a malformed payload (a custom
|
|
276
|
+
// handler bug) skips the cache update instead of throwing, because a
|
|
277
|
+
// hook error must not block the lifecycle pipeline (afterCommit,
|
|
278
|
+
// best-effort side effect).
|
|
279
|
+
if (typeof data.tenantId !== "string" || typeof data.tier !== "string")
|
|
280
|
+
return;
|
|
281
|
+
applyAssignment(data.tenantId, data.tier);
|
|
282
|
+
},
|
|
279
283
|
});
|
|
280
|
-
r.hook(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
284
|
+
r.hook({
|
|
285
|
+
type: "postDelete",
|
|
286
|
+
target: { allOf: "tier-assignment" },
|
|
287
|
+
handler: async (payload) => {
|
|
288
|
+
const data = payload.data; // @cast-boundary engine-payload
|
|
289
|
+
// skip: gleiche type-guard semantik wie postSave-hook oben.
|
|
290
|
+
if (typeof data.tenantId !== "string")
|
|
291
|
+
return;
|
|
292
|
+
const tenantId = data.tenantId;
|
|
293
|
+
takeTicket(tenantId);
|
|
294
|
+
cache.delete(tenantId);
|
|
295
|
+
publishAssignmentChange(tenantId);
|
|
296
|
+
},
|
|
289
297
|
});
|
|
290
298
|
// Auto-default-tier-on-tenant-signup: hook fires inTransaction (atomic
|
|
291
299
|
// mit tenant-create rollback), schreibt tier-assignment via Direct-
|
|
@@ -302,55 +310,61 @@ export function createTierEngineFeature(opts = {}) {
|
|
|
302
310
|
if (opts.defaultTier !== undefined) {
|
|
303
311
|
const defaultTier = opts.defaultTier;
|
|
304
312
|
const autoDefaultTierHookReason = "seeds the default tier-assignment stream of the tenant just created";
|
|
305
|
-
r.hook(
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
313
|
+
r.hook({
|
|
314
|
+
type: "postSave",
|
|
315
|
+
target: { allOf: "tenant" },
|
|
316
|
+
handler: async (result, ctx) => {
|
|
317
|
+
// result-shape: kumiko-framework's SaveContext mit isNew + data
|
|
318
|
+
const saveResult = result; // @cast-boundary engine-payload
|
|
319
|
+
// skip: nur bei tenant-create (initial) — tenant-updates feuern
|
|
320
|
+
// auch postSave aber wir wollen kein neues tier-assignment bei
|
|
321
|
+
// re-keying oder name-update.
|
|
322
|
+
if (saveResult.isNew !== true)
|
|
323
|
+
return;
|
|
324
|
+
const data = saveResult.data; // @cast-boundary engine-payload
|
|
325
|
+
// skip: defensive type-guard. Tenant-entity hat id zwingend, aber
|
|
326
|
+
// CrudExecutor's payload-shape ist runtime-unknown.
|
|
327
|
+
if (typeof data.id !== "string")
|
|
328
|
+
return;
|
|
329
|
+
const newTenantId = data.id; // @cast-boundary engine-payload
|
|
330
|
+
const aggregateId = tierAssignmentAggregateId(newTenantId);
|
|
331
|
+
// tenant is an r.systemScope() feature, so this cross-feature hook gets a
|
|
332
|
+
// fail-closed ctx.db — reach for ctx.systemDb instead (see entity-handlers.ts).
|
|
333
|
+
// Event-store paths need the raw DbConnection — TenantDb only exposes
|
|
334
|
+
// select/insert/update/delete, not execute (db.execute(sql`SELECT pg_notify(...)`) would TypeError).
|
|
335
|
+
const rawDb = ctx.systemDb
|
|
336
|
+
? ctx.systemDb.unsafeRaw(autoDefaultTierHookReason)
|
|
337
|
+
: ctx.db && "unsafeRaw" in ctx.db
|
|
338
|
+
? ctx.db.unsafeRaw()
|
|
339
|
+
: undefined;
|
|
340
|
+
// skip: defensive — inTransaction phase always sets db, but AppContext's
|
|
341
|
+
// type makes it optional. Throwing would be overreach (lifecycle
|
|
342
|
+
// blocking), silent-skip is defensive-soft.
|
|
343
|
+
if (!rawDb)
|
|
344
|
+
return;
|
|
345
|
+
// Idempotency: stream-existence-check vor create. Pattern aus
|
|
346
|
+
// seedTenant.ts. Bei re-replay (rebuild) nicht versionsbumpen.
|
|
347
|
+
const streamVersion = await getUnscopedAggregateStreamMaxVersion(rawDb, aggregateId);
|
|
348
|
+
// skip: idempotent — tier-assignment stream already seeded (rebuild/replay).
|
|
349
|
+
if (streamVersion > 0)
|
|
350
|
+
return;
|
|
351
|
+
// SystemUser für den NEUEN tenant — der Hook wird vom signup-
|
|
352
|
+
// user (anderer tenant, oder SystemAdmin) ausgelöst, aber das
|
|
353
|
+
// tier-assignment muss im stream des neu-erzeugten tenants
|
|
354
|
+
// landen (= aggregate-id deterministic auf newTenantId). Memory
|
|
355
|
+
// `feedback_event_store_tenant_consistency`: by.tenantId muss =
|
|
356
|
+
// ziel-tenant.
|
|
357
|
+
const systemUser = {
|
|
358
|
+
id: "00000000-0000-4000-8000-000000000001",
|
|
359
|
+
tenantId: newTenantId,
|
|
360
|
+
roles: ["SystemAdmin"],
|
|
361
|
+
};
|
|
362
|
+
const tdb = createTenantDb(rawDb, newTenantId, "system");
|
|
363
|
+
await tierAssignmentExecutor.create({ id: aggregateId, tier: defaultTier, source: TierAssignmentSources.default }, systemUser, tdb);
|
|
364
|
+
},
|
|
365
|
+
phase: HookPhases.inTransaction,
|
|
366
|
+
escapeHatch: { reason: autoDefaultTierHookReason },
|
|
367
|
+
});
|
|
354
368
|
}
|
|
355
369
|
// Extension-point declaration + self-registration. Pattern analog
|
|
356
370
|
// mail-foundation/file-foundation: das feature deklariert den
|
package/dist/user/feature.js
CHANGED
|
@@ -21,7 +21,7 @@ export function createUserFeature() {
|
|
|
21
21
|
recommended: true,
|
|
22
22
|
});
|
|
23
23
|
r.systemScope();
|
|
24
|
-
r.entity("user", userEntity);
|
|
24
|
+
r.entity({ name: "user", ...userEntity });
|
|
25
25
|
// Self-extension: `user` declares AND fulfils principalStatus (precedent:
|
|
26
26
|
// tier-engine/feature.ts) — wires the blocked-principal check into every stack that mounts `user`.
|
|
27
27
|
r.extendsRegistrar(EXT_PRINCIPAL_STATUS, {});
|
|
@@ -56,7 +56,7 @@ export function createUserDataRightsFeature(opts = {}) {
|
|
|
56
56
|
category: "compliance",
|
|
57
57
|
recommended: false,
|
|
58
58
|
});
|
|
59
|
-
r.requires("user", "data-retention", "compliance-profiles", "sessions");
|
|
59
|
+
r.requires({ features: ["user", "data-retention", "compliance-profiles", "sessions"] });
|
|
60
60
|
r.usesApi("compliance.forTenant");
|
|
61
61
|
r.usesApi("retention.policyFor");
|
|
62
62
|
// S2.U6 — restrict-account ruft sessions.revokeAllForUser cross-feature.
|
|
@@ -92,13 +92,13 @@ export function createUserDataRightsFeature(opts = {}) {
|
|
|
92
92
|
env: "TENANT_MODEL",
|
|
93
93
|
}));
|
|
94
94
|
// S2.U3 Atom 1b — ExportJob-Lifecycle-Entity.
|
|
95
|
-
r.entity("export-job", exportJobEntity);
|
|
95
|
+
r.entity({ name: "export-job", ...exportJobEntity });
|
|
96
96
|
// S2.U3 Atom 4a — Download-Token-Entity. Worker generiert Token beim
|
|
97
97
|
// Flip auf done (siehe run-export-jobs.ts). Hash in DB, plain im
|
|
98
98
|
// RunExportJobsResult fuer Atom 5 (Notification per Email).
|
|
99
|
-
r.entity("export-download-token", exportDownloadTokenEntity);
|
|
99
|
+
r.entity({ name: "export-download-token", ...exportDownloadTokenEntity });
|
|
100
100
|
// S2.U7 — Audit-Trail invalid Download-Attempts (DPO Brute-Force-Detection).
|
|
101
|
-
r.entity("download-attempt", downloadAttemptEntity);
|
|
101
|
+
r.entity({ name: "download-attempt", ...downloadAttemptEntity });
|
|
102
102
|
// S2.U6 — DSGVO Art. 18 Account-Freeze (Verarbeitungs-Pause).
|
|
103
103
|
// Endpoints fuer Restrict + Lift. Login-Block fuer Restricted Users
|
|
104
104
|
// lebt in auth-email-password/login.write.ts.
|
|
@@ -14,7 +14,7 @@ import { userSessionDeleteHook, userSessionExportHook, } from "./hooks/user-sess
|
|
|
14
14
|
// `user` (S2.H1) und `fileRef` (S2.H2).
|
|
15
15
|
//
|
|
16
16
|
// Architektur-Entscheidung (S2.H1+H2): user-data-rights selbst kann
|
|
17
|
-
// nicht r.requires("user", "files") + r.useExtension(EXT_USER_DATA, ...)
|
|
17
|
+
// nicht r.requires({ features: ["user", "files"] }) + r.useExtension(EXT_USER_DATA, ...)
|
|
18
18
|
// machen weil es selbst Provider von EXT_USER_DATA ist (Boot-Validator
|
|
19
19
|
// lehnt self-extension ab). Lösung: drittes optional-mountbares Feature
|
|
20
20
|
// das requires beide Sources + die useExtension-Calls macht.
|
|
@@ -40,7 +40,7 @@ export function createUserDataRightsDefaultsFeature() {
|
|
|
40
40
|
category: "compliance",
|
|
41
41
|
recommended: false,
|
|
42
42
|
});
|
|
43
|
-
r.requires("user", "files", "user-data-rights");
|
|
43
|
+
r.requires({ features: ["user", "files", "user-data-rights"] });
|
|
44
44
|
// Optional sources: hooks are registered unconditionally but each one
|
|
45
45
|
// no-ops at runtime when its source feature isn't mounted (see
|
|
46
46
|
// hooks/feature-mounted.ts) — the export runner has no per-hook
|
|
@@ -22,10 +22,10 @@ export function createUserProfileFeature(options) {
|
|
|
22
22
|
category: "identity",
|
|
23
23
|
recommended: true,
|
|
24
24
|
});
|
|
25
|
-
r.requires("user");
|
|
26
|
-
r.requires("auth-email-password");
|
|
27
|
-
r.requires("user-data-rights");
|
|
28
|
-
r.requires("user-data-rights-defaults");
|
|
25
|
+
r.requires({ features: ["user"] });
|
|
26
|
+
r.requires({ features: ["auth-email-password"] });
|
|
27
|
+
r.requires({ features: ["user-data-rights"] });
|
|
28
|
+
r.requires({ features: ["user-data-rights-defaults"] });
|
|
29
29
|
const handlers = allowEmailChange ? { changeEmail: r.writeHandler(changeEmailWrite) } : {};
|
|
30
30
|
// Boot-validator requires a "screen:<id>.title" key per r.screen(), plus
|
|
31
31
|
// one entry per i18nKey()-marked dot-form label below — kept inline (not
|
package/dist/waitlist/feature.js
CHANGED
|
@@ -15,7 +15,7 @@ export function createWaitlistFeature(opts = {}) {
|
|
|
15
15
|
r.describe("Public waitlist: an anonymous, rate-limited `submit` handler collects name, email and optional company, portfolio and message (a honeypot field and per-email dedupe keep bots and repeat submits out, and the response body is identical whether or not an address was already listed), and mails the submitter a confirmation. SystemAdmins review entries in a list screen and invite or reject them; an invite creates the entrant's own tenant (or joins one shared tenant) and mails an accept link with the configured membership role, never a global role. Entries are platform-wide, their personal data is crypto-shredding-ready, and the EXT_USER_DATA hooks export and erase entries matching a user's email.");
|
|
16
16
|
r.uiHints({ displayLabel: "Waitlist", category: "data", recommended: false });
|
|
17
17
|
r.systemScope();
|
|
18
|
-
r.requires("tenant", "auth-email-password", "user-data-rights");
|
|
18
|
+
r.requires({ features: ["tenant", "auth-email-password", "user-data-rights"] });
|
|
19
19
|
r.translations({ keys: WAITLIST_I18N });
|
|
20
20
|
r.notification("confirmation", {
|
|
21
21
|
variables: WAITLIST_CONFIRMATION_VARIABLES,
|
|
@@ -26,7 +26,7 @@ export function createWaitlistFeature(opts = {}) {
|
|
|
26
26
|
record: WAITLIST_ADMIN_NOTICE_RECORD,
|
|
27
27
|
localizedTemplate: waitlistAdminNoticeTemplate,
|
|
28
28
|
});
|
|
29
|
-
r.entity("waitlistEntry", waitlistEntryEntity);
|
|
29
|
+
r.entity({ name: "waitlistEntry", ...waitlistEntryEntity });
|
|
30
30
|
r.writeHandler(createSubmitHandler(opts));
|
|
31
31
|
r.writeHandler(createInviteHandler(opts.invite));
|
|
32
32
|
r.writeHandler(rejectHandler);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-bundled-features",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.366.0",
|
|
4
4
|
"description": "Built-in features — tenant, user, auth, delivery. The stuff you'd rewrite anyway, already typed.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -524,12 +524,12 @@
|
|
|
524
524
|
}
|
|
525
525
|
},
|
|
526
526
|
"dependencies": {
|
|
527
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
528
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
529
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
530
|
-
"@cosmicdrift/kumiko-renderer": "0.
|
|
531
|
-
"@cosmicdrift/kumiko-renderer-web": "0.
|
|
532
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
527
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.366.0",
|
|
528
|
+
"@cosmicdrift/kumiko-framework": "0.366.0",
|
|
529
|
+
"@cosmicdrift/kumiko-headless": "0.366.0",
|
|
530
|
+
"@cosmicdrift/kumiko-renderer": "0.366.0",
|
|
531
|
+
"@cosmicdrift/kumiko-renderer-web": "0.366.0",
|
|
532
|
+
"@cosmicdrift/kumiko-types": "0.366.0",
|
|
533
533
|
"@mollie/api-client": "^4.5.0",
|
|
534
534
|
"@node-rs/argon2": "^2.0.2",
|
|
535
535
|
"@tiptap/core": "3.31.3",
|
|
@@ -1078,9 +1078,9 @@
|
|
|
1078
1078
|
],
|
|
1079
1079
|
"devDependencies": {
|
|
1080
1080
|
"@testing-library/user-event": "^14.6.1",
|
|
1081
|
-
"@cosmicdrift/kumiko-locale-de": "0.
|
|
1082
|
-
"@cosmicdrift/kumiko-locale-es": "0.
|
|
1083
|
-
"@cosmicdrift/kumiko-renderer-mail-html": "0.
|
|
1081
|
+
"@cosmicdrift/kumiko-locale-de": "0.366.0",
|
|
1082
|
+
"@cosmicdrift/kumiko-locale-es": "0.366.0",
|
|
1083
|
+
"@cosmicdrift/kumiko-renderer-mail-html": "0.366.0",
|
|
1084
1084
|
"jsqr": "^1.4.0",
|
|
1085
1085
|
"unpdf": "^1.8.1"
|
|
1086
1086
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.366.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "Agent tool failures are classified instead of passing raw messages through",
|
|
6
|
+
"detail": "dispatchToolCall now adds a code to failed tool results. Client errors keep their message, rate limits also set retryable and retryAfterSeconds. Server errors and unknown throws are logged with their cause and returned to the model as \"Tool failed unexpectedly\", so internal details such as database messages no longer reach the model. ToolCallRequest accepts an optional log."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.353.0",
|
|
4
10
|
"type": "fix",
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.366.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "Removed unused AuthHandlers.inviteCancel constant",
|
|
6
|
+
"detail": "AuthHandlers.inviteCancel pointed at auth-email-password:write:invite-cancel, a handler that never existed. The constant is removed.",
|
|
7
|
+
"migration": "If you referenced AuthHandlers.inviteCancel, use tenant:write:cancel-invitation."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.366.0",
|
|
11
|
+
"type": "fix",
|
|
12
|
+
"title": "invite-create is no longer exposed to agents",
|
|
13
|
+
"detail": "The admin invite-create handler is now opted out of the agent tool catalog with agent: { expose: false }, like the other invite handlers, because it mails an accept link to an arbitrary address."
|
|
14
|
+
},
|
|
2
15
|
{
|
|
3
16
|
"version": "0.365.0",
|
|
4
17
|
"type": "fix",
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.366.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "cap-counter calendar settle is idempotent",
|
|
6
|
+
"detail": "Settling a calendar cap reservation now keeps the row as a tombstone (new column store_cap_reservations.settled_at, retained for 24 hours) instead of deleting it. A repeated settle with the same reservation id is a no-op, and confirm, give-back and expiry sweep ignore settled rows. The sweep deletes expired tombstones.",
|
|
7
|
+
"migration": "Apps with cap-counter generate a migration for the new column store_cap_reservations.settled_at (kumiko migrate generate)."
|
|
8
|
+
},
|
|
2
9
|
{
|
|
3
10
|
"version": "0.365.0",
|
|
4
11
|
"type": "breaking",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.366.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "forget-subject is covered for users stored before the KMS and users without an event stream",
|
|
6
|
+
"detail": "Tests now cover forget-subject for users stored as plaintext before the KMS was configured and for users without an event stream. Both succeed since the KMS tombstone fix, close the login door and write the audit event."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.365.1",
|
|
4
10
|
"type": "fix",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.366.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "Renaming a notification type keeps user preferences and address opt-outs",
|
|
6
|
+
"detail": "r.notification accepts renamedFrom, a list of former qualified names. Preferences and address opt-outs stored under a former name keep applying to the renamed notification, and a stored choice under the current name wins over one under a former name. New writes via setPreference and the unsubscribe and resubscribe handlers are stored under the current name, resubscribeAddress also lifts opt-outs under former names. Boot fails if an alias is a current notification name, is the wildcard, or is claimed by two notifications."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.365.0",
|
|
4
10
|
"type": "fix",
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.366.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "Inbound mail fetch can skip already-seen message ids",
|
|
6
|
+
"detail": "InboundMailProviderPlugin.fetch receives an optional filterUnknownMessageIds(providerMessageIds) hook. The watch supervisor implements it with a tenant- and account-scoped lookup of already-seen provider message ids and returns the ids not seen yet, so a plugin can avoid downloading messages it has already processed."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.366.0",
|
|
10
|
+
"type": "breaking",
|
|
11
|
+
"title": "InboundMailContext exposes metricsFor to provider plugins",
|
|
12
|
+
"detail": "InboundMailContext gains an optional metricsFor(featureName) returning a MetricsHandle. runProdApp, the worker app and the dev server wire it from the observability meter, so provider plugins can emit their own metrics through the same pipeline.",
|
|
13
|
+
"migration": "Code that builds SystemWireDeps itself adds metricsFor (createMetricsForFactory(meter))."
|
|
14
|
+
},
|
|
2
15
|
{
|
|
3
16
|
"version": "0.364.0",
|
|
4
17
|
"type": "fix",
|