@bongos/core 1.25.13 → 1.25.14

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 (42) hide show
  1. package/.bongos-core.json +65 -45
  2. package/clients/bongos-client/index.d.ts +2 -2
  3. package/docs/adr/0328-a-hosted-projects-authority-is-its-membership-row-not-its-owner-column.md +1 -1
  4. package/docs/adr/0407-a-project-grant-is-made-by-the-owner-not-witnessed-at-sign-in.md +124 -0
  5. package/docs/adr/README.md +1 -0
  6. package/docs/api/openapi.json +6 -0
  7. package/docs/api-reference.md +2 -2
  8. package/docs/copy-inventory.md +28 -34
  9. package/docs/copy-registry.json +41 -125
  10. package/docs/file-map.md +1 -1
  11. package/docs/module-api-changelog.md +2 -0
  12. package/docs/page-inventory.json +1 -0
  13. package/docs/page-readings.json +3 -3
  14. package/modules/front-door-guide/db.js +13 -5
  15. package/modules/front-door-guide/guide.js +8 -2
  16. package/modules/front-door-guide/migrations/front_door_guide_003_starting_point.sql +12 -0
  17. package/modules/front-door-guide/module.json +2 -2
  18. package/modules/front-door-guide/plan.js +15 -6
  19. package/modules/front-door-guide/routes/front-door-guide-plan.js +3 -2
  20. package/modules/front-door-guide/routes/front-door-guide.js +17 -4
  21. package/modules/front-door-guide/starting-point.js +55 -0
  22. package/modules/hall-ui/public/genesis-home.js +29 -2
  23. package/modules/hall-ui/public/goals-page.js +3 -29
  24. package/modules/hall-ui/public/index.html +2 -1
  25. package/modules/hall-ui/public/task-lib.js +45 -0
  26. package/modules/hall-ui/public/work.js +3 -47
  27. package/modules/lifecycle/kickoff-seed.js +9 -5
  28. package/modules/onboarding/genesis-home.js +1 -1
  29. package/package-lock.json +306 -3
  30. package/package.json +4 -2
  31. package/release-notes.json +18 -0
  32. package/scripts/bongos/package-core.js +4 -2
  33. package/src/bongos/module-scope-map.js +1 -0
  34. package/src/module-api.js +1 -1
  35. package/tests/cutover_codemod.mjs +1 -1
  36. package/tests/front_door_guide_db.mjs +6 -1
  37. package/tests/front_door_guide_existing.mjs +238 -0
  38. package/tests/genesis_home.mjs +80 -2
  39. package/tests/package_core.mjs +11 -7
  40. package/tests/pruned_lockfile_integrity.mjs +4 -2
  41. package/tests/status_page_no_dead_uptime.mjs +1 -1
  42. package/tests/task_lib.mjs +46 -0
@@ -641,54 +641,10 @@
641
641
  async function copyPromptForTask(taskId, btn) {
642
642
  const t = taskState.all.find((x) => String(x.id) === String(taskId));
643
643
  if (!t) return;
644
- const prompt = buildPromptForTask(t);
645
- const icon = btn.querySelector('.task__copy-icon');
646
- const label = btn.querySelector('.task__copy-label');
647
- try {
648
- await navigator.clipboard.writeText(prompt);
649
- btn.dataset.copied = '1';
650
- if (icon) icon.textContent = '✓';
651
- if (label) label.textContent = 'Copied';
652
- setTimeout(() => {
653
- btn.dataset.copied = '0';
654
- if (icon) icon.textContent = '📋';
655
- if (label) label.textContent = 'Copy prompt';
656
- }, 1600);
657
- toast(`Prompt for #${taskId} copied to your clipboard.`);
658
- } catch (err) {
659
- try {
660
- const ta = document.createElement('textarea');
661
- ta.value = prompt;
662
- ta.style.position = 'fixed';
663
- ta.style.opacity = '0';
664
- document.body.appendChild(ta);
665
- ta.select();
666
- document.execCommand('copy');
667
- ta.remove();
668
- toast(`Prompt for #${taskId} copied.`);
669
- } catch (_) {
670
- toast('Could not copy to the clipboard. Try again.');
671
- }
672
- }
673
- }
674
- async function copyText(text) {
675
- try { await navigator.clipboard.writeText(text); return true; }
676
- catch (_) {
677
- try {
678
- const ta = document.createElement('textarea');
679
- ta.value = text;
680
- ta.style.position = 'fixed';
681
- ta.style.opacity = '0';
682
- document.body.appendChild(ta);
683
- ta.select();
684
- const ok = document.execCommand('copy');
685
- ta.remove();
686
- return ok;
687
- } catch (_e) {
688
- return false;
689
- }
690
- }
644
+ await window.OTBTaskLib.copyTaskPrompt(t, btn, toast);
691
645
  }
