@cat-factory/server 0.112.0 → 0.112.2
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/crypto/WebCryptoPersonalSecretCipher.d.ts.map +1 -1
- package/dist/crypto/WebCryptoPersonalSecretCipher.js +38 -9
- package/dist/crypto/WebCryptoPersonalSecretCipher.js.map +1 -1
- package/dist/crypto/WebCryptoSecretCipher.d.ts.map +1 -1
- package/dist/crypto/WebCryptoSecretCipher.js +23 -6
- package/dist/crypto/WebCryptoSecretCipher.js.map +1 -1
- package/dist/runtime/escalateNotifications.d.ts +6 -0
- package/dist/runtime/escalateNotifications.d.ts.map +1 -1
- package/dist/runtime/escalateNotifications.js +10 -1
- package/dist/runtime/escalateNotifications.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebCryptoPersonalSecretCipher.d.ts","sourceRoot":"","sources":["../../src/crypto/WebCryptoPersonalSecretCipher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAyB/D,qBAAa,6BAA8B,YAAW,oBAAoB;IAClE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU/D;IAEK,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"WebCryptoPersonalSecretCipher.d.ts","sourceRoot":"","sources":["../../src/crypto/WebCryptoPersonalSecretCipher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAyB/D,qBAAa,6BAA8B,YAAW,oBAAoB;IAClE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU/D;IAEK,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmD9D;CACF"}
|
|
@@ -28,19 +28,48 @@ export class WebCryptoPersonalSecretCipher {
|
|
|
28
28
|
return [VERSION, base64url(salt), base64url(iv), base64url(new Uint8Array(sealed))].join('.');
|
|
29
29
|
}
|
|
30
30
|
async open(envelope, password) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
// Parse the `pv1.` envelope up front. A wrong structure OR an undecodable segment
|
|
32
|
+
// (base64url that `atob` rejects — a mid-envelope corruption) both mean the stored
|
|
33
|
+
// value is malformed: the ciphertext never even reaches the decrypt, so this is NOT a
|
|
34
|
+
// wrong password — the column is truncated/corrupted, or was written by a different
|
|
35
|
+
// scheme/version. Both funnel through one actionable message (original kept as `cause`).
|
|
36
|
+
let salt;
|
|
37
|
+
let iv;
|
|
38
|
+
let ciphertext;
|
|
39
|
+
try {
|
|
40
|
+
const parts = envelope.split('.');
|
|
41
|
+
if (parts.length !== 4 || parts[0] !== VERSION) {
|
|
42
|
+
throw new Error(`unexpected envelope structure (${parts.length} segments)`);
|
|
43
|
+
}
|
|
44
|
+
salt = base64urlToBytes(parts[1]);
|
|
45
|
+
iv = base64urlToBytes(parts[2]);
|
|
46
|
+
ciphertext = base64urlToBytes(parts[3]);
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
throw new Error('The stored personal subscription credential is not a valid encryption envelope: ' +
|
|
50
|
+
'it is truncated or corrupted, or was written by a different scheme/version. ' +
|
|
51
|
+
'Remove and re-add the subscription to re-seal it.', { cause: e });
|
|
34
52
|
}
|
|
35
|
-
const salt = base64urlToBytes(parts[1]);
|
|
36
|
-
const iv = base64urlToBytes(parts[2]);
|
|
37
|
-
const ciphertext = base64urlToBytes(parts[3]);
|
|
38
53
|
const key = await deriveKey(password, salt);
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
let plain;
|
|
55
|
+
try {
|
|
56
|
+
plain = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
// AES-GCM authentication failed. For this password-derived layer that almost
|
|
60
|
+
// always means the WRONG PASSWORD: the key is derived from the personal password,
|
|
61
|
+
// so a mismatch can't reproduce the auth tag. The raw failure is the opaque Web
|
|
62
|
+
// Crypto DOMException ("operation-specific reason"); rethrow an actionable message
|
|
63
|
+
// (original kept as `cause`). The service maps this to a `wrong_password` 428.
|
|
64
|
+
throw new Error('The personal password does not match the one this subscription was sealed under — ' +
|
|
65
|
+
're-enter it, or remove and re-add the subscription.', { cause: e });
|
|
66
|
+
}
|
|
41
67
|
const text = new TextDecoder().decode(plain);
|
|
42
68
|
if (!text.startsWith(MAGIC)) {
|
|
43
|
-
|
|
69
|
+
// GCM verified but the sealed magic prefix is absent — the stored value is corrupted
|
|
70
|
+
// or was sealed by a different scheme, not a simple wrong password.
|
|
71
|
+
throw new Error('This personal subscription credential failed its integrity check — the stored value ' +
|
|
72
|
+
'is corrupted or was sealed by a different scheme. Remove and re-add the subscription.');
|
|
44
73
|
}
|
|
45
74
|
return text.slice(MAGIC.length);
|
|
46
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebCryptoPersonalSecretCipher.js","sourceRoot":"","sources":["../../src/crypto/WebCryptoPersonalSecretCipher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAE3D,mFAAmF;AACnF,iFAAiF;AACjF,qFAAqF;AACrF,kFAAkF;AAClF,qFAAqF;AACrF,sFAAsF;AACtF,mBAAmB;AACnB,EAAE;AACF,wGAAwG;AACxG,EAAE;AACF,oFAAoF;AACpF,mFAAmF;AACnF,8EAA8E;AAE9E,MAAM,OAAO,GAAG,KAAK,CAAA;AACrB,MAAM,UAAU,GAAG,EAAE,CAAA;AACrB,MAAM,QAAQ,GAAG,EAAE,CAAA;AACnB,uFAAuF;AACvF,sDAAsD;AACtD,MAAM,iBAAiB,GAAG,OAAO,CAAA;AACjC,MAAM,KAAK,GAAG,UAAU,CAAA;AAExB,MAAM,OAAO,6BAA6B;IACxC,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,QAAgB;QAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;QAC/D,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC3D,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CACxC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EACvB,GAAG,EACH,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,CAC5C,CAAA;QACD,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/F,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,QAAgB;QAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"WebCryptoPersonalSecretCipher.js","sourceRoot":"","sources":["../../src/crypto/WebCryptoPersonalSecretCipher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebCryptoSecretCipher.d.ts","sourceRoot":"","sources":["../../src/crypto/WebCryptoSecretCipher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAmBvD,MAAM,WAAW,4BAA4B;IAC3C,4DAA4D;IAC5D,eAAe,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,qBAAa,qBAAsB,YAAW,YAAY;IAGxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyB;IAC9C,OAAO,CAAC,cAAc,CAAC,CAAoB;IAE3C,YAAY,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,4BAA4B,EAMlE;IAEK,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUhD;IAEK,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"WebCryptoSecretCipher.d.ts","sourceRoot":"","sources":["../../src/crypto/WebCryptoSecretCipher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAmBvD,MAAM,WAAW,4BAA4B;IAC3C,4DAA4D;IAC5D,eAAe,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,qBAAa,qBAAsB,YAAW,YAAY;IAGxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyB;IAC9C,OAAO,CAAC,cAAc,CAAC,CAAoB;IAE3C,YAAY,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,4BAA4B,EAMlE;IAEK,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUhD;IAEK,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C/C;IAED,OAAO,CAAC,OAAO;YASD,SAAS;CASxB"}
|
|
@@ -34,13 +34,30 @@ export class WebCryptoSecretCipher {
|
|
|
34
34
|
return [VERSION, base64url(salt), base64url(iv), base64url(new Uint8Array(sealed))].join('.');
|
|
35
35
|
}
|
|
36
36
|
async decrypt(envelope) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
// Parse the `v1.` envelope up front. A wrong structure OR an undecodable segment
|
|
38
|
+
// (base64url that `atob` rejects — a mid-envelope corruption) both mean the ciphertext
|
|
39
|
+
// never reaches decryption, so this is a corruption/format problem, not a key mismatch
|
|
40
|
+
// (that surfaces below as an authentication failure). Usual causes: a truncated database
|
|
41
|
+
// column, or a value copied between environments on a different encryption scheme/version.
|
|
42
|
+
// Both funnel through one actionable message (original kept as `cause`).
|
|
43
|
+
let salt;
|
|
44
|
+
let iv;
|
|
45
|
+
let ciphertext;
|
|
46
|
+
try {
|
|
47
|
+
const parts = envelope.split('.');
|
|
48
|
+
if (parts.length !== 4 || parts[0] !== VERSION) {
|
|
49
|
+
throw new Error(`unexpected envelope structure (${parts.length} segments)`);
|
|
50
|
+
}
|
|
51
|
+
salt = base64urlToBytes(parts[1]);
|
|
52
|
+
iv = base64urlToBytes(parts[2]);
|
|
53
|
+
ciphertext = base64urlToBytes(parts[3]);
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
throw new Error('A stored secret is not a valid encryption envelope: it is truncated or corrupted, ' +
|
|
57
|
+
'or was written by a different encryption scheme/version — most likely a truncated ' +
|
|
58
|
+
'database column, or a value copied between environments. Re-enter the affected ' +
|
|
59
|
+
'credential to re-seal it under the current ENCRYPTION_KEY.', { cause: e });
|
|
40
60
|
}
|
|
41
|
-
const salt = base64urlToBytes(parts[1]);
|
|
42
|
-
const iv = base64urlToBytes(parts[2]);
|
|
43
|
-
const ciphertext = base64urlToBytes(parts[3]);
|
|
44
61
|
const key = await this.deriveKey(salt);
|
|
45
62
|
let plain;
|
|
46
63
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebCryptoSecretCipher.js","sourceRoot":"","sources":["../../src/crypto/WebCryptoSecretCipher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAE3D,+EAA+E;AAC/E,oFAAoF;AACpF,yEAAyE;AACzE,8EAA8E;AAC9E,8EAA8E;AAC9E,kFAAkF;AAClF,qDAAqD;AACrD,EAAE;AACF,+FAA+F;AAE/F,MAAM,OAAO,GAAG,IAAI,CAAA;AACpB,MAAM,UAAU,GAAG,EAAE,CAAA;AACrB,MAAM,QAAQ,GAAG,EAAE,CAAA;AACnB,iFAAiF;AACjF,MAAM,YAAY,GAAG,0BAA0B,CAAA;AAc/C,MAAM,OAAO,qBAAqB;IAChC,8EAA8E;IAC9E,iEAAiE;IAChD,SAAS,CAAyB;IAClC,IAAI,CAAyB;IACtC,cAAc,CAAqB;IAE3C,YAAY,EAAE,eAAe,EAAE,IAAI,EAAgC;QACjE,IAAI,CAAC,SAAS,GAAG,gBAAgB,CAAC,eAAe,CAAC,IAAI,EAAE,CAA4B,CAAA;QACpF,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;QACpE,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,YAAY,CAA4B,CAAA;IACvF,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAiB;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;QAC/D,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC3D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CACxC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EACvB,GAAG,EACH,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CACpC,CAAA;QACD,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/F,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAgB;QAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"WebCryptoSecretCipher.js","sourceRoot":"","sources":["../../src/crypto/WebCryptoSecretCipher.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,12 @@ import type { ServerContainer } from '../http/env.js';
|
|
|
7
7
|
* resolves the `waitingEscalationMinutes` threshold (falling back to the default when the
|
|
8
8
|
* settings module isn't wired) and asks the notification service to escalate. Returns the
|
|
9
9
|
* total number escalated. A no-op when the notifications module isn't configured.
|
|
10
|
+
*
|
|
11
|
+
* The per-workspace escalation threshold is resolved in ONE batched read before the loop
|
|
12
|
+
* (`settings.service.getMany`) rather than a `get` point-read per workspace — this sweep
|
|
13
|
+
* runs every couple of minutes across every workspace on both facades, and the perf-item-9
|
|
14
|
+
* settings cache is pass-through on the Worker profile, so only a batch read avoids the N+1
|
|
15
|
+
* here.
|
|
10
16
|
*/
|
|
11
17
|
export declare function escalateStaleNotifications(container: ServerContainer, now: number): Promise<number>;
|
|
12
18
|
//# sourceMappingURL=escalateNotifications.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"escalateNotifications.d.ts","sourceRoot":"","sources":["../../src/runtime/escalateNotifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD
|
|
1
|
+
{"version":3,"file":"escalateNotifications.d.ts","sourceRoot":"","sources":["../../src/runtime/escalateNotifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,eAAe,EAC1B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAejB"}
|
|
@@ -7,6 +7,12 @@ import { DEFAULT_WORKSPACE_SETTINGS } from '@cat-factory/kernel';
|
|
|
7
7
|
* resolves the `waitingEscalationMinutes` threshold (falling back to the default when the
|
|
8
8
|
* settings module isn't wired) and asks the notification service to escalate. Returns the
|
|
9
9
|
* total number escalated. A no-op when the notifications module isn't configured.
|
|
10
|
+
*
|
|
11
|
+
* The per-workspace escalation threshold is resolved in ONE batched read before the loop
|
|
12
|
+
* (`settings.service.getMany`) rather than a `get` point-read per workspace — this sweep
|
|
13
|
+
* runs every couple of minutes across every workspace on both facades, and the perf-item-9
|
|
14
|
+
* settings cache is pass-through on the Worker profile, so only a batch read avoids the N+1
|
|
15
|
+
* here.
|
|
10
16
|
*/
|
|
11
17
|
export async function escalateStaleNotifications(container, now) {
|
|
12
18
|
const notifications = container.notifications;
|
|
@@ -14,9 +20,12 @@ export async function escalateStaleNotifications(container, now) {
|
|
|
14
20
|
return 0;
|
|
15
21
|
const settings = container.settings;
|
|
16
22
|
const workspaces = await container.workspaceService.list(null);
|
|
23
|
+
const settingsById = settings
|
|
24
|
+
? await settings.service.getMany(workspaces.map((ws) => ws.id))
|
|
25
|
+
: null;
|
|
17
26
|
let escalated = 0;
|
|
18
27
|
for (const ws of workspaces) {
|
|
19
|
-
const cfg =
|
|
28
|
+
const cfg = settingsById?.get(ws.id) ?? DEFAULT_WORKSPACE_SETTINGS;
|
|
20
29
|
const thresholdMs = cfg.waitingEscalationMinutes * 60_000;
|
|
21
30
|
escalated += await notifications.service.escalateStale(ws.id, thresholdMs, now);
|
|
22
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"escalateNotifications.js","sourceRoot":"","sources":["../../src/runtime/escalateNotifications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAGhE
|
|
1
|
+
{"version":3,"file":"escalateNotifications.js","sourceRoot":"","sources":["../../src/runtime/escalateNotifications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAGhE;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,SAA0B,EAC1B,GAAW;IAEX,MAAM,aAAa,GAAG,SAAS,CAAC,aAAa,CAAA;IAC7C,IAAI,CAAC,aAAa;QAAE,OAAO,CAAC,CAAA;IAC5B,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAA;IACnC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9D,MAAM,YAAY,GAAG,QAAQ;QAC3B,CAAC,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC,CAAC,IAAI,CAAA;IACR,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,0BAA0B,CAAA;QAClE,MAAM,WAAW,GAAG,GAAG,CAAC,wBAAwB,GAAG,MAAM,CAAA;QACzD,SAAS,IAAI,MAAM,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,CAAA;IACjF,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/server",
|
|
3
|
-
"version": "0.112.
|
|
3
|
+
"version": "0.112.2",
|
|
4
4
|
"description": "Runtime-neutral HTTP layer for the Agent Architecture Board: the Hono controllers, middleware (auth/authz/CORS/error), request helpers and the gateway seams shared by every deployment facade (Cloudflare Worker, Node service).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"hono": "^4.12.27",
|
|
31
31
|
"pino": "^10.3.1",
|
|
32
32
|
"valibot": "^1.4.2",
|
|
33
|
-
"@cat-factory/agents": "0.54.
|
|
34
|
-
"@cat-factory/integrations": "0.81.6",
|
|
33
|
+
"@cat-factory/agents": "0.54.1",
|
|
35
34
|
"@cat-factory/contracts": "0.127.0",
|
|
36
|
-
"@cat-factory/
|
|
37
|
-
"@cat-factory/orchestration": "0.106.
|
|
35
|
+
"@cat-factory/integrations": "0.81.8",
|
|
36
|
+
"@cat-factory/orchestration": "0.106.2",
|
|
37
|
+
"@cat-factory/kernel": "0.121.3",
|
|
38
38
|
"@cat-factory/prompt-fragments": "0.13.13",
|
|
39
|
-
"@cat-factory/spend": "0.12.
|
|
39
|
+
"@cat-factory/spend": "0.12.17"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^26.1.0",
|