@bongos/core 1.17.2 → 1.18.0

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.
Files changed (151) hide show
  1. package/.bongos-core.json +426 -96
  2. package/.devcontainer/healthcheck.sh +0 -0
  3. package/.devcontainer/init-firewall.sh +0 -0
  4. package/.devcontainer/post-create.sh +0 -0
  5. package/GOVERNANCE.md +1 -1
  6. package/README.md +26 -22
  7. package/bin/bongos.js +0 -0
  8. package/clients/bongos-client/README.md +1 -1
  9. package/clients/bongos-client/bongos-client.global.js +2 -0
  10. package/clients/bongos-client/index.cjs +2 -0
  11. package/clients/bongos-client/index.d.ts +4 -2
  12. package/clients/bongos-client/index.mjs +2 -0
  13. package/docker-entrypoint.sh +0 -0
  14. package/docs/adr/0139-platform-history-migration-to-cloudbongos.md +94 -0
  15. package/docs/adr/0140-cloudbongos-standalone-reprovision.md +43 -0
  16. package/docs/adr/README.md +3 -0
  17. package/docs/api/openapi.json +68 -370
  18. package/docs/api-reference.md +7 -18
  19. package/docs/file-map.md +7 -25
  20. package/docs/onboarding/diagrams/05-versioning.mmd +4 -6
  21. package/docs/onboarding/diagrams/assertions.json +5 -9
  22. package/modules/hall-ui/public/builders.js +132 -645
  23. package/modules/hall-ui/public/goal-inbox.js +67 -26
  24. package/modules/hall-ui/public/goals-page.js +102 -177
  25. package/modules/hall-ui/public/goals.css +183 -0
  26. package/modules/hall-ui/public/goals.html +35 -253
  27. package/modules/hall-ui/public/goals.js +7 -2
  28. package/modules/hall-ui/public/hall-kit.js +474 -0
  29. package/modules/hall-ui/public/hall-widgets.js +24 -20
  30. package/modules/hall-ui/public/instances-panel.js +24 -3
  31. package/modules/hall-ui/public/new-project-wizard.js +6 -5
  32. package/modules/hall-ui/public/settings.css +355 -0
  33. package/modules/hall-ui/public/settings.html +86 -414
  34. package/modules/hall-ui/public/settings.js +96 -35
  35. package/modules/hall-ui/public/style.css +156 -0
  36. package/modules/hall-ui/public/watch.css +184 -0
  37. package/modules/hall-ui/public/watch.html +111 -285
  38. package/modules/hall-ui/public/watch.js +59 -21
  39. package/modules/hall-ui/public/work.css +194 -0
  40. package/modules/hall-ui/public/work.html +46 -374
  41. package/modules/hall-ui/public/work.js +137 -102
  42. package/modules/lifecycle/criterion-suggest.js +80 -0
  43. package/modules/lifecycle/db.js +42 -5
  44. package/modules/lifecycle/routes/goals.js +26 -0
  45. package/modules/lifecycle/routes/tasks.js +21 -0
  46. package/package-lock.json +2 -2
  47. package/package.json +1 -1
  48. package/public-landing/create.html +83 -7
  49. package/public-landing/index.html +11 -76
  50. package/scripts/cron/style_guide_audit.sh +0 -0
  51. package/scripts/gds/api.js +0 -0
  52. package/scripts/gds/architect-audit.js +0 -0
  53. package/scripts/gds/audit-authorship.sh +0 -0
  54. package/scripts/gds/audit-replay.sh +0 -0
  55. package/scripts/gds/box.js +0 -0
  56. package/scripts/gds/capture.js +0 -0
  57. package/scripts/gds/conductor-dispatch.js +0 -0
  58. package/scripts/gds/coreB-carve-proof.sh +0 -0
  59. package/scripts/gds/db-backup-nightly.sh +0 -0
  60. package/scripts/gds/db-backup-offsite.sh +0 -0
  61. package/scripts/gds/doctor.js +0 -0
  62. package/scripts/gds/grade-smoke.js +0 -0
  63. package/scripts/gds/hooks/pre-push.js +0 -0
  64. package/scripts/gds/install-git-hooks.js +0 -0
  65. package/scripts/gds/main-audit.js +0 -0
  66. package/scripts/gds/oauth-secret.js +0 -0
  67. package/scripts/gds/onboarding-analyze.js +0 -0
  68. package/scripts/gds/onboarding-ship.js +0 -0
  69. package/scripts/gds/paste-token.js +0 -0
  70. package/scripts/gds/portability-smoke-art.sh +0 -0
  71. package/scripts/gds/portability-smoke-memory.sh +0 -0
  72. package/scripts/gds/provision.js +125 -4
  73. package/scripts/gds/push-main.js +0 -0
  74. package/scripts/gds/render-ideas.js +0 -0
  75. package/scripts/gds/security-baseline-check.sh +0 -0
  76. package/scripts/gds/session.js +0 -0
  77. package/scripts/gds/ship.js +11 -1
  78. package/scripts/gds/smoke-batch-claim.sh +0 -0
  79. package/scripts/gds/smoke-batch-release.sh +0 -0
  80. package/scripts/gds/smoke-box.sh +0 -0
  81. package/scripts/gds/smoke-claim-consistency.sh +0 -0
  82. package/scripts/gds/smoke-dependencies.sh +0 -0
  83. package/scripts/gds/smoke-write.sh +0 -0
  84. package/scripts/hall-preview/README.md +103 -0
  85. package/scripts/hall-preview/fixtures/access-requests.json +20 -0
  86. package/scripts/hall-preview/fixtures/achievements.json +76 -0
  87. package/scripts/hall-preview/fixtures/analytics__builder.json +251 -0
  88. package/scripts/hall-preview/fixtures/audit-log.json +68 -0
  89. package/scripts/hall-preview/fixtures/blockers__detail.json +12 -0
  90. package/scripts/hall-preview/fixtures/box__me.json +5 -0
  91. package/scripts/hall-preview/fixtures/boxes__cost-ledger.json +69 -0
  92. package/scripts/hall-preview/fixtures/builders__active-claims.json +1 -0
  93. package/scripts/hall-preview/fixtures/builders__directory.json +81 -0
  94. package/scripts/hall-preview/fixtures/builders__roster.json +48 -0
  95. package/scripts/hall-preview/fixtures/goals.json +502 -0
  96. package/scripts/hall-preview/fixtures/goals__25.json +96 -0
  97. package/scripts/hall-preview/fixtures/goals__26.json +67 -0
  98. package/scripts/hall-preview/fixtures/goals__3.json +103 -0
  99. package/scripts/hall-preview/fixtures/goals__35.json +49 -0
  100. package/scripts/hall-preview/fixtures/goals__conflicts.json +154 -0
  101. package/scripts/hall-preview/fixtures/goals__detail.json +96 -0
  102. package/scripts/hall-preview/fixtures/goals__inbox.json +5 -0
  103. package/scripts/hall-preview/fixtures/goals__requests.json +3 -0
  104. package/scripts/hall-preview/fixtures/grades__by-builder.json +32 -0
  105. package/scripts/hall-preview/fixtures/inbox.json +330 -0
  106. package/scripts/hall-preview/fixtures/inbox__detail.json +15 -0
  107. package/scripts/hall-preview/fixtures/instance.json +124 -0
  108. package/scripts/hall-preview/fixtures/leaderboard.json +184 -0
  109. package/scripts/hall-preview/fixtures/me.json +476 -0
  110. package/scripts/hall-preview/fixtures/me__art-key__own.json +6 -0
  111. package/scripts/hall-preview/fixtures/me__event-sound-prefs.json +209 -0
  112. package/scripts/hall-preview/fixtures/me__recent-ships.json +304 -0
  113. package/scripts/hall-preview/fixtures/me__render.json +5 -0
  114. package/scripts/hall-preview/fixtures/me__skill-prefs.json +143 -0
  115. package/scripts/hall-preview/fixtures/me__sound-prefs.json +67 -0
  116. package/scripts/hall-preview/fixtures/me__wandering.json +43 -0
  117. package/scripts/hall-preview/fixtures/override-requests.json +15 -0
  118. package/scripts/hall-preview/fixtures/provisioning__fleet.json +1 -0
  119. package/scripts/hall-preview/fixtures/provisioning__fleet__cost-ledger.json +1 -0
  120. package/scripts/hall-preview/fixtures/provisioning__instances.json +1 -0
  121. package/scripts/hall-preview/fixtures/public__analytics__ecosystem.json +516 -0
  122. package/scripts/hall-preview/fixtures/public__bounty-table.json +37 -0
  123. package/scripts/hall-preview/fixtures/public__cost-summary.json +742 -0
  124. package/scripts/hall-preview/fixtures/public__estimation-drift.json +41 -0
  125. package/scripts/hall-preview/fixtures/public__grades.json +50 -0
  126. package/scripts/hall-preview/fixtures/public__progress.json +124 -0
  127. package/scripts/hall-preview/fixtures/public__recent-shipped.json +426 -0
  128. package/scripts/hall-preview/fixtures/public__repo-health.json +160 -0
  129. package/scripts/hall-preview/fixtures/public__repo-info.json +5 -0
  130. package/scripts/hall-preview/fixtures/security__docs.json +10 -0
  131. package/scripts/hall-preview/fixtures/security__reports.json +31 -0
  132. package/scripts/hall-preview/fixtures/sessions__search.json +9 -0
  133. package/scripts/hall-preview/fixtures/tasks.json +2420 -0
  134. package/scripts/hall-preview/fixtures/tasks__claimable.json +2555 -0
  135. package/scripts/hall-preview/fixtures/tasks__detail.json +111 -0
  136. package/scripts/hall-preview/fixtures/tasks__peer-votes__feed.json +330 -0
  137. package/scripts/hall-preview/fixtures/versions.json +89 -0
  138. package/scripts/hall-preview/refresh-fixtures.js +77 -0
  139. package/scripts/hall-preview/server.js +195 -0
  140. package/scripts/migrate.sh +29 -4
  141. package/scripts/migrate_cost_ledger.sh +0 -0
  142. package/scripts/render-diagrams.sh +0 -0
  143. package/scripts/security/dep-audit.js +0 -0
  144. package/scripts/setup-builder.js +0 -0
  145. package/scripts/setup-builder.sh +0 -0
  146. package/scripts/snapshots/maybe-render-on-deploy.sh +0 -0
  147. package/src/bongos/optimizer.js +37 -2
  148. package/src/module-api.js +20 -1
  149. package/tests/criterion_suggest.mjs +106 -0
  150. package/tests/migrate_root_resolution.mjs +97 -0
  151. package/tests/provision.mjs +69 -0