646
+ // The hall's one clipboard write (task-lib.js), kept under this name for the ctx below.
647
+ const copyText = (text) => window.OTBTaskLib.copyText(text);
692
648
 
693
649
  // ---- bulk selection (task 1759) -------------------------------------------
694
650
 
@@ -112,20 +112,24 @@ async function seedGenesisStages({ builderId = null, existing = false } = {}, de
112
112
  return { seeded, versionId };
113
113
  }
114
114
 
115
- // genesisStageTasks(deps) → { stageKey: [{ id, title, status }] } for every genesis
116
- // task on the board, grouped by the stage its source_ref names. The genesis home lists
117
- // them, and a stage close hands their ids to the Board Room's finished-tasks gate.
115
+ // genesisStageTasks(deps) → { stageKey: [{ id, title, status, description }] } for every
116
+ // genesis task on the board, grouped by the stage its source_ref names. The genesis home
117
+ // lists them, and a stage close hands their ids to the Board Room's finished-tasks gate.
118
+ // The description rides along so each row's Copy prompt carries the task's own words
119
+ // (task 1005109); the read stays bounded, it is only the few seeded genesis tasks.
118
120
  async function genesisStageTasks(deps = {}) {
119
121
  const pool = deps.pool || api.pool;
120
122
  const { rows } = await pool.query(
121
- `SELECT id, title, status, source_ref FROM tasks WHERE source = $1 ORDER BY id ASC`,
123
+ `SELECT id, title, status, description, source_ref FROM tasks WHERE source = $1 ORDER BY id ASC`,
122
124
  [GENESIS_SOURCE],
123
125
  );
124
126
  const out = {};
125
127
  for (const r of rows) {
126
128
  const stage = String(r.source_ref || '').split(':')[1];
127
129
  if (!stage) continue;
128
- (out[stage] = out[stage] || []).push({ id: String(r.id), title: r.title, status: r.status });
130
+ (out[stage] = out[stage] || []).push({
131
+ id: String(r.id), title: r.title, status: r.status, description: r.description || '',
132
+ });
129
133
  }
130
134
  return out;
131
135
  }
@@ -146,7 +146,7 @@ const FINISHED = Object.freeze(['shipped', 'abandoned']); // the Board Room's ow
146
146
  // shapeGenesis({ mode, plan, tasks, board, stageAt }) — PURE. The genesis home's view.
147
147
  // mode foundingModeFor's shape (non-null)
148
148
  // plan the saved plan or null (deciding)
149
- // tasks { stage: [{ id, title, status }] }
149
+ // tasks { stage: [{ id, title, status, description }] }
150
150
  // board { stage: genesisStageStatus row } or {}
151
151
  // stageAt { stage: ISO } — when each stage began, for its due date
