@bongos/core 1.19.138 → 1.19.139

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/.bongos-core.json CHANGED
@@ -2,11 +2,11 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.138",
6
- "core_contract": "1.19.138",
7
- "source_commit": "c881ff7b166e960c529748049090f53ad17276c8",
5
+ "core_version": "1.19.139",
6
+ "core_contract": "1.19.139",
7
+ "source_commit": "f5c30a288b3d2e438db66a6c80a845c6d389c3b7",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-15T14:53:14.334Z",
9
+ "built_at": "2026-08-15T15:00:38.021Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 303,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 1574,
20
- "tree_sha256": "09b573285811157440bc46ef823f8ae2adf4735d9a0d559e656a7a68793a0bdf",
20
+ "tree_sha256": "a3c1891b3b817e057662118da1da9b7952ea9c428344f02c4fbc87cf15fb468f",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -4177,12 +4177,12 @@
4177
4177
  {
4178
4178
  "path": "package-lock.json",
4179
4179
  "mode": "0000644",
4180
- "sha256": "b3bd34c7f961631c76f810499e202ecf7ff7b28beb3933da63fd89be5b684e6b"
4180
+ "sha256": "82837d1851e437e93bd6027ad59f49e9b1cff5fe4cbc0ba6d1bb8685b243308d"
4181
4181
  },
4182
4182
  {
4183
4183
  "path": "package.json",
4184
4184
  "mode": "0000644",
4185
- "sha256": "470274822238a12b1ad33021c5c9fc233f69beefdb30730fc7208257e01a11ef"
4185
+ "sha256": "eddbbbd8e503347796b3df0c99c4891a15815c91d86223cc19384bde1e1abec1"
4186
4186
  },
