@bongos/core 1.24.14 → 1.24.15
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 +296 -136
- package/.claude/skills/blocker-review/SKILL.md +2 -0
- package/.claude/skills/session-board/SKILL.md +29 -0
- package/.claude/skills/strand-fix/SKILL.md +1 -1
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +14 -0
- package/clients/bongos-client/index.cjs +14 -0
- package/clients/bongos-client/index.d.ts +23 -2
- package/clients/bongos-client/index.mjs +14 -0
- package/docs/adr/0385-money-lives-with-a-processor-credits-stay-a-project-meter.md +4 -0
- package/docs/api/openapi.json +369 -6
- package/docs/api-reference.md +19 -4
- package/docs/architecture.md +6 -0
- package/docs/copy-inventory.md +138 -123
- package/docs/copy-registry.json +296 -171
- package/docs/file-map.md +1 -0
- package/docs/module-api-changelog.md +2 -2
- package/docs/page-inventory.json +6 -1
- package/docs/page-readings.json +1040 -1021
- package/migrations/core_289_task_short_name.sql +34 -0
- package/modules/ai-studio/db.js +10 -0
- package/modules/ai-studio/gemini.js +73 -5
- package/modules/ai-studio/openrouter.js +17 -2
- package/modules/ai-studio/routes/ai-studio.js +7 -1
- package/modules/ai-studio/studio.js +8 -0
- package/modules/builder-settings/checkout-freshness.js +71 -0
- package/modules/builder-settings/routes/settings.js +26 -0
- package/modules/builder-settings/settings.js +2 -0
- package/modules/economy/migrations/economy_002_project_account.sql +83 -0
- package/modules/economy/module.json +1 -1
- package/modules/economy/project-account.js +166 -0
- package/modules/economy/routes/project-account.js +40 -0
- package/modules/hall-ui/public/ai-studio.css +3 -0
- package/modules/hall-ui/public/ai-studio.html +2 -1
- package/modules/hall-ui/public/ai-studio.js +72 -1
- package/modules/hall-ui/public/atlas.html +1 -1
- package/modules/hall-ui/public/blockers.html +1 -1
- package/modules/hall-ui/public/board-room.html +1 -1
- package/modules/hall-ui/public/city.html +1 -1
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/commands.html +1 -1
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/deploy.html +1 -1
- package/modules/hall-ui/public/diagrams.html +1 -1
- package/modules/hall-ui/public/drachmae.html +1 -1
- package/modules/hall-ui/public/fleet.html +1 -1
- package/modules/hall-ui/public/gate.html +1 -1
- package/modules/hall-ui/public/github-chip.js +85 -0
- package/modules/hall-ui/public/goal-map.html +1 -1
- package/modules/hall-ui/public/goals.html +1 -1
- package/modules/hall-ui/public/government.html +1 -1
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/ideas.html +1 -1
- package/modules/hall-ui/public/index.html +1 -1
- package/modules/hall-ui/public/market-watch-item.html +2 -2
- package/modules/hall-ui/public/market-watch-item.js +10 -3
- package/modules/hall-ui/public/market-watch-item.states.json +41 -0
- package/modules/hall-ui/public/market-watch-lib.js +36 -5
- package/modules/hall-ui/public/market-watch-rules.html +1 -1
- package/modules/hall-ui/public/market-watch-settings.html +1 -1
- package/modules/hall-ui/public/market-watch.css +5 -0
- package/modules/hall-ui/public/market-watch.html +2 -2
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/my-agents.html +1 -1
- package/modules/hall-ui/public/my-agents.js +3 -0
- package/modules/hall-ui/public/primer.html +1 -1
- package/modules/hall-ui/public/profile.html +1 -1
- package/modules/hall-ui/public/project-settings.html +1 -1
- package/modules/hall-ui/public/ranks.html +1 -1
- package/modules/hall-ui/public/roadmap.html +1 -1
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/sessions.html +1 -1
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell.js +22 -22
- package/modules/hall-ui/public/street.html +1 -1
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/style.css +28 -0
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/thinking.html +1 -1
- package/modules/hall-ui/public/tweak-editor.html +1 -1
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/ideas/blockers.js +13 -7
- package/modules/lifecycle/db-claim-reads.js +1 -1
- package/modules/lifecycle/db-ship.js +2 -2
- package/modules/lifecycle/db-tasks.js +4 -4
- package/modules/lifecycle/migrations/lifecycle_019_pay_type_gates.sql +50 -0
- package/modules/lifecycle/module.json +1 -0
- package/modules/lifecycle/pay-type-gates.js +180 -0
- package/modules/lifecycle/publish-reconciler.js +31 -1
- package/modules/lifecycle/rebase-gate.js +3 -2
- package/modules/lifecycle/routes/claims.js +3 -2
- package/modules/lifecycle/routes/pay-type-gates.js +59 -0
- package/modules/lifecycle/routes/project-settings.js +4 -0
- package/modules/lifecycle/routes/task-write-routes.js +43 -0
- package/modules/lifecycle/ship-card.js +4 -1
- package/modules/lifecycle/task-name-db.js +55 -0
- package/modules/lifecycle/task-name.js +140 -0
- package/modules/market-watch/db.js +10 -1
- package/modules/market-watch/migrations/market_watch_004_entry_corrections.sql +20 -0
- package/modules/market-watch/pages.js +20 -1
- package/modules/market-watch/proposals.js +57 -7
- package/modules/market-watch/routes/pages.js +2 -0
- package/modules/market-watch/routes/rules.js +4 -0
- package/modules/platform-identity/terms-acceptance.js +9 -9
- package/modules/public-landing/public/account-google.states.json +14 -0
- package/modules/public-landing/public/assets/cosmos.css +12 -0
- package/modules/public-landing/public/assets/hub-bar.js +44 -1
- package/modules/public-landing/public/privacy.html +5 -1
- package/modules/public-landing/public/projects-google.states.json +14 -0
- package/modules/public-landing/public/projects.html +39 -0
- package/modules/public-landing/public/terms.html +12 -2
- package/modules/ui-design/kit/fixtures/me-google.json +10 -0
- package/modules/ui-design/kit/fixtures/me-sign-in-methods-google.json +4 -0
- package/modules/ui-design/kit/serve.js +7 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +49 -1
- package/scripts/bongos/claim.js +4 -2
- package/scripts/bongos/land-watch.js +1 -0
- package/scripts/bongos/report-checkout.js +30 -0
- package/scripts/bongos/run-unit-tests.js +11 -0
- package/scripts/bongos/sessions-board.js +264 -0
- package/scripts/bongos/ship-finish.js +1 -0
- package/scripts/bongos/ship-flow.js +5 -2
- package/scripts/bongos/strand-lease.js +5 -3
- package/scripts/bongos/strand-watch.js +38 -7
- package/scripts/gds/report-checkout.js +7 -0
- package/scripts/gds/sessions-board.js +7 -0
- package/src/bongos/agent-standing-rules.js +13 -3
- package/src/bongos/routes/me.js +7 -1
- package/src/module-api.js +1 -1
- package/tests/agent_standing_rules.mjs +18 -1
- package/tests/ai_studio_billing.mjs +13 -0
- package/tests/ai_studio_gemini_models.mjs +81 -0
- package/tests/ai_studio_requests.mjs +24 -0
- package/tests/blocker_detail_hydration.mjs +5 -3
- package/tests/blocker_tasks_named_db.mjs +74 -0
- package/tests/claim_gate_ci_unblock.mjs +1 -1
- package/tests/github_chip.mjs +217 -0
- package/tests/hall_ai_studio.mjs +129 -5
- package/tests/host_topology_skips.mjs +1 -0
- package/tests/hub_account_page.mjs +3 -2
- package/tests/landing_legal_pages.mjs +3 -2
- package/tests/market_watch_data_db.mjs +6 -0
- package/tests/market_watch_pages.mjs +87 -2
- package/tests/market_watch_rules.mjs +101 -5
- package/tests/market_watch_rules_db.mjs +42 -0
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/pay_terms.mjs +8 -0
- package/tests/pay_type_gates.mjs +234 -0
- package/tests/pay_type_gates_db.mjs +84 -0
- package/tests/project_account.mjs +125 -0
- package/tests/project_account_db.mjs +97 -0
- package/tests/self_healing_start.mjs +162 -0
- package/tests/sessions_board.mjs +153 -0
- package/tests/stop_refcheck.mjs +40 -0
- package/tests/task_name.mjs +237 -0
- package/tests/task_name_db.mjs +79 -0
- package/tests/terms_acceptance.mjs +25 -3
- package/tests/terms_grandfather_db.mjs +11 -4
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
229
229
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
230
230
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
231
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
231
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
232
232
|
<script src="/builders/palette.js" defer></script>
|
|
233
233
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
234
234
|
<script src="/builders/vote-control.js"></script>
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
<script src="/builders/welcome-boot.js?v=2026-10-23-city1" defer></script>
|
|
120
120
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab" defer></script>
|
|
121
121
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch" defer></script>
|
|
122
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
122
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip" defer></script>
|
|
123
123
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
124
124
|
<script src="/builders/palette.js" defer></script>
|
|
125
125
|
<!-- task 2166: the shared component kit (window.OTBKit) — pager/ledger/rail.
|
|
@@ -68,13 +68,13 @@
|
|
|
68
68
|
</div>
|
|
69
69
|
</div>
|
|
70
70
|
|
|
71
|
-
<dialog class="mw-dialog" id="mw-propose" aria-
|
|
71
|
+
<dialog class="mw-dialog" id="mw-propose" aria-labelledby="mw-propose-title"></dialog>
|
|
72
72
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
73
73
|
|
|
74
74
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
75
75
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
76
76
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
77
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
77
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
78
78
|
<script src="/builders/palette.js" defer></script>
|
|
79
79
|
<script src="/builders/hall-kit.js"></script>
|
|
80
80
|
<script src="/builders/market-watch-lib.js"></script>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
const last = o.latest;
|
|
37
37
|
const word = it.kind === 'partner' ? 'fit' : 'likeness';
|
|
38
38
|
const runs = v.runs.length;
|
|
39
|
-
const solid = v.entries.filter((e) => e.confidence === 3).length;
|
|
39
|
+
const solid = v.entries.filter((e) => e.confidence === 3 && !(e.corrected && e.corrected.wrong)).length;
|
|
40
40
|
const pinned = MW.pins.has(it.id);
|
|
41
41
|
$('mw-card').innerHTML = `<div class="mw-holo"><span class="mw-holo__kind">${esc(it.kind)}</span><span class="mw-holo__ini" aria-hidden="true">${esc(MW.initials(it.name))}</span><div class="mw-holo__nm" title="${esc(it.name)}">${esc(it.name)}</div></div>
|
|
42
42
|
<div class="mw-lvl"><div class="mw-ring" style="--p:${last == null ? 0 : Math.round((last / 10) * 100)}"><b>${last == null ? '–' : esc(last)}</b></div>
|
|
@@ -85,13 +85,20 @@
|
|
|
85
85
|
if (k === 'confidence') return (a.confidence - b.confidence) || (a.id - b.id);
|
|
86
86
|
return String(a[k] || '').localeCompare(String(b[k] || '')) || (a.id - b.id);
|
|
87
87
|
}
|
|
88
|
+
// The small note under an entry an approved proposal corrected (task 1005016): when,
|
|
89
|
+
// and why on hover. The reason is a member's words, so it is escaped.
|
|
90
|
+
function fixedNote(c) {
|
|
91
|
+
if (!c) return '';
|
|
92
|
+
const what = c.wrong ? 'marked wrong' : 'corrected';
|
|
93
|
+
return `<span class="mw-fixed mw-one"${c.reason ? ` title="${esc(c.reason)}"` : ''}>${what} ${esc(MW.fmtDay(c.on))}${c.reason ? ` · ${esc(c.reason)}` : ''}</span>`;
|
|
94
|
+
}
|
|
88
95
|
function drawLog() {
|
|
89
96
|
const rows = VIEW.entries.filter((e) => !TYPE || e.type === TYPE).sort((a, b) => (Number(b.pinned) - Number(a.pinned)) || SORT.dir * cmp(a, b));
|
|
90
|
-
$('mw-log').innerHTML = rows.length ? rows.map((e) => `<tr class="${e.pinned ? 'pin' : ''}">
|
|
97
|
+
$('mw-log').innerHTML = rows.length ? rows.map((e) => `<tr class="${[e.pinned ? 'pin' : '', e.corrected && e.corrected.wrong ? 'wrong' : ''].filter(Boolean).join(' ')}">
|
|
91
98
|
<td class="mw-date">${esc(MW.fmtDay(e.found_on))}</td>
|
|
92
99
|
<td class="mw-c-run mw-run">${e.run == null ? '–' : `run ${esc(e.run)}`}</td>
|
|
93
100
|
<td>${MW.typePill(e.type)}</td>
|
|
94
|
-
<td class="mw-tk"><div class="mw-one" title="${esc(e.takeaway)}">${esc(e.takeaway)}</div
|
|
101
|
+
<td class="mw-tk"><div class="mw-one" title="${esc(e.takeaway)}">${esc(e.takeaway)}</div>${fixedNote(e.corrected)}</td>
|
|
95
102
|
<td class="mw-c-conf">${MW.confDots(e.confidence)}</td>
|
|
96
103
|
<td><a class="mw-src" href="${MW.safeHref(e.source_url)}" target="_blank" rel="noopener noreferrer">${esc(e.source_label || 'source')} ↗</a></td></tr>`).join('')
|
|
97
104
|
: `<tr><td colspan="6" class="mw-quiet">${TYPE ? `No ${esc(TYPE)} entries yet.` : 'Nothing found on it yet.'}</td></tr>`;
|
|
@@ -89,6 +89,47 @@
|
|
|
89
89
|
]
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
|
+
"correct": {
|
|
93
|
+
"auth": true,
|
|
94
|
+
"_": "Correct an entry (task 1005016): the entry picker, the box that starts as the entry's own words, and the mark-as-wrong choice.",
|
|
95
|
+
"actions": [
|
|
96
|
+
[
|
|
97
|
+
"wait",
|
|
98
|
+
900
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
"clickIfVisible",
|
|
102
|
+
"[data-craft-close]"
|
|
103
|
+
],
|
|
104
|
+
[
|
|
105
|
+
"wait",
|
|
106
|
+
200
|
|
107
|
+
],
|
|
108
|
+
[
|
|
109
|
+
"click",
|
|
110
|
+
"[data-act=\"propose\"]"
|
|
111
|
+
],
|
|
112
|
+
[
|
|
113
|
+
"wait",
|
|
114
|
+
300
|
|
115
|
+
],
|
|
116
|
+
[
|
|
117
|
+
"select",
|
|
118
|
+
"#mw-propose select[name=\"kind\"]",
|
|
119
|
+
"correct_entry"
|
|
120
|
+
],
|
|
121
|
+
[
|
|
122
|
+
"wait",
|
|
123
|
+
200
|
|
124
|
+
]
|
|
125
|
+
],
|
|
126
|
+
"expect": {
|
|
127
|
+
"visible": [
|
|
128
|
+
"#mw-propose input[name=\"takeaway\"]",
|
|
129
|
+
"#mw-propose input[name=\"wrong\"]"
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
},
|
|
92
133
|
"filtered": {
|
|
93
134
|
"auth": true,
|
|
94
135
|
"_": "The case file filtered to one type through the kit filter bar (insight): one row on the seeded Copilot item.",
|
|
@@ -152,15 +152,15 @@
|
|
|
152
152
|
var it = ctx.item || {};
|
|
153
153
|
var h = '<form method="dialog" novalidate>';
|
|
154
154
|
if (mode === 'scout') {
|
|
155
|
-
h += '<span class="mw-label">send a new scout</span>';
|
|
155
|
+
h += '<span class="mw-label" id="mw-propose-title">send a new scout</span>';
|
|
156
156
|
h += '<label>What should we watch?<select name="scout"><option value="competitor">A competitor</option><option value="partner">A partner</option><option value="topic">A topic</option></select></label>';
|
|
157
157
|
h += '<label>Its name<input name="name" maxlength="120" autocomplete="off" required></label>';
|
|
158
158
|
h += '<label>A link, if it has one<input name="url" type="url" maxlength="500" placeholder="https://" autocomplete="off"></label>';
|
|
159
159
|
} else if (mode === 'stop') {
|
|
160
|
-
h += '<span class="mw-label">stop tracking</span>';
|
|
160
|
+
h += '<span class="mw-label" id="mw-propose-title">stop tracking</span>';
|
|
161
161
|
h += '<p class="mw-quiet" style="margin:0 0 12px">Asks the government to take ' + esc(it.name) + ' off the watch. Its case file stays readable.</p>';
|
|
162
162
|
} else {
|
|
163
|
-
h += '<span class="mw-label">propose a change</span>';
|
|
163
|
+
h += '<span class="mw-label" id="mw-propose-title">propose a change</span>';
|
|
164
164
|
h += '<label>What should change?<select name="kind">';
|
|
165
165
|
CHANGE_KINDS.forEach(function (k) {
|
|
166
166
|
if (k[0] === 'move_kind' && it.kind === 'topic') return;
|
|
@@ -175,7 +175,11 @@
|
|
|
175
175
|
h += '<div data-for="add_source" hidden><label>The source<input name="url" type="url" maxlength="500" placeholder="https://" autocomplete="off"></label></div>';
|
|
176
176
|
h += '<div data-for="correct_entry" hidden><label>Which entry<select name="log_entry_id">';
|
|
177
177
|
(ctx.entries || []).forEach(function (e) { h += '<option value="' + esc(e.id) + '">' + esc(fmtDay(e.found_on)) + ' · ' + esc(String(e.takeaway).slice(0, 70)) + '</option>'; });
|
|
178
|
-
h += '</select></label
|
|
178
|
+
h += '</select></label>';
|
|
179
|
+
// The correction itself (task 1005016): the entry as it should read, or a flag that
|
|
180
|
+
// it is wrong. Approving the proposal applies it to the entry.
|
|
181
|
+
h += '<label>It should read<input name="takeaway" maxlength="500" autocomplete="off" placeholder="the takeaway, corrected"></label>';
|
|
182
|
+
h += '<label class="mw-check"><input name="wrong" type="checkbox" value="true"> Mark it as wrong instead</label></div>';
|
|
179
183
|
}
|
|
180
184
|
h += '<label>Why, in one line<input name="reason" maxlength="280" autocomplete="off" required placeholder="' + (mode === 'scout' ? 'e.g. they launched an agent marketplace this week' : mode === 'stop' ? 'e.g. they shut down in September' : 'e.g. they now pay maintainers, so economy should be 4') + '"></label>';
|
|
181
185
|
h += '<p class="mw-dialog__err" role="alert"></p>';
|
|
@@ -192,7 +196,11 @@
|
|
|
192
196
|
var b = { kind: kind, item_id: item.id, reason: v('reason') };
|
|
193
197
|
if (kind === 'rescore') { b.dimension = v('dimension'); b.value = v('value'); }
|
|
194
198
|
if (kind === 'add_source') b.url = v('url');
|
|
195
|
-
if (kind === 'correct_entry')
|
|
199
|
+
if (kind === 'correct_entry') {
|
|
200
|
+
b.log_entry_id = v('log_entry_id');
|
|
201
|
+
var w = f.elements.wrong;
|
|
202
|
+
if (w && w.checked) b.wrong = true; else b.takeaway = v('takeaway');
|
|
203
|
+
}
|
|
196
204
|
return b;
|
|
197
205
|
}
|
|
198
206
|
|
|
@@ -200,6 +208,11 @@
|
|
|
200
208
|
var doc = root.document;
|
|
201
209
|
var dlg = doc.getElementById('mw-propose');
|
|
202
210
|
dlg.innerHTML = dialogHtml(mode, ctx);
|
|
211
|
+
// The dialog's accessible name is its own visible title, so a screen reader hears
|
|
212
|
+
// "stop tracking" or "send a new scout" when that is what opened (task 1005018). A
|
|
213
|
+
// fixed aria-label would win over aria-labelledby, so none is left on the element.
|
|
214
|
+
dlg.removeAttribute('aria-label');
|
|
215
|
+
dlg.setAttribute('aria-labelledby', 'mw-propose-title');
|
|
203
216
|
var f = dlg.querySelector('form');
|
|
204
217
|
var err = dlg.querySelector('.mw-dialog__err');
|
|
205
218
|
var sync = function () {
|
|
@@ -208,10 +221,28 @@
|
|
|
208
221
|
};
|
|
209
222
|
if (f.elements.kind) f.elements.kind.addEventListener('change', sync);
|
|
210
223
|
sync();
|
|
224
|
+
// Correct an entry: the box starts as the picked entry's own words, to edit; marking
|
|
225
|
+
// it wrong instead greys the box out. Only the 'change' dialog has these fields.
|
|
226
|
+
if (mode === 'change') {
|
|
227
|
+
var pick = f.elements.log_entry_id;
|
|
228
|
+
var tk = f.elements.takeaway;
|
|
229
|
+
var wr = f.elements.wrong;
|
|
230
|
+
var fill = function () {
|
|
231
|
+
var e = (ctx.entries || []).filter(function (x) { return String(x.id) === String(pick.value); })[0];
|
|
232
|
+
tk.value = e ? String(e.takeaway) : '';
|
|
233
|
+
};
|
|
234
|
+
pick.addEventListener('change', fill);
|
|
235
|
+
fill();
|
|
236
|
+
wr.addEventListener('change', function () { tk.disabled = wr.checked; });
|
|
237
|
+
}
|
|
211
238
|
dlg.querySelector('[data-cancel]').addEventListener('click', function () { dlg.close(); });
|
|
212
239
|
f.addEventListener('submit', function (ev) {
|
|
213
240
|
ev.preventDefault();
|
|
214
241
|
var body = bodyFor(mode, f, ctx.item || {});
|
|
242
|
+
if (body.kind === 'correct_entry' && !body.wrong) {
|
|
243
|
+
var was = (ctx.entries || []).filter(function (x) { return String(x.id) === String(body.log_entry_id); })[0];
|
|
244
|
+
if (!body.takeaway || (was && String(was.takeaway).trim() === body.takeaway)) { err.textContent = 'Change the words, or mark it as wrong.'; return; }
|
|
245
|
+
}
|
|
215
246
|
if (!body.reason) { err.textContent = 'Say why, in one line.'; return; }
|
|
216
247
|
var btn = f.querySelector('[type=submit]');
|
|
217
248
|
btn.disabled = true;
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
44
44
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
45
45
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
46
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
46
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
47
47
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
48
48
|
<script src="/builders/palette.js" defer></script>
|
|
49
49
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
106
106
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
107
107
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
108
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
108
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
109
109
|
<script src="/builders/palette.js" defer></script>
|
|
110
110
|
<script src="/builders/hall-kit.js"></script>
|
|
111
111
|
<script src="/builders/market-watch-settings.js"></script>
|
|
@@ -145,6 +145,9 @@
|
|
|
145
145
|
.mw-log tr.pin td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
|
|
146
146
|
.mw-log td.mw-tk { max-width: 0; width: 100%; }
|
|
147
147
|
.mw-date, .mw-run { font: 400 12px var(--font-mono); color: var(--ink-faint); white-space: nowrap; }
|
|
148
|
+
/* an entry an approved proposal corrected (task 1005016): one small note under the line */
|
|
149
|
+
.mw-fixed { display: block; font-size: 11.5px; color: var(--ink-faint); }
|
|
150
|
+
.mw-log tr.wrong .mw-tk .mw-one { text-decoration: line-through; color: var(--ink-faint); }
|
|
148
151
|
@media (max-width: 760px) {
|
|
149
152
|
.mw-log thead { display: none; }
|
|
150
153
|
.mw-log tr { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 4px 10px; padding: 10px 12px; border-bottom: 1px solid var(--rule-soft); }
|
|
@@ -162,6 +165,8 @@
|
|
|
162
165
|
.mw-dialog::backdrop { background: var(--scrim); }
|
|
163
166
|
.mw-dialog label { display: block; font-size: 13px; color: var(--ink-soft); margin-bottom: 12px; }
|
|
164
167
|
.mw-dialog input, .mw-dialog select { display: block; width: 100%; margin-top: 6px; font: inherit; color: var(--ink); background: var(--bg); border: 1px solid var(--rule); border-radius: var(--radius-sm); padding: 8px 9px; min-height: 36px; }
|
|
168
|
+
.mw-dialog label.mw-check { display: flex; gap: 8px; align-items: center; }
|
|
169
|
+
.mw-dialog label.mw-check input { display: inline-block; width: auto; min-height: 0; margin: 0; }
|
|
165
170
|
.mw-dialog .mw-row2 { display: grid; grid-template-columns: minmax(0, 1fr) 90px; gap: 8px; }
|
|
166
171
|
.mw-dialog__acts { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
|
|
167
172
|
.mw-dialog__err { color: var(--danger); font-size: 12.5px; margin: 0 0 8px; min-height: 1em; }
|
|
@@ -96,13 +96,13 @@
|
|
|
96
96
|
</div>
|
|
97
97
|
</div>
|
|
98
98
|
|
|
99
|
-
<dialog class="mw-dialog" id="mw-propose" aria-
|
|
99
|
+
<dialog class="mw-dialog" id="mw-propose" aria-labelledby="mw-propose-title"></dialog>
|
|
100
100
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
101
101
|
|
|
102
102
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
103
103
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
104
104
|
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
105
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
105
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
106
106
|
<script src="/builders/palette.js" defer></script>
|
|
107
107
|
<script src="/builders/hall-kit.js"></script>
|
|
108
108
|
<script src="/builders/market-watch-lib.js"></script>
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
129
129
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
130
130
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
131
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
131
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
132
132
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
133
133
|
<script src="/builders/palette.js" defer></script>
|
|
134
134
|
<script src="/builders/brand-apply.js"></script>
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
63
63
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
64
64
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
65
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
65
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
66
66
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
67
67
|
<script src="/builders/palette.js" defer></script>
|
|
68
68
|
<script src="/builders/gov-living.js?v=2026-10-10-real1"></script>
|
|
@@ -239,6 +239,9 @@
|
|
|
239
239
|
const laws = arr(sent && sent.laws).map((l, i) => ({ id: str(l.id), no: Number(l.no) || i + 1, text: str(l.text), effect: str(l.effect_on_ai) }));
|
|
240
240
|
const mine = [];
|
|
241
241
|
if (inter) mine.push({ key: 'interaction', title: 'How it talks to you', sent: !!inter.inject, text: inter.inject ? str(inter.contract) : '' });
|
|
242
|
+
// task 1005021: your computer's project folder, as your own session last reported it.
|
|
243
|
+
const co = obj(me.checkout_freshness);
|
|
244
|
+
if (co && co.behind && co.line) mine.push({ key: 'checkout', title: 'Your computer', sent: true, text: str(co.line), note: 'Your next session will try to update it. If it cannot, your agent will offer to.' });
|
|
242
245
|
if (wand) {
|
|
243
246
|
mine.push({
|
|
244
247
|
key: 'wandering', title: 'Off-task', sent: !!wand.inject,
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
114
114
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
115
115
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
116
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
116
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
117
117
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
118
118
|
<script src="/builders/palette.js" defer></script>
|
|
119
119
|
<!-- the shared markdown reader (window.OTBMdReader) — primer.js renders through
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
209
209
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
210
210
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
211
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
211
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
212
212
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
213
213
|
<script src="/builders/palette.js" defer></script>
|
|
214
214
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
73
73
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
74
74
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
75
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
75
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
76
76
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
77
77
|
<script src="/builders/palette.js" defer></script>
|
|
78
78
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
75
75
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
76
76
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
77
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
77
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
78
78
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
79
79
|
<script src="/builders/palette.js" defer></script>
|
|
80
80
|
<script src="/builders/founding-mark.js?v=2026-09-30-founding"></script>
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
45
45
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
46
46
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
47
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
47
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
48
48
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
49
49
|
<script src="/builders/palette.js" defer></script>
|
|
50
50
|
<!-- The chart kit and the timeline's series builders (task 1003447). Both MUST
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
57
57
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
58
58
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
59
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
59
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
60
60
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
61
61
|
<script src="/builders/palette.js" defer></script>
|
|
62
62
|
<!-- the branding pack's currency label, loaded BEFORE roster.js. -->
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
113
113
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
114
114
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
115
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
115
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
116
116
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
117
117
|
<script src="/builders/palette.js" defer></script>
|
|
118
118
|
<script src="/builders/task-detail.js?v=2026-07-03-taskdetail"></script>
|
|
@@ -487,7 +487,7 @@
|
|
|
487
487
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
488
488
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
489
489
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
490
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
490
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
491
491
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
492
492
|
<script src="/builders/palette.js" defer></script>
|
|
493
493
|
<!-- shared component kit (window.OTBKit) — section rail (task 2166). -->
|
|
@@ -535,10 +535,8 @@
|
|
|
535
535
|
TRAIL.backLinkHtml() +
|
|
536
536
|
'<h2 class="topbar-title" id="topbar-title"></h2>' +
|
|
537
537
|
'<div class="topbar-side"><span class="topbar-note" id="welcome-line"></span>' +
|
|
538
|
-
// task 2178: the jump-palette slot
|
|
539
|
-
//
|
|
540
|
-
// therefore shows no slot and runs no palette code (progressive
|
|
541
|
-
// enhancement): the shell never calls into it, so nothing can throw.
|
|
538
|
+
// task 2178: the jump-palette slot, inert + hidden until palette.js wires it; a page without
|
|
539
|
+
// palette.js shows no slot and runs no palette code — the shell never calls into it.
|
|
542
540
|
'<button class="topbar-jump" id="topbar-jump" type="button" hidden aria-label="Jump to a page or record">' +
|
|
543
541
|
'<svg viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true"><circle cx="8" cy="8" r="4.5"/><path d="M11.5 11.5 15 15"/></svg>' +
|
|
544
542
|
'<span class="topbar-jump__label">Jump to…</span>' +
|
|
@@ -778,12 +776,23 @@
|
|
|
778
776
|
if (res.data.moved) renderCoreMoveNotice(res.data.moved); // task 1004731: loads core-move-notice.js, which draws it
|
|
779
777
|
}, function () { /* fail-soft: no banner is the correct answer to no answer */ });
|
|
780
778
|
}
|
|
779
|
+
// One hall script on demand, stamped with the shell's own ?v= (task 1004996 made it one helper).
|
|
780
|
+
function loadHallScript(file, onload, onerror) {
|
|
781
|
+
var head = document.head, tag = head && head.appendChild && document.createElement ? document.createElement('script') : null;
|
|
782
|
+
if (!tag) { if (onerror) onerror(); return; }
|
|
783
|
+
tag.src = '/builders/' + file + (SHELL_V ? '?v=' + SHELL_V : '');
|
|
784
|
+
tag.onload = onload; tag.onerror = onerror || null;
|
|
785
|
+
head.appendChild(tag);
|
|
786
|
+
}
|
|
781
787
|
function renderCoreMoveNotice(moved) {
|
|
782
|
-
if (
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
788
|
+
loadHallScript('core-move-notice.js', function () { if (window.CoreMoveNotice) window.CoreMoveNotice.render(moved, { api: api, href: SOFTWARE_UPDATE_HREF }); });
|
|
789
|
+
}
|
|
790
|
+
var githubChipAsked = false; // task 1004996: the Link GitHub chip (github-chip.js), asked once a page
|
|
791
|
+
function loadGithubChip(builder) {
|
|
792
|
+
var hub = window.OTB && window.OTB.hubOrigin ? window.OTB.hubOrigin() : null;
|
|
793
|
+
if (githubChipAsked || !hub) return;
|
|
794
|
+
githubChipAsked = true;
|
|
795
|
+
loadHallScript('github-chip.js', function () { if (window.OTBGithubChip) window.OTBGithubChip.mount({ api: api, builder: builder, hub: hub }); });
|
|
787
796
|
}
|
|
788
797
|
|
|
789
798
|
// Where the banner's Upgrade goes (task 1004296). The platform's hall runs the deploy
|
|
@@ -1063,18 +1072,9 @@
|
|
|
1063
1072
|
var positionsLibAsk = null;
|
|
1064
1073
|
function positionsLib() {
|
|
1065
1074
|
if (window.GovPositions) return Promise.resolve(window.GovPositions);
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
if (!head || !head.appendChild || !document.createElement) { resolve(null); return; }
|
|
1070
|
-
var tag = document.createElement('script');
|
|
1071
|
-
tag.src = '/builders/gov-positions.js' + (SHELL_V ? '?v=' + SHELL_V : '');
|
|
1072
|
-
tag.onload = function () { resolve(window.GovPositions || null); };
|
|
1073
|
-
tag.onerror = function () { resolve(null); };
|
|
1074
|
-
head.appendChild(tag);
|
|
1075
|
-
});
|
|
1076
|
-
}
|
|
1077
|
-
return positionsLibAsk;
|
|
1075
|
+
return positionsLibAsk || (positionsLibAsk = new Promise(function (resolve) {
|
|
1076
|
+
loadHallScript('gov-positions.js', function () { resolve(window.GovPositions || null); }, function () { resolve(null); });
|
|
1077
|
+
}));
|
|
1078
1078
|
}
|
|
1079
1079
|
// `sent` is /me's `positions` block as the server resolved it (undefined: not told).
|
|
1080
1080
|
function loadPositions(builder, sent) {
|
|
@@ -1176,7 +1176,7 @@
|
|
|
1176
1176
|
}
|
|
1177
1177
|
if (state.builder) { renderUser(state.builder); applyCraftEmphasis(state.builder); }
|
|
1178
1178
|
// task 1004713: which seats this builder holds — /me's server-resolved block.
|
|
1179
|
-
if (state.builder && access.authed === true) loadPositions(state.builder, state.positions);
|
|
1179
|
+
if (state.builder && access.authed === true) { loadPositions(state.builder, state.positions); loadGithubChip(state.builder); }
|
|
1180
1180
|
}
|
|
1181
1181
|
document.querySelectorAll('#app-sidebar [data-gate]').forEach(function (el) {
|
|
1182
1182
|
var ok = gateAllows(el.dataset.gate);
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
232
232
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
233
233
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
234
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
234
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
235
235
|
<script src="/builders/palette.js" defer></script>
|
|
236
236
|
<script src="/builders/gov-living.js?v=2026-10-09-positions1"></script>
|
|
237
237
|
<script src="/builders/gov-feeds.js?v=2026-10-09-living3"></script>
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
220
220
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
221
221
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
222
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
222
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
223
223
|
<script src="/builders/palette.js" defer></script>
|
|
224
224
|
<!-- The kit, for its ONE renderer: the full-size ship-time visual figure
|
|
225
225
|
(task 1003829), which the older reviews still show. -->
|
|
@@ -4416,6 +4416,34 @@ a.stat-tile:hover .stat-tile__sub { color: var(--ink-soft); }
|
|
|
4416
4416
|
white-space: nowrap;
|
|
4417
4417
|
}
|
|
4418
4418
|
|
|
4419
|
+
/* ---------- the Link GitHub chip (task 1004996, github-chip.js) ----------
|
|
4420
|
+
Very small and quiet on purpose: shown only to someone with no GitHub linked,
|
|
4421
|
+
it is a plain link, never a banner — ideating and art go on without it. The
|
|
4422
|
+
engineer's glyph says what it is for; the label folds away on a phone. */
|
|
4423
|
+
.gh-chip {
|
|
4424
|
+
display: inline-flex;
|
|
4425
|
+
align-items: center;
|
|
4426
|
+
gap: 5px;
|
|
4427
|
+
min-height: 24px;
|
|
4428
|
+
min-width: 24px;
|
|
4429
|
+
padding: 0 8px 0 6px;
|
|
4430
|
+
border: 1px solid var(--rule);
|
|
4431
|
+
border-radius: var(--radius-pill, 999px);
|
|
4432
|
+
color: var(--ink-soft);
|
|
4433
|
+
font-size: 12px;
|
|
4434
|
+
line-height: 1;
|
|
4435
|
+
text-decoration: none;
|
|
4436
|
+
white-space: nowrap;
|
|
4437
|
+
flex-shrink: 0;
|
|
4438
|
+
}
|
|
4439
|
+
.gh-chip:hover { color: var(--ink); border-color: var(--ink-faint); }
|
|
4440
|
+
.gh-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
4441
|
+
.gh-chip svg { width: 13px; height: 13px; flex-shrink: 0; }
|
|
4442
|
+
@media (max-width: 640px) {
|
|
4443
|
+
.gh-chip { padding: 0; justify-content: center; }
|
|
4444
|
+
.gh-chip__label { display: none; }
|
|
4445
|
+
}
|
|
4446
|
+
|
|
4419
4447
|
.palette { position: fixed; inset: 0; z-index: 2100; }
|
|
4420
4448
|
.palette__scrim { position: absolute; inset: 0; background: var(--scrim); }
|
|
4421
4449
|
.palette__panel {
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
60
60
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
61
61
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
62
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
62
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
63
63
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
64
64
|
<script src="/builders/palette.js" defer></script>
|
|
65
65
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N deep-link overlay
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
142
142
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
143
143
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
144
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
144
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
145
145
|
<script src="/builders/palette.js" defer></script>
|
|
146
146
|
|
|
147
147
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
146
146
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
147
147
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
148
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
148
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
149
149
|
<script src="/builders/palette.js" defer></script>
|
|
150
150
|
<script src="/builders/brand-holes.js?v=2026-09-29-aqfix"></script>
|
|
151
151
|
<script src="/builders/tweak-editor-lib.js?v=2026-09-29-tw27"></script>
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
167
167
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
168
168
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
169
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
169
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
170
170
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
171
171
|
<script src="/builders/palette.js" defer></script>
|
|
172
172
|
<!-- shared component kit (window.OTBKit) — tabs, ledger, pager (task 2166). -->
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
175
175
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
176
176
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
177
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
177
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
178
178
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
179
179
|
<script src="/builders/palette.js" defer></script>
|
|
180
180
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -12,11 +12,17 @@ const { pool } = require('../../src/module-api');
|
|
|
12
12
|
// Shared by listOpenBlockers + getBlocker so the two reads can never drift
|
|
13
13
|
// (task 1002459 — getBlocker used to omit this column entirely, so a
|
|
14
14
|
// link-then-verify against the detail route read as a false negative).
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
) AS
|
|
15
|
+
// task 1004958: ONE lateral read gives both shapes — the ids (the hall reads those)
|
|
16
|
+
// and the same tasks with their 2-3 word names, so a session can write
|
|
17
|
+
// "task N - payout approvals" instead of a bare number.
|
|
18
|
+
const BLOCKING_TASK_IDS_SQL = `COALESCE(bl.ids, ARRAY[]::bigint[]) AS blocking_task_ids,
|
|
19
|
+
COALESCE(bl.tasks, '[]'::json) AS blocking_tasks`;
|
|
20
|
+
const BLOCKING_TASKS_JOIN = `LEFT JOIN LATERAL (
|
|
21
|
+
SELECT array_agg(tb.task_id ORDER BY tb.task_id) AS ids,
|
|
22
|
+
json_agg(json_build_object('id', tb.task_id, 'short_name', bt.short_name) ORDER BY tb.task_id) AS tasks
|
|
23
|
+
FROM task_blockers tb LEFT JOIN tasks bt ON bt.id = tb.task_id
|
|
24
|
+
WHERE tb.blocker_id = b.id
|
|
25
|
+
) bl ON true`;
|
|
20
26
|
|
|
21
27
|
// Optional { limit, offset } pushes the page into SQL so a small slice (the Home
|
|
22
28
|
// attention inbox reads limit=5 on every load) never scans the whole open set
|
|
@@ -32,7 +38,7 @@ async function listOpenBlockers({ limit, offset } = {}) {
|
|
|
32
38
|
`SELECT b.id, b.title, b.body_md, b.status, b.created_at,
|
|
33
39
|
b.source, b.source_ref,
|
|
34
40
|
${BLOCKING_TASK_IDS_SQL}
|
|
35
|
-
FROM blockers b
|
|
41
|
+
FROM blockers b ${BLOCKING_TASKS_JOIN}
|
|
36
42
|
WHERE b.status = 'open'
|
|
37
43
|
ORDER BY b.id${page}`,
|
|
38
44
|
params
|
|
@@ -50,7 +56,7 @@ async function getBlocker(id) {
|
|
|
50
56
|
`SELECT b.id, b.title, b.body_md, b.status, b.created_at, b.resolved_at, b.resolved_by,
|
|
51
57
|
b.resolution_note, b.source, b.source_ref,
|
|
52
58
|
${BLOCKING_TASK_IDS_SQL}
|
|
53
|
-
FROM blockers b WHERE b.id = $1`,
|
|
59
|
+
FROM blockers b ${BLOCKING_TASKS_JOIN} WHERE b.id = $1`,
|
|
54
60
|
[id]
|
|
55
61
|
);
|
|
56
62
|
return rows[0] || null;
|