152
152
  function shapeGenesis({ mode, plan, tasks = {}, board = {}, stageAt = {} }) {
package/package-lock.json CHANGED
@@ -1,16 +1,232 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.25.13",
3
+ "version": "1.25.14",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.25.13",
9
+ "version": "1.25.14",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
13
- "pg": "^8.20.0"
13
+ "pg": "^8.20.0",
14
+ "pino": "^9.14.0",
15
+ "@simplewebauthn/browser": "^13.3.0",
16
+ "@simplewebauthn/server": "^13.3.3"
17
+ }
18
+ },
19
+ "node_modules/@hexagon/base64": {
20
+ "version": "1.1.28",
21
+ "resolved": "https://registry.npmjs.org/@hexagon/base64/-/base64-1.1.28.tgz",
22
+ "integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==",
23
+ "license": "MIT"
24
+ },
25
+ "node_modules/@levischuck/tiny-cbor": {
26
+ "version": "0.2.11",
27
+ "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.2.11.tgz",
28
+ "integrity": "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==",
29
+ "license": "MIT"
30
+ },
31
+ "node_modules/@peculiar/asn1-android": {
32
+ "version": "2.11.0",
33
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.11.0.tgz",
34
+ "integrity": "sha512-llW/qjavL+tOxt5i9whUv4wsbsLpUwI6k/DrvKsdA/H7A/TB/6CosMFgvei28fcJ8ncD0c5lig1oBBlo4KGMCw==",
35
+ "license": "MIT",
36
+ "dependencies": {
37
+ "@peculiar/asn1-schema": "^2.11.0",
38
+ "asn1js": "^3.0.10",
39
+ "tslib": "^2.8.1"
40
+ },
41
+ "engines": {
42
+ "node": ">=14"
43
+ }
44
+ },
45
+ "node_modules/@peculiar/asn1-cms": {
46
+ "version": "2.11.0",
47
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.11.0.tgz",
48
+ "integrity": "sha512-SlAiDoT/Cd8qaNmbTt78gqyaEvu2fQd6ML6KWJkdjXGrgDKnHHrusVkfQUelkfinL2p665IIADb0JBixtT8W1g==",
49
+ "license": "MIT",
50
+ "dependencies": {
51
+ "@peculiar/asn1-schema": "^2.11.0",
52
+ "@peculiar/asn1-x509": "^2.11.0",
53
+ "@peculiar/asn1-x509-attr": "^2.11.0",
54
+ "asn1js": "^3.0.10",
55
+ "tslib": "^2.8.1"
56
+ },
57
+ "engines": {
58
+ "node": ">=14"
59
+ }
60
+ },
61
+ "node_modules/@peculiar/asn1-csr": {
62
+ "version": "2.11.0",
63
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.11.0.tgz",
64
+ "integrity": "sha512-M/ED0yJ05qMK+UADPKnIa8vhAeewOJALSxTAZB7RQ/batRHhIJZkwznCcWAbFO5saHJ1yEQ+m4lncEcG9RnQSg==",
65
+ "license": "MIT",
66
+ "dependencies": {
67
+ "@peculiar/asn1-schema": "^2.11.0",
68
+ "@peculiar/asn1-x509": "^2.11.0",
69
+ "asn1js": "^3.0.10",
70
+ "tslib": "^2.8.1"
71
+ },
72
+ "engines": {
73
+ "node": ">=14"
74
+ }
75
+ },
76
+ "node_modules/@peculiar/asn1-ecc": {
77
+ "version": "2.11.0",
78
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.11.0.tgz",
79
+ "integrity": "sha512-jj1alGEKev7/un+cI+exyVK9m31lmP7cCBMCZuCb0wkFQH2zmKmJzNiG4wqXFNzlcP8timHLnzf3lV3OxBpb/Q==",
80
+ "license": "MIT",
81
+ "dependencies": {
82
+ "@peculiar/asn1-schema": "^2.11.0",
83
+ "@peculiar/asn1-x509": "^2.11.0",
84
+ "asn1js": "^3.0.10",
85
+ "tslib": "^2.8.1"
86
+ },
87
+ "engines": {
88
+ "node": ">=14"
89
+ }
90
+ },
91
+ "node_modules/@peculiar/asn1-pfx": {
92
+ "version": "2.11.0",
93
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.11.0.tgz",
94
+ "integrity": "sha512-ykSAWRu8KkmzU8LRpk9ZQC3zuLmBEtoSMjIv9XHVamD5W7amqreV5wttKqnvtjWOzzSJQxA/HVT8/tHwpEEGSQ==",
95
+ "license": "MIT",
96
+ "dependencies": {
97
+ "@peculiar/asn1-cms": "^2.11.0",
98
+ "@peculiar/asn1-pkcs8": "^2.11.0",
99
+ "@peculiar/asn1-rsa": "^2.11.0",
100
+ "@peculiar/asn1-schema": "^2.11.0",
101
+ "asn1js": "^3.0.10",
102
+ "tslib": "^2.8.1"
103
+ },
104
+ "engines": {
105
+ "node": ">=14"
106
+ }
107
+ },
108
+ "node_modules/@peculiar/asn1-pkcs8": {
109
+ "version": "2.11.0",
110
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.11.0.tgz",
111
+ "integrity": "sha512-lragjkjQGnQ5luxC+sxoAfAO/jBiQ7hOEGlDKJUk7MC5zY3AzjB2DU0GyPUH1Sswdv10t7DurY0zylOYMLb88w==",
112
+ "license": "MIT",
113
+ "dependencies": {
114
+ "@peculiar/asn1-schema": "^2.11.0",
115
+ "@peculiar/asn1-x509": "^2.11.0",
116
+ "asn1js": "^3.0.10",
117
+ "tslib": "^2.8.1"
118
+ },
119
+ "engines": {
120
+ "node": ">=14"
121
+ }
122
+ },
123
+ "node_modules/@peculiar/asn1-pkcs9": {
124
+ "version": "2.11.0",
125
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.11.0.tgz",
126
+ "integrity": "sha512-gDdFjpqV0weJjgNUvueUVf4D8uVbpq+VbG0TsxLAY2QGljAkJyL9qwQ7avol9j0jaYSJ7Ey7v7RZp0M3GTcQSA==",
127
+ "license": "MIT",
128
+ "dependencies": {
129
+ "@peculiar/asn1-cms": "^2.11.0",
130
+ "@peculiar/asn1-pfx": "^2.11.0",
131
+ "@peculiar/asn1-pkcs8": "^2.11.0",
132
+ "@peculiar/asn1-schema": "^2.11.0",
133
+ "@peculiar/asn1-x509": "^2.11.0",
134
+ "@peculiar/asn1-x509-attr": "^2.11.0",
135
+ "asn1js": "^3.0.10",
136
+ "tslib": "^2.8.1"
137
+ },
138
+ "engines": {
139
+ "node": ">=14"
140
+ }
141
+ },
142
+ "node_modules/@peculiar/asn1-rsa": {
143
+ "version": "2.11.0",
144
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.11.0.tgz",
145
+ "integrity": "sha512-S2sBJmbfI09Kzdt9cEhE6pDNjHpVTkURs+811+PxS8AvsTLxC4woMNRhxHYaIbClkkNfAVt0tZxJdINVfUmzuA==",
146
+ "license": "MIT",
147
+ "dependencies": {
148
+ "@peculiar/asn1-schema": "^2.11.0",
149
+ "@peculiar/asn1-x509": "^2.11.0",
150
+ "asn1js": "^3.0.10",
151
+ "tslib": "^2.8.1"
152
+ },
153
+ "engines": {
154
+ "node": ">=14"
155
+ }
156
+ },
157
+ "node_modules/@peculiar/asn1-schema": {
158
+ "version": "2.11.0",
159
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.11.0.tgz",
160
+ "integrity": "sha512-8xh4avo53/vXO6UEv9yaoJ83hY581geaLTygf61NPIXP5AeIZCPjJhpTaYU23IZkG+NpLN/C9FYzWp7hphIT9A==",
161
+ "license": "MIT",
162
+ "dependencies": {
163
+ "@peculiar/utils": "^2.0.2",
164
+ "asn1js": "^3.0.10",
165
+ "tslib": "^2.8.1"
166
+ },
167
+ "engines": {
168
+ "node": ">=14"
169
+ }
170
+ },
171
+ "node_modules/@peculiar/asn1-x509": {
172
+ "version": "2.11.0",
173
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.11.0.tgz",
174
+ "integrity": "sha512-J1sHAwGNlk+8J+FeR1eLVc6Gq0T9f9ITc3HWyPYgJraoW6U8AJuQiWVJ3SCEpltfTdpOY7fHdHT5oKAsbK/jww==",
175
+ "license": "MIT",
176
+ "dependencies": {
177
+ "@peculiar/asn1-schema": "^2.11.0",
178
+ "@peculiar/utils": "^2.0.2",
179
+ "asn1js": "^3.0.10",
180
+ "tslib": "^2.8.1"
181
+ },
182
+ "engines": {
183
+ "node": ">=14"
184
+ }
185
+ },
186
+ "node_modules/@peculiar/asn1-x509-attr": {
187
+ "version": "2.11.0",
188
+ "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.11.0.tgz",
189
+ "integrity": "sha512-Fgvnd9REmLxEj/4cbDP54dNUNUXkzUksXLqEHqs1mHBuSRjSTCUSPM/WQIZYSvrdG7ND9CX1AQtPoIBekhgQSA==",
190
+ "license": "MIT",
191
+ "dependencies": {
192
+ "@peculiar/asn1-schema": "^2.11.0",
193
+ "@peculiar/asn1-x509": "^2.11.0",
194
+ "asn1js": "^3.0.10",
195
+ "tslib": "^2.8.1"
196
+ },
197
+ "engines": {
198
+ "node": ">=14"
199
+ }
200
+ },
201
+ "node_modules/@peculiar/utils": {
202
+ "version": "2.0.3",
203
+ "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz",
204
+ "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==",
205
+ "license": "MIT",
206
+ "dependencies": {
207
+ "tslib": "^2.8.1"
208
+ }
209
+ },
210
+ "node_modules/@peculiar/x509": {
211
+ "version": "1.14.3",
212
+ "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz",
213
+ "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==",
214
+ "license": "MIT",
215
+ "dependencies": {
216
+ "@peculiar/asn1-cms": "^2.6.0",
217
+ "@peculiar/asn1-csr": "^2.6.0",
218
+ "@peculiar/asn1-ecc": "^2.6.0",
219
+ "@peculiar/asn1-pkcs9": "^2.6.0",
220
+ "@peculiar/asn1-rsa": "^2.6.0",
221
+ "@peculiar/asn1-schema": "^2.6.0",
222
+ "@peculiar/asn1-x509": "^2.6.0",
223
+ "pvtsutils": "^1.3.6",
224
+ "reflect-metadata": "^0.2.2",
225
+ "tslib": "^2.8.1",
226
+ "tsyringe": "^4.10.0"
227
+ },
228
+ "engines": {
229
+ "node": ">=20.0.0"
14
230
  }
15
231
  },
