@blamejs/core 0.14.5 → 0.14.7

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 (93) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -2
  3. package/lib/agent-event-bus.js +4 -4
  4. package/lib/agent-idempotency.js +6 -6
  5. package/lib/agent-orchestrator.js +9 -9
  6. package/lib/agent-posture-chain.js +10 -10
  7. package/lib/agent-saga.js +6 -7
  8. package/lib/agent-snapshot.js +8 -8
  9. package/lib/agent-stream.js +3 -3
  10. package/lib/agent-tenant.js +4 -4
  11. package/lib/agent-trace.js +5 -5
  12. package/lib/ai-disclosure.js +3 -3
  13. package/lib/app.js +2 -2
  14. package/lib/archive-read.js +1 -1
  15. package/lib/archive-tar-read.js +1 -1
  16. package/lib/archive-wrap.js +5 -5
  17. package/lib/audit-tools.js +65 -5
  18. package/lib/audit.js +2 -2
  19. package/lib/auth/ciba.js +1 -1
  20. package/lib/auth/dpop.js +1 -1
  21. package/lib/auth/fal.js +1 -1
  22. package/lib/auth/fido-mds3.js +2 -3
  23. package/lib/auth/jwt-external.js +2 -2
  24. package/lib/auth/oauth.js +9 -9
  25. package/lib/auth/oid4vci.js +7 -7
  26. package/lib/auth/oid4vp.js +1 -1
  27. package/lib/auth/openid-federation.js +5 -5
  28. package/lib/auth/passkey.js +6 -6
  29. package/lib/auth/saml.js +1 -1
  30. package/lib/auth/sd-jwt-vc.js +3 -6
  31. package/lib/backup/index.js +18 -18
  32. package/lib/cache.js +4 -4
  33. package/lib/calendar.js +5 -5
  34. package/lib/circuit-breaker.js +1 -1
  35. package/lib/cms-codec.js +2 -2
  36. package/lib/compliance.js +14 -14
  37. package/lib/cra-report.js +3 -3
  38. package/lib/crypto-field.js +58 -21
  39. package/lib/crypto.js +5 -6
  40. package/lib/db-query.js +131 -9
  41. package/lib/db.js +106 -22
  42. package/lib/external-db.js +64 -16
  43. package/lib/framework-schema.js +4 -4
  44. package/lib/guard-list-id.js +2 -2
  45. package/lib/guard-list-unsubscribe.js +1 -2
  46. package/lib/incident-report.js +150 -0
  47. package/lib/mail-crypto-smime.js +1 -1
  48. package/lib/mail-deploy.js +3 -3
  49. package/lib/mail-server-managesieve.js +2 -2
  50. package/lib/mail-server-pop3.js +2 -2
  51. package/lib/mail-store.js +1 -1
  52. package/lib/metrics.js +8 -8
  53. package/lib/middleware/age-gate.js +20 -7
  54. package/lib/middleware/bearer-auth.js +36 -35
  55. package/lib/middleware/bot-guard.js +17 -5
  56. package/lib/middleware/cors.js +28 -12
  57. package/lib/middleware/csrf-protect.js +23 -15
  58. package/lib/middleware/daily-byte-quota.js +27 -13
  59. package/lib/middleware/deny-response.js +140 -0
  60. package/lib/middleware/dpop.js +37 -24
  61. package/lib/middleware/fetch-metadata.js +21 -12
  62. package/lib/middleware/host-allowlist.js +19 -8
  63. package/lib/middleware/idempotency-key.js +21 -22
  64. package/lib/middleware/index.js +3 -0
  65. package/lib/middleware/network-allowlist.js +24 -10
  66. package/lib/middleware/protected-resource-metadata.js +2 -2
  67. package/lib/middleware/rate-limit.js +22 -5
  68. package/lib/middleware/require-aal.js +25 -10
  69. package/lib/middleware/require-auth.js +32 -16
  70. package/lib/middleware/require-bound-key.js +49 -18
  71. package/lib/middleware/require-content-type.js +19 -8
  72. package/lib/middleware/require-methods.js +17 -7
  73. package/lib/middleware/require-mtls.js +27 -14
  74. package/lib/network-dns-resolver.js +2 -2
  75. package/lib/network-dns.js +1 -2
  76. package/lib/network-tls.js +0 -1
  77. package/lib/network.js +4 -4
  78. package/lib/outbox.js +1 -1
  79. package/lib/pqc-agent.js +1 -1
  80. package/lib/retention.js +1 -1
  81. package/lib/retry.js +1 -1
  82. package/lib/safe-archive.js +2 -2
  83. package/lib/safe-ical.js +2 -2
  84. package/lib/safe-mime.js +1 -1
  85. package/lib/self-update-standalone-verifier.js +1 -1
  86. package/lib/self-update.js +2 -2
  87. package/lib/static.js +1 -1
  88. package/lib/subject.js +2 -2
  89. package/lib/vault/index.js +64 -1
  90. package/lib/vault/rotate.js +19 -0
  91. package/lib/vendor-data.js +1 -1
  92. package/package.json +1 -1
  93. package/sbom.cdx.json +6 -6
