@bongos/core 1.25.26 → 1.25.27

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/bongos/package-core.js",
5
- "core_version": "1.25.26",
6
- "core_contract": "1.25.26",
7
- "source_commit": "333272867d71e2400d7ed05f8ebb2fd7fe522ed6",
5
+ "core_version": "1.25.27",
6
+ "core_contract": "1.25.27",
7
+ "source_commit": "b321f053c5b89fb964e23d3501fb95204d4bfe83",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-11-14T12:08:53.368Z",
9
+ "built_at": "2026-11-14T12:30:46.728Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 658,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 4781,
20
- "tree_sha256": "b92f75ed02e59a4b90c41c591c58928e9301ba2e5c90686d4bb1864f931073df",
20
+ "tree_sha256": "1a404673caec4bc1439d64975360a33e6b364ab2d3305053c0e024b9c044b40d",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -3102,7 +3102,7 @@
3102
3102
  {
3103
3103
  "path": "docs/module-api-changelog.md",
3104
3104
  "mode": "0000644",
3105
- "sha256": "8faf34734c00080a73a11b33921860c3976f8b732f82135d47e665dc5668ba57"
3105
+ "sha256": "982cd09fb469c00defeab1c14286f4754015379bae3cfdc2bd0b61b2554f570a"
3106
3106
  },
