@bongos/core 1.19.143 → 1.19.144

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.143",
6
- "core_contract": "1.19.143",
7
- "source_commit": "31df926208597154ce684504f0aa15d6b1dde113",
5
+ "core_version": "1.19.144",
6
+ "core_contract": "1.19.144",
7
+ "source_commit": "36beb6c51bf7da7c8677cd6cf29d3b3739b1fc86",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-15T15:52:12.410Z",
9
+ "built_at": "2026-08-15T16:06:10.087Z",
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": 1575,
20
- "tree_sha256": "a9a3320aae0cbec4eb5ec01e7b50675d69a50814017d7f4658efa4e52493deb4",
20
+ "tree_sha256": "5c594013e8ee432b685ee793f28efedacd67b463904cda4eb9942dd7dd6b62d3",
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": "5f68e2c2d9e7f46d2884dce06d8bc7a5ed71f7716800c1815d550e43bd896176"
4180
+ "sha256": "a315183a94657af4ee558bc70eb2860782fa07576b9c55d0a028295f4287e2fc"
4181
4181
  },
4182
4182
  {
4183
4183
  "path": "package.json",
4184
4184
  "mode": "0000644",
4185
- "sha256": "51affa4342af5f89f0cfda20e74bb4120338ef58c2d0309c706a7dbdb25c4d8f"
4185
+ "sha256": "385cb6e8816fd2bfefa4a04d5a8bc4a9dac9e4d540903d9f736883b8d8abbc5c"
4186
4186
  },
