@bongos/core 1.25.19 → 1.25.20
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 +108 -78
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +3 -1
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/api/openapi.json +36 -2
- package/docs/api-reference.md +5 -4
- package/docs/copy-inventory.md +217 -215
- package/docs/copy-registry.json +256 -238
- package/docs/module-api-changelog.md +2 -0
- package/docs/page-readings.json +348 -347
- package/docs/project-context.template.md +1 -1
- package/modules/front-door-guide/handoff.js +120 -0
- package/modules/front-door-guide/module.json +1 -1
- package/modules/front-door-guide/routes/front-door-guide-plan.js +24 -0
- 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/deploy.html +1 -1
- package/modules/hall-ui/public/genesis-home.js +23 -4
- 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/home-city-draw.js +14 -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 +1 -1
- package/modules/hall-ui/public/market-watch-rules.html +1 -1
- package/modules/hall-ui/public/market-watch.html +1 -1
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/money.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/roster.html +1 -1
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell.js +32 -20
- 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 +9 -4
- 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/lifecycle/home-city.js +17 -3
- package/modules/onboarding/founding-mode.js +45 -1
- package/modules/onboarding/genesis-home.js +2 -0
- package/modules/onboarding/guide-handoff.js +109 -0
- package/modules/onboarding/routes/genesis-work.js +9 -5
- package/modules/provisioning/guide-handoff.js +65 -0
- package/modules/provisioning/provisioning.js +2 -2
- package/modules/provisioning/routes/provisioning.js +4 -2
- package/modules/public-landing/public/projects.html +79 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +10 -0
- package/src/bongos/founding-page-gate.js +67 -0
- package/src/bongos/serve-internal.js +3 -0
- package/src/branding.js +4 -0
- package/src/module-api.js +1 -1
- package/tests/founding_mode.mjs +84 -8
- package/tests/founding_page_gate.mjs +105 -0
- package/tests/front_door_guide_existing.mjs +1 -0
- package/tests/genesis_home.mjs +24 -0
- package/tests/guide_handoff.mjs +322 -0
- package/tests/home_city.mjs +52 -0
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/provision_settings_apply.mjs +2 -1
- package/tests/provisioning_settings_env.mjs +2 -2
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
>
|
|
5
5
|
> **Relationship to the rest of the project:**
|
|
6
6
|
> - [`CLAUDE.md`](../CLAUDE.md) is the **portable methodology core** Cloud Bongos ships — working rules, session protocol, claim→ship lifecycle, the [ADR 0061](adr/0061-context-layer-decomposition.md) content charter, the nested-`CLAUDE.md` pattern. Instance-agnostic; you do not author it.
|
|
7
|
-
> - **The founder's own answers come first.** What the project is, who it is for, what success looks like and the bet it makes are asked in the genesis scope interview and stored as answers in Bongos, not here. `node scripts/bongos/genesis.js context` (or `npx bongos genesis context`) prints them. Where this file and those answers disagree, the answers are the founder's latest word ([ADR 0408](adr/0408-a-genesis-stage-is-three-doors-onto-one-record.md), task 1005114).
|
|
7
|
+
> - **The founder's own answers come first.** What the project is, who it is for, what success looks like and the bet it makes are asked in the genesis scope interview and stored as answers in Bongos, not here. `node scripts/bongos/genesis.js context` (or `npx bongos genesis context`) prints them. Where this file and those answers disagree, the answers are the founder's latest word ([ADR 0408](adr/0408-a-genesis-stage-is-three-doors-onto-one-record.md), task 1005114). A founder who planned the project with the start-a-project guide before signing up also has a hand-off file (where the project started, the plan, the recommended modules and the first steps); the same command prints it first (task 1005274).
|
|
8
8
|
> - **This file is the *prose* identity** — lore, vision, the why. The **machine-readable** identity (exact strings code reads: product/world/company names, domains, cookie/OAuth origins, currency label, palette, repo binding) lives in the branding contract [`config/branding.json`](../config/branding.json) ([`docs/branding-contract.md`](branding-contract.md)). **Where a name must be exact for code, the branding contract wins** — never re-hardcode a contract-owned string here.
|
|
9
9
|
|
|
10
10
|
<!--
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// modules/front-door-guide/handoff.js — THE GUIDE'S HAND-OFF (task 1005274, goal 1000106):
|
|
4
|
+
// what a founder told the start-a-project guide, carried forward so nothing is asked twice.
|
|
5
|
+
// PURE: a saved Plan in, words out. Nothing here calls an AI; it moves saved answers.
|
|
6
|
+
//
|
|
7
|
+
// Three readers, one source (the Plan the guide saved, plan.js):
|
|
8
|
+
// * the creation page's pre-fill reads the Plan itself (GET /front-door-guide/mine);
|
|
9
|
+
// * scopeAnswers(plan) → the Genesis scope interview's carried-over answers;
|
|
10
|
+
// * handoffMarkdown(plan) → the hand-off file: what the project is, the plan, the
|
|
11
|
+
// recommended modules and the first steps, written for the founder's own AI.
|
|
12
|
+
//
|
|
13
|
+
// THE SCOPE MAP IS EXPLICIT, and a question the plan does not answer stays EMPTY. The
|
|
14
|
+
// plan's fields are what the guide asked; the scope interview's six questions
|
|
15
|
+
// (modules/onboarding/genesis-work.js QUESTIONS.scope) are the founder's own. Only one
|
|
16
|
+
// field says the same thing as a scope question. Every other question maps to null on
|
|
17
|
+
// purpose: inventing "who it is for" or "the bet" from a chat that never asked would put
|
|
18
|
+
// words in the founder's mouth, which is the one thing genesis exists to prevent.
|
|
19
|
+
|
|
20
|
+
const SCOPE_MAP = Object.freeze({
|
|
21
|
+
what_creating: 'summary', // "what are you creating" ← the guide's summary of what they said
|
|
22
|
+
goal_impact: null, // the guide never asks why or for what impact
|
|
23
|
+
success_two_years: null, // nor what success looks like
|
|
24
|
+
reach_who: null, // the summary may mention who, but not as an answer to this
|
|
25
|
+
work_with_who: null, // nor who they want working with them
|
|
26
|
+
others_wrong: null, // nor the bet
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const ANSWER_MAX = 4000; // genesis-work.js LIMITS.answer
|
|
30
|
+
const MARKDOWN_MAX = 12000; // the hand-off rides an env line to the new project; keep it bounded
|
|
31
|
+
const PROJECT_TYPE_WORDS = Object.freeze({
|
|
32
|
+
game: 'A game', research: 'Research', business: 'A business', 'non-profit': 'A non-profit', 'not-sure': 'Not decided yet',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const str = (v) => (typeof v === 'string' ? v.trim() : '');
|
|
36
|
+
const list = (v) => (Array.isArray(v) ? v : []);
|
|
37
|
+
|
|
38
|
+
// scopeAnswers(plan) → { question_id: text } for the questions the plan answers, and only
|
|
39
|
+
// those. An empty object for no plan.
|
|
40
|
+
function scopeAnswers(plan) {
|
|
41
|
+
const out = {};
|
|
42
|
+
if (!plan || typeof plan !== 'object') return out;
|
|
43
|
+
for (const [question, field] of Object.entries(SCOPE_MAP)) {
|
|
44
|
+
if (!field) continue;
|
|
45
|
+
const words = str(plan[field]).slice(0, ANSWER_MAX);
|
|
46
|
+
if (words) out[question] = words;
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// handoffMarkdown(plan, { name }) → the hand-off file, or '' for no usable plan. Written
|
|
52
|
+
// so an AI session that reads ONLY this file can say what the project is for and what to
|
|
53
|
+
// do next, and knows these are carried-over words the founder has not yet confirmed.
|
|
54
|
+
function handoffMarkdown(plan, { name = '' } = {}) {
|
|
55
|
+
if (!plan || typeof plan !== 'object' || !str(plan.summary)) return '';
|
|
56
|
+
const title = str(name);
|
|
57
|
+
const lines = [
|
|
58
|
+
`# ${title ? `${title}: ` : ''}where this project started`,
|
|
59
|
+
'',
|
|
60
|
+
'Before signing up, the founder talked with the start-a-project guide. This is what came out of that conversation, carried over so nobody asks them the same things again.',
|
|
61
|
+
'',
|
|
62
|
+
'If you are an AI session working on this project: read this first. It is a starting point, not the founder\'s final word. Where the founder has since answered the Genesis questions (`npx bongos genesis context`), their answers win. Confirm anything below with them before relying on it, and never ask them again what is already written here.',
|
|
63
|
+
'',
|
|
64
|
+
'## What the project is',
|
|
65
|
+
'',
|
|
66
|
+
str(plan.summary),
|
|
67
|
+
'',
|
|
68
|
+
];
|
|
69
|
+
const type = PROJECT_TYPE_WORDS[plan.project_type];
|
|
70
|
+
if (type) lines.push(`**Kind of project:** ${type}`, '');
|
|
71
|
+
if (plan.starting_point === 'existing') {
|
|
72
|
+
lines.push('**Starting point:** they already have something.', '');
|
|
73
|
+
const have = list(plan.what_you_have).map(str).filter(Boolean);
|
|
74
|
+
if (have.length) lines.push('What they said they already have:', '', ...have.map((h) => `- ${h}`), '');
|
|
75
|
+
} else if (plan.starting_point === 'fresh') {
|
|
76
|
+
lines.push('**Starting point:** starting fresh.', '');
|
|
77
|
+
}
|
|
78
|
+
const how = list(plan.how_it_works).map(str).filter(Boolean);
|
|
79
|
+
if (how.length) lines.push('## The plan', '', ...how.map((h) => `- ${h}`), '');
|
|
80
|
+
const modules = list(plan.modules).filter((m) => m && str(m.key));
|
|
81
|
+
if (modules.length) {
|
|
82
|
+
lines.push('## Recommended modules', '');
|
|
83
|
+
for (const m of modules) {
|
|
84
|
+
const why = str(m.why);
|
|
85
|
+
lines.push(`- **${str(m.label) || str(m.key)}** (\`${str(m.key)}\`)${str(m.summary) ? `: ${str(m.summary)}` : ''}${why ? ` Why: ${why}` : ''}`);
|
|
86
|
+
}
|
|
87
|
+
lines.push('');
|
|
88
|
+
}
|
|
89
|
+
const steps = list(plan.steps).filter((s) => s && str(s.title));
|
|
90
|
+
if (steps.length) {
|
|
91
|
+
lines.push('## First steps', '');
|
|
92
|
+
steps.forEach((s, i) => lines.push(`${i + 1}. **${str(s.title)}**${str(s.detail) ? ` ${str(s.detail)}` : ''}`));
|
|
93
|
+
lines.push('');
|
|
94
|
+
}
|
|
95
|
+
const needs = list(plan.needs).filter((n) => n && str(n.item));
|
|
96
|
+
if (needs.length) {
|
|
97
|
+
lines.push('## What they will need', '');
|
|
98
|
+
for (const n of needs) lines.push(`- **${str(n.item)}**${str(n.detail) ? `: ${str(n.detail)}` : ''}`);
|
|
99
|
+
lines.push('');
|
|
100
|
+
}
|
|
101
|
+
const open = list(plan.open_questions).map(str).filter(Boolean);
|
|
102
|
+
if (open.length) lines.push('## Still open', '', ...open.map((q) => `- ${q}`), '');
|
|
103
|
+
lines.push('## Your next step', '',
|
|
104
|
+
steps.length
|
|
105
|
+
? `Start with step 1, "${str(steps[0].title)}". Then open the Genesis scope questions with the founder (\`npx bongos genesis show scope\`): only "what are you creating" was carried over, and the rest are theirs to answer.`
|
|
106
|
+
: 'Open the Genesis scope questions with the founder (`npx bongos genesis show scope`): only "what are you creating" was carried over, and the rest are theirs to answer.',
|
|
107
|
+
'');
|
|
108
|
+
const md = lines.join('\n');
|
|
109
|
+
return md.length > MARKDOWN_MAX ? `${md.slice(0, MARKDOWN_MAX - 40).trimEnd()}\n\n(The rest was cut for length.)\n` : md;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// handoffFor(plan, opts) → { scope, markdown } | null — what the provisioning port hands the
|
|
113
|
+
// create route to stamp on a new project.
|
|
114
|
+
function handoffFor(plan, opts = {}) {
|
|
115
|
+
const markdown = handoffMarkdown(plan, opts);
|
|
116
|
+
if (!markdown) return null;
|
|
117
|
+
return { scope: scopeAnswers(plan), markdown };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = { SCOPE_MAP, MARKDOWN_MAX, scopeAnswers, handoffMarkdown, handoffFor };
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// POST /front-door-guide/conversations/:id/plan write (or re-read) the plan { token, website? }
|
|
6
6
|
// POST /front-door-guide/conversations/:id/attach put the chat on my account { token }
|
|
7
7
|
// GET /front-door-guide/mine my newest chat and its plan
|
|
8
|
+
// GET /front-door-guide/mine/handoff.md my plan as the hand-off file, a download (?name=)
|
|
8
9
|
//
|
|
9
10
|
// The plan is ONE structured-output call per chat (a JSON schema, never parsed prose),
|
|
10
11
|
// asked once the visitor has said something; a second request re-reads the stored plan
|
|
@@ -29,6 +30,7 @@ const claude = require('../claude');
|
|
|
29
30
|
const { readSettings } = require('../settings');
|
|
30
31
|
const L = require('../limits');
|
|
31
32
|
const C = require('../context');
|
|
33
|
+
const H = require('../handoff');
|
|
32
34
|
|
|
33
35
|
const log = api.logger('front-door-guide');
|
|
34
36
|
const ID_RE = /^\d{1,18}$/;
|
|
@@ -62,8 +64,19 @@ function mineView(conv, settings) {
|
|
|
62
64
|
};
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
// The `front-door-guide.handoff` port (task 1005274): the signed-in builder's newest attached
|
|
68
|
+
// plan as { scope, markdown }, or null. The hub's create route stamps it on a new project
|
|
69
|
+
// (modules/provisioning/guide-handoff.js), which is how the guide's answers reach a project
|
|
70
|
+
// whose database this process cannot touch. Read-only.
|
|
71
|
+
async function handoffForBuilder(builderId, { name = '' } = {}) {
|
|
72
|
+
if (builderId == null) return null;
|
|
73
|
+
const conv = await db.latestForBuilder(builderId);
|
|
74
|
+
return conv && conv.plan ? H.handoffFor(conv.plan, { name }) : null;
|
|
75
|
+
}
|
|
76
|
+
|
|
65
77
|
module.exports = function buildFrontDoorGuidePlanRouter() {
|
|
66
78
|
const router = express.Router();
|
|
79
|
+
if (!api.hasProvider('front-door-guide.handoff')) api.registerProvider('front-door-guide.handoff', handoffForBuilder);
|
|
67
80
|
let current = readSettings();
|
|
68
81
|
const fresh = (req, res, next) => { current = readSettings(); next(); };
|
|
69
82
|
const planLimit = L.makeLimiter({ windowMs: 60_000, max: () => current.messagesPerMinute, scope: 'front-door-guide-plan' });
|
|
@@ -141,5 +154,16 @@ module.exports = function buildFrontDoorGuidePlanRouter() {
|
|
|
141
154
|
res.json({ ok: true, conversation: conv ? mineView(conv, current) : null });
|
|
142
155
|
}));
|
|
143
156
|
|
|
157
|
+
// rank: builder — my plan as the hand-off file (task 1005274), offered as a download on the
|
|
158
|
+
// creation page. 404 with no plan. The name is only the file's title; it is never stored.
|
|
159
|
+
router.get('/front-door-guide/mine/handoff.md', api.requireBuilder, api.asyncHandler('GET /front-door-guide/mine/handoff.md', async (req, res) => {
|
|
160
|
+
const name = typeof req.query.name === 'string' ? req.query.name.replace(/[\r\n#]/g, ' ').trim().slice(0, 80) : '';
|
|
161
|
+
const h = await handoffForBuilder(req.builder.id, { name });
|
|
162
|
+
if (!h) return res.status(404).json({ ok: false, error: 'no_plan' });
|
|
163
|
+
res.set('Cache-Control', 'no-store');
|
|
164
|
+
res.set('Content-Disposition', 'attachment; filename="PROJECT-HANDOFF.md"');
|
|
165
|
+
res.type('text/markdown; charset=utf-8').send(h.markdown);
|
|
166
|
+
}));
|
|
167
|
+
|
|
144
168
|
return router;
|
|
145
169
|
};
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
93
93
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
94
94
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
95
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
95
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
96
96
|
<script src="/builders/hall-dialog.js"></script>
|
|
97
97
|
<script src="/builders/palette.js" defer></script>
|
|
98
98
|
<script src="/builders/tweak-editor-lib.js?v=2026-09-28-tw23"></script>
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
94
94
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
95
95
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
96
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
96
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
97
97
|
<script src="/builders/hall-dialog.js"></script>
|
|
98
98
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
99
99
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
63
63
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
64
64
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
65
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
65
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
66
66
|
<script src="/builders/hall-dialog.js"></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>
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
65
65
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
66
66
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
67
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
67
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
68
68
|
<script src="/builders/hall-dialog.js"></script>
|
|
69
69
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
70
70
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
<script src="/builders/shell-game.js?v=2026-11-11-view2" defer></script>
|
|
117
117
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers" defer></script>
|
|
118
118
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor" defer></script>
|
|
119
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
119
|
+
<script src="/builders/shell.js?v=2026-11-13-founding" defer></script>
|
|
120
120
|
<script src="/builders/hall-dialog.js" defer></script>
|
|
121
121
|
<!-- task 1005148: the visor (glass over the scene, game mode only; ADR 0399), after the shell and hall-dialog.js -->
|
|
122
122
|
<script src="/builders/visor.js?v=2026-11-11-helm3" defer></script>
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
164
164
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
165
165
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
166
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
166
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
167
167
|
<script src="/builders/hall-dialog.js"></script>
|
|
168
168
|
<script src="/builders/palette.js" defer></script>
|
|
169
169
|
<script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
56
56
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
57
57
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
58
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
58
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
59
59
|
<script src="/builders/hall-dialog.js"></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>
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
182
182
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
183
183
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
184
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
184
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
185
185
|
<script src="/builders/hall-dialog.js"></script>
|
|
186
186
|
<script src="/builders/palette.js" defer></script>
|
|
187
187
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
83
83
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
84
84
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
85
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
85
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
86
86
|
<script src="/builders/hall-dialog.js"></script>
|
|
87
87
|
<script src="/builders/palette.js" defer></script>
|
|
88
88
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -171,9 +171,24 @@
|
|
|
171
171
|
return s.total ? s.finished + ' of ' + s.total + ' done' : 'in progress';
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
// The government district's buildings, by the city's key (city-draw.js CIVIC_SLOTS).
|
|
175
|
+
var BUILDING = {
|
|
176
|
+
charter: 'Charter', release: 'Release', planning: 'Planning', automation: 'Automation', treasury: 'Treasury',
|
|
177
|
+
rules: 'Rules', disputes: 'Disputes', people: 'People', review: 'Review',
|
|
178
|
+
};
|
|
179
|
+
function gainsText(s) {
|
|
180
|
+
var wakes = (s.wakes || []).map(function (id) { return ROOM[id] || id; });
|
|
181
|
+
var raises = (s.raises || []).map(function (k) { return BUILDING[k] || k; });
|
|
182
|
+
var parts = [];
|
|
183
|
+
if (wakes.length) parts.push('Wakes ' + wakes.join(', '));
|
|
184
|
+
if (raises.length) parts.push('raises ' + raises.join(', '));
|
|
185
|
+
if (!wakes.length && s.earns) parts.push(s.earns.charAt(0).toLowerCase() + s.earns.slice(1));
|
|
186
|
+
var line = parts.join(' · ');
|
|
187
|
+
return line ? line.charAt(0).toUpperCase() + line.slice(1) : '';
|
|
188
|
+
}
|
|
189
|
+
|
|
174
190
|
function stagesHtml(g) {
|
|
175
191
|
return '<ol class="genesis__stages">' + g.stages.map(function (s) {
|
|
176
|
-
var wakes = (s.wakes || []).map(function (id) { return ROOM[id] || id; });
|
|
177
192
|
// A demo's stage is minutes long (task 1004506): say how long, and due at a time.
|
|
178
193
|
var due = s.minutes
|
|
179
194
|
? ' · ' + s.minutes + ' min' + (s.state === 'now' && s.due ? ', due ' + new Date(s.due).toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' }) : '')
|
|
@@ -181,7 +196,9 @@
|
|
|
181
196
|
return '<li class="genesis__stage is-' + s.state + '">'
|
|
182
197
|
+ '<span class="genesis__stage-n">0' + s.number + '</span>'
|
|
183
198
|
+ '<span class="genesis__stage-t"><b>' + esc(s.label) + '</b>'
|
|
184
|
-
|
|
199
|
+
// task 1005112: what finishing the stage gives — the rooms it wakes, the district
|
|
200
|
+
// buildings it raises, and for a stage that wakes no room, what it earns.
|
|
201
|
+
+ '<span>' + esc(gainsText(s)) + esc(due) + '</span>'
|
|
185
202
|
+ (s.state === 'later' && s.can_close ? '<span><button type="button" class="btn-ghost" data-genesis-close="' + esc(s.key) + '">Put to the board</button></span>' : '')
|
|
186
203
|
+ '</span>'
|
|
187
204
|
+ '<span class="genesis__stage-st">' + esc(stateText(s)) + '</span></li>';
|
|
@@ -221,13 +238,15 @@
|
|
|
221
238
|
var state = t.state === 'done' || t.state === 'locked' ? t.state : 'open';
|
|
222
239
|
var check = window.OTB.CHECK_SVG || '';
|
|
223
240
|
var mark = '<span class="genesis__mark" aria-hidden="true">' + (state === 'done' ? check : '') + '</span>';
|
|
224
|
-
|
|
241
|
+
// Only the states the status pill does not already say: an open row's pill names its
|
|
242
|
+
// own status, and a second word beside it could disagree with it.
|
|
243
|
+
var said = { done: 'Done: ', locked: 'Locked: ' }[state] || '';
|
|
225
244
|
var after = (t.waits_on || []).map(function (w) { return w.title; }).filter(Boolean);
|
|
226
245
|
var tail = state === 'locked'
|
|
227
246
|
? '<span class="genesis__task-wait">' + esc(after.length ? 'after ' + after.join(', ') : 'after an earlier task') + '</span>'
|
|
228
247
|
: window.OTB.statusPill(t.status, { small: true, extraClass: 'genesis__task-st' }) + copyButtonHtml(t);
|
|
229
248
|
return '<li class="genesis__task is-' + state + '">' + mark
|
|
230
|
-
+ '<span class="sr-only">' + said + '
|
|
249
|
+
+ (said ? '<span class="sr-only">' + said + '</span>' : '')
|
|
231
250
|
+ '<a class="genesis__task-t" href="/task/' + encodeURIComponent(t.id) + '">' + esc(t.title) + '</a>'
|
|
232
251
|
+ tail + '</li>';
|
|
233
252
|
}
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
143
143
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
144
144
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
145
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
145
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
146
146
|
<script src="/builders/hall-dialog.js"></script>
|
|
147
147
|
<!-- task 1005148: the visor (glass over the scene, game mode only; ADR 0399), after the shell and hall-dialog.js -->
|
|
148
148
|
<script src="/builders/visor.js?v=2026-11-11-helm3"></script>
|
|
@@ -254,7 +254,7 @@
|
|
|
254
254
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
255
255
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
256
256
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
257
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
257
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
258
258
|
<script src="/builders/hall-dialog.js"></script>
|
|
259
259
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
260
260
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
159
159
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
160
160
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
161
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
161
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
162
162
|
<script src="/builders/hall-dialog.js"></script>
|
|
163
163
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
164
164
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -172,6 +172,8 @@
|
|
|
172
172
|
return {
|
|
173
173
|
weeks, W, areas, unplaced: all.length - areas.length,
|
|
174
174
|
px: TOWER_PX / tallest, people, sites, waiting, ideas, version,
|
|
175
|
+
// task 1005112: while founding, the district buildings not raised yet (server-decided)
|
|
176
|
+
unbuilt: d.founding && d.founding.unbuilt && typeof d.founding.unbuilt === 'object' ? Object.assign({}, d.founding.unbuilt) : null,
|
|
175
177
|
width: GROUND.w, depth: GROUND.d,
|
|
176
178
|
};
|
|
177
179
|
}
|
|
@@ -362,12 +364,23 @@
|
|
|
362
364
|
const CI = Gov.isoTheme();
|
|
363
365
|
const k = Gov.isoKit(TW, TH, vb.OX, vb.OY, CIVIC_S, CI, true);
|
|
364
366
|
const kids = [face([P(CORE.x0, CORE.y0), P(CORE.x1, CORE.y0), P(CORE.x1, CORE.y1), P(CORE.x0, CORE.y1)], I.plaza, I.plazaLine)];
|
|
367
|
+
const unbuilt = m.unbuilt || {};
|
|
368
|
+
let raised = 0;
|
|
365
369
|
Gov.CIVIC_SLOTS.slice().sort((p, q) => (p[1] + p[2]) - (q[1] + q[2])).forEach((sl) => {
|
|
370
|
+
// task 1005112: a building whose genesis stage is still ahead is a marked-out
|
|
371
|
+
// foundation on the plaza, and rises when that stage is done.
|
|
372
|
+
if (unbuilt[sl[0]]) {
|
|
373
|
+
const x0 = sl[1] - 0.55, y0 = sl[2] - 0.55, w = 1.1;
|
|
374
|
+
kids.push(node('path', { d: pts([P(x0, y0), P(x0 + w, y0), P(x0 + w, y0 + w), P(x0, y0 + w)]), fill: 'none', stroke: I.plazaLine, 'stroke-width': 1, 'stroke-dasharray': '3 3', class: 'hc-face hc-foundation', 'data-building': sl[0] }));
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
raised += 1;
|
|
366
378
|
const list = [];
|
|
367
379
|
Gov.isoInstitution(list, k, sl[0], sl[1] - 0.6, sl[2] - 0.6, {});
|
|
368
380
|
list.forEach((pa) => kids.push(node('path', { d: pa.d, fill: pa.f, stroke: pa.s, 'stroke-width': pa.w, 'stroke-dasharray': pa.dash, 'stroke-linejoin': 'round', class: 'hc-face' })));
|
|
369
381
|
});
|
|
370
|
-
|
|
382
|
+
const told = raised === Gov.CIVIC_SLOTS.length ? 'nine buildings, one for each part of the government' : raised + ' of nine buildings raised so far; each founding stage raises more';
|
|
383
|
+
return node('a', { href: Gov.STREET_HREF || '/street', class: 'hc-door hc-core' + quiet('core'), 'aria-label': 'The government district: ' + told + '. Walk the street.', 'data-tip': 'Government', 'data-tip-body': 'The Cloud Bongos core: ' + told + '. Click to walk the street.' }, kids);
|
|
371
384
|
}
|
|
372
385
|
|
|
373
386
|
// The art museum and its garden, after the Cleveland Museum of Art: a long white
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
55
55
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
56
56
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
57
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
57
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
58
58
|
<script src="/builders/hall-dialog.js"></script>
|
|
59
59
|
<script src="/builders/palette.js" defer></script>
|
|
60
60
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N overlay, so a ref
|
|
@@ -229,7 +229,7 @@
|
|
|
229
229
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
230
230
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
231
231
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
232
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
232
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
233
233
|
<script src="/builders/hall-dialog.js"></script>
|
|
234
234
|
<script src="/builders/palette.js" defer></script>
|
|
235
235
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
<script src="/builders/shell-game.js?v=2026-11-11-view2" defer></script>
|
|
107
107
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers" defer></script>
|
|
108
108
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor" defer></script>
|
|
109
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
109
|
+
<script src="/builders/shell.js?v=2026-11-13-founding" defer></script>
|
|
110
110
|
<script src="/builders/hall-dialog.js" defer></script>
|
|
111
111
|
<!-- task 1005148: the visor (glass over the scene, game mode only; ADR 0399), after the shell and hall-dialog.js -->
|
|
112
112
|
<script src="/builders/visor.js?v=2026-11-12-runner" defer></script>
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
76
76
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
77
77
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
78
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
78
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
79
79
|
<script src="/builders/hall-dialog.js"></script>
|
|
80
80
|
<script src="/builders/palette.js" defer></script>
|
|
81
81
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
45
45
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
46
46
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
47
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
47
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
48
48
|
<script src="/builders/hall-dialog.js"></script>
|
|
49
49
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
50
50
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
187
187
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
188
188
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
189
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
189
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
190
190
|
<script src="/builders/hall-dialog.js"></script>
|
|
191
191
|
<script src="/builders/palette.js" defer></script>
|
|
192
192
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
130
130
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
131
131
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
132
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
132
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
133
133
|
<script src="/builders/hall-dialog.js"></script>
|
|
134
134
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
135
135
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
84
84
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
85
85
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
86
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
86
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
87
87
|
<script src="/builders/hall-dialog.js"></script>
|
|
88
88
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
89
89
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
86
86
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
87
87
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
88
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
88
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
89
89
|
<script src="/builders/hall-dialog.js"></script>
|
|
90
90
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
91
91
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
115
115
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
116
116
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
117
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
117
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
118
118
|
<script src="/builders/hall-dialog.js"></script>
|
|
119
119
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
120
120
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -251,7 +251,7 @@
|
|
|
251
251
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
252
252
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
253
253
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
254
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
254
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
255
255
|
<script src="/builders/hall-dialog.js"></script>
|
|
256
256
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
257
257
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
79
79
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
80
80
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
81
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
81
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
82
82
|
<script src="/builders/hall-dialog.js"></script>
|
|
83
83
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
84
84
|
<script src="/builders/palette.js" defer></script>
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
61
61
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
62
62
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
63
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
63
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
64
64
|
<script src="/builders/hall-dialog.js"></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>
|
|
@@ -420,7 +420,7 @@
|
|
|
420
420
|
<script src="/builders/shell-game.js?v=2026-11-11-view2"></script>
|
|
421
421
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
422
422
|
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
423
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
423
|
+
<script src="/builders/shell.js?v=2026-11-13-founding"></script>
|
|
424
424
|
<script src="/builders/hall-dialog.js"></script>
|
|
425
425
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
426
426
|
<script src="/builders/palette.js" defer></script>
|