16
232
  "node_modules/@pinojs/redact": {
@@ -19,6 +235,31 @@
19
235
  "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==",
20
236
  "license": "MIT"
21
237
  },
238
+ "node_modules/@simplewebauthn/browser": {
239
+ "version": "13.3.0",
240
+ "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.3.0.tgz",
241
+ "integrity": "sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ==",
242
+ "license": "MIT"
243
+ },
244
+ "node_modules/@simplewebauthn/server": {
245
+ "version": "13.3.3",
246
+ "resolved": "https://registry.npmjs.org/@simplewebauthn/server/-/server-13.3.3.tgz",
247
+ "integrity": "sha512-LelX/lcy5cjc15A86i/aNxHhB5eU7dd20QsbP0VLAf9e38+SLlsnqCCyecx3xqfGofhmX05h1J9fKRYWxw+luA==",
248
+ "license": "MIT",
249
+ "dependencies": {
250
+ "@hexagon/base64": "^1.1.27",
251
+ "@levischuck/tiny-cbor": "^0.2.2",
252
+ "@peculiar/asn1-android": "^2.6.0",
253
+ "@peculiar/asn1-ecc": "^2.6.1",
254
+ "@peculiar/asn1-rsa": "^2.6.1",
255
+ "@peculiar/asn1-schema": "^2.6.0",
256
+ "@peculiar/asn1-x509": "^2.6.1",
257
+ "@peculiar/x509": "^1.14.3"
258
+ },
259
+ "engines": {
260
+ "node": ">=20.0.0"
261
+ }
262
+ },
22
263
  "node_modules/accepts": {
23
264
  "version": "1.3.8",
24
265
  "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -38,6 +279,20 @@
38
279
  "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
39
280
  "license": "MIT"
40
281
  },