package/lib/network.js CHANGED
@@ -108,8 +108,8 @@ function _socketDefaults() {
108
108
  }
109
109
 
110
110
  /**
111
- * @primitive b.network.applyToSocket
112
- * @signature b.network.applyToSocket(socket)
111
+ * @primitive b.network.socket.applyToSocket
112
+ * @signature b.network.socket.applyToSocket(socket)
113
113
  * @since 0.7.68
114
114
  * @related b.network.bootFromEnv, b.network.snapshot
115
115
  *
@@ -124,7 +124,7 @@ function _socketDefaults() {
124
124
  * @example
125
125
  * var net = require("net");
126
126
  * var s = new net.Socket();
127
- * var ret = b.network.applyToSocket(s);
127
+ * var ret = b.network.socket.applyToSocket(s);
128
128
  * ret === s;
129
129
  * // → true
130
130
  * s.destroy();
@@ -164,7 +164,7 @@ var ntpFacade = {
164
164
  * @primitive b.network.bootFromEnv
165
165
  * @signature b.network.bootFromEnv(opts)
166
166
  * @since 0.7.68
167
- * @related b.network.snapshot, b.network.applyToSocket
167
+ * @related b.network.snapshot, b.network.socket.applyToSocket
168
168
  *
169
169
  * Read `BLAMEJS_*` environment variables once and apply the union to
170
170
  * the live network facade. Recognised keys cover NTP servers /
package/lib/outbox.js CHANGED
@@ -342,7 +342,7 @@ function create(opts) {
342
342
  var stopping = false;
343
343
  var inFlight = null;
344
344
 
345
- // SUBSTRATE-23 — `FOR UPDATE SKIP LOCKED` is Postgres / MySQL 8+ only.
345
+ // `FOR UPDATE SKIP LOCKED` is Postgres / MySQL 8+ only.
346
346
  // SQLite (single-writer at the DB level, but WAL mode lets multiple
347
347
  // processes share the file with concurrent SELECTs) doesn't support
348
348
  // SKIP LOCKED — feeding it Postgres syntax silently double-publishes
package/lib/pqc-agent.js CHANGED
@@ -322,7 +322,7 @@ function _getDefaultAgent() {
322
322
  * logger.info("pqc-agent reloaded", res);
323
323
  */