3107
3107
  {
3108
3108
  "path": "docs/modules-contract.md",
@@ -12397,7 +12397,7 @@
12397
12397
  {
12398
12398
  "path": "modules/ui-design/scripts/gen-design-reference.js",
12399
12399
  "mode": "0000644",
12400
- "sha256": "d59b046a2aabda513d2d580a574c74ae43b04e97c847315c16eaa2ab50144ffb"
12400
+ "sha256": "44ff275872e8e507cb5eb01e776d9b36397af2a6cf6eb2b05651e3202201202d"
12401
12401
  },
12402
12402
  {
12403
12403
  "path": "modules/ui-design/scripts/gen-design-tokens.js",
@@ -12517,12 +12517,12 @@
12517
12517
  {
12518
12518
  "path": "package-lock.json",
12519
12519
  "mode": "0000644",
12520
- "sha256": "fae7574993d6498dcb88ab2fb6c096377e3f0c1dc6f0c7f269983c8a2adcede2"
12520
+ "sha256": "0b23626017f0c3887b6d928ef51bdc1d6526ada92d9a192bd4133e4afcefa442"
12521
12521
  },
12522
12522
  {
12523
12523
  "path": "package.json",
12524
12524
  "mode": "0000644",
12525
- "sha256": "31c7a80481f182612abb3c939c0ac183ca8c0bd73bc483dfa02da185b4fee6c8"
12525
+ "sha256": "e501947d6ce6cb236c3ad900e54e9cf56ceda5cc436e6c67d5a17227a870c225"
12526
12526
  },
12527
12527
  {
12528
12528
  "path": "public-docs/index.html",
@@ -12542,7 +12542,7 @@
12542
12542
  {
12543
12543
  "path": "release-notes.json",
12544
12544
  "mode": "0000644",
12545
- "sha256": "99b7a75257ba26c793f17beccdf179602f0f8170e0460b523919a8003dc226fa"
12545
+ "sha256": "939ee4a2830217d56ff5497f54e725473fb27070e191b80c0a14855a97d0a9b5"
12546
12546
  },
12547
12547
  {
12548
12548
  "path": "scripts/bongos/CLAUDE.md",
@@ -13162,7 +13162,7 @@
13162
13162
  {
13163
13163
  "path": "scripts/bongos/gen-brand.js",
13164
13164
  "mode": "0000644",
13165
- "sha256": "bc3ce6eebc646e7f2359ef2495a99878e060d7b41c27673833d824d428a379bd"
13165
+ "sha256": "a275ed2efd592a718b2a9ed0475f7f735bb414be8daf37a4c76e607d56b6f6d7"
13166
13166
  },
13167
13167
  {
13168
13168
  "path": "scripts/bongos/gen-diagrams.js",
@@ -16622,7 +16622,7 @@
16622
16622
  {
16623
16623
  "path": "src/module-api.js",
16624
16624
  "mode": "0000644",
16625
- "sha256": "56af6386047adbdea50e906ae27716d3b32d4ae5e362dbda28c04bcb751fbb81"
16625
+ "sha256": "12ea79d0c2153b6c8641dee679ed5c9afa30fe03d141f44bf82304db083dc714"
16626
16626
  },
16627
16627
  {
16628
16628
  "path": "src/module-loader/catalog.js",
@@ -17447,7 +17447,7 @@
17447
17447
  {
17448
17448
  "path": "tests/brand_mark.mjs",
17449
17449
  "mode": "0000644",
17450
- "sha256": "68ff85560c05b7426139527cea3832429e17da4b64c96bbc26ba46c02305d97e"
17450
+ "sha256": "466efb92e78175fe4a5c95bbae20fe060b568566fc5e7a24e639383fea136866"
17451
17451
  },
17452
17452
  {
17453
17453
  "path": "tests/brand_surfaces.mjs",
@@ -18217,12 +18217,12 @@
18217
18217
  {
18218
18218
  "path": "tests/design_counts_ratchet.mjs",
18219
18219
  "mode": "0000644",
18220
- "sha256": "3e7457685c915d01d11ba4dd1481e726f82c83a3ce481f5190893e4b0636b7bc"
18220
+ "sha256": "07ea7fe6b707753d8abc96e54bb75caa6fb3f0ed9127242c1f6f65e57053107d"
18221
18221
  },
18222
18222
  {
18223
18223
  "path": "tests/design_reference.mjs",
18224
18224
  "mode": "0000644",
18225
- "sha256": "56594abdea98132ba15a7c7c4e207934a429a0bd746de54055f567a8c193fd1d"
18225
+ "sha256": "f1b4bdecc8b33b9d7cb3c6e97a724381e99537f2ec0d2cfbdf80a8ab68bd5c55"
18226
18226
  },
18227
18227
  {
18228
18228
  "path": "tests/design_tokens_generated.mjs",
@@ -19662,7 +19662,7 @@
19662
19662
  {
19663
19663
  "path": "tests/hall_dialog.mjs",
19664
19664
  "mode": "0000644",
19665
- "sha256": "62d44b70c822b7e99d5e732a8321eb6d2f9c88d6168ceec83bd6ca38b07f97a4"
19665
+ "sha256": "e68494039638141179b82f79dc24bc0eaef031a3969dd74e63b5f4a04b0daa76"
19666
19666
  },
19667
19667
  {
19668
19668
  "path": "tests/hall_error_envelope.mjs",
@@ -3490,5 +3490,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
3490
3490
  landed since 1.25.24 with no explicit bump. run 43537450687. (task 1002620)
3491
3491
  1.25.26 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3492
3492
  landed since 1.25.25 with no explicit bump. run 43593222072. (task 1002620)
3493
+ 1.25.27 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
3494
+ landed since 1.25.26 with no explicit bump. run 43595061258. (task 1002620)
3493
3495
  ---------------------------------------------------------------------------
3494
3496
  ```
@@ -339,7 +339,9 @@ module.exports = { build, blockVars };
339
339
 
340
340
  if (require.main === module) {
341
341
  const next = build();
342
- const current = fs.existsSync(OUT) ? fs.readFileSync(OUT, 'utf8') : '';
342
+ // task 1005296: compare content, not line endings. A `core.autocrlf=true` checkout reads
343
+ // brand.html back as CRLF while build() is LF, which read as stale forever.
344
+ const current = fs.existsSync(OUT) ? fs.readFileSync(OUT, 'utf8').replace(/\r\n/g, '\n') : '';
343
345
  if (process.argv.includes('--check')) {
344
346
  if (current === next) process.stdout.write('brand.html: current\n');
345
347
  else {
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.25.26",
3
+ "version": "1.25.27",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.25.26",
9
+ "version": "1.25.27",
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.25.26",
3
+ "version": "1.25.27",
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",
@@ -11924,5 +11924,15 @@
11924
11924
  "id": "1005266",
11925
11925
  "text": "In game mode the visor now steps out of the way while you look around and fades back in, slimmer than before, when you reach for a command."
11926
11926
  }
11927
+ ],
11928
+ "1.25.27": [
11929
+ {
11930
+ "id": "1005296",
11931
+ "text": "The pre-ship health check no longer wrongly says the brand page and logo files are out of date on Windows computers."
11932
+ },
11933
+ {
11934
+ "id": "1005197",
11935
+ "text": "A hall check that always failed on Windows computers now works there, so it can again spot a page loading its scripts in the wrong order."
11936
+ }
11927
11937
  ]
11928
11938
  }
@@ -35,6 +35,7 @@ const path = require('node:path');
35
35
  const crypto = require('node:crypto');
36
36
  const { readMarkSource, markParts, markFile, faviconSvg } = require('../../src/brand-mark');
37
37
  const { escapeHtml } = require('../../src/html-escape');
38
+ const { sameContent } = require('./gen-freshness'); // eol-insensitive freshness (CRLF checkouts, task 1005296)
38
39
 
39
40
  const ROOT = path.resolve(__dirname, '..', '..');
40
41
 
@@ -158,7 +159,7 @@ async function main() {
158
159
  for (const [name, text] of Object.entries(files)) {
159
160
  const file = path.join(dir, name);
160
161
  const cur = fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : null;
161
- if (cur === text) continue;
162
+ if (cur !== null && sameContent(cur, text)) continue;
162
163
  stale.push(name);
163
164
  if (!args.includes('--check')) fs.writeFileSync(file, text);
164
165
  }
package/src/module-api.js CHANGED
@@ -81,7 +81,7 @@ const { sleep } = require('./sleep');
81
81
  // MAJOR (see allowBoxScope below): passes the request through untouched.
82
82
  function deprecatedNoopMiddleware(_req, _res, next) { next(); }
83
83
 
84
- const CORE_VERSION = '1.25.26'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
84
+ const CORE_VERSION = '1.25.27'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
85
85
 
86
86
  // A namespaced logger so a module's log lines are attributable + consistent.
87
87
  // Usage: const log = api.logger('discord'); log.info('mounted');
@@ -95,7 +95,8 @@ test('the brand folder holds exactly what gen-brand.js writes from the source (l
95
95
  const { brandFiles, packColors } = require('../scripts/bongos/gen-brand.js');
96
96
  const files = brandFiles(read(BRAND_DIR, 'mark.svg'), packColors());
97
97
  for (const [name, text] of Object.entries(files)) {
98
- assert.equal(read(BRAND_DIR, name), text, `${name} is stale — run node scripts/bongos/gen-brand.js`);
98
+ assert.equal(read(BRAND_DIR, name).replace(/\r\n/g, '\n'), text, // CRLF checkouts (task 1005296)
99
+ `${name} is stale — run node scripts/bongos/gen-brand.js`);
99
100
  }
100
101
  const c = packColors();
101
102
  assert.match(files['mark-light.svg'], new RegExp(c.ink));
@@ -99,6 +99,7 @@ const GENERATOR_SOURCES = [
99
99
  'modules/hall-ui/public/controls.css',
100
100
  'modules/hall-ui/public/dom-utils.js',
101
101
  'scripts/bongos/gen-brand.js',
102
+ 'scripts/bongos/gen-freshness.js',
102
103
  'src/brand-mark.js',
103
104
  'src/html-escape.js',
104
105
  'DESIGN.md',
@@ -135,6 +136,26 @@ test('the freshness gate passes on a fresh tree and fails when the token sheet c
135
136
  }
136
137
  });
137
138
 
139
+ // task 1005296: a `core.autocrlf=true` checkout (every default Windows clone) hands the
140
+ // generators CRLF copies of brand.html and the logo SVGs, while they build LF. Freshness is
141
+ // about content, so line endings alone must not read as stale — but a real edit still must.
142
+ test('the freshness gate ignores CRLF line endings on the brand page and the logo set', () => {
143
+ const dir = copiedTree();
144
+ const toCrlf = (f) => fs.writeFileSync(f, fs.readFileSync(f, 'utf8').replace(/\r\n/g, '\n').replace(/\n/g, '\r\n'));
145
+ try {
146
+ const page = path.join(dir, 'modules/ui-design/public/brand.html');
147
+ const brand = path.join(dir, 'modules/ui-design/public/brand');
148
+ toCrlf(page);
149
+ for (const f of fs.readdirSync(brand).filter((n) => n.endsWith('.svg'))) toCrlf(path.join(brand, f));
150
+ assert.ok(fs.readFileSync(page, 'utf8').includes('\r\n'), 'the brand page should now carry CRLF');
151
+ assert.deepEqual(checkDesignGeneratorsFresh(dir), [], 'CRLF alone must not read as stale');
152
+ fs.appendFileSync(page, '<!-- hand edit -->\r\n');
153
+ assert.ok(checkDesignGeneratorsFresh(dir).some((x) => x.startsWith('modules/ui-design/public/brand.html')), 'a real edit must still read as stale');
154
+ } finally {
155
+ fs.rmSync(dir, { recursive: true, force: true });
156
+ }
157
+ });
158
+
138
159
  // task 1005133: the logo set joins the gate. Editing the one source (mark.svg) without
139
160
  // running gen-brand.js fails it; so does a PNG whose source page moved (the pack's ground)
140
161
  // or a PNG swapped by hand — the PNGs are checked by hash, not just their pixel size.
@@ -48,7 +48,7 @@ function sources() {
48
48
  // ── 1. generated ─────────────────────────────────────────────────────────────
49
49
 
50
50
  test('the committed page is exactly what the generator writes', () => {
51
- assert.equal(PAGE, gen.build(),
51
+ assert.equal(PAGE.replace(/\r\n/g, '\n'), gen.build(), // CRLF checkouts (task 1005296)
52
52
  'modules/ui-design/public/brand.html is stale or hand-edited: run node modules/ui-design/scripts/gen-design-reference.js');
53
53
  });
54
54
 
@@ -290,10 +290,29 @@ test('the guard catches a browser box when one comes back, and leaves the shared
290
290
  }
291
291
  });
292
292
 
293
+ // shell.js's tag, then hall-dialog.js's on the very next line. Either line ending: git's
294
+ // core.autocrlf checks every page out with CRLF on Windows, and an LF-only `\n` here failed every
295
+ // page there, so a real misordering (task 1005148's visor.js between the two) read as noise.
296
+ // Task 1005197.
297
+ function shellThenDialog(html) {
298
+ return html.match(/<script src="\/builders\/shell\.js[^"]*"( defer)?><\/script>\r?\n<script src="\/builders\/hall-dialog\.js"( defer)?><\/script>/);
299
+ }
300
+
301
+ test('the shell-then-dialog order check reads LF and CRLF pages alike, and still catches a misorder', () => {
302
+ const pair = ['<script src="/builders/shell.js?v=1" defer></script>', '<script src="/builders/hall-dialog.js" defer></script>'];
303
+ for (const eol of ['\n', '\r\n']) {
304
+ const m = shellThenDialog(pair.join(eol));
305
+ assert.ok(m, `matched with ${JSON.stringify(eol)} line endings`);
306
+ assert.equal(m[1], m[2]);
307
+ const between = [pair[0], '<script src="/builders/visor.js" defer></script>', pair[1]].join(eol);
308
+ assert.equal(shellThenDialog(between), null, `a script between them is caught with ${JSON.stringify(eol)}`);
309
+ }
310
+ });
311
+
293
312
  test('every hall page loads the shared dialog right after the shell, deferred alike', () => {
294
313
  for (const f of fs.readdirSync(PUB).filter((n) => n.endsWith('.html'))) {
295
314
  const html = read(f);
296
- const shell = html.match(/<script src="\/builders\/shell\.js[^"]*"( defer)?><\/script>\n<script src="\/builders\/hall-dialog\.js"( defer)?><\/script>/);
315
+ const shell = shellThenDialog(html);
297
316
  if (!/\/builders\/shell\.js/.test(html)) continue;
298
317
  assert.ok(shell, `${f} loads hall-dialog.js right after shell.js`);
299
318
  assert.equal(shell[1], shell[2], `${f}: deferred alike`);