282
+ "node_modules/asn1js": {
283
+ "version": "3.0.10",
284
+ "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz",
285
+ "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==",
286
+ "license": "BSD-3-Clause",
287
+ "dependencies": {
288
+ "pvtsutils": "^1.3.6",
289
+ "pvutils": "^1.1.5",
290
+ "tslib": "^2.8.1"
291
+ },
292
+ "engines": {
293
+ "node": ">=12.0.0"
294
+ }
295
+ },
41
296
  "node_modules/atomic-sleep": {
42
297
  "version": "1.0.0",
43
298
  "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
@@ -804,6 +1059,24 @@
804
1059
  "url": "https://opencollective.com/express"
805
1060
  }
806
1061
  },
1062
+ "node_modules/pvtsutils": {
1063
+ "version": "1.3.6",
1064
+ "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz",
1065
+ "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==",
1066
+ "license": "MIT",
1067
+ "dependencies": {
1068
+ "tslib": "^2.8.1"
1069
+ }
1070
+ },
1071
+ "node_modules/pvutils": {
1072
+ "version": "1.2.0",
1073
+ "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.2.0.tgz",
1074
+ "integrity": "sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==",
1075
+ "license": "MIT",
1076
+ "engines": {
1077
+ "node": ">=16.0.0"
1078
+ }
1079
+ },
807
1080
  "node_modules/qs": {
808
1081
  "version": "6.15.2",
809
1082
  "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
@@ -858,6 +1131,12 @@
858
1131
  "node": ">= 12.13.0"
859
1132
  }