324
324
  function reload() {
325
- // CRYPTO-9 — null the cached agent BEFORE calling destroy. The
325
+ // Null the cached agent BEFORE calling destroy. The
326
326
  // previous order let a concurrent _getDefaultAgent() see the
327
327
  // destroyed-not-null agent and hand it to a caller; the caller
328
328
  // then tries to issue a request through a torn-down keep-alive
package/lib/retention.js CHANGED
@@ -569,7 +569,7 @@ function complianceFloor(posture, candidateTtlMs) {
569
569
  return candidateTtlMs > floor ? candidateTtlMs : floor;
570
570
  }
571
571
 
572
- // applyPosture — F-POSTURE-1 cascade hook. b.compliance.set(posture)
572
+ // applyPosture — cascade hook. b.compliance.set(posture)
573
573
  // calls this to merge posture defaults into retention's state. The
574
574
  // retention module itself doesn't carry per-instance global defaults;
575
575
  // the cascade's job here is to surface the posture's audit-log
package/lib/retry.js CHANGED
@@ -275,7 +275,7 @@ function backoffDelay(attempt, opts) {
275
275
  opts = opts || DEFAULT_RETRY;
276
276
  var base = opts.baseDelayMs * Math.pow(2, attempt - 1);
277
277
  var capped = Math.min(base, opts.maxDelayMs);
278
- // CRYPTO-12 — jitter exists to spread retry storms across the
278
+ // Jitter exists to spread retry storms across the
279
279
  // millisecond window so N peer clients waking from the same
280
280
  // upstream outage don't all hit the recovering service at the same
281
281
  // tick. The value is observable to every client by construction
@@ -225,7 +225,7 @@ async function extract(opts) {
225
225
  }
226
226
  inner = await archiveWrap().unwrapWithPassphrase(sealedBytes, { passphrase: opts.passphrase });
227
227
  }
228
- // Codex P1 on v0.12.15 PR #166 — close the original source
228
+ // Close the original source
229
229
  // adapter BEFORE replacing it. When opts.source was a string
230
230
  // path, the fs adapter opened a file descriptor; overwriting
231
231
  // `source` loses the close reference and the descriptor
@@ -236,7 +236,7 @@ async function extract(opts) {
236
236
  if (typeof source.close === "function" && typeof opts.source === "string") {
237
237
  try { source.close(); } catch (_e) { /* drop-silent */ }
238
238
  }
239
- // Codex P2 on v0.12.15 PR #166 — forward opts.signal to the
239
+ // Forward opts.signal to the
240
240
  // inner buffer adapter so abort propagation stays intact
241
241
  // across the unwrap boundary. Without it, an abort raised
242
242
  // after unwrapping would no longer cancel inner range()
package/lib/safe-ical.js CHANGED
@@ -251,9 +251,9 @@ function parse(text, opts) {
251
251
  var vcal = consumed.component;
252
252
  // RFC 5545 §3.4 — a stream may carry multiple VCALENDAR objects.
253
253
  // Walk the remainder so trailing objects are validated under the
254
- // same caps + control-char + property allowlist (Codex P2 — without
254
+ // same caps + control-char + property allowlist; without
255
255
  // this, CalDAV ingest can pass validation on the first object while
256
- // trailing malformed objects ride through untouched).
256
+ // trailing malformed objects ride through untouched.
257
257
  var vcalendars = [_shapeVcalendar(vcal)];
258
258
  var cursor = consumed.nextIdx;
259
259
  while (cursor < lines.length) {
package/lib/safe-mime.js CHANGED
@@ -549,7 +549,7 @@ function _splitMultipart(buf, boundary) {
549
549
  // Per RFC 2046 §5.1.1 a boundary delimiter is `--<value>` preceded
550
550
  // by CRLF (or LF) — OR at the very start of the body. A boundary-
551
551
  // shaped sequence elsewhere in a part's body MUST NOT be treated
552
- // as a delimiter. Per Codex P1 on PR #49.
552
+ // as a delimiter.
553
553
  var idx = _findBoundaryAtLineStart(buf, delimiter, pos);
554
554
  if (idx < 0) break;
555
555
  if (buf[idx + delimiter.length] === 0x2D && buf[idx + delimiter.length + 1] === 0x2D) {
@@ -208,7 +208,7 @@ function verify(assetPath, signaturePath, pubkeyPem) {
208
208
  // produces. 64 KiB chunks match the framework's hash-while-streaming
209
209
  // convention elsewhere.
210
210
  //
211
- // CRYPTO-2 hardening (v0.9.58): fstat the asset BEFORE the read loop
211
+ // Hardening (v0.9.58): fstat the asset BEFORE the read loop
212
212
  // for every alg path, clamp every readSync to (assetStat.size -
213
213
  // fullOff), and reject if the final fullOff diverges from
214
214
  // assetStat.size. A grow-during-read race (writer appends as we
@@ -115,7 +115,7 @@ function _normalizeTag(tag) {
115
115
  * Missing numeric components on either side are treated as `"0"` so
116
116
  * `"1.0"` and `"1.0.0"` compare equal.
117
117
  *
118
- * CRYPTO-20 (v0.9.58) — pre-v0.9.58 the pre-release segment fell back
118
+ * Hardening (v0.9.58) — pre-v0.9.58 the pre-release segment fell back
119
119
  * to lexicographic comparison, which silently misordered `"1.0.0-alpha.10"`
120
120
  * (the strict-§11 LARGER pre-release) and `"1.0.0-alpha.9"`: as strings
121
121
  * "10" < "9" so `alpha.10 < alpha.9`, and a downstream consumer polling
@@ -294,7 +294,7 @@ function _matchAsset(name, pattern, fallback) {
294
294
  * timeoutMs: number, // request timeout (default 15s)
295
295
  * headers: object, // additional request headers
296
296
  * etag: string, // last-seen etag for If-None-Match
297
- * // (CRYPTO-16 — etags are RFC 9110 §13.1.1
297
+ * // (etags are RFC 9110 §13.1.1
298
298
  * // per-resource; an etag captured for
299
299
  * // releasesUrl=A is meaningless against
300
300
  * // releasesUrl=B. Operators rotating
package/lib/static.js CHANGED
@@ -216,7 +216,7 @@ function _resolveSafe(root, requestedPath) {
216
216
  // deposited disk content: shell-exec extensions (.exe / .bin / .so /
217
217
  // legitimate `<name>.<hash>.js` bundler output) are valid here. The
218
218
  // other balanced checks still reject the traversal + smuggling
219
- // surface the user surfaced.
219
+ // surface.
220
220
  var fname = nodePath.basename(resolved);
221
221
  var rv = guardFilename().validate(fname, {
222
222
  profile: "balanced",
package/lib/subject.js CHANGED
@@ -362,7 +362,7 @@ function erase(subjectId, opts) {
362
362
 
363
363
  // ---- Crypto-shred erase (Art. 17 + WAL/replica residual closure) ----
364
364
  //
365
- // F-RTBF-3 — when a table opts into per-row keying via
365
+ // When a table opts into per-row keying via
366
366
  // b.cryptoField.declarePerRowKey, this primitive deletes the
367
367
  // per-row K_row entries from _blamejs_per_row_keys, leaving any
368
368
  // residual ciphertext in WAL / replica / backup storage
@@ -477,7 +477,7 @@ function eraseHard(subjectId, opts) {
477
477
  totalDeleted += deleted;
478
478
  perTable[spec.name] = deleted;
479
479
  // REINDEX the table so B-tree pages holding the deleted row's
480
- // index entries are rebuilt — closes the F-RTBF-2 residual class.
480
+ // index entries are rebuilt — closes the erase-vacuum residual class.
481
481
  try { db().runSql('REINDEX "' + spec.name + '"'); } // table name comes from FRAMEWORK_SCHEMA
482
482
  catch (_e) { /* cluster mode / unsupported dialect */ }
483
483
  }
@@ -102,11 +102,12 @@ function resolvePaths(dataDir) {
102
102
  plaintext: nodePath.join(dataDir, "vault.key"),
103
103
  sealed: nodePath.join(dataDir, "vault.key.sealed"),
104
104
  derivedHashSalt: nodePath.join(dataDir, "vault.derived-hash-salt"),
105
+ derivedHashMacKey: nodePath.join(dataDir, "vault.derived-hash-mac.sealed"),
105
106
  };
106
107
  }
107
108
 
108
109
  // derivedHashSalt — per-deployment salt for crypto-field
109
- // derivedHashes (D-H1). Pre-v0.8.42 the deterministic
110
+ // derivedHashes. Pre-v0.8.42 the deterministic
110
111
  // sha3(namespace + plaintext) shape allowed cross-deployment
111
112
  // rainbow + cross-table correlation; binding a 32-byte
112
113
  // per-deployment salt closes that class without breaking
@@ -175,6 +176,66 @@ function getDerivedHashSalt() {
175
176
  return _cachedDerivedHashSalt;
176
177
  }
177
178
 
179
+ // derivedHashMacKey — per-deployment SECRET key for crypto-field's
180
+ // keyed (hmac-shake256) derived-hash mode. Unlike the salt, this is
181
+ // SEALED at rest (vault.derived-hash-mac.sealed), so an attacker with
182
+ // disk access alone cannot recompute the keyed digest and correlate
183
+ // low-entropy plaintexts. Like the salt, it is keypair-bound and
184
+ // survives a passphrase-only rotation; an ENVELOPE rotation re-seals it
185
+ // because it is registered in rotate's additionalSealed sweep.
186
+ function _readOrCreateDerivedHashMacKey() {
187
+ if (!paths) {
188
+ throw new VaultError("vault/not-initialized",
189
+ "vault.getDerivedHashMacKey() requires init()");
190
+ }
191
+ if (nodeFs.existsSync(paths.derivedHashMacKey)) {
192
+ var sealed = atomicFile.readSync(paths.derivedHashMacKey, { encoding: "utf8" }).trim();
193
+ var b64 = unseal(sealed);
194
+ var key = Buffer.from(b64, "base64");
195
+ if (key.length !== 32) { // 32-byte (256-bit) MAC key
196
+ throw new VaultError("vault/derived-hash-mac-key-corrupted",
197
+ "vault.derived-hash-mac key must unseal to exactly 32 bytes; got " + key.length);
198
+ }
199
+ return key;
200
+ }
201
+ var nodeCrypto = require("node:crypto");
202
+ var raw = nodeCrypto.randomBytes(32); // 32-byte MAC key
203
+ atomicFile.writeSync(paths.derivedHashMacKey, seal(raw.toString("base64")), { fileMode: 0o600 });
204
+ log("generated per-deployment derivedHash MAC key at " + paths.derivedHashMacKey);
205
+ return raw;
206
+ }
207
+
208
+ var _cachedDerivedHashMacKey = null;
209
+ /**
210
+ * @primitive b.vault.getDerivedHashMacKey
211
+ * @signature b.vault.getDerivedHashMacKey()
212
+ * @since 0.14.7
213
+ * @related b.vault.getDerivedHashSalt, b.cryptoField.registerTable
214
+ *
215
+ * Returns the 32-byte per-deployment SECRET key that backs crypto-
216
+ * field's keyed (`hmac-shake256`) derived-hash mode. Generated once on
217
+ * first use, SEALED at rest (`vault.derived-hash-mac.sealed`, mode
218
+ * `0o600`) so disk access alone does not expose it, and re-sealed by an
219
+ * envelope vault rotation. Distinct from `getDerivedHashSalt`, which is
220
+ * a non-secret salt stored in plaintext.
221
+ *
222
+ * Throws `VaultError("vault/not-initialized")` before `init()`, or
223
+ * `vault/derived-hash-mac-key-corrupted` if the sealed file does not
224
+ * unseal to exactly 32 bytes.
225
+ *
226
+ * @example
227
+ * await b.vault.init({ dataDir: "/var/lib/blamejs", mode: "plaintext" });
228
+ * var k = b.vault.getDerivedHashMacKey();
229
+ * k.length; // → 32
230
+ * Buffer.isBuffer(k); // → true
231
+ */
232
+ function getDerivedHashMacKey() {
233
+ if (_cachedDerivedHashMacKey === null) {
234
+ _cachedDerivedHashMacKey = _readOrCreateDerivedHashMacKey();
235
+ }
236
+ return _cachedDerivedHashMacKey;
237
+ }
238
+
178
239
  // ---- Init dispatch ----
179
240
 
180
241
  /**
@@ -620,6 +681,7 @@ module.exports = {
620
681
  seal: seal,
621
682
  unseal: unseal,
622
683
  getDerivedHashSalt: getDerivedHashSalt,
684
+ getDerivedHashMacKey: getDerivedHashMacKey,
623
685
  _zeroizeAndReplace: _zeroizeAndReplace,
624
686
  aad: vaultAad,
625
687
  getKeysJson: getKeysJson,
@@ -633,6 +695,7 @@ module.exports = {
633
695
  _resetForTest: function () {
634
696
  if (currentPassphrase) safeBuffer.secureZero(currentPassphrase);
635
697
  keys = null; initialized = false; currentPassphrase = null; paths = null; currentMode = null;
698
+ _cachedDerivedHashSalt = null; _cachedDerivedHashMacKey = null;
636
699
  },
637
700
  _getKeysForTest: function () { return keys; },
638
701
  _getPathsForTest: function () { return paths; },
@@ -651,6 +651,25 @@ async function rotate(opts) {
651
651
  _reSealValue(current, oldKeys, newKeys), { mode: 0o600 });
652
652
  }
653
653
 
654
+ // 3b. Framework-managed crypto-field derived-hash files — always
655
+ // rotated regardless of operator opts.paths, so the staging copy is
656
+ // complete. The plaintext salt is copied verbatim; the SEALED MAC key
657
+ // (keyed hmac-shake256 mode) is re-sealed under the new keypair so an
658
+ // envelope rotation doesn't orphan it (a passphrase-only rotation
659
+ // re-seals to the same value since the keypair is unchanged).
660
+ var saltSrc = nodePath.join(dataDir, "vault.derived-hash-salt");
661
+ if (nodeFs.existsSync(saltSrc)) {
662
+ nodeFs.copyFileSync(saltSrc, nodePath.join(stagingDir, "vault.derived-hash-salt"));
663
+ }
664
+ var macSrc = nodePath.join(dataDir, "vault.derived-hash-mac.sealed");
665
+ if (nodeFs.existsSync(macSrc)) {
666
+ var macCurrent = nodeFs.readFileSync(macSrc, "utf8").trim();
667
+ if (macCurrent.indexOf(C.VAULT_PREFIX) === 0) {
668
+ nodeFs.writeFileSync(nodePath.join(stagingDir, "vault.derived-hash-mac.sealed"),
669
+ _reSealValue(macCurrent, oldKeys, newKeys), { mode: 0o600 });
670
+ }
671
+ }
672
+
654
673
  // 4. decrypt + rotate + re-encrypt db.enc
655
674
  _emit(progress, { phase: "rotate_db" });
656
675
  var encDbPath = nodePath.join(dataDir, paths.encryptedDb);
@@ -306,7 +306,7 @@ function _loadAndVerify(name) {
306
306
  // Memoized — "sha256:" + sha256(pemToRaw(PUBKEY_PEM)). Matches the
307
307
  // canonical fingerprint shape `scripts/vendor-data-gen.js` writes into
308
308
  // each .data.js's `metadata.publicKeyFingerprint`. Computed lazily on
309
- // first verify (also lazily by verifyAll at boot). CRYPTO-11 — every
309
+ // first verify (also lazily by verifyAll at boot). Every
310
310
  // per-entry verify cross-checks this against the entry's declared
311
311
  // `meta.publicKeyFingerprint` so a pubkey-swap attack fails before
312
312
  // signature verify even runs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.14.5",
3
+ "version": "0.14.7",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
package/sbom.cdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:5c0853e1-1ea7-4fb1-8fb6-58b2ae51671f",
5
+ "serialNumber": "urn:uuid:5777b851-3edb-4e73-9a6a-0538d8e52a91",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-05-30T15:10:40.322Z",
8
+ "timestamp": "2026-05-30T21:03:08.883Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/core@0.14.5",
22
+ "bom-ref": "@blamejs/core@0.14.7",
23
23
  "type": "application",
24
24
  "name": "blamejs",
25
- "version": "0.14.5",
25
+ "version": "0.14.7",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "The Node framework that owns its stack.",
29
- "purl": "pkg:npm/%40blamejs/core@0.14.5",
29
+ "purl": "pkg:npm/%40blamejs/core@0.14.7",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/core@0.14.5",
57
+ "ref": "@blamejs/core@0.14.7",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]