@bongos/core 1.19.149 → 1.19.150

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.149",
6
- "core_contract": "1.19.149",
7
- "source_commit": "38bb790f0c03376979720a73d20e7a966749e06c",
5
+ "core_version": "1.19.150",
6
+ "core_contract": "1.19.150",
7
+ "source_commit": "ba28eaba03c65c990128c56929d0e30a18a2cb14",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-16T14:37:21.742Z",
9
+ "built_at": "2026-08-16T14:43:24.321Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 304,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 1579,
20
- "tree_sha256": "4d4238a80aa501af9cdf8257ebb99f5f51c806b2f9a87c9b02adcb878cda1af0",
20
+ "tree_sha256": "5429ba0237ab985ff79be4a1b9a03dd24cacd6260fdc604247b7eef8a36583dc",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -3162,7 +3162,7 @@
3162
3162
  {
3163
3163
  "path": "modules/hall-ui/public/goals-page.js",
3164
3164
  "mode": "0000644",
3165
- "sha256": "fcfe94b3e0cd00ddc881283d9897121518a7acc00b3d05b0715552911e2a0705"
3165
+ "sha256": "f24cfdca48676d882cfa51754fcf1519ade4646a760cb2be1db71fbc27571bca"
3166
3166
  },
3167
3167
  {
3168
3168
  "path": "modules/hall-ui/public/goals.css",
@@ -3197,7 +3197,7 @@
3197
3197
  {
3198
3198
  "path": "modules/hall-ui/public/hall-kit.js",
3199
3199
  "mode": "0000644",
3200
- "sha256": "672ef980513a150a81773ad674750e7d1560535dd08cbf2e1463155fbe00d7f6"
3200
+ "sha256": "4d5ec8f334fc00f23e81fe21283b7ea2fb173b253c638a08ef48b97111cc654f"
3201
3201
  },
3202
3202
  {
3203
3203
  "path": "modules/hall-ui/public/hall-widgets.js",
@@ -3407,7 +3407,7 @@
3407
3407
  {
3408
3408
  "path": "modules/hall-ui/public/task.js",
3409
3409
  "mode": "0000644",
3410
- "sha256": "2430a3b351d80ae55724c1bfd1c514855e9a5c04ceaa1012e4475d2dc09b9d84"
3410
+ "sha256": "ac6bfa459924a43005625e9c2655a5a1397c941dfa0727594bb25f930180d36a"
3411
3411
  },
3412
3412
  {
3413
3413
  "path": "modules/hall-ui/public/watch.css",
@@ -3427,7 +3427,7 @@
3427
3427
  {
3428
3428
  "path": "modules/hall-ui/public/work.css",
3429
3429
  "mode": "0000644",
3430
- "sha256": "8ad8c570a2196aabb46c86e8efcfab2b0d22451b4f23aa10a02b4f52d1415690"
3430
+ "sha256": "e5dd2fd84b31174d10bb6558920cbbc9e34b1776d775db3c69518810a1c7b96c"
3431
3431
  },
3432
3432
  {
3433
3433
  "path": "modules/hall-ui/public/work.html",
@@ -3437,7 +3437,7 @@
3437
3437
  {
3438
3438
  "path": "modules/hall-ui/public/work.js",
3439
3439
  "mode": "0000644",
3440
- "sha256": "eb7e5919af8d60c5ae6f68e05a5d97e4b7ca97fa17941b79086eec39c9af7faf"
3440
+ "sha256": "8ee189def6ded1c8669212d7233f57948ac58bf23ad8277422996ffd8914e537"
3441
3441
  },
3442
3442
  {
3443
3443
  "path": "modules/ideas/CLAUDE.md",
@@ -4187,12 +4187,12 @@
4187
4187
  {
4188
4188
  "path": "package-lock.json",
4189
4189
  "mode": "0000644",
4190
- "sha256": "4683e76f97deb0d808cc94b82abc8bba5b4332646d073cbb95155a305dce7bac"
4190
+ "sha256": "86e259a725603b58d5659d630124568731893e6497d933327cbc29ab733955b8"
4191
4191
  },
4192
4192
  {
4193
4193
  "path": "package.json",
4194
4194
  "mode": "0000644",
4195
- "sha256": "0ba329b9178e83c2d379bc65d0defde57428ae8b317a4c9ad0d900c872eb1d64"
4195
+ "sha256": "cf358f722d2710aa11787645b256c890c6508e5c34ff735044ef8a9b28951d7e"
4196
4196
  },
4197
4197
  {
4198
4198
  "path": "public-docs/index.html",
@@ -5782,7 +5782,7 @@
5782
5782
  {
5783
5783
  "path": "src/module-api.js",
5784
5784
  "mode": "0000644",
5785
- "sha256": "f551b1a40bb56bfbdef3ad3f40cbbae092c6ac42ac0683c43db63d033aa0a1bb"
5785
+ "sha256": "6cdc6cf28bcb58d18a41a575a253e9066e4fc6d1f86b8d1f7be60e12b99784db"
5786
5786
  },
5787
5787
  {
5788
5788
  "path": "src/module-loader/catalog.js",
@@ -529,6 +529,9 @@
529
529
  const touchesChip = touches.length
530
530
  ? `<span class="task__touches" title="${escapeHtml(touches.join('\n'))}">✎ ${touches.length} file${touches.length === 1 ? '' : 's'}</span>`
531
531
  : '';
532
+ // task 1002955: same age chip the board renders — reviewing a goal for stale
533
+ // work is the case that needed it most.
534
+ const ageChip = window.OTBKit.ageChipHtml(t.created_at);
532
535
  const claim = state.claimsByTask.get(id);
533
536
  const isReady = t.status === 'ready' && !!state.me;
534
537
  const mineActive = t.status === 'active' && claim && sameId(claim.builder_id, selfId());
@@ -569,6 +572,7 @@
569
572
  <span>${minutesText}</span>
570
573
  <span>${cpmText}</span>
571
574
  ${touchesChip}
575
+ ${ageChip}
572
576
  </div>
573
577
  </div>
574
578
  <div class="task__credits">
@@ -417,6 +417,66 @@
417
417
  };
418
418
  }
419
419
 
420
+ // ---- age (task 1002955) ------------------------------------------------------
421
+ // How old is this row? The board, the goal Work card and the task panel all
422
+ // render a task's kind/estimate/credits but never said when it was written, so
423
+ // a queue of 40 ready tasks read as equally fresh whether it was filed
424
+ // yesterday or three months ago. Kit-level because the card markup is
425
+ // duplicated across work.js + goals-page.js (task 1002463) and a third
426
+ // hand-rolled date helper is exactly what this file exists to prevent.
427
+
428
+ // Coarse buckets on purpose: past a week nobody cares about the hour, and the
429
+ // exact day is one hover away (ageChipHtml puts it on title=). Anything in the
430
+ // future — a clock skew, a seeded row — clamps to "new" rather than "-3d".
431
+ const AGE_STALE_DAYS = 30;
432
+ function fmtAge(iso) {
433
+ if (!iso) return '';
434
+ const ms = Date.now() - new Date(iso).getTime();
435
+ if (!Number.isFinite(ms)) return '';
436
+ const days = Math.floor(ms / 86400000);
437
+ if (days < 0) return 'new';
438
+ if (days === 0) return 'today';
439
+ if (days === 1) return '1d';
440
+ if (days < 14) return `${days}d`;
441
+ if (days < 60) return `${Math.floor(days / 7)}w`;
442
+ // Clamped at 11: 30-day months overshoot, so days 330-364 would otherwise
443
+ // print "12mo" immediately before the year bucket takes over at 365.
444
+ if (days < 365) return `${Math.min(11, Math.floor(days / 30))}mo`;
445
+ const years = Math.floor(days / 365);
446
+ const rem = Math.floor((days % 365) / 30);
447
+ return rem ? `${years}y ${rem}mo` : `${years}y`;
448
+ }
449
+
450
+ // Absolute date for the tooltip — locale-formatted, no time (the age chip is
451
+ // about which week something was filed, not which minute).
452
+ function fmtAbsDate(iso) {
453
+ if (!iso) return '';
454
+ const d = new Date(iso);
455
+ if (Number.isNaN(d.getTime())) return '';
456
+ try {
457
+ return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
458
+ } catch (_) { return d.toISOString().slice(0, 10); }
459
+ }
460
+
461
+ function ageDays(iso) {
462
+ if (!iso) return null;
463
+ const ms = Date.now() - new Date(iso).getTime();
464
+ return Number.isFinite(ms) ? Math.floor(ms / 86400000) : null;
465
+ }
466
+
467
+ // ageChipHtml(iso, opts?) → the meta-row chip. Past AGE_STALE_DAYS it gains
468
+ // .task__age--stale, so scanning a goal's queue for work that has been sitting
469
+ // is a glance rather than an API call. `label` names the date in the tooltip
470
+ // ("Created" by default) so the same chip can carry other timestamps.
471
+ function ageChipHtml(iso, { label = 'Created' } = {}) {
472
+ const text = fmtAge(iso);
473
+ if (!text) return '';
474
+ const days = ageDays(iso);
475
+ const stale = days != null && days >= AGE_STALE_DAYS;
476
+ const abs = fmtAbsDate(iso);
477
+ return `<span class="task__age${stale ? ' task__age--stale' : ''}" title="${esc(label)} ${esc(abs)}">${esc(text)}</span>`;
478
+ }
479
+
420
480
  // ---- empty state / skeleton / collapsible ------------------------------------
421
481
 
422
482
  // One standard empty pattern: a short line + at most one action link. An
@@ -465,6 +525,8 @@
465
525
  makeLedger, makeFilterBar, makeTabs, makeSectionRail,
466
526
  // states
467
527
  emptyStateHtml, skeletonRows, collapsibleCard,
528
+ // age (task 1002955)
529
+ fmtAge, fmtAbsDate, ageChipHtml, AGE_STALE_DAYS,
468
530
  };
469
531
 
470
532
  // Node-require-safe (the dom-utils.js pattern): assignment is the only
@@ -184,6 +184,14 @@
184
184
  if (t.est_minutes) meta.push(`${t.est_minutes}m`);
185
185
  parts.push(`<p class="deeplink-card__meta">${meta.join(' · ')}</p>`);
186
186
 
187
+ // task 1002955: when was this written? The panel showed a shipped date but
188
+ // never a created one, so an untouched task carried no age at all. Absolute
189
+ // date first (the panel has the room the card chip doesn't), age after it.
190
+ if (t.created_at) {
191
+ const age = fmtRel(t.created_at);
192
+ parts.push(`<p class="deeplink-card__note">Created ${escapeHtml(fmtDate(t.created_at))}${age ? ` — ${escapeHtml(age)}` : ''}.</p>`);
193
+ }
194
+
187
195
  if (t.goal_id) {
188
196
  parts.push(`<p class="td-goal">Goal: <a href="/goals#/goal/${encodeURIComponent(t.goal_id)}">Goal #${escapeHtml(String(t.goal_id))}</a></p>`);
189
197
  }
@@ -66,6 +66,21 @@
66
66
  cursor: help;
67
67
  }
68
68
 
69
+ /* How old the task is (task 1002955, OTBKit.ageChipHtml). Quiet by default —
70
+ it's orientation, not a call to act — but a task past the stale threshold
71
+ steps up from faint to soft+bold so a queue that has been sitting reads at a
72
+ glance instead of needing the API. The exact date is on the tooltip, hence
73
+ `cursor: help`. Deliberately NOT --warn: that token is a dark amber paired
74
+ with --warn-weak behind it, and as bare text it loses contrast on the dark
75
+ theme's card. --ink-soft steps up legibly in both. */
76
+ .task__age {
77
+ color: var(--ink-faint);
78
+ font-size: 12px;
79
+ white-space: nowrap;
80
+ cursor: help;
81
+ }
82
+ .task__age--stale { color: var(--ink-soft); font-weight: 600; }
83
+
69
84
  .task__tag--newcomer {
70
85
  background: var(--ok-weak);
71
86
  color: var(--ok);
@@ -360,6 +360,9 @@
360
360
  const touchesChip = touches.length
361
361
  ? `<span class="task__touches" title="${escapeHtml(touches.join('\n'))}">✎ ${touches.length} file${touches.length === 1 ? '' : 's'}</span>`
362
362
  : '';
363
+ // task 1002955: how old is this task? A ready queue reads as equally fresh
364
+ // without it; the exact date rides the tooltip.
365
+ const ageChip = window.OTBKit.ageChipHtml(t.created_at);
363
366
  const selected = selection.claim.has(String(t.id));
364
367
  return `
365
368
  <div class="task${selected ? ' task--selected' : ''}" data-task-id="${t.id}">
@@ -380,6 +383,7 @@
380
383
  <span>${minutesText}</span>
381
384
  <span>${cpmText}</span>
382
385
  ${touchesChip}
386
+ ${ageChip}
383
387
  </div>
384
388
  </div>
385
389
  <div class="task__credits">
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.149",
3
+ "version": "1.19.150",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.149",
9
+ "version": "1.19.150",
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.149",
3
+ "version": "1.19.150",
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",
package/src/module-api.js CHANGED
@@ -725,8 +725,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
725
725
  // landed since 1.19.147 with no explicit bump. run 31952592623. (task 1002620)
726
726
  // 1.19.149 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
727
727
  // landed since 1.19.148 with no explicit bump. run 31953207683. (task 1002620)
728
+ // 1.19.150 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
729
+ // landed since 1.19.149 with no explicit bump. run 31953504697. (task 1002620)
728
730
  // ---------------------------------------------------------------------------
729
- const CORE_VERSION = '1.19.149'; // CI auto-patch carrier (ADR 0161); see changelog above
731
+ const CORE_VERSION = '1.19.150'; // CI auto-patch carrier (ADR 0161); see changelog above
730
732
 
731
733
  // A namespaced logger so a module's log lines are attributable + consistent.
732
734
  // Usage: const log = api.logger('dev-box'); log.info('mounted');