@@ -10,354 +10,10 @@
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
11
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
12
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
- <style>
14
- /* Page-local styles for Settings — components layered on the shared design
15
- system (style.css). Everything derives from the shared tokens so instance
16
- theme packs reskin this page too. */
17
-
18
- /* ---- grouped layout: left sub-nav rail + one visible group (task 1723) ---- */
19
- .settings-layout {
20
- display: grid;
21
- grid-template-columns: 180px minmax(0, 1fr);
22
- gap: 24px;
23
- align-items: start;
24
- }
25
- .settings-layout[hidden] { display: none !important; }
26
- /* Only the active group's sections render. Each grouped element is a direct
27
- child of .settings-groups carrying data-group; a section's own [hidden]
28
- attribute always wins (the !important rule below), so the per-section
29
- reveal logic in settings.js is unchanged. */
30
- .settings-groups > [data-group] { display: none; }
31
- .settings-groups[data-active="account"] > [data-group="account"],
32
- .settings-groups[data-active="devbox"] > [data-group="devbox"],
33
- .settings-groups[data-active="access"] > [data-group="access"],
34
- .settings-groups[data-active="preferences"] > [data-group="preferences"],
35
- .settings-groups[data-active="sound"] > [data-group="sound"],
36
- .settings-groups[data-active="extensions"] > [data-group="extensions"] { display: block; }
37
- .settings-groups > [data-group][hidden] { display: none !important; }
38
-
39
- @media (max-width: 768px) {
40
- /* Collapse to one column; the shared .section-rail ≤768px rules turn the
41
- rail into a sticky horizontal chip strip just under the top bar. */
42
- .settings-layout { grid-template-columns: minmax(0, 1fr); }
43
- }
44
-
45
- .settings-status {
46
- font-size: 13px;
47
- color: var(--ink-soft);
48
- min-height: 1.2em;
49
- margin-top: 8px;
50
- }
51
- .section-note {
52
- color: var(--ink-faint);
53
- font-size: 12.5px;
54
- margin-top: 12px;
55
- }
56
-
57
- /* ---- Voices (per-skill model picker) ---- */
58
- .voices-scroll { /* keep many rows compact within a bounded, scrollable box */ }
59
- .voices-wrap {
60
- max-height: 460px;
61
- overflow-y: auto;
62
- margin-top: 6px;
63
- border: 1px solid var(--border);
64
- border-radius: var(--radius-sm);
65
- }
66
- table.voices {
67
- width: 100%;
68
- border-collapse: collapse;
69
- font-size: 13.5px;
70
- color: var(--ink);
71
- }
72
- table.voices th, table.voices td {
73
- padding: 8px 12px;
74
- text-align: left;
75
- border-bottom: 1px solid var(--rule-soft);
76
- vertical-align: middle;
77
- }
78
- table.voices th {
79
- /* sticks inside .voices-wrap's own scroller, not the window — top:0 is
80
- relative to the wrap, so no --topbar-h offset needed here */
81
- position: sticky;
82
- top: 0;
83
- z-index: 1;
84
- background: var(--surface);
85
- font-size: 11px;
86
- font-weight: 600;
87
- letter-spacing: 0.06em;
88
- text-transform: uppercase;
89
- color: var(--ink-faint);
90
- border-bottom: 1px solid var(--border-strong);
91
- }
92
- table.voices tr:last-child td { border-bottom: none; }
93
- table.voices tbody tr:hover td { background: var(--surface-2); }
94
- .voices__skill code {
95
- font-size: 12.5px;
96
- color: var(--info);
97
- }
98
- .voices__default {
99
- font-size: 12.5px;
100
- color: var(--ink-soft);
101
- }
102
- select.voices__select { min-width: 140px; }
103
- .voices-empty, .craft-empty {
104
- color: var(--ink-faint);
105
- font-style: italic;
106
- font-size: 13px;
107
- padding: 10px 0;
108
- }
109
-
110
- /* ---- Sounds (per-sound on/off toggles) ---- */
111
- .sound-rows { margin-top: 8px; }
112
- .sound-row {
113
- display: flex;
114
- align-items: center;
115
- justify-content: space-between;
116
- gap: 16px;
117
- padding: 11px 0;
118
- border-bottom: 1px solid var(--rule-soft);
119
- }
120
- .sound-row:last-child { border-bottom: none; }
121
- .sound-row__text { min-width: 0; }
122
- .sound-row__label {
123
- font-size: 14px;
124
- color: var(--ink);
125
- font-weight: 600;
126
- }
127
- .sound-row__desc {
128
- font-size: 12.5px;
129
- color: var(--ink-soft);
130
- margin-top: 2px;
131
- }
132
- button.sound-toggle {
133
- font-family: var(--font-body);
134
- font-size: 12.5px;
135
- font-weight: 600;
136
- padding: 5px 16px;
137
- min-width: 72px;
138
- border-radius: 999px;
139
- border: 1px solid var(--border-strong);
140
- background: var(--surface);
141
- color: var(--ink-soft);
142
- cursor: pointer;
143
- flex-shrink: 0;
144
- }
145
- button.sound-toggle[data-on="1"] {
146
- background: var(--accent);
147
- border-color: var(--accent);
148
- color: #fff;
149
- }
150
- button.sound-toggle:disabled { opacity: 0.5; cursor: default; }
151
- .sound-volume {
152
- display: flex;
153
- align-items: center;
154
- gap: 14px;
155
- padding: 4px 0 14px;
156
- border-bottom: 1px solid var(--border);
157
- margin-bottom: 4px;
158
- }
159
- .sound-volume__label {
160
- font-size: 11px;
161
- font-weight: 600;
162
- text-transform: uppercase;
163
- letter-spacing: 0.06em;
164
- color: var(--ink-faint);
165
- flex-shrink: 0;
166
- }
167
- .sound-volume input[type="range"] {
168
- flex: 1;
169
- accent-color: var(--accent);
170
- cursor: pointer;
171
- }
172
- .sound-volume__pct {
173
- font-size: 13px;
174
- color: var(--ink);
175
- min-width: 3.2em;
176
- text-align: right;
177
- font-variant-numeric: tabular-nums;
178
- }
179
-
180
- /* ---- Event sounds (per-event variant dropdowns, task 582) ---- */
181
- .event-sound-rows { margin-top: 8px; }
182
- .event-sound-row {
183
- display: flex;
184
- align-items: center;
185
- justify-content: space-between;
186
- gap: 16px;
187
- padding: 12px 0;
188
- border-bottom: 1px solid var(--rule-soft);
189
- }
190
- .event-sound-row:last-child { border-bottom: none; }
191
- .event-sound-row__text { flex: 1; min-width: 0; }
192
- .event-sound-row__label {
193
- font-size: 14px;
194
- color: var(--ink);
195
- font-weight: 600;
196
- }
197
- .event-sound-row__desc {
198
- font-size: 12.5px;
199
- color: var(--ink-soft);
200
- margin-top: 2px;
201
- }
202
- .event-sound-row__controls {
203
- display: flex;
204
- align-items: center;
205
- gap: 8px;
206
- flex-shrink: 0;
207
- }
208
- .event-sound-select { cursor: pointer; }
209
- .event-sound-preview {
210
- font-family: var(--font-body);
211
- font-size: 12px;
212
- font-weight: 600;
213
- padding: 5px 12px;
214
- border-radius: 999px;
215
- border: 1px solid var(--border-strong);
216
- background: transparent;
217
- color: var(--ink-soft);
218
- cursor: pointer;
219
- }
220
- .event-sound-preview:active { opacity: 0.7; }
221
-
222
- /* ---- Disciplines (preference chips) ---- */
223
- .craft-chips {
224
- display: flex;
225
- flex-wrap: wrap;
226
- gap: 10px;
227
- margin-top: 8px;
228
- }
229
- .craft-chip {
230
- display: inline-flex;
231
- align-items: center;
232
- gap: 8px;
233
- font-size: 13.5px;
234
- color: var(--ink);
235
- background: var(--surface);
236
- border: 1px solid var(--border-strong);
237
- border-radius: 999px;
238
- padding: 7px 14px;
239
- cursor: pointer;
240
- user-select: none;
241
- text-transform: capitalize;
242
- }
243
- .craft-chip:hover { background: var(--surface-2); }
244
- .craft-chip input { cursor: pointer; }
245
- .craft-chip[data-on="1"] {
246
- background: var(--accent);
247
- border-color: var(--accent);
248
- color: #fff;
249
- }
250
- .craft-actions {
251
- display: flex;
252
- align-items: center;
253
- gap: 14px;
254
- margin-top: 16px;
255
- flex-wrap: wrap;
256
- }
257
-
258
- /* ---- Buttons (Save / card actions) ---- */
259
- button.craft-save, .settings-btn {
260
- font-family: var(--font-body);
261
- font-size: 13px;
262
- font-weight: 600;
263
- padding: 7px 16px;
264
- border: 1px solid var(--accent);
265
- background: var(--surface);
266
- color: var(--accent-text);
267
- border-radius: var(--radius-sm);
268
- cursor: pointer;
269
- display: inline-block;
270
- text-decoration: none;
271
- }
272
- button.craft-save:hover:not(:disabled), .settings-btn:hover:not(:disabled) {
273
- background: var(--accent);
274
- color: #fff;
275
- text-decoration: none;
276
- }
277
- button.craft-save:disabled, .settings-btn:disabled { opacity: 0.5; cursor: default; }
278
- /* Discord brand button — keeps its blurple so it's recognisable. */
279
- .settings-btn--discord {
280
- background: #5865F2;
281
- border-color: #4853c4;
282
- color: #fff;
283
- }
284
- .settings-btn--discord:hover { background: #4853c4; color: #fff; }
285
- .settings-btn--quiet {
286
- border-color: var(--border-strong);
287
- color: var(--ink-soft);
288
- }
289
- .settings-btn--quiet:hover:not(:disabled) { background: var(--surface-2); color: var(--ink); }
290
-
291
- /* ---- Display name (single editable field, task 1669) ---- */
292
- .display-name-row {
293
- display: flex;
294
- flex-wrap: wrap;
295
- align-items: center;
296
- gap: 12px;
297
- margin-top: 8px;
298
- }
299
- input.display-name-input {
300
- flex: 1 1 280px;
301
- min-width: 0;
302
- }
303
-
304
- /* ---- Connections + CLI access cards ---- */
305
- .settings-card {
306
- margin-top: 8px;
307
- display: flex;
308
- flex-wrap: wrap;
309
- align-items: center;
310
- gap: 12px;
311
- }
312
- .settings-card__hint { color: var(--ink-soft); font-size: 13px; }
313
- .settings-card__ok { font-weight: 600; color: var(--ok); }
314
- .cli-result { flex-basis: 100%; margin-top: 4px; }
315
- .cli-result pre {
316
- background: var(--bg-deep);
317
- color: var(--ink);
318
- padding: 10px 12px;
319
- border: 1px solid var(--border);
320
- border-radius: var(--radius-sm);
321
- overflow-x: auto;
322
- font-size: 12.5px;
323
- margin: 6px 0;
324
- }
325
-
326
- /* ---- Image key (task 1013) — the "we cover it" / "action needed" banner
327
- uses the shared semantic status tokens. ---- */
328
- .artkey-banner {
329
- border-radius: var(--radius-sm);
330
- padding: 10px 14px;
331
- font-size: 13px;
332
- line-height: 1.45;
333
- border: 1px solid var(--border);
334
- margin-bottom: 10px;
335
- }
336
- .artkey-banner--covered {
337
- background: var(--ok-weak);
338
- border-color: color-mix(in srgb, var(--ok) 45%, var(--border));
339
- color: var(--ok);
340
- }
341
- .artkey-banner--action {
342
- background: var(--warn-weak);
343
- border-color: color-mix(in srgb, var(--warn) 45%, var(--border));
344
- color: var(--warn);
345
- }
346
- .artkey-entry-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; flex-basis: 100%; }
347
- .artkey-input {
348
- flex: 1 1 280px;
349
- min-width: 0;
350
- padding: 7px 10px;
351
- border: 1px solid var(--border-strong);
352
- border-radius: var(--radius-sm);
353
- background: var(--surface);
354
- color: var(--ink);
355
- font-family: ui-monospace, "SF Mono", Menlo, monospace;
356
- font-size: 13px;
357
- }
358
- .artkey-actions { display: flex; gap: 10px; flex-wrap: wrap; }
359
- #artkey-entry { flex-basis: 100%; }
360
- </style>
13
+ <!-- Page-local styles (task 2172) — extracted from the old inline <style>
14
+ block per the hall placement rules; the rail comes from style.css's
15
+ shared .section-rail/.rail-link rules. -->
16
+ <link rel="stylesheet" href="/builders/settings.css">
361
17
  </head>
