@bongos/core 1.24.14 → 1.24.16
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 +308 -138
- 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 +231 -204
- package/docs/copy-registry.json +488 -255
- package/docs/file-map.md +1 -0
- package/docs/module-api-changelog.md +4 -2
- package/docs/page-inventory.json +7 -1
- package/docs/page-readings.json +1132 -1103
- 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/panel.css +5 -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-age.js +65 -0
- package/modules/hall-ui/public/settings.html +27 -1
- package/modules/hall-ui/public/settings.js +1 -0
- 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 +55 -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/settings_age.mjs +110 -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,
|
|
@@ -341,3 +341,8 @@ button.craft-save { display: inline-flex; align-items: center; justify-content:
|
|
|
341
341
|
.prow--pick { flex-direction: row; align-items: flex-start; }
|
|
342
342
|
.pinput, .display-name-input, .artkey-input, .join input, .join-note { max-width: none; }
|
|
343
343
|
}
|
|
344
|
+
|
|
345
|
+
/* ---- Your age (task 1005028): four radio choices, one per line ---------------- */
|
|
346
|
+
.age-choices { border: 0; padding: 0; margin: 0 0 var(--space-3, 14px); display: grid; gap: 2px; }
|
|
347
|
+
.age-choices label { display: flex; align-items: center; gap: 10px; min-height: 32px; cursor: pointer; }
|
|
348
|
+
.age-choices input { width: 18px; height: 18px; margin: 0; }
|
|
@@ -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>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// modules/hall-ui/public/settings-age.js — the "Your age" panel on /builders/settings
|
|
2
|
+
// (task 1005028). Shows the age band on record and records a new one. AI Studio and
|
|
3
|
+
// payouts read the latest record; the server only accepts it from a person signed in
|
|
4
|
+
// on the website (POST /me/payout-age), so this page is the one way to write it.
|
|
5
|
+
(() => {
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const API = '/api/bongos';
|
|
9
|
+
const { $ } = window.OTB;
|
|
10
|
+
const toast = (msg) => window.OTB.toast(msg);
|
|
11
|
+
const api = window.BongosClient.createClient({ baseUrl: '', credentials: 'same-origin', throwOnError: false });
|
|
12
|
+
|
|
13
|
+
const LABELS = { adult: '18 or older', '16_17': '16 to 17', '13_15': '13 to 15', under_13: 'Under 13' };
|
|
14
|
+
|
|
15
|
+
// The server's error envelope is { error: { message } }.
|
|
16
|
+
const why = (res) => (res.data && res.data.error && res.data.error.message) || `HTTP ${res.status}`;
|
|
17
|
+
|
|
18
|
+
const currentText = (tier) => (LABELS[tier]
|
|
19
|
+
? `On record: ${LABELS[tier]}.`
|
|
20
|
+
: 'Nothing on record yet, so AI Studio stays closed to you.');
|
|
21
|
+
|
|
22
|
+
async function load() {
|
|
23
|
+
const res = await api.request('GET', `${API}/me/payouts`);
|
|
24
|
+
if (res.status === 401) { window.location.assign(`${API}/auth/web/start`); return; }
|
|
25
|
+
if (!res.ok) throw new Error(why(res));
|
|
26
|
+
const tier = res.data && res.data.age_tier;
|
|
27
|
+
$('#age-current').textContent = currentText(tier);
|
|
28
|
+
// Only a known band is looked up, so nothing from the response reaches a selector.
|
|
29
|
+
const pick = LABELS[tier] ? document.querySelector(`input[name="age-tier"][value="${tier}"]`) : null;
|
|
30
|
+
if (pick) pick.checked = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function save() {
|
|
34
|
+
const chosen = document.querySelector('input[name="age-tier"]:checked');
|
|
35
|
+
const status = $('#age-status');
|
|
36
|
+
if (!chosen) { status.textContent = 'Pick the group you are in first.'; return; }
|
|
37
|
+
const btn = $('#age-save');
|
|
38
|
+
btn.disabled = true;
|
|
39
|
+
status.textContent = 'Saving…';
|
|
40
|
+
try {
|
|
41
|
+
const res = await api.request('POST', `${API}/me/payout-age`, { body: { tier: chosen.value } });
|
|
42
|
+
if (!res.ok) throw new Error(why(res));
|
|
43
|
+
status.textContent = '';
|
|
44
|
+
$('#age-current').textContent = currentText(chosen.value);
|
|
45
|
+
toast('Age saved.');
|
|
46
|
+
} catch (err) {
|
|
47
|
+
status.textContent = '';
|
|
48
|
+
toast(`Could not save your age: ${err.message}`);
|
|
49
|
+
} finally {
|
|
50
|
+
btn.disabled = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function setup() {
|
|
55
|
+
try {
|
|
56
|
+
await load();
|
|
57
|
+
$('#age-scroll').hidden = false;
|
|
58
|
+
$('#age-save').addEventListener('click', save);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
toast(`Could not load your age: ${err.message}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
setup();
|
|
65
|
+
})();
|
|
@@ -91,6 +91,31 @@
|
|
|
91
91
|
<p class="section-note">Saves when you press Save; shows everywhere at once.</p>
|
|
92
92
|
</section>
|
|
93
93
|
|
|
94
|
+
<!-- YOUR AGE — the band on record, and where you record it (task 1005028).
|
|
95
|
+
AI Studio and payouts both read the latest payout_age_records row, and
|
|
96
|
+
the only writer is POST /me/payout-age, which needs a person signed in
|
|
97
|
+
on the website. Rendered by settings-age.js; only the band is kept. -->
|
|
98
|
+
<section class="scroll" id="age-scroll" aria-labelledby="age-h" data-group="account" hidden>
|
|
99
|
+
<h2 id="age-h" class="scroll__h">Your age</h2>
|
|
100
|
+
<p class="scroll__lede">
|
|
101
|
+
AI Studio and getting paid both depend on your age. Pick the group you
|
|
102
|
+
are in. Only the group is kept, never your birthday.
|
|
103
|
+
</p>
|
|
104
|
+
<p class="settings-card__hint" id="age-current" aria-live="polite"></p>
|
|
105
|
+
<fieldset class="age-choices" id="age-choices">
|
|
106
|
+
<legend class="field-label">I am</legend>
|
|
107
|
+
<label><input type="radio" name="age-tier" value="adult"> 18 or older</label>
|
|
108
|
+
<label><input type="radio" name="age-tier" value="16_17"> 16 to 17</label>
|
|
109
|
+
<label><input type="radio" name="age-tier" value="13_15"> 13 to 15</label>
|
|
110
|
+
<label><input type="radio" name="age-tier" value="under_13"> Under 13</label>
|
|
111
|
+
</fieldset>
|
|
112
|
+
<div class="display-name-row">
|
|
113
|
+
<button type="button" class="craft-save" id="age-save">Save</button>
|
|
114
|
+
</div>
|
|
115
|
+
<p class="settings-status" id="age-status" role="status" aria-live="polite"></p>
|
|
116
|
+
<p class="section-note">AI Studio is for adults only, because the AI companies behind it only serve adults.</p>
|
|
117
|
+
</section>
|
|
118
|
+
|
|
94
119
|
<!-- PROFILE AND PRIVACY — one link out to the hub's account page
|
|
95
120
|
(task 1004259, ADR 0337 D4.3). Handle, bio, links, public/private,
|
|
96
121
|
recruiters and the hide-my-numbers switch belong to the platform
|
|
@@ -487,7 +512,7 @@
|
|
|
487
512
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
488
513
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
489
514
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
490
|
-
<script src="/builders/shell.js?v=2026-10-30-
|
|
515
|
+
<script src="/builders/shell.js?v=2026-10-30-github-chip"></script>
|
|
491
516
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
492
517
|
<script src="/builders/palette.js" defer></script>
|
|
493
518
|
<!-- shared component kit (window.OTBKit) — section rail (task 2166). -->
|
|
@@ -501,6 +526,7 @@
|
|
|
501
526
|
settings.js, which sits close to the 1500-line size ratchet. -->
|
|
502
527
|
<script src="/builders/settings-sessions.js?v=2026-08-29-sessions"></script>
|
|
503
528
|
<script src="/builders/settings-passkeys.js?v=2026-10-15-passkeys"></script>
|
|
529
|
+
<script src="/builders/settings-age.js?v=2026-10-30-age"></script>
|
|
504
530
|
<script src="/builders/settings-ai-keys.js?v=2026-10-28-ai-keys"></script>
|
|
505
531
|
<!-- task 1002514: the interaction-profile panel ("How Claude talks to you"), on
|
|
506
532
|
the same precedent and for the same reason — settings.js is against the
|
|
@@ -1107,6 +1107,7 @@
|
|
|
1107
1107
|
const PANEL_ANCHORS = {
|
|
1108
1108
|
'connections': 'connections-scroll',
|
|
1109
1109
|
'display-name': 'display-name-scroll',
|
|
1110
|
+
'age': 'age-scroll',
|
|
1110
1111
|
// task 1004259: the two privacy panels became one link-out row; their old
|
|
1111
1112
|
// anchors still land on it (the hall profile links /settings#cross-project).
|
|
1112
1113
|
'profile-privacy': 'account-hub-scroll',
|
|
@@ -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. -->
|