4187
4187
  {
4188
4188
  "path": "public-docs/index.html",
@@ -4422,7 +4422,7 @@
4422
4422
  {
4423
4423
  "path": "public-landing/assets/cosmos.css",
4424
4424
  "mode": "0000644",
4425
- "sha256": "06ed45b09cb35cc8b2e20816416c45a07dd6ca47f418ac9c239ab8c949796f8b"
4425
+ "sha256": "4641a5c0c0222c0948ecdf57db9bb3cd88b5500089bbbbe735597abd4d44d4da"
4426
4426
  },
4427
4427
  {
4428
4428
  "path": "public-landing/buddha.png",
@@ -4437,7 +4437,7 @@
4437
4437
  {
4438
4438
  "path": "public-landing/projects.html",
4439
4439
  "mode": "0000644",
4440
- "sha256": "aa37e8e5b14f169f593a55eb71a0c21117c818a07d34d23a35c45219c646a5dd"
4440
+ "sha256": "deae8db82f897ee77633ffb2b7f5144960d9961ba4cdb9e052346c6cb127b0c9"
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": "7ac4130655324a65c52dfd04a7b57c72371904149e8a126a16d341f82d3d1625"
5770
+ "sha256": "8b8d833fa63b772e134faf867ad771f33293f81d8af3dd695221489217dd7c89"
5771
5771
  },
5772
5772
  {
5773
5773
  "path": "src/module-loader/catalog.js",
@@ -6277,7 +6277,7 @@
6277
6277
  {
6278
6278
  "path": "tests/cosmos_token_contrast.mjs",
6279
6279
  "mode": "0000644",
6280
- "sha256": "6343c10b95c8ed1da86ae32367882a9970f19266bccedb26b3e15b73c5bdd37a"
6280
+ "sha256": "dfb0f0b083a118c2bf8f424232f1e36e96f48aa962921649c487c93d5ce4eda2"
6281
6281
  },
6282
6282
  {
6283
6283
  "path": "tests/cost.mjs",
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.143",
3
+ "version": "1.19.144",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.143",
9
+ "version": "1.19.144",
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.143",
3
+ "version": "1.19.144",
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",
@@ -171,6 +171,18 @@
171
171
  navy pack accent falls under 4.5:1 on --bg-deep. Chrome keeps --accent-deep;
172
172
  only rules that paint a link inside prose take this. */
173
173
  --link-ink:var(--accent-deep);
174
+ /* CONTROL BOUNDARIES ONLY (task 1002824) — the edge that tells you a text
175
+ field IS a field. --line is a CARD hairline and measures 1.16:1 light /
176
+ 1.09:1 dark, so a resting input drawn with it was invisible until focus
177
+ (its fill is 1.02:1 on the card too, so the border is the ONLY boundary
178
+ there is); WCAG 1.4.11 asks 3:1. --line itself must not move — it also
179
+ draws .review, .humanSteps>li, .kv, .ghlist, the unselected .tpill and the
180
+ .choice cards, and darkening it globally would restyle every card in both
181
+ modes. Ink-derived on purpose, never accent-derived: a boundary that
182
+ changed hue with a re-theme would read as a state. 55% clears 3:1 with
183
+ headroom in the binding (light) mode — 3.75:1 on --card, 3.82:1 on the
184
+ input's own --bg-card fill; dark lands at 5.41/5.35. */
185
+ --ctl-line:color-mix(in srgb, var(--ink) 55%, var(--bg-card));
174
186
  --neutral-soft:color-mix(in srgb, var(--ink) 8%, var(--bg-card));
175
187
  /* ink-derived so the shadow is a WARM brown on the marigold ground instead of
176
188
  the cold navy it used to cast. The dark blocks override it with a plain black
@@ -296,7 +308,7 @@ h1{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3.4vw,32
296
308
  .addr .none{color:var(--ink-faint);font-style:italic;}
297
309
  .addr code{font-family:var(--font-mono);font-size:13px;background:var(--bg-deep);border-radius:6px;padding:1px 7px;color:var(--accent-deep);}
298
310
  .attach{display:flex;gap:10px;margin-top:10px;flex-wrap:wrap;}
299
- .attach input[type=text]{flex:1;min-width:220px;font-family:var(--font-body);font-size:15px;font-weight:600;color:var(--ink);background:var(--bg-card);border:2px solid var(--line);border-radius:12px;padding:9px 14px;outline:none;transition:border-color .15s ease, box-shadow .15s ease;}
311
+ .attach input[type=text]{flex:1;min-width:220px;font-family:var(--font-body);font-size:15px;font-weight:600;color:var(--ink);background:var(--bg-card);border:2px solid var(--ctl-line);border-radius:12px;padding:9px 14px;outline:none;transition:border-color .15s ease, box-shadow .15s ease;}
300
312
  .attach input[type=text]::placeholder{color:var(--ink-faint);font-weight:500;}
301
313
  .attach input[type=text]:focus{border-color:var(--accent);box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 13%,transparent);}
302
314
  .projMsg{font-size:13.5px;font-weight:600;margin-top:10px;min-height:18px;color:var(--ink-soft);line-height:1.5;}
@@ -660,7 +672,7 @@ p.sec-p{font-size:var(--fs-lede);font-weight:500;color:var(--ink-soft);line-heig
660
672
  the chip outcomes; it never relabels them — "Live" holds both `live` and
661
673
  `live?` because neither is known-down, and each card still says which. ── */
662
674
  .mineBar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:20px;}
663
- .mineBar .search{background:var(--bg-card);border-color:var(--line);}
675
+ .mineBar .search{background:var(--bg-card);border-color:var(--ctl-line);}
664
676
  .mineBar .search input{color:var(--ink);}
665
677
  .mineBar .search input::placeholder{color:var(--ink-faint);}
666
678
  .mineBar .search svg{stroke:var(--ink-faint);}
@@ -80,7 +80,7 @@ h1[tabindex="-1"]:focus{outline:none;}
80
80
  .wizField small{font-weight:500;color:var(--ink-faint);}
81
81
  #view-new input[type=text]{
82
82
  width:100%;font-family:var(--font-body);font-size:17px;font-weight:600;color:var(--ink);
83
- background:var(--bg-card);border:2px solid var(--line);border-radius:14px;padding:13px 16px;outline:none;
83
+ background:var(--bg-card);border:2px solid var(--ctl-line);border-radius:14px;padding:13px 16px;outline:none;
84
84
  transition:border-color .15s ease, box-shadow .15s ease;
85
85
  }
86
86
  /* no fade toward the card — a 70% mix washed placeholders to 2.89:1 (task 1002749) */
package/src/module-api.js CHANGED
@@ -713,8 +713,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
713
713
  // landed since 1.19.141 with no explicit bump. run 31893298770. (task 1002620)
714
714
  // 1.19.143 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
715
715
  // landed since 1.19.142 with no explicit bump. run 31893905320. (task 1002620)
716
+ // 1.19.144 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
717
+ // landed since 1.19.143 with no explicit bump. run 31894547582. (task 1002620)
716
718
  // ---------------------------------------------------------------------------
717
- const CORE_VERSION = '1.19.143'; // CI auto-patch carrier (ADR 0161); see changelog above
719
+ const CORE_VERSION = '1.19.144'; // CI auto-patch carrier (ADR 0161); see changelog above
718
720
 
719
721
  // A namespaced logger so a module's log lines are attributable + consistent.
720
722
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -19,6 +19,17 @@ const CSS = path.join(
19
19
  );
20
20
  const src = fs.readFileSync(CSS, 'utf8');
21
21
 
22
+ // The two sheets that actually ship, comment-stripped. Several static guards
23
+ // below read these instead of resolved colors, so they are declared here beside
24
+ // `src` rather than beside their first consumer — as source-order constants they
25
+ // were only reachable because node:test defers a test body past module
26
+ // evaluation, which is a thin thing to rest on.
27
+ const cssSrc = src.replace(/\/\*[\s\S]*?\*\//g, '');
28
+ const pageSrc = fs
29
+ .readFileSync(path.join(path.dirname(CSS), '..', 'projects.html'), 'utf8')
30
+ .replace(/<!--[\s\S]*?-->/g, '')
31
+ .replace(/\/\*[\s\S]*?\*\//g, '');
32
+
22
33
  // ── parse ────────────────────────────────────────────────────────────────────
23
34
  const declarations = (body) => {
24
35
  const out = {};
@@ -236,6 +247,23 @@ const PAIRS = [
236
247
  ['typeCard heading · business', 'color-mix(in srgb,var(--terracotta) 40%,var(--ink))', 'color-mix(in srgb,var(--terracotta) 9%,var(--bg-card))', 4.5],
237
248
  ['typeCard heading · non-profit', 'color-mix(in srgb,var(--gold-soft) 40%,var(--ink))', 'color-mix(in srgb,var(--gold-soft) 9%,var(--bg-card))', 4.5],
238
249
  ['typeCard heading · not-sure', 'color-mix(in srgb,var(--rule-soft) 40%,var(--ink))', 'color-mix(in srgb,var(--rule-soft) 9%,var(--bg-card))', 4.5],
250
+ // --ctl-line (task 1002824): the ONLY rows in this file that measure a border
251
+ // token as a FOREGROUND. WCAG 1.4.11 asks 3:1 of the boundary that IDENTIFIES
252
+ // a control, and a text field has nothing else to identify it — its --bg-card
253
+ // fill is 1.02:1 on the card it sits in, so the border IS the boundary. Both
254
+ // adjacent colors are measured: the --card outside and the fill inside.
255
+ //
256
+ // --line stays exactly where it is and is deliberately NOT held to this bar.
257
+ // It is a CARD hairline (1.16:1 light / 1.09:1 dark) drawing .review,
258
+ // .humanSteps>li, .kv, .ghlist, the unselected .tpill and the .choice cards.
259
+ // Two washed-down variants of it are likewise EXEMPT because they are
260
+ // DECORATIVE, not identifying: .humanSteps>li.slocked (55% line mix, ~1.06:1 —
261
+ // task 1002751) says "locked" through its number chip and muted text, and
262
+ // .proj.gone (the same mix — task 1002823) says "torn down" through its
263
+ // ghosted orb, its chip and a line of copy. Neither border carries state on
264
+ // its own, so raising them would buy nothing and restyle every card.
265
+ ['--ctl-line boundary on the card', 'var(--ctl-line)', 'var(--card)', 3.0],
266
+ ['--ctl-line boundary vs input fill', 'var(--ctl-line)', CARD, 3.0],
239
267
  ['?view=new input ::placeholder', 'var(--ink-faint)', CARD, 4.5],
240
268
  ['?view=new .ghlist .hint on deep', 'var(--ink-faint)', 'var(--bg-deep)', 4.5],
241
269
  ['--chrome-accent wordmark', 'var(--chrome-accent)', 'var(--page-bg)', 4.5],
@@ -360,6 +388,25 @@ test('no text link is left painting --accent-deep', () => {
360
388
  assert.deepEqual(strays, [], `\n ${strays.join('\n ')}\n`);
361
389
  });
362
390
 
391
+ test('no text-entry control draws its boundary with --line', () => {
392
+ // The companion to the --ctl-line PAIRS rows: the token only helps the rules
393
+ // that take it, and these live in two sheets (cosmos.css owns .attach and
394
+ // .mineBar .search, projects.html owns the wizard's own #view-new fields), so
395
+ // fixing one sheet leaves the other invisible. Text-entry selectors only —
396
+ // --line is still correct for every card, list and pill it draws, which is the
397
+ // whole reason this became a second token instead of a change to --line.
398
+ const strays = [];
399
+ for (const [where, text] of [['cosmos.css', cssSrc], ['projects.html', pageSrc]]) {
400
+ for (const m of text.matchAll(/([^{}@]+)\{([^{}]*)\}/g)) {
401
+ if (!/\b(?:input|textarea|select)\b|\.search\b/.test(m[1])) continue;
402
+ if (/border(?:-color|-\w+)?\s*:[^;]*var\(\s*--line\s*\)/.test(m[2])) {
403
+ strays.push(`${where}: ${m[1].trim().slice(0, 70)}`);
404
+ }
405
+ }
406
+ }
407
+ assert.deepEqual(strays, [], `\n ${strays.join('\n ')}\n`);
408
+ });
409
+
363
410
  // The gate's LOCKED sky palette — deliberately absent from COLOR_VARS, so a
364
411
  // branding pack can never re-theme these. Dark GROUNDS are allowed (dark mode IS
365
412
  // the gate's space, by design); text painted with one shows Cloud Bongos orange
@@ -411,11 +458,6 @@ test('dark blocks never re-point a token at the locked space palette', () => {
411
458
  // Known limits, accepted: @keyframes bodies, animation-fill-mode resting
412
459
  // values, and JS-set inline opacity are out of static reach — never make an
413
460
  // animation or script the resting presenter of text or a state mark.
414
- const pageSrc = fs
415
- .readFileSync(path.join(path.dirname(CSS), '..', 'projects.html'), 'utf8')
416
- .replace(/<!--[\s\S]*?-->/g, '')
417
- .replace(/\/\*[\s\S]*?\*\//g, '');
418
- const cssSrc = src.replace(/\/\*[\s\S]*?\*\//g, '');
419
461
  const dimsBelowFull = (body) => {
420
462
  const m = body.match(/opacity\s*:\s*([\d.]+%?)/);
421
463
  if (!m) return false;