4187
4187
  {
4188
4188
  "path": "public-docs/index.html",
@@ -4437,7 +4437,7 @@
4437
4437
  {
4438
4438
  "path": "public-landing/projects.html",
4439
4439
  "mode": "0000644",
4440
- "sha256": "060cfd1249c09576e634c7c84c8470207cf55b93cb0719cc89821c8c59aa2a17"
4440
+ "sha256": "1cc492c8b781bd67f284d3fbcb3d2d46a7159dc6de8af3fb92e2b5589e4f7b10"
4441
4441
  },
4442
4442
  {
4443
4443
  "path": "public-landing/world/assets/clouds/cloud-island-large.png",
@@ -5767,7 +5767,7 @@
5767
5767
  {
5768
5768
  "path": "src/module-api.js",
5769
5769
  "mode": "0000644",
5770
- "sha256": "b5bbd063bab04b41b5fa8769f2c8de1e0919c28be09bcdf45345ff9440558205"
5770
+ "sha256": "599d420de3284de8a307b0ab87a3506faa8f3e3c9f0014d5bdd36bdeaa1a7317"
5771
5771
  },
5772
5772
  {
5773
5773
  "path": "src/module-loader/catalog.js",
@@ -7312,7 +7312,7 @@
7312
7312
  {
7313
7313
  "path": "tests/projects_hub.mjs",
7314
7314
  "mode": "0000644",
7315
- "sha256": "ee5c944f9e3bd3d618c977e76d4e2ba3e663ce59bf7833f9427a0191717ba57d"
7315
+ "sha256": "5a3f724b4e84324d7560254517612b45fd4e4e31e57ebbb0b35a4021d712df6b"
7316
7316
  },
7317
7317
  {
7318
7318
  "path": "tests/provision.mjs",
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.138",
3
+ "version": "1.19.139",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.138",
9
+ "version": "1.19.139",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.138",
3
+ "version": "1.19.139",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -1438,9 +1438,16 @@ h1[tabindex="-1"]:focus{outline:none;}
1438
1438
  setView('mine');
1439
1439
  tryAnchor(); /* the list may already be rendered from an earlier visit */
1440
1440
  }
1441
+ /* Card-shell lookup by instance id. CSS.escape, not esc(): the data-inst
1442
+ attribute holds the DECODED value, so an HTML-escaped id would never match
1443
+ — and raw interpolation is selector injection. esc() stays correct for
1444
+ RENDERING data-inst into markup; this is the only selector path. */
1445
+ function liFor(id) {
1446
+ return document.querySelector('li[data-inst="' + CSS.escape(String(id == null ? '' : id)) + '"]');
1447
+ }
1441
1448
  function tryAnchor() {
1442
1449
  if (!pendingAnchor) return;
1443
- var li = document.querySelector('li[data-inst="' + pendingAnchor + '"]');
1450
+ var li = liFor(pendingAnchor);
1444
1451
  if (!li) return;
1445
1452
  pendingAnchor = null;
1446
1453
  /* a search or state filter that hides the target would turn the anchor
@@ -3112,7 +3119,7 @@ h1[tabindex="-1"]:focus{outline:none;}
3112
3119
  var shown = 0;
3113
3120
  Object.keys(byId).forEach(function (id) {
3114
3121
  var inst = byId[id];
3115
- var li = document.querySelector('[data-inst="' + esc(String(id)) + '"]');
3122
+ var li = liFor(id);
3116
3123
  if (!li) return;
3117
3124
  var keep = (mineFilter === 'all' || groupFor(inst) === mineFilter) &&
3118
3125
  (!q || findText(inst).indexOf(q) !== -1);
@@ -3379,10 +3386,11 @@ h1[tabindex="-1"]:focus{outline:none;}
3379
3386
  }
3380
3387
 
3381
3388
  function renderCard(inst) {
3382
- /* ids are server-generated, but escape anyway — every interpolated field in
3383
- this file goes through esc(), no exceptions (the grader's rule is right) */
3389
+ /* iid is for MARKUP interpolation only (esc() = HTML escape); the DOM
3390
+ lookup goes through liFor(), which CSS-escapes — the two escapes are
3391
+ not interchangeable */
3384
3392
  var iid = esc(String(inst.id));
3385
- var li = document.querySelector('[data-inst="' + iid + '"]');
3393
+ var li = liFor(inst.id);
3386
3394
  if (!li) return;
3387
3395
  var gone = inst.status === 'torn_down';
3388
3396
  li.className = 'proj' + (gone ? ' gone' : '');
package/src/module-api.js CHANGED
@@ -703,8 +703,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
703
703
  // landed since 1.19.136 with no explicit bump. run 31890033301. (task 1002620)
704
704
  // 1.19.138 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
705
705
  // landed since 1.19.137 with no explicit bump. run 31891128524. (task 1002620)
706
+ // 1.19.139 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
707
+ // landed since 1.19.138 with no explicit bump. run 31891461224. (task 1002620)
706
708
  // ---------------------------------------------------------------------------
707
- const CORE_VERSION = '1.19.138'; // CI auto-patch carrier (ADR 0161); see changelog above
709
+ const CORE_VERSION = '1.19.139'; // CI auto-patch carrier (ADR 0161); see changelog above
708
710
 
709
711
  // A namespaced logger so a module's log lines are attributable + consistent.
710
712
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -765,6 +765,23 @@ test('an owned orb\'s job is manage, not the public site', () => {
765
765
  'the orb route key must not collide with the manage list\'s card identity');
766
766
  });
767
767
 
768
+ test('the card-shell lookup CSS-escapes the id — HTML-escape never reaches a selector (task 1002893)', () => {
769
+ const fn = (SCRIPT.match(/function liFor\(([\s\S]*?)\n \}/) || [, ''])[1];
770
+ assert.ok(fn, 'liFor() must be extractable');
771
+ assert.match(fn, /CSS\.escape\(/, 'the selector path escapes with CSS.escape, not esc()');
772
+ // liFor is the ONLY data-inst selector site — esc() belongs to markup
773
+ // rendering, where it stays; a second selector site could quietly restore
774
+ // the esc()-in-selector (or no-escape) shape this test exists to kill
775
+ const sel = SCRIPT.match(/\[data-inst="' \+/g) || [];
776
+ assert.equal(sel.length, 1, 'exactly one data-inst selector concatenation (inside liFor)');
777
+ assert.match(SCRIPT, /\[data-inst="' \+ CSS\.escape\(/, 'and that one site CSS-escapes');
778
+ // the two prior wrong shapes, by name
779
+ assert.doesNotMatch(SCRIPT, /\[data-inst="' \+ esc\(/,
780
+ 'an HTML-escaped id must never be interpolated into a selector');
781
+ assert.doesNotMatch(SCRIPT, /\[data-inst="' \+ pendingAnchor/,
782
+ 'raw interpolation into a selector is the injection-shaped site');
783
+ });
784
+
768
785
  test('the orb chip is the manage list\'s truth, never a second story (C6)', () => {
769
786
  const orbs = (SCRIPT.match(/function renderOrbs\(([\s\S]*?)\n \}/) || [, ''])[1];
770
787
  // exactly ONE chip site, and it defers to chipFor() — a second site could