860
1133
  },
1134
+ "node_modules/reflect-metadata": {
1135
+ "version": "0.2.2",
1136
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
1137
+ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
1138
+ "license": "Apache-2.0"
1139
+ },
861
1140
  "node_modules/safe-buffer": {
862
1141
  "version": "5.2.1",
863
1142
  "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1061,6 +1340,30 @@
1061
1340
  "node": ">=0.6"
1062
1341
  }
1063
1342
  },
1343
+ "node_modules/tslib": {
1344
+ "version": "2.8.1",
1345
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1346
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1347
+ "license": "0BSD"
1348
+ },
1349
+ "node_modules/tsyringe": {
1350
+ "version": "4.10.0",
1351
+ "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz",
1352
+ "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==",
1353
+ "license": "MIT",
1354
+ "dependencies": {
1355
+ "tslib": "^1.9.3"
1356
+ },
1357
+ "engines": {
1358
+ "node": ">= 6.0.0"
1359
+ }
1360
+ },
1361
+ "node_modules/tsyringe/node_modules/tslib": {
1362
+ "version": "1.14.1",
1363
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
1364
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
1365
+ "license": "0BSD"
1366
+ },
1064
1367
  "node_modules/type-is": {
1065
1368
  "version": "1.6.18",
1066
1369
  "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.25.13",
3
+ "version": "1.25.14",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -25,7 +25,9 @@
25
25
  "dependencies": {
26
26
  "express": "^4.21.2",
27
27
  "pg": "^8.20.0",
28
- "pino": "^9.14.0"
28
+ "pino": "^9.14.0",
29
+ "@simplewebauthn/browser": "^13.3.0",
30
+ "@simplewebauthn/server": "^13.3.3"
29
31
  },
30
32
  "overrides": {
31
33
  "undici": "^6.29.1"
@@ -11788,5 +11788,23 @@
11788
11788
  "id": "1005273",
11789
11789
  "text": "The project guide now ends with a written plan (with recommended features drawn only from what Bongos really offers), saves the chat so visitors can come back to it, moves it onto their account when they sign up, and deletes i"
11790
11790
  }
11791
+ ],
11792
+ "1.25.14": [
11793
+ {
11794
+ "id": "1004753",
11795
+ "text": "Designed how a project owner can give a teammate access to help run their hosted project, without letting anyone who merely signs in act on it."
11796
+ },
11797
+ {
11798
+ "id": "1005109",
11799
+ "text": "Founders setting up a new project can now copy each setup task's prompt straight from the Genesis page, without opening the task."
11800
+ },
11801
+ {
11802
+ "id": "1005269",
11803
+ "text": "Adding a security card works again on sites that install Bongos as a package: the card libraries are now included in the released core."
11804
+ },
11805
+ {
11806
+ "id": "1005279",
11807
+ "text": "The project guide now asks whether you are starting fresh or already have something, and for an existing project plans from your own description, without ever reading your files or code."
11808
+ }
11791
11809
  ]
