@bongos/core 1.19.529 → 1.19.531

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 CHANGED
@@ -2,22 +2,22 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.529",
6
- "core_contract": "1.19.529",
7
- "source_commit": "80d814daa7174fe0e760966095ee9339a29d7d1d",
5
+ "core_version": "1.19.531",
6
+ "core_contract": "1.19.531",
7
+ "source_commit": "9044e13dacbf2160d02eef08915ffa74dbc669be",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-04T13:17:35.687Z",
9
+ "built_at": "2026-09-04T13:41:13.821Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 435,
13
13
  "agent_docs_stubbed": 24,
14
- "functional_verbatim": 1976,
14
+ "functional_verbatim": 1979,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 2435,
20
- "tree_sha256": "a029bcb3e7adddef9f33b68cd23f96158ebb345a0b1a60e28dc8f2553809d595",
19
+ "file_count": 2438,
20
+ "tree_sha256": "0d93f09e833a982f219a54f124fe11808be718651cd93d5258119ef9e50a7954",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -1767,12 +1767,12 @@
1767
1767
  {
1768
1768
  "path": "docs/copy-inventory.md",
1769
1769
  "mode": "0000644",
1770
- "sha256": "42f1210b3c422d2b05b719c38eabfb3ed25ed31988a757394dfc2caed045ee36"
1770
+ "sha256": "729633c41036ec0026d3ef1ac787f68cb6fb7ab77e3eb578f855b5ec2d63280f"
1771
1771
  },
1772
1772
  {
1773
1773
  "path": "docs/copy-registry.json",
1774
1774
  "mode": "0000644",
1775
- "sha256": "0d9a040a9bac5670b2034e98479d86706070853dbb65b799d770b76e488534a6"
1775
+ "sha256": "344a451940b630b1f6db2f97acb45eb387616311675b243dcc4381dc604ef77d"
1776
1776
  },
