@bongos/core 1.24.30 → 1.24.31
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 +153 -103
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +8 -0
- package/clients/bongos-client/index.cjs +8 -0
- package/clients/bongos-client/index.d.ts +8 -0
- package/clients/bongos-client/index.mjs +8 -0
- package/docs/api/openapi.json +139 -1
- package/docs/api-reference.md +7 -3
- package/docs/copy-inventory.md +192 -187
- package/docs/copy-registry.json +530 -458
- package/docs/module-api-changelog.md +2 -2
- package/docs/page-inventory.json +15 -35
- package/docs/page-readings.json +226 -263
- package/modules/copy-desk/module.json +1 -1
- package/modules/copy-desk/routes/copy-desk-studio.js +103 -0
- package/modules/copy-desk/tests/copy_no_cms.mjs +2 -2
- package/modules/hall-ui/public/ai-studio.html +1 -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/craft-mode.js +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/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/hall-render.js +62 -86
- package/modules/hall-ui/public/home-city-draw.js +360 -52
- package/modules/hall-ui/public/home-city.css +47 -11
- package/modules/hall-ui/public/home-city.js +156 -40
- package/modules/hall-ui/public/home-gallery.css +129 -0
- package/modules/hall-ui/public/home-gallery.js +349 -0
- package/modules/hall-ui/public/home-studio.css +72 -0
- package/modules/hall-ui/public/home-studio.js +203 -0
- 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 +4 -1
- package/modules/hall-ui/public/market-watch-item.html +1 -1
- package/modules/hall-ui/public/market-watch-rules.html +1 -1
- package/modules/hall-ui/public/market-watch-settings.js +6 -1
- package/modules/hall-ui/public/market-watch.html +141 -54
- package/modules/hall-ui/public/market-watch.js +54 -0
- package/modules/hall-ui/public/market-watch.states.json +2 -1
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/my-agents.html +1 -1
- 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 +2 -3
- package/modules/hall-ui/public/street.html +1 -1
- package/modules/hall-ui/public/studio.html +9 -1
- package/modules/hall-ui/public/style.css +74 -27
- 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/hall-ui/records/home-city.md +123 -0
- package/modules/hall-ui/records/loader.md +1 -1
- package/modules/hall-ui/records/market-watch-settings.md +16 -3
- package/modules/hall-ui/records/market-watch.md +3 -1
- package/modules/lifecycle/home-city.js +58 -10
- package/modules/lifecycle/home-gallery.js +320 -0
- package/modules/lifecycle/migrations/lifecycle_020_work_appreciations.sql +36 -0
- package/modules/lifecycle/module.json +1 -0
- package/modules/lifecycle/routes/home-gallery.js +37 -0
- package/modules/market-watch/routes/settings.js +1 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +29 -1
- package/scripts/bongos/leak-scan-allowlist.js +8 -0
- package/scripts/hall-preview/README.md +1 -0
- package/scripts/hall-preview/server.js +10 -0
- package/src/bongos/serve-internal.js +17 -3
- package/src/module-api.js +1 -1
- package/tests/hall_builders_page_pass.mjs +18 -27
- package/tests/hall_loading.mjs +1 -1
- package/tests/hall_nav.mjs +11 -4
- package/tests/hall_page_gate_map.mjs +7 -4
- package/tests/home_city.mjs +200 -5
- package/tests/home_city_widget.mjs +167 -27
- package/tests/home_gallery.mjs +255 -0
- package/tests/home_gallery_widget.mjs +220 -0
- package/tests/home_studio.mjs +169 -0
- package/tests/home_studio_widget.mjs +157 -0
- package/tests/market_watch_pages.mjs +162 -0
- package/tests/nav_permission_atoms.mjs +2 -2
- package/modules/hall-ui/public/market-watch-settings.html +0 -115
- package/modules/hall-ui/public/market-watch-settings.states.json +0 -14
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"category": { "parent": "quality" },
|
|
8
8
|
"default": true,
|
|
9
9
|
"maintenance": { "status": "core-maintained" },
|
|
10
|
-
"contributes": { "routes": ["copy-desk", "copy-desk-artist", "copy-desk-release"], "migrations": true, "skills": ["tweak"], "pollers": ["stuck-page-digest", "auto-close-rounds"] },
|
|
10
|
+
"contributes": { "routes": ["copy-desk", "copy-desk-artist", "copy-desk-release", "copy-desk-studio"], "migrations": true, "skills": ["tweak"], "pollers": ["stuck-page-digest", "auto-close-rounds"] },
|
|
11
11
|
"provides": ["copy-desk.artistStats", "copy-desk.stuckPageTweaksFor"],
|
|
12
12
|
"consumes": ["lifecycle"]
|
|
13
13
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// modules/copy-desk/routes/copy-desk-studio.js — the artist's studio, its copy-desk
|
|
2
|
+
// half (task 1005061, Home v16 step 4; mock docs/design/mocks/hall/home/v16-studio.html).
|
|
3
|
+
//
|
|
4
|
+
// GET /copy-desk/studio — one bounded read for three of the studio's shelves:
|
|
5
|
+
//
|
|
6
|
+
// easel the page round the caller holds (the Tweak/CopyWrite Flow's `resume`), or,
|
|
7
|
+
// with nothing held, the page the flow would recommend next.
|
|
8
|
+
// waiting "Waiting for new inspiration": pages whose words changed since an artist
|
|
9
|
+
// last designed them (the recommendation's `changed` tier, drift from the
|
|
10
|
+
// page readings), most changed lines first, at most MAX_WAITING, with the
|
|
11
|
+
// whole count.
|
|
12
|
+
// words "Words to tune": the newest open copy-desk flags, at most MAX_WORDS.
|
|
13
|
+
//
|
|
14
|
+
// Everything is composed by the flow's own reader (page-status.js composeNext over
|
|
15
|
+
// the inventory, the readings, the ledger's page rounds and the page asks), so the
|
|
16
|
+
// studio and the Studio page can never disagree about a page. Read only: it writes no
|
|
17
|
+
// row and returns no replacement wording (copy_no_cms.mjs holds every route file here
|
|
18
|
+
// to that). The other two shelves, the works the caller pinned and signed, are the
|
|
19
|
+
// lifecycle module's (GET /home/studio/works).
|
|
20
|
+
//
|
|
21
|
+
// Apart from routes/copy-desk.js because that file sits at the 1,500-line ratchet.
|
|
22
|
+
|
|
23
|
+
'use strict';
|
|
24
|
+
|
|
25
|
+
const express = require('express');
|
|
26
|
+
const api = require('../../../src/module-api');
|
|
27
|
+
const flags = require('../flags');
|
|
28
|
+
const pageData = require('../page-data');
|
|
29
|
+
const pageStatus = require('../page-status');
|
|
30
|
+
|
|
31
|
+
const log = api.logger('copy-desk');
|
|
32
|
+
|
|
33
|
+
const MAX_WAITING = 4;
|
|
34
|
+
const MAX_WORDS = 3;
|
|
35
|
+
const SURFACE_NAMES = Object.freeze({ landing: 'The public site', builders: 'The builders’ hall', status: 'The status page' });
|
|
36
|
+
|
|
37
|
+
function editorPath(pageId) { return `/tweak-editor?page=${encodeURIComponent(pageId)}`; }
|
|
38
|
+
|
|
39
|
+
// The studio's shape from the flow's answer and the newest open flags. Pure.
|
|
40
|
+
function composeStudio({ next, flagRows }) {
|
|
41
|
+
const n = next || {};
|
|
42
|
+
const all = [n.recommended, ...(n.alternatives || [])].filter(Boolean);
|
|
43
|
+
const changed = all.filter((c) => c.tier === 'changed' && c.changed_lines > 0)
|
|
44
|
+
.sort((a, b) => b.changed_lines - a.changed_lines);
|
|
45
|
+
const r = n.resume;
|
|
46
|
+
const easel = r
|
|
47
|
+
? { held: true, page_id: r.page_id, title: r.title, place: SURFACE_NAMES[r.surface] || null, round: r.round || null, open: editorPath(r.page_id) }
|
|
48
|
+
: (n.recommended
|
|
49
|
+
? { held: false, page_id: n.recommended.page_id, title: n.recommended.title, place: SURFACE_NAMES[n.recommended.surface] || null, why: n.recommended.why || null, open: editorPath(n.recommended.page_id) }
|
|
50
|
+
: null);
|
|
51
|
+
return {
|
|
52
|
+
easel,
|
|
53
|
+
waiting: {
|
|
54
|
+
total: changed.length,
|
|
55
|
+
pages: changed.slice(0, MAX_WAITING).map((c) => ({
|
|
56
|
+
page_id: c.page_id, title: c.title, place: SURFACE_NAMES[c.surface] || null, changed_lines: c.changed_lines, open: editorPath(c.page_id),
|
|
57
|
+
})),
|
|
58
|
+
},
|
|
59
|
+
words: (flagRows || []).slice(0, MAX_WORDS).map((f) => ({
|
|
60
|
+
id: String(f.id),
|
|
61
|
+
text: f.text_at_flag || null,
|
|
62
|
+
reason: f.reason || '',
|
|
63
|
+
place: SURFACE_NAMES[f.surface] || null,
|
|
64
|
+
})),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = function buildCopyDeskStudioRouter() {
|
|
69
|
+
const router = express.Router();
|
|
70
|
+
|
|
71
|
+
// rank: any-builder — GET /copy-desk/studio, the caller's easel, the pages waiting
|
|
72
|
+
// for an artist and the newest open flags. A work list, like /copy-desk/next and
|
|
73
|
+
// /copy-desk/queue, which any signed-in builder may already read.
|
|
74
|
+
router.get('/copy-desk/studio', api.requireBuilder, async (req, res) => {
|
|
75
|
+
try {
|
|
76
|
+
const inv = pageData.loadInventory();
|
|
77
|
+
const lifecycle = api.resolveOptional && api.resolveOptional('lifecycle');
|
|
78
|
+
const readsOk = inv.ok && !!lifecycle && typeof lifecycle.listPageTweakTasks === 'function';
|
|
79
|
+
const readings = pageData.loadReadings();
|
|
80
|
+
const [tasks, asks, flagRows] = await Promise.all([
|
|
81
|
+
readsOk ? lifecycle.listPageTweakTasks() : Promise.resolve([]),
|
|
82
|
+
readsOk ? flags.pageAskSummary() : Promise.resolve([]),
|
|
83
|
+
flags.listFlags({ status: 'open', scopes: flags.FLAG_SCOPES, limit: MAX_WORDS }),
|
|
84
|
+
]);
|
|
85
|
+
// Every candidate, not the flow's four alternatives: the waiting shelf is a filter
|
|
86
|
+
// over all of them. Bounded by the inventory's pages, never the corpus.
|
|
87
|
+
const next = readsOk ? pageStatus.composeNext({
|
|
88
|
+
inventory: inv.data, readings: readings.ok ? readings.data : null, tasks, asks, builderId: req.builder.id,
|
|
89
|
+
alternatives: (inv.data.pages || []).length,
|
|
90
|
+
}) : null;
|
|
91
|
+
res.set('Cache-Control', 'private, no-store');
|
|
92
|
+
res.json(composeStudio({ next, flagRows }));
|
|
93
|
+
} catch (err) {
|
|
94
|
+
log.error({ err }, 'GET /copy-desk/studio failed');
|
|
95
|
+
if (!res.headersSent) res.fail('copy_studio_failed', 500);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return router;
|
|
100
|
+
};
|
|
101
|
+
module.exports.composeStudio = composeStudio;
|
|
102
|
+
module.exports.MAX_WAITING = MAX_WAITING;
|
|
103
|
+
module.exports.MAX_WORDS = MAX_WORDS;
|
|
@@ -74,8 +74,8 @@ const MODULE_FILES = ['registry.js', 'flags.js', 'proposals.js', 'pages.js', 'pa
|
|
|
74
74
|
|
|
75
75
|
console.log('copy-desk: NO LIVE CMS');
|
|
76
76
|
|
|
77
|
-
await test('the route files are exactly the
|
|
78
|
-
assert.deepEqual(ROUTE_FILES, ['routes/copy-desk-artist.js', 'routes/copy-desk-release.js', 'routes/copy-desk.js'],
|
|
77
|
+
await test('the route files are exactly the four the module declares', () => {
|
|
78
|
+
assert.deepEqual(ROUTE_FILES, ['routes/copy-desk-artist.js', 'routes/copy-desk-release.js', 'routes/copy-desk-studio.js', 'routes/copy-desk.js'],
|
|
79
79
|
'a new route file is a new place a write could hide: add it here, and to the write-surface scan below');
|
|
80
80
|
});
|
|
81
81
|
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
90
90
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
91
91
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
92
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
92
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
93
93
|
<script src="/builders/palette.js" defer></script>
|
|
94
94
|
<script src="/builders/tweak-editor-lib.js?v=2026-09-28-tw23"></script>
|
|
95
95
|
<script src="/builders/studio-lib.js?v=2026-10-09-day"></script>
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
93
93
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
94
94
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
95
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
95
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
96
96
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
97
97
|
<script src="/builders/palette.js" defer></script>
|
|
98
98
|
<script src="/builders/atlas.js?v=2026-09-02-index" defer></script>
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
62
62
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
63
63
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
64
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
64
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
65
65
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
66
66
|
<script src="/builders/palette.js" defer></script>
|
|
67
67
|
<!-- the branding pack's currency label, loaded BEFORE blockers.js. -->
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
64
64
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
65
65
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
66
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
66
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
67
67
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
68
68
|
<script src="/builders/palette.js" defer></script>
|
|
69
69
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
109
109
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab" defer></script>
|
|
110
110
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch" defer></script>
|
|
111
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
111
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch" defer></script>
|
|
112
112
|
<script src="/builders/palette.js" defer></script>
|
|
113
113
|
<script src="/builders/gov-living.js?v=2026-10-09-positions1" defer></script>
|
|
114
114
|
<script src="/builders/gov-feeds.js?v=2026-10-09-living3" defer></script>
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
163
163
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
164
164
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
165
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
165
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
166
166
|
<script src="/builders/palette.js" defer></script>
|
|
167
167
|
<script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
|
|
168
168
|
<script src="/builders/collab.js?v=2026-09-24-archive"></script>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
55
55
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
56
56
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
57
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
57
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
58
58
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
59
59
|
<script src="/builders/palette.js" defer></script>
|
|
60
60
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -180,7 +180,7 @@
|
|
|
180
180
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
181
181
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
182
182
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
183
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
183
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
184
184
|
<script src="/builders/palette.js" defer></script>
|
|
185
185
|
<script src="/builders/hall-kit.js"></script>
|
|
186
186
|
<script src="/builders/copy-desk.js?v=2026-09-01-redesign"></script>
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
artistry: ['studio', 'goals', 'thinking'],
|
|
108
108
|
ideating: ['goal-map', 'thinking', 'goals', 'market-watch'],
|
|
109
109
|
governing: ['city', 'blockers', 'board-room',
|
|
110
|
-
'watch', 'gate', 'sessions', 'project-settings', 'deploy', 'fleet', '
|
|
110
|
+
'watch', 'gate', 'sessions', 'project-settings', 'deploy', 'fleet', 'government'],
|
|
111
111
|
};
|
|
112
112
|
// A mode can lead with ONE tab and fold the rest of its own under a dropdown
|
|
113
113
|
// (owner, 2026-10-08: the city is Governing's tab, everything else under it).
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
82
82
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
83
83
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
84
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
84
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
85
85
|
<script src="/builders/palette.js" defer></script>
|
|
86
86
|
<script src="/builders/hall-kit.js"></script>
|
|
87
87
|
<!-- the shared ask card the move is drawn with (task 1004829) -->
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
98
98
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
99
99
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
100
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
100
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
101
101
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
102
102
|
<script src="/builders/palette.js" defer></script>
|
|
103
103
|
<script src="/builders/diagram-viewer.js?v=2026-06-14-diagviewer-1" defer></script>
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
98
98
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
99
99
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
100
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
100
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
101
101
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
102
102
|
<script src="/builders/palette.js" defer></script>
|
|
103
103
|
<script src="/builders/md-reader.js?v=2026-09-02-mdreader-2"></script>
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
61
61
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
62
62
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
63
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
63
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
64
64
|
<script src="/builders/palette.js" defer></script>
|
|
65
65
|
<script src="/builders/hall-kit.js"></script>
|
|
66
66
|
<script src="/builders/fleet-costs.js"></script>
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
68
68
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
69
69
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
70
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
70
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
71
71
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
72
72
|
<script src="/builders/palette.js" defer></script>
|
|
73
73
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
141
141
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
142
142
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
143
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
143
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
144
144
|
<script src="/builders/palette.js" defer></script>
|
|
145
145
|
|
|
146
146
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
245
245
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
246
246
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
247
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
247
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
248
248
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
249
249
|
<script src="/builders/palette.js" defer></script>
|
|
250
250
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
158
158
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
159
159
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
160
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
160
|
+
<script src="/builders/shell.js?v=2026-11-04-one-market-watch"></script>
|
|
161
161
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
162
162
|
<script src="/builders/palette.js" defer></script>
|
|
163
163
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -273,69 +273,40 @@
|
|
|
273
273
|
return v === 'open' || v === 'invite_only' ? v : 'apply';
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
//
|
|
277
|
-
//
|
|
276
|
+
// The signed-out page is one centred card (task: sign-in redesign): the
|
|
277
|
+
// sign-in button leads in every mode, and the door below it is the only part
|
|
278
|
+
// that depends on joinability — open → nothing to do, invite_only → nothing
|
|
279
|
+
// to apply for, apply → the request form, folded behind a disclosure so the
|
|
280
|
+
// card stays a sign-in screen rather than a form.
|
|
278
281
|
function landingDoorHtml(mode) {
|
|
279
|
-
const hub = `This is the builders' hub for ${brandWorld()} — where builders claim work, earn ${curLabel()}, and see what they have accomplished.`;
|
|
280
282
|
const admitter = escapeHtml(rankLabel('archon'));
|
|
281
|
-
const signIn = `<p class="landing__cta"><a class="landing__btn" href="${API}/auth/web/start">Sign in with GitHub</a></p>`;
|
|
282
283
|
if (mode === 'open') {
|
|
283
284
|
return `
|
|
284
|
-
<p class="
|
|
285
|
-
<div class="landing__request" id="landing-request">
|
|
286
|
-
<h3 class="landing__request-h">New here — sign in to join</h3>
|
|
287
|
-
<p class="landing__request-lede">No request and no invite needed. Sign in with GitHub, and a step-by-step guide takes you the rest of the way.</p>
|
|
288
|
-
${signIn}
|
|
289
|
-
</div>`;
|
|
285
|
+
<p class="landing__door" id="landing-request">New here? Signing in creates your account.</p>`;
|
|
290
286
|
}
|
|
291
287
|
if (mode === 'invite_only') {
|
|
292
288
|
return `
|
|
293
|
-
<p class="
|
|
294
|
-
<div class="landing__request" id="landing-request">
|
|
295
|
-
<h3 class="landing__request-h">Invited? Sign in</h3>
|
|
296
|
-
<p class="landing__request-lede">If the ${admitter} has invited you, sign in with GitHub and you're in. If not, ask them for an invite — this project doesn't take requests.</p>
|
|
297
|
-
${signIn}
|
|
298
|
-
</div>`;
|
|
289
|
+
<p class="landing__door" id="landing-request">Invite-only — there is nothing to apply for here.</p>`;
|
|
299
290
|
}
|
|
300
291
|
return `
|
|
301
|
-
<
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
</label>
|
|
320
|
-
<label class="landing__field">
|
|
321
|
-
<span>Your name <span class="landing__opt">(optional)</span></span>
|
|
322
|
-
<input type="text" id="ar-name" name="display_name" autocomplete="name"
|
|
323
|
-
placeholder="So the Archon knows who you are" maxlength="100">
|
|
324
|
-
</label>
|
|
325
|
-
<label class="landing__field">
|
|
326
|
-
<span>A word on why <span class="landing__opt">(optional)</span></span>
|
|
327
|
-
<input type="text" id="ar-note" name="note"
|
|
328
|
-
placeholder="How you got here, what you'd build" maxlength="500">
|
|
329
|
-
</label>
|
|
330
|
-
<p class="landing__form-hint">
|
|
331
|
-
No GitHub account yet? Make a free one at
|
|
332
|
-
<a href="https://github.com/signup" target="_blank" rel="noopener noreferrer">github.com</a>
|
|
333
|
-
first — your username is all we need.
|
|
334
|
-
</p>
|
|
335
|
-
<button type="submit" class="landing__btn landing__btn--request" id="ar-submit">Request access</button>
|
|
336
|
-
<p class="landing__request-status" id="ar-status" aria-live="polite"></p>
|
|
337
|
-
</form>
|
|
338
|
-
</div>`;
|
|
292
|
+
<details class="landing__disclosure">
|
|
293
|
+
<summary class="landing__summary">New here? Request access</summary>
|
|
294
|
+
<div class="landing__request" id="landing-request">
|
|
295
|
+
<form class="landing__form" id="access-request-form" novalidate>
|
|
296
|
+
<label class="landing__field">
|
|
297
|
+
<span>GitHub username</span>
|
|
298
|
+
<input type="text" id="ar-login" name="github_login" autocomplete="username"
|
|
299
|
+
placeholder="e.g. octocat" maxlength="40" required>
|
|
300
|
+
</label>
|
|
301
|
+
<label class="landing__field">
|
|
302
|
+
<span>Why you'd like in <span class="landing__opt">(optional)</span></span>
|
|
303
|
+
<input type="text" id="ar-note" name="note" maxlength="500">
|
|
304
|
+
</label>
|
|
305
|
+
<button type="submit" class="landing__btn landing__btn--quiet landing__btn--block" id="ar-submit">Request access</button>
|
|
306
|
+
<p class="landing__request-status" id="ar-status" aria-live="polite"></p>
|
|
307
|
+
</form>
|
|
308
|
+
</div>
|
|
309
|
+
</details>`;
|
|
339
310
|
}
|
|
340
311
|
|
|
341
312
|
// task 1002835: a karma vote on a peer's ship was a vote on a title alone.
|
|
@@ -360,28 +331,39 @@
|
|
|
360
331
|
}
|
|
361
332
|
return `<span class="acclaim__evidence">${parts.join(' · ')}</span>`;
|
|
362
333
|
}
|
|
363
|
-
// The
|
|
364
|
-
//
|
|
365
|
-
|
|
366
|
-
// one — those modes keep the prose note alone. Only the `apply` door, whose
|
|
367
|
-
// primary control is the request FORM, left signing in as a footnote link.
|
|
368
|
-
// It gets a real button: the request button's geometry so it reads as a
|
|
369
|
-
// control, a quieter fill so the request path still leads for the strangers
|
|
370
|
-
// who are most of this page's traffic.
|
|
371
|
-
function returningDoorHtml(mode) {
|
|
372
|
-
if (mode !== 'apply') return '';
|
|
334
|
+
// The sign-in itself — the card's one primary control, in every mode, so a
|
|
335
|
+
// returning builder never hunts for it below a form (task 1002851's intent).
|
|
336
|
+
function returningDoorHtml() {
|
|
373
337
|
return `
|
|
374
|
-
<
|
|
375
|
-
<
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
338
|
+
<a class="landing__btn landing__btn--block" id="landing-signin" href="${API}/auth/web/start">
|
|
339
|
+
<svg class="landing__gh" viewBox="0 0 16 16" width="18" height="18" aria-hidden="true"><path fill="currentColor" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg>
|
|
340
|
+
Sign in with GitHub
|
|
341
|
+
</a>`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// The project's mark, as the sidebar draws it: the pack's own logo when it has
|
|
345
|
+
// one (theme.logo, ADR 0358), otherwise the Cloud Bongos ring-and-moon.
|
|
346
|
+
function landingLogoHtml() {
|
|
347
|
+
const b = window.__BRANDING__ || {};
|
|
348
|
+
const logo = b.theme && b.theme.logo;
|
|
349
|
+
return logo
|
|
350
|
+
? `<img class="landing__logo" src="${escapeHtml(logo)}" alt="" width="56" height="56" decoding="async">`
|
|
351
|
+
: '<svg class="landing__logo" viewBox="0 0 200 200" aria-hidden="true"><path class="landing__ring" d="M137 31 A78 78 0 1 0 170 66" fill="none" stroke-width="15" stroke-linecap="round"/><circle class="landing__planet" cx="100" cy="100" r="55"/><circle cx="156" cy="46" r="12" fill="#fb9569"/></svg>';
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Strip the hall's chrome (rail, top bar, foot) for the signed-out card —
|
|
355
|
+
// html[data-door="out"], styled in style.css. The test vm has no
|
|
356
|
+
// documentElement, hence the guard.
|
|
357
|
+
function markSignedOut() {
|
|
358
|
+
const root = document.documentElement;
|
|
359
|
+
if (root && root.dataset) root.dataset.door = 'out';
|
|
379
360
|
}
|
|
380
361
|
|
|
381
362
|
function renderLanding() {
|
|
382
|
-
// task 1723: collapse the shell nav to the signed-out minimum
|
|
383
|
-
//
|
|
363
|
+
// task 1723: collapse the shell nav to the signed-out minimum. Cosmetic —
|
|
364
|
+
// the server gates every page regardless.
|
|
384
365
|
window.OTBShell?.applyAccess({ authed: false });
|
|
366
|
+
markSignedOut();
|
|
385
367
|
|
|
386
368
|
const welcome = $('#welcome-line');
|
|
387
369
|
if (welcome) welcome.textContent = '';
|
|
@@ -390,20 +372,12 @@
|
|
|
390
372
|
if (landing) {
|
|
391
373
|
landing.hidden = false;
|
|
392
374
|
const mode = joinabilityMode();
|
|
393
|
-
// On the apply door the sign-in is a real button above, so the note keeps
|
|
394
|
-
// only the privacy sentence — one sign-in path per landing, never two.
|
|
395
|
-
const signInNote = mode === 'apply'
|
|
396
|
-
? ''
|
|
397
|
-
: `Already a member? <a href="${API}/auth/web/start">Sign in with GitHub</a>. `;
|
|
398
375
|
landing.innerHTML = `
|
|
399
|
-
<div class="
|
|
400
|
-
|
|
401
|
-
|
|
376
|
+
<div class="landing">
|
|
377
|
+
${landingLogoHtml()}
|
|
378
|
+
<h2 class="landing__title">${brandWorld()}</h2>
|
|
402
379
|
${returningDoorHtml(mode)}
|
|
403
|
-
|
|
404
|
-
<p class="landing__signin-note">
|
|
405
|
-
${signInNote}We store only your GitHub login, avatar, and the work you ship.
|
|
406
|
-
</p>
|
|
380
|
+
${landingDoorHtml(mode)}
|
|
407
381
|
</div>
|
|
408
382
|
`;
|
|
409
383
|
wireAccessRequestForm();
|
|
@@ -419,6 +393,7 @@
|
|
|
419
393
|
// deleted. Say so, and offer the way out: sign out, then sign in again.
|
|
420
394
|
function renderSessionRefused(code) {
|
|
421
395
|
window.OTBShell?.applyAccess({ authed: false });
|
|
396
|
+
markSignedOut();
|
|
422
397
|
const landing = $('#landing-root');
|
|
423
398
|
if (!landing) return;
|
|
424
399
|
landing.hidden = false;
|
|
@@ -427,11 +402,12 @@
|
|
|
427
402
|
? `This account has been switched off, so it cannot open the hall. If that is a mistake, ask the ${admitter} to switch it back on.`
|
|
428
403
|
: 'This sign-in is no longer accepted, so the hall cannot open with it.';
|
|
429
404
|
landing.innerHTML = `
|
|
430
|
-
<div class="
|
|
431
|
-
|
|
405
|
+
<div class="landing">
|
|
406
|
+
${landingLogoHtml()}
|
|
407
|
+
<h2 class="landing__title">You can't get in with this account</h2>
|
|
432
408
|
<p class="landing__request-lede">${why}</p>
|
|
433
409
|
<p class="landing__request-lede">Sign out, then sign in with the GitHub account you use now. A new account needs the ${admitter}'s approval first.</p>
|
|
434
|
-
<
|
|
410
|
+
<button type="button" class="landing__btn landing__btn--block" id="refused-signout">Sign out</button>
|
|
435
411
|
</div>
|
|
436
412
|
`;
|
|
437
413
|
$('#refused-signout')?.addEventListener('click', () => {
|