11792
11810
  }
@@ -288,7 +288,9 @@ function isNpmStripped(pathRel) {
288
288
  // published core without it crashes MODULE_NOT_FOUND at startup (task 1003160).
289
289
  // discord.js (+ its undici requirement) is an OPTIONAL MODULE dependency, not
290
290
  // core; a consumer that enables the discord module installs it itself.
291
- const CORE_DEP_NAMES = ['express', 'pg', 'pino'];
291
+ // The security-card libraries joined in task 1005269: routes/my-passkeys.js serves the browser bundle
292
+ // and requires the server lib, and a package without them answers bundle_missing on every instance.
293
+ const CORE_DEP_NAMES = ['express', 'pg', 'pino', '@simplewebauthn/browser', '@simplewebauthn/server'];
292
294
 
293
295
  // Pure — takes the source package.json's `dependencies`/`overrides` as plain
294
296
  // objects so this is unit-testable with no disk I/O. Throws if a required core
@@ -928,7 +930,7 @@ function main() {
928
930
  const sourcePkgLock = JSON.parse(pkgLockRaw.toString('utf8'));
929
931
  const corePkgJson = buildPackageJson({ version, sourceDeps: sourcePkgJson.dependencies, sourceOverrides: sourcePkgJson.overrides });
930
932
  const corePkgLock = prunePackageLock(sourcePkgLock, {
931
- name: corePkgJson.name, version, rootRanges: { express: corePkgJson.dependencies.express, pg: corePkgJson.dependencies.pg },
933
+ name: corePkgJson.name, version, rootRanges: { ...corePkgJson.dependencies },
932
934
  });
933
935
  console.error(`[package-core] synthesized package.json (${Object.keys(corePkgJson.dependencies).join(', ')}) + pruned package-lock.json (${Object.keys(corePkgLock.packages).length - 1} of ${Object.keys(sourcePkgLock.packages).length - 1} locked packages kept).`);
934
936
 
@@ -191,6 +191,7 @@ const MODULE_GLOBS = {
191
191
  'front-door-guide': [
192
192
  'modules/front-door-guide/', 'tests/front_door_guide.mjs',
193
193
  'tests/front_door_guide_plan.mjs', 'tests/front_door_guide_db.mjs',
194
+ 'tests/front_door_guide_existing.mjs',
194
195
  ],
195
196
  // The /raise investor page (task 1004847, ADR 0384): hub-only.
196
197
  raise: [
package/src/module-api.js CHANGED
@@ -81,7 +81,7 @@ const { sleep } = require('./sleep');
81
81
  // MAJOR (see allowBoxScope below): passes the request through untouched.
82
82
  function deprecatedNoopMiddleware(_req, _res, next) { next(); }
83
83
 
84
- const CORE_VERSION = '1.25.13'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
84
+ const CORE_VERSION = '1.25.14'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
85
85
 
86
86
  // A namespaced logger so a module's log lines are attributable + consistent.
87
87
  // Usage: const log = api.logger('discord'); log.info('mounted');
@@ -183,7 +183,7 @@ t('planCodemod rewrites host files, skips core files, reports unmapped', () => {
183
183
 
184
184
  t('every CORE_INTERNAL_MAP target is exported by the core package (a rewrite never outruns an export)', () => {
185
185
  const { buildPackageJson } = require('../scripts/bongos/package-core.js');
186
- const pkg = buildPackageJson({ version: '0.0.0-test', sourceDeps: { express: '^4.0.0', pg: '^8.0.0', pino: '^9.0.0' } });
186
+ const pkg = buildPackageJson({ version: '0.0.0-test', sourceDeps: { express: '^4.0.0', pg: '^8.0.0', pino: '^9.0.0', '@simplewebauthn/browser': '^13.0.0', '@simplewebauthn/server': '^13.0.0' } });
187
187
  for (const mapped of Object.values(CORE_INTERNAL_MAP)) {
188
188
  assert.ok(pkg.exports[`./${mapped}`], `@bongos/core must export ./${mapped} (targeted by the codemod)`);
189
189
  }
@@ -25,6 +25,7 @@ const db = require('../modules/front-door-guide/db.js');
25
25
  const sql = (n) => readFileSync(new URL(`../modules/front-door-guide/migrations/${n}`, import.meta.url), 'utf8');
26
26
  const M1 = sql('front_door_guide_001_conversations.sql');
27
27
  const M2 = sql('front_door_guide_002_plan_and_account.sql');
28
+ const M3 = sql('front_door_guide_003_starting_point.sql');
28
29
 
29
30
  const pool = new Pool({ connectionString: process.env.DATABASE_URL || undefined });
30
31
  try {
@@ -48,7 +49,7 @@ async function cleanup() {
48
49
  const call = (over = {}) => ({ visitorHash: V, model: 'claude-opus-5-5', inputTokens: 800, outputTokens: 200, cacheReadTokens: 0, cacheWriteTokens: 0, costMicro: 9000, stopReason: 'end_turn', ...over });
49
50
 
50
51
  try {
51
- for (const m of [M1, M2, M1, M2]) await x(m); // applies, then re-applies as a no-op
52
+ for (const m of [M1, M2, M3, M1, M2, M3]) await x(m); // applies, then re-applies as a no-op
52
53
  await cleanup();
53
54
  await insertTestBuilders(pool, [{ id: ALICE, login: 't1005273-alice' }, { id: BOB, login: 't1005273-bob' }]);
54
55
 
@@ -99,6 +100,10 @@ try {
99
100
  assert.equal(await db.siteSpendMicro('day', x), before, 'the budgets still count the deleted chat\'s money');
100
101
  assert.ok(before >= dayBefore + 9000 + 20000 + 1 + 5 + 7000);
101
102
 
103
+ // The starting point (task 1005279): set, read back, and nothing else accepted.
104
+ assert.equal((await db.setStartingPoint(conv.id, 'existing', x)).starting_point, 'existing');
105
+ await assert.rejects(x(`UPDATE front_door_guide_conversations SET starting_point = 'repo' WHERE id = $1`, [conv.id]));
106
+
102
107
  // Refusals the schema owns.
103
108
  await assert.rejects(x(`INSERT INTO front_door_guide_calls (visitor_hash, model, cost_micro, kind) VALUES ($1, 'm', 1, 'other')`, [V]));
104
109
  await assert.rejects(x(`INSERT INTO front_door_guide_calls (visitor_hash, model, cost_micro) VALUES ($1, 'm', -1)`, [V]));