1777
1777
  {
1778
1778
  "path": "docs/design/apex-pass-2-direction.md",
@@ -2617,7 +2617,7 @@
2617
2617
  {
2618
2618
  "path": "docs/module-api-changelog.md",
2619
2619
  "mode": "0000644",
2620
- "sha256": "8a6ba922b7918d974e9374510472ce2a67c28790e60875b36efe7ceccda84e2f"
2620
+ "sha256": "fa1785c5b0009ea7431a5fcf3fd13dcb5b65563c481e8d417d62c2eea6050af6"
2621
2621
  },
2622
2622
  {
2623
2623
  "path": "docs/modules-contract.md",
@@ -6064,10 +6064,15 @@
6064
6064
  "mode": "0000644",
6065
6065
  "sha256": "4c933aad1307378496d47960e24c9d797a1f122f28aefa27b769f336e4cf2e75"
6066
6066
  },
6067
+ {
6068
+ "path": "modules/provisioning/routes/callback-page.js",
6069
+ "mode": "0000644",
6070
+ "sha256": "6b43ebf71a778277b94de1b9400f690fac9f51b48010e50a159af57195f99f02"
6071
+ },
6067
6072
  {
6068
6073
  "path": "modules/provisioning/routes/provisioning.js",
6069
6074
  "mode": "0000644",
6070
- "sha256": "69ec9994c833b54466fa0e83a3aa2c09eada6b0aefadf73e6eb50b085996aaa6"
6075
+ "sha256": "e08199bc9146bd3122ca038637a0e390b9f5e636a102fa290dba414cf6cafdc1"
6071
6076
  },
6072
6077
  {
6073
6078
  "path": "modules/provisioning/starter-bundles.js",
@@ -6882,12 +6887,12 @@
6882
6887
  {
6883
6888
  "path": "modules/status-ui/public/explore.html",
6884
6889
  "mode": "0000644",
6885
- "sha256": "e80fc1d5f44667f82761c9732433d1b38f074321024f493be0f74d9c037973ff"
6890
+ "sha256": "7bdde42ca7bc23acaabf1966c928c6d0816e29677c243f82175a0e20bd995c07"
6886
6891
  },
6887
6892
  {
6888
6893
  "path": "modules/status-ui/public/explore.js",
6889
6894
  "mode": "0000644",
6890
- "sha256": "48769902093fa8d7d68ee38ee799eef70a2ac3190242886428fd635bf2a6e9ce"
6895
+ "sha256": "a6311740e338d81cdeb9d5ce38733bd1dd4d978a6a5399c4f103017daf6f5cf2"
6891
6896
  },
6892
6897
  {
6893
6898
  "path": "modules/status-ui/public/index.html",
@@ -7327,12 +7332,12 @@
7327
7332
  {
7328
7333
  "path": "package-lock.json",
7329
7334
  "mode": "0000644",
7330
- "sha256": "43ac8c190119cd19cbd7884c854dd616d4dce8947f9435367acbf04c3058d7b1"
7335
+ "sha256": "03ecbc56365c6b70ada0bdfd2ca666962f3ed8edcf95ef52acf93f2d0b82de51"
7331
7336
  },
7332
7337
  {
7333
7338
  "path": "package.json",
7334
7339
  "mode": "0000644",
7335
- "sha256": "9baba915b700faa5eda5733b68bffd4aaeaa54b5a3076502440c39a944944f3d"
7340
+ "sha256": "0eaf9886acaf585da2ecc97408dcb6f879a801ff20cead40a20bac221e8ea32f"
7336
7341
  },
7337
7342
  {
7338
7343
  "path": "public-docs/index.html",
@@ -9012,7 +9017,7 @@
9012
9017
  {
9013
9018
  "path": "src/module-api.js",
9014
9019
  "mode": "0000644",
9015
- "sha256": "532e7d3dc98b5ff136f1cb7484232b17f2f3c750dad15315493224b2619ef78f"
9020
+ "sha256": "a534c8a215f1f744707ef9835905ac2850c991757a76545f77a191f8c3827e7b"
9016
9021
  },
9017
9022
  {
9018
9023
  "path": "src/module-loader/catalog.js",
@@ -9752,7 +9757,7 @@
9752
9757
  {
9753
9758
  "path": "tests/design_tokens_sync.mjs",
9754
9759
  "mode": "0000644",
9755
- "sha256": "0454ee692bbbf19d02c7f19c029f4da5a4dd939b84c4d67ebb713d12de179c2a"
9760
+ "sha256": "6fc1f0a595d3042b5b57b708643cfdc18007b3b33bb6684ffbeb46217da4c376"
9756
9761
  },
9757
9762
  {
9758
9763
  "path": "tests/dev_lib.mjs",
@@ -9929,6 +9934,11 @@
9929
9934
  "mode": "0000644",
9930
9935
  "sha256": "d6a78357533fdeea3bc33fe97cfcd27b1d04747c600d0a7800ddfca5199dbb1f"
9931
9936
  },
9937
+ {
9938
+ "path": "tests/explore_visible_states.mjs",
9939
+ "mode": "0000644",
9940
+ "sha256": "015588572bf3c75c1af00b3bb591f133dff7e604be1f9b40272f1f963b24bf71"
9941
+ },
9932
9942
  {
9933
9943
  "path": "tests/extract_json.mjs",
9934
9944
  "mode": "0000644",
@@ -11274,6 +11284,11 @@
11274
11284
  "mode": "0000644",
11275
11285
  "sha256": "9a04386b3047177bb55b6d392db88764f06f92e5c0b20c16ed9e0f8ce520b07d"
11276
11286
  },
11287
+ {
11288
+ "path": "tests/provisioning_callback_page.mjs",
11289
+ "mode": "0000644",
11290
+ "sha256": "74d53ae7f3c93883bdc6db5187c904cc6c641267233d70bfef1a25d5b2a4ca05"
11291
+ },
11277
11292
  {
11278
11293
  "path": "tests/provisioning_default_domain.mjs",
11279
11294
  "mode": "0000644",
@@ -11292,7 +11307,7 @@
11292
11307
  {
11293
11308
  "path": "tests/provisioning_module_selection.mjs",
11294
11309
  "mode": "0000644",
11295
- "sha256": "48fc7c59efae4b7d1b9ab565882473483d7b4d8a40635583a789d0749da16578"
11310
+ "sha256": "4a27e1641d949f261a8ba1b72816a8b077fc8a55862c4eef4091b453b7cfd45c"
11296
11311
  },
11297
11312
  {
11298
11313
  "path": "tests/provisioning_onboard_mode.mjs",
@@ -4,14 +4,14 @@
4
4
  > Deterministic on a given tree — regenerate and commit rather than hand-editing.
5
5
  > Machine-readable twin: [`copy-registry.json`](copy-registry.json).
6
6
 
7
- **1645 strings** across 3 surfaces · 1427 distinct pieces of copy · 1645 certain, 0 heuristic · 154 shown in more than one place.
7
+ **1647 strings** across 3 surfaces · 1429 distinct pieces of copy · 1647 certain, 0 heuristic · 154 shown in more than one place.
8
8
 
9
9
  ## Surfaces
10
10
 
11
11
  | surface | lives at | files | strings |
12
12
  |---|---|---|---|
13
13
  | `builders-hall` | `modules/hall-ui/public` | 73 | 1187 |
14
- | `status-dashboard` | `modules/status-ui/public` | 4 | 98 |
14
+ | `status-dashboard` | `modules/status-ui/public` | 4 | 100 |
15
15
  | `landing` | `modules/public-landing/public` | 5 | 360 |
16
16
 
17
17
  ## Confidence, and why it is on every row
@@ -1270,7 +1270,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1270
1270
  | `7e1bb38d4777` | certain | 🔒 Request to join | `modules/hall-ui/public/goals-render.js:861` |
1271
1271
  | `cce9c199e874` | certain | 🛡 Archon-mediated | `modules/hall-ui/public/goals-render.js:803` |
1272
1272
 
1273
- ## `status-dashboard` — 98 strings
1273
+ ## `status-dashboard` — 100 strings
1274
1274
 
1275
1275
  | id | conf | text | where |
1276
1276
  |---|---|---|---|
@@ -1278,6 +1278,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1278
1278
  | `c5fbe5ea4335` | certain | , a third-party logistics house in Cleveland, Ohio. | `modules/status-ui/public/index.html:355` |
1279
1279
  | `2045078fb115` | certain | 90 days ago | `modules/status-ui/public/status.js:477` |
1280
1280
  | `e4848e2d9386` | certain | A new portrait is set down each time the city's stones are reshaped. Scroll to see how {{worldName}} has grown | `modules/status-ui/public/index.html:344` |
1281
+ | `390faeaffb47` | certain | A project | `modules/status-ui/public/explore.js:71` |
1281
1282
  | `f4a664041da5` | certain | A shipping container has washed ashore upon the coast south of Athens. About it a new civilization rises. Set | `modules/status-ui/public/index.html:126` |
1282
1283
  | `623d6b7ae6b7` | certain | A true-to-life portrait of {{worldName}} as she stands today, rendered from the city's own stones. | `modules/status-ui/public/index.html:332` |
1283
1284
  | `155d14ab692a` | certain | All categories | `modules/status-ui/public/index.html:280` |
@@ -1290,11 +1291,10 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1290
1291
  | `c8959bdc0e59` | certain | Breakdown filtered to {…}: {…} of {…} ({…}% of all spend). | `modules/status-ui/public/status.js:659` |
1291
1292
  | `1fe8937399f5` | certain | By order of the Senate | `modules/status-ui/public/index.html:354` |
1292
1293
  | `21f644463d57` | certain | Citizens who have set the most stone. | `modules/status-ui/public/index.html:201` |
1293
- | `87af953708b3` | certain | Couldn't load projects right now. | `modules/status-ui/public/explore.html:56` |
1294
+ | `87af953708b3` | certain | Couldn't load projects right now. | `modules/status-ui/public/explore.html:109` |
1294
1295
  | `3aa071ef1142` | certain | Cross into the city → | `modules/status-ui/public/index.html:128` |
1295
- | `f70f217504ce` | certain | Explore — featured projects | `modules/status-ui/public/explore.html:6` |
1296
- | `f70f217504ce` | certain | Explore — featured projects | `modules/status-ui/public/explore.html:6` |
1297
- | `4db99e47bc50` | certain | Featured projects built on the platform. | `modules/status-ui/public/explore.html:52` |
1296
+ | `f151456aedc1` | certain | Explore — projects on the map | `modules/status-ui/public/explore.html:6` |
1297
+ | `f151456aedc1` | certain | Explore — projects on the map | `modules/status-ui/public/explore.html:6` |
1298
1298
  | `14d6b38bc659` | certain | Filter inscriptions by date range | `modules/status-ui/public/index.html:309` |
1299
1299
  | `194f07002413` | certain | Filter spend by category | `modules/status-ui/public/index.html:279` |
1300
1300
  | `183993d780be` | certain | Filter spend by source | `modules/status-ui/public/index.html:273` |
@@ -1315,15 +1315,17 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
1315
1315
  | `37b171a6195a` | certain | No architects yet — be the first to lay a stone. | `modules/status-ui/public/index.html:205` |
1316
1316
  | `7816fbe0add8` | certain | No builders yet — be the first. | `modules/status-ui/public/status.js:1117` |
1317
1317
  | `0b097f051d6f` | certain | No endeavors underway just now. | `modules/status-ui/public/status.js:516` |
1318
- | `837af36041de` | certain | No featured projects yet — check back soon. | `modules/status-ui/public/explore.html:55` |
1318
+ | `ed9b06f79234` | certain | No projects on the map yet — check back soon. | `modules/status-ui/public/explore.html:108` |
1319
1319
  | `4b1a11bfdf10` | certain | No works yet inscribed in this window. | `modules/status-ui/public/status.js:947` |
1320
1320
  | `7a8afe641683` | certain | No works yet inscribed. | `modules/status-ui/public/index.html:318` |
1321
1321
  | `3e8205a358d9` | certain | No {…} yet attributed to a hand. | `modules/status-ui/public/status.js:746` |
1322
1322
  | `c9efa62c36e7` | certain | No {…} yet spent. | `modules/status-ui/public/status.js:684` |
1323
1323
  | `2df94faddc8c` | certain | Not enough shipped works yet to draw the curve. | `modules/status-ui/public/index.html:224` |
1324
1324
  | `9d8692476139` | certain | Previous page | `modules/status-ui/public/index.html:321` |
1325
+ | `f1b103f87df2` | certain | Projects on the map, and how each one stands on it. | `modules/status-ui/public/explore.html:105` |
1325
1326
  | `48473324e839` | certain | Sections of the ledger | `modules/status-ui/public/index.html:144` |
1326
1327
  | `81cb441627b8` | certain | Show history of earlier portraits | `modules/status-ui/public/index.html:342` |
1328
+ | `abd2ce869517` | certain | Something is here. Its name, and everything else about it, stay with its owner. | `modules/status-ui/public/explore.js:74` |
1327
1329
  | `0cc023b5f470` | certain | Split by hand — {{currency}} spent by each builder at the workshop. | `modules/status-ui/public/index.html:295` |
1328
1330
  | `fddc39dcf1eb` | certain | Tablet being consulted… | `modules/status-ui/public/index.html:130` |
1329
1331
  | `8f86e1c9ad44` | certain | Text size | `modules/status-ui/public/index.html:18` |
@@ -3,9 +3,9 @@
3
3
  "generator": "scripts/gds/copy-inventory.js",
4
4
  "goal": 1000074,
5
5
  "counts": {
6
- "strings": 1645,
7
- "unique_ids": 1427,
8
- "certain": 1645,
6
+ "strings": 1647,
7
+ "unique_ids": 1429,
8
+ "certain": 1647,
9
9
  "heuristic": 0,
10
10
  "duplicate_ids": 154
11
11
  },
@@ -18,7 +18,7 @@
18
18
  "status-dashboard": {
19
19
  "at": "modules/status-ui/public",
20
20
  "files": 4,
21
- "strings": 98
21
+ "strings": 100
22
22
  },
23
23
  "landing": {
24
24
  "at": "modules/public-landing/public",
@@ -693,9 +693,9 @@
693
693
  ]
694
694
  },
695
695
  {
696
- "id": "f70f217504ce",
696
+ "id": "f151456aedc1",
697
697
  "surface": "status-dashboard",
698
- "text": "Explore — featured projects",
698
+ "text": "Explore — projects on the map",
699
699
  "occurrences": 2,
700
700
  "at": [
701
701
  "modules/status-ui/public/explore.html:6",
@@ -15603,6 +15603,15 @@
15603
15603
  "origin": "html-text",
15604
15604
  "confidence": "certain"
15605
15605
  },
15606
+ {
15607
+ "id": "390faeaffb47",
15608
+ "surface": "status-dashboard",
15609
+ "text": "A project",
15610
+ "file": "modules/status-ui/public/explore.js",
15611
+ "line": 71,
15612
+ "origin": "js-text-assign",
15613
+ "confidence": "certain"
15614
+ },
15606
15615
  {
15607
15616
  "id": "f4a664041da5",
15608
15617
  "surface": "status-dashboard",
@@ -15716,7 +15725,7 @@
15716
15725
  "surface": "status-dashboard",
15717
15726
  "text": "Couldn't load projects right now.",
15718
15727
  "file": "modules/status-ui/public/explore.html",
15719
- "line": 56,
15728
+ "line": 109,
15720
15729
  "origin": "html-text",
15721
15730
  "confidence": "certain"
15722
15731
  },
@@ -15730,32 +15739,23 @@
15730
15739
  "confidence": "certain"
15731
15740
  },
15732
15741
  {
15733
- "id": "f70f217504ce",
15742
+ "id": "f151456aedc1",
15734
15743
  "surface": "status-dashboard",
15735
- "text": "Explore — featured projects",
15744
+ "text": "Explore — projects on the map",
15736
15745
  "file": "modules/status-ui/public/explore.html",
15737
15746
  "line": 6,
15738
15747
  "origin": "html-text",
15739
15748
  "confidence": "certain"
15740
15749
  },
15741
15750
  {
15742
- "id": "f70f217504ce",
15751
+ "id": "f151456aedc1",
15743
15752
  "surface": "status-dashboard",
15744
- "text": "Explore — featured projects",
15753
+ "text": "Explore — projects on the map",
15745
15754
  "file": "modules/status-ui/public/explore.html",
15746
15755
  "line": 6,
15747
15756
  "origin": "html-title",
15748
15757
  "confidence": "certain"
15749
15758
  },
15750
- {
15751
- "id": "4db99e47bc50",
15752
- "surface": "status-dashboard",
15753
- "text": "Featured projects built on the platform.",
15754
- "file": "modules/status-ui/public/explore.html",
15755
- "line": 52,
15756
- "origin": "html-text",
15757
- "confidence": "certain"
15758
- },
15759
15759
  {
15760
15760
  "id": "14d6b38bc659",
15761
15761
  "surface": "status-dashboard",
@@ -15937,11 +15937,11 @@
15937
15937
  "confidence": "certain"
15938
15938
  },
15939
15939
  {
15940
- "id": "837af36041de",
15940
+ "id": "ed9b06f79234",
15941
15941
  "surface": "status-dashboard",
15942
- "text": "No featured projects yet — check back soon.",
15942
+ "text": "No projects on the map yet — check back soon.",
15943
15943
  "file": "modules/status-ui/public/explore.html",
15944
- "line": 55,
15944
+ "line": 108,
15945
15945
  "origin": "html-text",
15946
15946
  "confidence": "certain"
15947
15947
  },
@@ -15999,6 +15999,15 @@
15999
15999
  "origin": "html-attr:aria-label",
16000
16000
  "confidence": "certain"
16001
16001
  },
16002
+ {
16003
+ "id": "f1b103f87df2",
16004
+ "surface": "status-dashboard",
16005
+ "text": "Projects on the map, and how each one stands on it.",
16006
+ "file": "modules/status-ui/public/explore.html",
16007
+ "line": 105,
16008
+ "origin": "html-text",
16009
+ "confidence": "certain"
16010
+ },
16002
16011
  {
16003
16012
  "id": "48473324e839",
16004
16013
  "surface": "status-dashboard",
@@ -16017,6 +16026,15 @@
16017
16026
  "origin": "html-text",
16018
16027
  "confidence": "certain"
16019
16028
  },
16029
+ {
16030
+ "id": "abd2ce869517",
16031
+ "surface": "status-dashboard",
16032
+ "text": "Something is here. Its name, and everything else about it, stay with its owner.",
16033
+ "file": "modules/status-ui/public/explore.js",
16034
+ "line": 74,
16035
+ "origin": "js-text-assign",
16036
+ "confidence": "certain"
16037
+ },
16020
16038
  {
16021
16039
  "id": "0cc023b5f470",
16022
16040
  "surface": "status-dashboard",
@@ -1495,5 +1495,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
1495
1495
  landed since 1.19.527 with no explicit bump. run 33829339717. (task 1002620)
1496
1496
  1.19.529 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1497
1497
  landed since 1.19.528 with no explicit bump. run 33877197857. (task 1002620)
1498
+ 1.19.530 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1499
+ landed since 1.19.529 with no explicit bump. run 33878817005. (task 1002620)
1500
+ 1.19.531 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1501
+ landed since 1.19.530 with no explicit bump. run 33879403011. (task 1002620)
1498
1502
  ---------------------------------------------------------------------------
1499
1503
  ```
@@ -0,0 +1,159 @@
1
+ // modules/provisioning/routes/callback-page.js — the standalone HTML the public
2
+ // GitHub-App-Manifest redirect lands on (task 1003570; the page itself is task 2096).
3
+ //
4
+ // WHY. This is pure PRESENTATION for exactly one route — `GET /provisioning/
5
+ // github-app/callback` in routes/provisioning.js — and it is ~135 lines of escaper,
6
+ // palette, stylesheet, client script and template with no request, DB or auth logic
7
+ // in it. Carrying it inside the route file pushed that file onto the 1500-line
8
+ // OVERSIZE_LINES fitness ratchet (scripts/gds/fitness-ratchets.js), where the next
9
+ // single added line failed `unit` and the only obvious escape — raising the baseline
10
+ // — is the one thing the ratchet forbids (ADR 0243 §4/§5 for the argument that put
11
+ // it there). Moved here verbatim so the route file has room to change again.
12
+ //
13
+ // Reaches core ONLY through the doorway src/module-api.js (the one-way rule, ADR
14
+ // 0083); it is required by routes/provisioning.js and by nothing else.
15
+ //
16
+ // Shape: no DB, no network, no request object — given a plain options bag it returns
17
+ // a string. `esc` and `callbackPage` are the whole surface; PAGE_STYLE and
18
+ // CALLBACK_SCRIPT stay private because they are only ever this page's own body.
19
+ 'use strict';
20
+
21
+ const api = require('../../../src/module-api');
22
+
23
+ // Minimal HTML escaper for the callback landing page (no template engine here).
24
+ function esc(s) {
25
+ return String(s == null ? '' : s).replace(/[&<>"']/g, (c) => (
26
+ { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]
27
+ ));
28
+ }
29
+
30
+ // Accent pair resolved from the instance's own branding — the pack is the palette
31
+ // authority (task 1002810); the literal fallbacks are the neutral pack's values, so
32
+ // a branding validation error still paints the current family, never a stale one.
33
+ const ACCENT = (() => {
34
+ try {
35
+ const c = api.branding().theme?.ui?.colors || {};
36
+ return { sun: c.accent || '#fb9569', sun600: c.accentDeep || '#a3481a' };
37
+ } catch { return { sun: '#fb9569', sun600: '#a3481a' }; }
38
+ })();
39
+
40
+ // Brand styling for the standalone onboarding pages — sunrise palette + Baloo 2 /
41
+ // Quicksand (accents from the branding pack, config/branding.neutral.json resolved
42
+ // under the instance's own config/branding.json). Light + dark aware; no external
43
+ // dependency beyond an optional Google-Fonts link (system fallback if it doesn't load).
44
+ const PAGE_STYLE = `
45
+ :root{color-scheme:light dark;--sun:${ACCENT.sun};--sun600:${ACCENT.sun600};--sunInk:#2a1305;--coral:#fb7185;--sky:#38bdf8;--sky600:#0284c7;--ok:#16a34a;--warn:#f59e0b;--ink:#2a1f17;--inkSoft:#6b5d52;--card:#fffdfa;--line:#f0e2cf;--bg1:#fde8c8;--bg2:#fff4e6;--bg3:#fffdfa}
46
+ @media (prefers-color-scheme:dark){:root{--ink:#f5efe6;--inkSoft:#cbbdad;--card:#241b13;--line:#3a2c1e;--bg1:#2a1d10;--bg2:#1b130b;--bg3:#130d07}}
47
+ *{box-sizing:border-box}html,body{height:100%}
48
+ body{margin:0;font-family:"Quicksand",system-ui,-apple-system,"Segoe UI",sans-serif;color:var(--ink);background:linear-gradient(180deg,var(--bg1) 0%,var(--bg2) 45%,var(--bg3) 100%);background-attachment:fixed;display:flex;align-items:center;justify-content:center;padding:1.5rem;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
49
+ .card{width:100%;max-width:30rem;background:var(--card);border:1px solid var(--line);border-radius:20px;padding:2.4rem 2rem 2rem;text-align:center;box-shadow:0 18px 50px -22px rgba(120,60,10,.4),0 2px 8px rgba(120,60,10,.07)}
50
+ .badge-warn{font-size:2.4rem;line-height:1;margin:0 auto 1rem}
51
+ h1{font-family:"Baloo 2",system-ui,sans-serif;font-weight:700;font-size:1.5rem;line-height:1.15;margin:.2rem 0 .55rem}
52
+ .sub{color:var(--inkSoft);font-size:1.02rem;line-height:1.5;margin:0 auto;max-width:24rem}
53
+ .sub p{margin:.6rem 0}
54
+ code{font-family:"Fira Code",ui-monospace,SFMono-Regular,monospace;background:rgba(56,189,248,.14);color:var(--sky600);padding:.12em .45em;border-radius:6px;font-size:.9em;overflow-wrap:anywhere}
55
+ @media (prefers-color-scheme:dark){code{color:var(--sky)}}
56
+ .steps{display:flex;align-items:flex-start;justify-content:center;margin:1.9rem 0 1.1rem}
57
+ .step{flex:1 1 0;max-width:9rem;position:relative}
58
+ .step::before{content:"";position:absolute;top:16px;left:-50%;width:100%;height:3px;background:var(--line);z-index:0;transition:background .4s ease}
59
+ .step:first-child::before{display:none}
60
+ .dot{width:34px;height:34px;border-radius:50%;margin:0 auto;display:grid;place-items:center;background:var(--bg3);border:2px solid var(--line);color:var(--inkSoft);font-weight:700;font-size:.95rem;position:relative;z-index:1;transition:all .4s ease}
61
+ .lbl{margin-top:.55rem;font-size:.78rem;color:var(--inkSoft);font-weight:600;line-height:1.25;padding:0 .2rem}
62
+ .step.done .dot{background:var(--ok);border-color:var(--ok);color:#fff}
63
+ .step.done::before{background:var(--ok)}
64
+ .step.active .dot{border-color:var(--sun);color:var(--sun600);animation:pulse 1.5s ease-in-out infinite}
65
+ .step.active .lbl{color:var(--ink)}
66
+ .step.active .dot::after{content:"";position:absolute;inset:-3px;border-radius:50%;border:2px solid transparent;border-top-color:var(--sun);animation:spin .8s linear infinite}
67
+ @keyframes spin{to{transform:rotate(360deg)}}
68
+ @keyframes pulse{0%,100%{box-shadow:0 0 0 4px rgba(249,115,22,.15)}50%{box-shadow:0 0 0 9px rgba(249,115,22,.04)}}
69
+ @media (prefers-reduced-motion:reduce){.step.active .dot,.step.active .dot::after{animation:none}}
70
+ .status-line{min-height:1.4em;color:var(--inkSoft);font-size:.94rem;margin:.4rem auto 0;max-width:24rem;line-height:1.45}
71
+ .cta{margin-top:1.4rem}
72
+ .btn{display:inline-block;background:var(--sun);color:var(--sunInk);text-decoration:none;font-weight:700;font-family:"Baloo 2",system-ui,sans-serif;padding:.72rem 1.5rem;border-radius:999px;font-size:1.02rem;box-shadow:0 10px 22px -8px rgba(249,115,22,.7);transition:transform .15s ease,box-shadow .15s ease}
73
+ .btn:hover{transform:translateY(-1px);box-shadow:0 14px 28px -8px rgba(249,115,22,.8)}
74
+ .muted{color:var(--inkSoft);opacity:.9;font-size:.85rem;margin:1.1rem auto 0;max-width:24rem;line-height:1.45}
75
+ .hidden{display:none!important}
76
+ `;
77
+
78
+ // Client script for the PROGRESS variant only (task 2096): poll the public status
79
+ // endpoint, advance the stepper, and auto-open the instance the moment its credentials
80
+ // land. Deliberately contains NO backticks and NO ${...} so it survives the outer
81
+ // template literal verbatim; the only server data it reads is the JSON config block
82
+ // written just above it. Fails soft — a poll hiccup just retries; a long wait reveals a
83
+ // manual "open" button rather than ever falsely erroring. The auto-open countdown runs
84
+ // ONLY when this page is the wizard's pop-up; a same-tab return (pop-up blocked) keeps
85
+ // the founder here with the door and a way back to the checklist (task 1003236).
86
+ const CALLBACK_SCRIPT = `
87
+ (function(){
88
+ var cfg=window.__CB_SETUP__||{};
89
+ var state=cfg.state||'',domain=cfg.domain||'';
90
+ if(!state||!domain)return;
91
+ var target='https://'+domain;
92
+ var pollUrl=location.pathname.replace('/callback','/status')+'?state='+encodeURIComponent(state);
93
+ var steps=document.getElementById('steps'),statusEl=document.getElementById('status');
94
+ var cta=document.getElementById('cta'),go=document.getElementById('go'),foot=document.getElementById('foot'),back=document.getElementById('back');
95
+ /* Opened from the wizard as a pop-up (window.opener alive, or the tab still carries the name the wizard gave it):
96
+ the checklist is in the other tab, so this one may auto-open the instance. Same-tab fallback (pop-up blocked,
97
+ form target=_self): this IS the founder's checklist tab — never navigate it away; offer both doors (task 1003236). */
98
+ var popup=!!window.opener||window.name==='ghAppSetup';
99
+ var finished=false,tries=0,manual=false;
100
+ function dot(n){return steps.querySelector('[data-step="'+n+'"]');}
101
+ function setActive(n){for(var i=1;i<=3;i++){var el=dot(i);if(!el)continue;el.classList.remove('active','done');if(i<n){el.classList.add('done');el.querySelector('.dot').textContent='\\u2713';}else if(i===n){el.classList.add('active');}}}
102
+ function allDone(){for(var i=1;i<=3;i++){var el=dot(i);if(!el)continue;el.classList.remove('active');el.classList.add('done');el.querySelector('.dot').textContent='\\u2713';}}
103
+ function ready(){if(finished)return;finished=true;allDone();statusEl.textContent='Your instance is ready \\u2014 sign in with GitHub to claim it as owner.';cta.classList.remove('hidden');
104
+ if(!popup){go.textContent='Open '+domain+' \\u2192';if(back)back.classList.remove('hidden');if(foot)foot.textContent='Your setup checklist is waiting where you left it \\u2014 finish it first, or open your instance now.';return;}
105
+ var n=4;(function tick(){if(n<=0){location.href=target;return;}go.textContent='Opening '+domain+' in '+n+'\\u2026';n--;setTimeout(tick,1000);})();}
106
+ function failed(){if(finished)return;finished=true;statusEl.textContent='Setup didn\\u2019t finish. Open your instance page and start the GitHub sign-in setup again.';cta.classList.remove('hidden');go.textContent='Open '+domain+' \\u2192';}
107
+ function revealManual(){if(manual||finished)return;manual=true;cta.classList.remove('hidden');go.textContent='Open '+domain+' \\u2192';if(foot)foot.textContent='This is taking a little longer than usual \\u2014 you can open your instance now, or keep waiting.';}
108
+ function schedule(){if(!finished)setTimeout(poll,3000);}
109
+ function poll(){tries++;fetch(pollUrl,{headers:{accept:'application/json'},cache:'no-store'}).then(function(r){return r.ok?r.json():null;}).then(function(j){if(!j){schedule();return;}if(j.ready||j.status==='done'){ready();return;}if(j.status==='error'||j.status==='expired'){failed();return;}setActive(2);if(tries===40)revealManual();schedule();}).catch(function(){schedule();});}
110
+ setActive(2);poll();
111
+ })();
112
+ `;
113
+
114
+ // The standalone landing page for the public GitHub redirect (the mothership serves it;
115
+ // it is NOT the hall shell). Two variants share the Cloud Bongos brand shell (task 2096):
116
+ // • progress — ok + state + domain: an animated stepper that polls the status endpoint
117
+ // and auto-opens the instance when its credentials are placed.
118
+ // • message — everything else (errors + the no-domain success fallback): a calm badge
119
+ // + `body` (server-authored, trusted HTML).
120
+ function callbackPage({ ok, title, body, state, domain }) {
121
+ const progress = !!(ok && state && domain);
122
+ const cfgJson = JSON.stringify({ state: state || '', domain: domain || '' }).replace(/</g, '\\u003c');
123
+ const head = `<!doctype html><html lang="en"><head><meta charset="utf-8">
124
+ <meta name="viewport" content="width=device-width, initial-scale=1">
125
+ <meta name="color-scheme" content="light dark">
126
+ <title>${esc(title)}</title>
127
+ <link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
128
+ <link href="https://fonts.googleapis.com/css2?family=Baloo+2:wght@600;700;800&family=Quicksand:wght@400;500;600;700&family=Fira+Code&display=swap" rel="stylesheet">
129
+ <style>${PAGE_STYLE}</style></head><body>`;
130
+ if (progress) {
131
+ return `${head}
132
+ <main class="card">
133
+ <h1>${esc(title)}</h1>
134
+ <p class="sub">Finishing sign-in setup for <code>${esc(domain)}</code>.</p>
135
+ <div class="steps" id="steps" aria-label="Setup progress">
136
+ <div class="step done" data-step="1"><div class="dot">✓</div><div class="lbl">GitHub app created</div></div>
137
+ <div class="step active" data-step="2"><div class="dot">2</div><div class="lbl">Placing credentials</div></div>
138
+ <div class="step" data-step="3"><div class="dot">3</div><div class="lbl">Ready to sign in</div></div>
139
+ </div>
140
+ <p class="status-line" id="status">Hang tight — keep this tab open while we finish.</p>
141
+ <div class="cta hidden" id="cta"><a class="btn" id="go" href="https://${esc(domain)}">Open ${esc(domain)} →</a></div>
142
+ <p class="muted hidden" id="back"><a href="/projects?view=new">Finish your remaining setup steps →</a></p>
143
+ <p class="muted" id="foot">This page opens <code>${esc(domain)}</code> for you the moment it’s ready.</p>
144
+ <noscript><p class="muted">When setup finishes, open <a href="https://${esc(domain)}">${esc(domain)}</a> and sign in with GitHub — that first sign-in makes you the owner.</p></noscript>
145
+ </main>
146
+ <script>window.__CB_SETUP__=${cfgJson};</script>
147
+ <script>${CALLBACK_SCRIPT}</script>
148
+ </body></html>`;
149
+ }
150
+ return `${head}
151
+ <main class="card">
152
+ <div class="badge-warn">${ok ? '✓' : '⚠️'}</div>
153
+ <h1>${esc(title)}</h1>
154
+ <div class="sub">${body || ''}</div>
155
+ </main>
156
+ </body></html>`;
157
+ }
158
+
159
+ module.exports = { esc, callbackPage };