362
18
  <body data-page="settings" data-page-title="Settings">
363
19
 
@@ -378,19 +34,13 @@
378
34
  <p class="scroll__lede" id="gate-body">You're not signed in yet. Sign in to manage your preferences.</p>
379
35
  </section>
380
36
 
381
- <!-- Grouped layout (task 1723): the sections sit in six groups behind a
382
- left sub-nav rail. settings.js wires the rail clicks + hash deep
383
- links; only the active group's sections display. -->
37
+ <!-- Grouped layout (task 1723 → kit, task 2172): the sections sit in six
38
+ groups behind a left sub-nav rail built by OTBKit.makeSectionRail
39
+ (switch mode). settings.js wires the rail + per-panel anchor deep
40
+ links (/settings#cli, /settings#dev-box, …); only the active group's
41
+ sections display. -->
384
42
  <div class="settings-layout" id="settings-layout">
385
- <nav class="section-rail" id="settings-rail" aria-label="Settings sections">
386
- <a class="rail-link rail-link--active" href="#account" data-group="account">Account</a>
387
- <a class="rail-link" href="#devbox" data-group="devbox">Dev box</a>
388
- <a class="rail-link" href="#access" data-group="access">Access &amp; keys</a>
389
- <a class="rail-link" href="#preferences" data-group="preferences">Preferences</a>
390
- <a class="rail-link" href="#sound" data-group="sound">Sound &amp; voice</a>
391
- <!-- Revealed by settings.js only when a module contributed a panel. -->
392
- <a class="rail-link" href="#extensions" data-group="extensions" id="rail-extensions" hidden>Extensions</a>
393
- </nav>
43
+ <nav class="section-rail" id="settings-rail" aria-label="Settings sections"></nav>
394
44
 
395
45
  <div class="settings-groups" id="settings-groups" data-active="account">
396
46
 
@@ -405,6 +55,28 @@
405
55
  server with your rank role already set — no invite to share or leak.
406
56
  </p>
407
57
  <div class="settings-card" id="discord-card"></div>
58
+ <p class="section-note">Linking opens Discord's consent screen; unlinking applies at once.</p>
59
+ </section>
60
+
61
+ <!-- DISPLAY NAME — the label shown next to your work (task 1669).
62
+ GET/PATCH /api/bongos/me/display-name. Seeded from GitHub at sign-up;
63
+ this is the only place to change it. Stable identity (sign-in,
64
+ attribution) stays the GitHub login — this is just the rendered name. -->
65
+ <section class="scroll" id="display-name-scroll" aria-labelledby="display-name-h" data-group="account" hidden>
66
+ <h2 id="display-name-h" class="scroll__h">Display name</h2>
67
+ <p class="scroll__lede">
68
+ The name shown beside your work — in the roster, the leaderboard,
69
+ and the work feed. Your sign-in and the credit for shipped work stay
70
+ tied to your account, not this label.
71
+ </p>
72
+ <div class="display-name-row">
73
+ <input type="text" class="display-name-input" id="display-name-input"
74
+ maxlength="60" autocomplete="off" spellcheck="false"
75
+ aria-label="Display name" placeholder="Your display name">
76
+ <button type="button" class="craft-save" id="display-name-save">Save</button>
77
+ </div>
78
+ <p class="settings-status" id="display-name-status" role="status" aria-live="polite"></p>
79
+ <p class="section-note">Saves when you press Save; shows everywhere at once.</p>
408
80
  </section>
409
81
 
410
82
  <!-- CRAFT — discipline preferences (GET /me, PATCH /me/disciplines). -->
@@ -419,26 +91,45 @@
419
91
  <button type="button" class="craft-save" id="craft-save">Save</button>
420
92
  <span class="settings-status" id="craft-status" role="status" aria-live="polite"></span>
421
93
  </div>
94
+ <p class="section-note">Saves when you press Save; your next <code>/builder-start</code> reflects it.</p>
422
95
  </section>
423
96
 
424
- <!-- DISPLAY NAME — the label shown next to your work (task 1669).
425
- GET/PATCH /api/bongos/me/display-name. Seeded from GitHub at sign-up;
426
- this is the only place to change it. Stable identity (sign-in,
427
- attribution) stays the GitHub login — this is just the rendered name. -->
428
- <section class="scroll" id="display-name-scroll" aria-labelledby="display-name-h" data-group="account" hidden>
429
- <h2 id="display-name-h" class="scroll__h">Display name</h2>
97
+ <!-- ============ group: access ============ -->
98
+
99
+ <!-- CLI ACCESS — re-issue a CLI bearer from this browser session
100
+ (V3.R91 #401), the UI-first alternative to Device Flow. -->
101
+ <section class="scroll" id="cli-scroll" aria-labelledby="cli-h" data-group="access" hidden>
102
+ <h2 id="cli-h" class="scroll__h">CLI access</h2>
430
103
  <p class="scroll__lede">
431
- The name shown beside your work — in the roster, the leaderboard,
432
- and the work feed. Change it whenever you like; your sign-in and
433
- the credit for shipped work stay tied to your account, not this label.
104
+ Mint a fresh CLI token using this browser session and paste it into
105
+ your terminal — the quick way back in when a <code>/builder-*</code>
106
+ command says your session expired.
434
107
  </p>
435
- <div class="display-name-row">
436
- <input type="text" class="display-name-input" id="display-name-input"
437
- maxlength="60" autocomplete="off" spellcheck="false"
438
- aria-label="Display name" placeholder="Your display name">
439
- <button type="button" class="craft-save" id="display-name-save">Save</button>
108
+ <div class="settings-card">
109
+ <button type="button" class="settings-btn" id="cli-reissue-btn">Re-issue CLI token</button>
110
+ <span class="settings-card__hint">paste it into your terminal — bypasses Device Flow.</span>
111
+ <div id="cli-reissue-result" class="cli-result" hidden></div>
440
112
  </div>
441
- <p class="settings-status" id="display-name-status" role="status" aria-live="polite"></p>
113
+ <p class="section-note">Tokens refresh on use; re-issuing never signs you out anywhere else.</p>
114
+ </section>
115
+
116
+ <!-- IMAGE KEY — per-builder Gemini key (task 1013 / ADR 0073).
117
+ GET/PUT/DELETE /api/bongos/me/art-key/own. Write-only (set/replace/
118
+ remove); the full key is never shown again after save (masked,
119
+ last-4 only). The banner + tone adapt to /me `needs`. id="art-key"
120
+ is the anchor the hall's "Add your key" action + the CLI nudge
121
+ link target — settings.js activates this group for that deep link. -->
122
+ <section class="scroll" id="art-key" aria-labelledby="artkey-h" data-group="access" hidden>
123
+ <h2 id="artkey-h" class="scroll__h">Image-generation key</h2>
124
+ <p class="scroll__lede">
125
+ The art pipeline draws tiles and sprites with Google AI Studio
126
+ (Gemini). Needed only if you generate art — your key, your bill,
127
+ paid only for what you make.
128
+ </p>
129
+ <div class="artkey-banner" id="artkey-banner" hidden></div>
130
+ <div class="settings-card" id="artkey-card"></div>
131
+ <p class="settings-status" id="artkey-status" role="status" aria-live="polite"></p>
132
+ <p class="section-note">Stored encrypted; never shown again after saving — only its last four digits.</p>
442
133
  </section>
443
134
 
444
135
  <!-- ============ group: devbox ============ -->
@@ -451,10 +142,10 @@
451
142
  <h2 id="box-h" class="scroll__h">Your dev box</h2>
452
143
  <p class="scroll__lede">
453
144
  The hosted machine your work runs on. Open it in your browser (the
454
- online terminal) or connect over SSH — whichever you prefer. Closing
455
- the box stops and deletes it; you can start a fresh one anytime.
145
+ online terminal) or connect over SSH — whichever you prefer.
456
146
  </p>
457
147
  <div class="setup__box" id="box-mount"></div>
148
+ <p class="section-note">Actions apply at once. Closing stops and deletes the box; you can start a fresh one anytime.</p>
458
149
  </section>
459
150
 
460
151
  <!-- DEV BOX APP — the desktop switch (#904, ADR 0044). Static download
@@ -484,42 +175,19 @@
484
175
  </p>
485
176
  </section>
486
177
 
487
- <!-- ============ group: access ============ -->
488
-
489
- <!-- CLI ACCESS — re-issue a CLI bearer from this browser session
490
- (V3.R91 #401), the UI-first alternative to Device Flow. -->
491
- <section class="scroll" id="cli-scroll" aria-labelledby="cli-h" data-group="access" hidden>
492
- <h2 id="cli-h" class="scroll__h">CLI access</h2>
178
+ <!-- PAIRING — link out to the dedicated pair page (task 2172): keeps
179
+ the whole dev-box story reachable from this group. -->
180
+ <section class="scroll" id="pairing-scroll" aria-labelledby="pairing-h" data-group="devbox" hidden>
181
+ <h2 id="pairing-h" class="scroll__h">Pair Claude Desktop</h2>
493
182
  <p class="scroll__lede">
494
- Mint a fresh CLI token using this browser session and paste it into
495
- your terminal — the quick way back in when a <code>/builder-*</code>
496
- command says your session expired. Refreshes on use.
183
+ Connect your Claude Desktop to your dev box with a one-time pairing
184
+ code — the guided flow lives on its own page.
497
185
  </p>
498
186
  <div class="settings-card">
499
- <button type="button" class="settings-btn" id="cli-reissue-btn">Re-issue CLI token</button>
500
- <span class="settings-card__hint">paste it into your terminal — bypasses Device Flow.</span>
501
- <div id="cli-reissue-result" class="cli-result" hidden></div>
187
+ <a class="settings-btn" href="/pair">Open the pairing page</a>
502
188
  </div>
503
189
  </section>
504
190
 
505
- <!-- IMAGE KEY — per-builder Gemini key (task 1013 / ADR 0073).
506
- GET/PUT/DELETE /api/bongos/me/art-key/own. Write-only (set/replace/
507
- remove); the full key is never shown again after save (masked,
508
- last-4 only). The banner + tone adapt to /me `needs`. id="art-key"
509
- is the anchor the hall's "Add your key" action + the CLI nudge
510
- link target — settings.js activates this group for that deep link. -->
511
- <section class="scroll" id="art-key" aria-labelledby="artkey-h" data-group="access" hidden>
512
- <h2 id="artkey-h" class="scroll__h">Image-generation key</h2>
513
- <p class="scroll__lede">
514
- The art pipeline draws tiles and sprites with Google AI Studio
515
- (Gemini). Needed only if you generate art — your key, your bill,
516
- paid only for what you make.
517
- </p>
518
- <div class="artkey-banner" id="artkey-banner" hidden></div>
519
- <div class="settings-card" id="artkey-card"></div>
520
- <p class="settings-status" id="artkey-status" role="status" aria-live="polite"></p>
521
- </section>
522
-
523
191
  <!-- ============ group: preferences ============ -->
524
192
 
525
193
  <!-- WANDERING — how readily the agent opens off-task threads (task 1268).
@@ -530,9 +198,8 @@
530
198
  <p class="scroll__lede">
531
199
  How readily Claude opens a <em>new thread</em> of work — a tangent, an
532
200
  investigation, an unprompted suggestion — instead of staying on your
533
- claimed task. Lower keeps it focused; higher makes it a freer thinking
534
- partner. It never limits the work on the task itself. Your rank sets
535
- the starting point; newcomers stay locked low.
201
+ claimed task. It never limits the work on the task itself. Your rank
202
+ sets the starting point; newcomers stay locked low.
536
203
  </p>
537
204
  <div class="sound-rows" id="wander-rows"></div>
538
205
  <p class="settings-status" id="wandering-status" role="status" aria-live="polite"></p>
@@ -548,12 +215,12 @@
548
215
  <p class="scroll__lede">
549
216
  Whether your session cards — what <code>/builder-start</code>, claiming,
550
217
  and shipping show — render as rich in-feed widgets or as plain text.
551
- The widgets are prettier, but Claude must relay their full markup every
552
- time, which spends tokens. Turn them off to save those tokens; nothing
553
- else about the work changes.
218
+ Widgets are prettier but spend tokens; plain text is cheaper with the
219
+ same information.
554
220
  </p>
555
221
  <div class="sound-rows" id="render-rows"></div>
556
222
  <p class="settings-status" id="render-status" role="status" aria-live="polite"></p>
223
+ <p class="section-note">Saves the moment you toggle; applies from your next session.</p>
557
224
  </section>
558
225
 
559
226
  <!-- ============ group: sound ============ -->
@@ -633,8 +300,13 @@
633
300
  <script src="/builders/shell.js?v=2026-07-02-shell1"></script>
634
301
  <!-- shared frontend toolkit (window.OTB) — loaded before consuming IIFEs. -->
635
302
  <script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
303
+ <!-- shared component kit (window.OTBKit) — section rail (task 2166). -->
304
+ <script src="/builders/hall-kit.js"></script>
305
+ <!-- shared record overlay (#/idea|blocker/N) — every hall page carries it; this
306
+ page was the one gap (task 2172). -->
307
+ <script src="/builders/task-detail.js?v=2026-07-03-taskdetail"></script>
636
308
  <!-- #807: shared dev-box panel — loaded before settings.js so OTBBoxPanel exists. -->
637
309
  <script src="/builders/box-panel.js?v=2026-06-14-domutils"></script>
638
- <script src="/builders/settings.js?v=2026-06-28-display-name"></script>
310
+ <script src="/builders/settings.js?v=2026-07-10-regroup"></script>
639
311
  </body>
640
312
  </html>