@bongos/core 1.23.11 → 1.23.12
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 +38 -18
- package/docs/copy-inventory.md +70 -70
- package/docs/copy-registry.json +83 -83
- package/docs/module-api-changelog.md +2 -0
- package/docs/page-inventory.json +7 -1
- package/docs/page-readings.json +63 -57
- package/modules/public-landing/public/community-owner-two.states.json +16 -0
- package/modules/public-landing/public/community-owner.states.json +16 -0
- package/modules/public-landing/public/community.html +122 -10
- package/modules/ui-design/kit/fixtures/my-projects-owner-two.json +1 -0
- package/modules/ui-design/kit/fixtures/my-projects-owner.json +1 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +6 -0
- package/src/module-api.js +1 -1
- package/tests/hub_community_page.mjs +128 -6
package/docs/page-inventory.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"pages": 47,
|
|
14
14
|
"surfaces": 3,
|
|
15
15
|
"with_states": 40,
|
|
16
|
-
"states":
|
|
16
|
+
"states": 342
|
|
17
17
|
},
|
|
18
18
|
"surfaces": [
|
|
19
19
|
{
|
|
@@ -1452,6 +1452,8 @@
|
|
|
1452
1452
|
"states_files": [
|
|
1453
1453
|
"modules/public-landing/public/community.states.json",
|
|
1454
1454
|
"modules/public-landing/public/community-empty.states.json",
|
|
1455
|
+
"modules/public-landing/public/community-owner.states.json",
|
|
1456
|
+
"modules/public-landing/public/community-owner-two.states.json",
|
|
1455
1457
|
"modules/public-landing/public/community-recruiter.states.json"
|
|
1456
1458
|
],
|
|
1457
1459
|
"states": [
|
|
@@ -1468,6 +1470,10 @@
|
|
|
1468
1470
|
"in-recruiters",
|
|
1469
1471
|
"in",
|
|
1470
1472
|
"out-empty",
|
|
1473
|
+
"in-owner",
|
|
1474
|
+
"in-owner-find",
|
|
1475
|
+
"in-owner-two",
|
|
1476
|
+
"in-owner-two-picked",
|
|
1471
1477
|
"in-recruiter"
|
|
1472
1478
|
]
|
|
1473
1479
|
},
|
package/docs/page-readings.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"adr": "0341 D3",
|
|
6
6
|
"reread": "node scripts/bongos/page-reader.js --stale",
|
|
7
7
|
"how": ["Generated by node scripts/bongos/page-reader.js (BV2.TW04, task 1004315; ADR 0341 D3). Do not hand-edit.","One entry per page of docs/page-inventory.json. Lines are in page order: the default state first, and a line only another state shows sits where that state shows it, with its state named.","placement: placed = a docs/copy-registry.json row renders it (file, line, string_id); shared = shell text every page of the surface carries (top bar, sidebar, footer), with its row when the registry has one; unplaced = the registry cannot place it (a rewrite becomes an engineer task, ADR 0341 D4).","text keeps {…} where the registry row has a hole, or where a value the page read from its API was filled in. A string that is only such data is counted under omitted.data, not listed.","reading_hash is over the non-shared lines (key, section, text); files_hash is over the page's inventory files. --check compares files_hash only and never opens a browser.","Rendered through the hall-preview harness (hall) and the ui-design kit stub (landing, status), at 1280x800 with the clock pinned, so a reading is the fixture world's page."],
|
|
8
|
-
"counts": {"pages":47,"lines":
|
|
8
|
+
"counts": {"pages":47,"lines":5226,"placed":1582,"shared":419,"unplaced":3225,"omitted_data":3534},
|
|
9
9
|
"pages": [
|
|
10
10
|
{
|
|
11
11
|
"id": "builders:atlas",
|
|
@@ -4490,79 +4490,85 @@
|
|
|
4490
4490
|
"id": "landing:community",
|
|
4491
4491
|
"surface": "landing",
|
|
4492
4492
|
"title": "{{productName}} — Community",
|
|
4493
|
-
"states_read": ["out","out-30d","out-artists","out-community-band","in-community-band","in-projects-band","out-projects-band","out-find","out-find-search","out-recruiters","in-recruiters","in","out-empty","in-recruiter"],
|
|
4494
|
-
"files_hash": "
|
|
4495
|
-
"reading_hash": "
|
|
4496
|
-
"counts": {"lines":
|
|
4497
|
-
"omitted": {"data":
|
|
4493
|
+
"states_read": ["out","out-30d","out-artists","out-community-band","in-community-band","in-projects-band","out-projects-band","out-find","out-find-search","out-recruiters","in-recruiters","in","out-empty","in-owner","in-owner-find","in-owner-two","in-owner-two-picked","in-recruiter"],
|
|
4494
|
+
"files_hash": "8bd332ba8f0f0243",
|
|
4495
|
+
"reading_hash": "6b81da8cd8fdb090",
|
|
4496
|
+
"counts": {"lines":72,"placed":27,"shared":12,"unplaced":33},
|
|
4497
|
+
"omitted": {"data":30},
|
|
4498
4498
|
"notes": [],
|
|
4499
4499
|
"lines": [
|
|
4500
4500
|
{"key":"L0001","section":"top bar","text":"Community","placement":"shared"},
|
|
4501
4501
|
{"key":"L0002","section":"top bar","text":"Projects","placement":"shared"},
|
|
4502
4502
|
{"key":"L0003","section":"top bar","text":"Review","placement":"shared","state":"in-community-band"},
|
|
4503
4503
|
{"key":"L0004","section":"page top","text":"Sky","placement":"unplaced","state":"in-projects-band"},
|
|
4504
|
-
{"key":"L0005","section":"page top","text":"the sky of every project","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4504
|
+
{"key":"L0005","section":"page top","text":"the sky of every project","placement":"placed","file":"modules/public-landing/public/community.html","line":144,"string_id":"8fa12f730019","state":"in-projects-band"},
|
|
4505
4505
|
{"key":"L0006","section":"page top","text":"Table","placement":"unplaced","state":"in-projects-band"},
|
|
4506
|
-
{"key":"L0007","section":"page top","text":"the same projects as rows","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4507
|
-
{"key":"L0008","section":"page top","text":"Your projects","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4508
|
-
{"key":"L0009","section":"page top","text":"the ones you own","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4509
|
-
{"key":"L0010","section":"page top","text":"New project","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4510
|
-
{"key":"L0011","section":"page top","text":"five questions and a home","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4511
|
-
{"key":"L0012","section":"top bar","text":"Sign in","placement":"shared","file":"modules/public-landing/public/community.html","line":
|
|
4512
|
-
{"key":"L0013","section":"Open to recruiters","text":"Open to recruiters","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4513
|
-
{"key":"L0014","section":"Open to recruiters","text":"Builders who keep their numbers hidden but are open to hearing from projects. Only project owners see who they are, and only by name.","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4506
|
+
{"key":"L0007","section":"page top","text":"the same projects as rows","placement":"placed","file":"modules/public-landing/public/community.html","line":145,"string_id":"21453b3ba5c3","state":"in-projects-band"},
|
|
4507
|
+
{"key":"L0008","section":"page top","text":"Your projects","placement":"placed","file":"modules/public-landing/public/community.html","line":146,"string_id":"4e25e6872321","state":"in-projects-band"},
|
|
4508
|
+
{"key":"L0009","section":"page top","text":"the ones you own","placement":"placed","file":"modules/public-landing/public/community.html","line":146,"string_id":"a0fa148c60a6","state":"in-projects-band"},
|
|
4509
|
+
{"key":"L0010","section":"page top","text":"New project","placement":"placed","file":"modules/public-landing/public/community.html","line":147,"string_id":"0a81a82d10c4","state":"in-projects-band"},
|
|
4510
|
+
{"key":"L0011","section":"page top","text":"five questions and a home","placement":"placed","file":"modules/public-landing/public/community.html","line":147,"string_id":"94a3462373d2","state":"in-projects-band"},
|
|
4511
|
+
{"key":"L0012","section":"top bar","text":"Sign in","placement":"shared","file":"modules/public-landing/public/community.html","line":127,"string_id":"ad80586f802a"},
|
|
4512
|
+
{"key":"L0013","section":"Open to recruiters","text":"Open to recruiters","placement":"placed","file":"modules/public-landing/public/community.html","line":136,"string_id":"1e116d8fe95a","state":"out-recruiters"},
|
|
4513
|
+
{"key":"L0014","section":"Open to recruiters","text":"Builders who keep their numbers hidden but are open to hearing from projects. Only project owners see who they are, and only by name.","placement":"placed","file":"modules/public-landing/public/community.html","line":234,"string_id":"932bb6ad495b","state":"out-recruiters"},
|
|
4514
4514
|
{"key":"L0015","section":"Open to recruiters","text":"GitHub: {…}","placement":"unplaced","state":"in-recruiter","occurrences":3},
|
|
4515
|
-
{"key":"L0016","section":"Open to recruiters","text":"Only project owners can see this list.","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4516
|
-
{"key":"L0017","section":"Open to recruiters","text":"Sign in to see whether this list is open to you.","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4517
|
-
{"key":"L0018","section":"Open to recruiters","text":"Sign in with GitHub","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4518
|
-
{"key":"L0019","section":"footer","text":"A non-profit, capture-resistant commons.","placement":"shared","file":"modules/public-landing/public/community.html","line":
|
|
4519
|
-
{"key":"L0020","section":"footer","text":"Built by agents, on Cloud Bongos.","placement":"shared","file":"modules/public-landing/public/community.html","line":
|
|
4520
|
-
{"key":"L0021","section":"footer","text":"Open source","placement":"shared","file":"modules/public-landing/public/community.html","line":
|
|
4515
|
+
{"key":"L0016","section":"Open to recruiters","text":"Only project owners can see this list.","placement":"placed","file":"modules/public-landing/public/community.html","line":243,"string_id":"6bcd385b13d5","state":"in-recruiters"},
|
|
4516
|
+
{"key":"L0017","section":"Open to recruiters","text":"Sign in to see whether this list is open to you.","placement":"placed","file":"modules/public-landing/public/community.html","line":237,"string_id":"f59de6034af4","state":"out-recruiters"},
|
|
4517
|
+
{"key":"L0018","section":"Open to recruiters","text":"Sign in with GitHub","placement":"placed","file":"modules/public-landing/public/community.html","line":239,"string_id":"df38941b25a6","state":"out-recruiters"},
|
|
4518
|
+
{"key":"L0019","section":"footer","text":"A non-profit, capture-resistant commons.","placement":"shared","file":"modules/public-landing/public/community.html","line":251,"string_id":"afe83bbbd0d4","state":"out-recruiters","occurrences":3},
|
|
4519
|
+
{"key":"L0020","section":"footer","text":"Built by agents, on Cloud Bongos.","placement":"shared","file":"modules/public-landing/public/community.html","line":251,"string_id":"bd315dd71ea7","state":"out-recruiters","occurrences":3},
|
|
4520
|
+
{"key":"L0021","section":"footer","text":"Open source","placement":"shared","file":"modules/public-landing/public/community.html","line":251,"string_id":"d6314ddcc1d0","state":"out-recruiters","occurrences":3},
|
|
4521
4521
|
{"key":"L0022","section":"footer","text":"AGPL-3.0","placement":"shared","state":"out-recruiters","occurrences":3},
|
|
4522
4522
|
{"key":"L0023","section":"navigation","text":"Privacy","placement":"shared","state":"out-recruiters","occurrences":3},
|
|
4523
4523
|
{"key":"L0024","section":"navigation","text":"Terms","placement":"shared","state":"out-recruiters","occurrences":3},
|
|
4524
4524
|
{"key":"L0025","section":"navigation","text":"Contact","placement":"shared","state":"out-recruiters","occurrences":3},
|
|
4525
|
-
{"key":"L0026","section":"navigation","text":"Builders' hall","placement":"shared","file":"modules/public-landing/public/community.html","line":
|
|
4526
|
-
{"key":"L0027","section":"Find a builder","text":"Find a builder","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4527
|
-
{"key":"L0028","section":"Find a builder","text":"Their name or handle","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4528
|
-
{"key":"L0029","section":"Find a builder","text":"Any role","placement":"placed","file":"modules/public-landing/public/community.html","line":
|
|
4525
|
+
{"key":"L0026","section":"navigation","text":"Builders' hall","placement":"shared","file":"modules/public-landing/public/community.html","line":251,"string_id":"90a128c97eae","state":"out-recruiters","occurrences":3},
|
|
4526
|
+
{"key":"L0027","section":"Find a builder","text":"Find a builder","placement":"placed","file":"modules/public-landing/public/community.html","line":135,"string_id":"f1e93ba98ceb","state":"out-find"},
|
|
4527
|
+
{"key":"L0028","section":"Find a builder","text":"Their name or handle","placement":"placed","file":"modules/public-landing/public/community.html","line":208,"string_id":"541d5a7612a9","attr":"placeholder","state":"out-find"},
|
|
4528
|
+
{"key":"L0029","section":"Find a builder","text":"Any role","placement":"placed","file":"modules/public-landing/public/community.html","line":212,"string_id":"648862c67a23","state":"out-find"},
|
|
4529
4529
|
{"key":"L0030","section":"Find a builder","text":"Engineers","placement":"unplaced","state":"out-find"},
|
|
4530
4530
|
{"key":"L0031","section":"Find a builder","text":"Artists","placement":"unplaced","state":"out-find"},
|
|
4531
4531
|
{"key":"L0032","section":"Find a builder","text":"Ideators","placement":"unplaced","state":"out-find"},
|
|
4532
4532
|
{"key":"L0033","section":"Find a builder","text":"Designers","placement":"unplaced","state":"out-find"},
|
|
4533
4533
|
{"key":"L0034","section":"Find a builder","text":"Search","placement":"unplaced","state":"out-find"},
|
|
4534
|
-
{"key":"L0035","section":"Find a builder","text":"
|
|
4535
|
-
{"key":"L0036","section":"Find a builder","text":"
|
|
4536
|
-
{"key":"L0037","section":"
|
|
4537
|
-
{"key":"L0038","section":"
|
|
4538
|
-
{"key":"L0039","section":"page top","text":"
|
|
4539
|
-
{"key":"L0040","section":"page top","text":"
|
|
4540
|
-
{"key":"L0041","section":"page top","text":"
|
|
4541
|
-
{"key":"L0042","section":"page top","text":"
|
|
4542
|
-
{"key":"L0043","section":"page top","text":"
|
|
4543
|
-
{"key":"L0044","section":"page top","text":"
|
|
4544
|
-
{"key":"L0045","section":"
|
|
4545
|
-
{"key":"L0046","section":"
|
|
4546
|
-
{"key":"L0047","section":"Leaderboard","text":"
|
|
4547
|
-
{"key":"L0048","section":"Leaderboard","text":"
|
|
4548
|
-
{"key":"L0049","section":"Leaderboard","text":"
|
|
4549
|
-
{"key":"L0050","section":"Leaderboard","text":"
|
|
4550
|
-
{"key":"L0051","section":"Leaderboard","text":"
|
|
4551
|
-
{"key":"L0052","section":"Leaderboard","text":"
|
|
4552
|
-
{"key":"L0053","section":"Leaderboard","text":"
|
|
4553
|
-
{"key":"L0054","section":"Leaderboard","text":"
|
|
4554
|
-
{"key":"L0055","section":"Leaderboard","text":"
|
|
4555
|
-
{"key":"L0056","section":"Leaderboard","text":"
|
|
4556
|
-
{"key":"L0057","section":"Leaderboard","text":"
|
|
4557
|
-
{"key":"L0058","section":"Leaderboard","text":"
|
|
4558
|
-
{"key":"L0059","section":"Leaderboard","text":"
|
|
4559
|
-
{"key":"L0060","section":"Leaderboard","text":"
|
|
4560
|
-
{"key":"L0061","section":"Leaderboard","text":"
|
|
4561
|
-
{"key":"L0062","section":"Leaderboard","text":"
|
|
4562
|
-
{"key":"L0063","section":"Leaderboard","text":"
|
|
4563
|
-
{"key":"L0064","section":"Leaderboard","text":"
|
|
4564
|
-
{"key":"L0065","section":"Leaderboard","text":"
|
|
4565
|
-
{"key":"L0066","section":"Leaderboard","text":"
|
|
4534
|
+
{"key":"L0035","section":"Find a builder","text":"Recruit opens {…}’s hall with their name filled in, and you send the invite there.","placement":"unplaced","state":"in-owner-find"},
|
|
4535
|
+
{"key":"L0036","section":"Find a builder","text":"2 builders found.","placement":"unplaced","state":"out-find-search"},
|
|
4536
|
+
{"key":"L0037","section":"Find a builder","text":"{…} · designer","placement":"unplaced","state":"out-find-search"},
|
|
4537
|
+
{"key":"L0038","section":"Find a builder","text":"Recruit","placement":"unplaced","state":"in-owner-find","occurrences":2},
|
|
4538
|
+
{"key":"L0039","section":"page top","text":"Leaderboard","placement":"unplaced","state":"out-community-band"},
|
|
4539
|
+
{"key":"L0040","section":"page top","text":"who earned the most, across every project","placement":"placed","file":"modules/public-landing/public/community.html","line":134,"string_id":"776e80cf232d","state":"out-community-band"},
|
|
4540
|
+
{"key":"L0041","section":"page top","text":"Find a builder","placement":"placed","file":"modules/public-landing/public/community.html","line":135,"string_id":"f1e93ba98ceb","state":"out-community-band"},
|
|
4541
|
+
{"key":"L0042","section":"page top","text":"anyone building here, by name or role","placement":"placed","file":"modules/public-landing/public/community.html","line":135,"string_id":"a4e84a1501c5","state":"out-community-band"},
|
|
4542
|
+
{"key":"L0043","section":"page top","text":"Open to recruiters","placement":"placed","file":"modules/public-landing/public/community.html","line":136,"string_id":"1e116d8fe95a","state":"out-community-band"},
|
|
4543
|
+
{"key":"L0044","section":"page top","text":"who is open to recruiting, for project owners","placement":"placed","file":"modules/public-landing/public/community.html","line":136,"string_id":"15ac45627fab","state":"out-community-band"},
|
|
4544
|
+
{"key":"L0045","section":"page top","text":"Builders you may know","placement":"placed","file":"modules/public-landing/public/community.html","line":137,"string_id":"724de83c77c6","state":"in-community-band"},
|
|
4545
|
+
{"key":"L0046","section":"page top","text":"connections or projects in common","placement":"placed","file":"modules/public-landing/public/community.html","line":137,"string_id":"171cee573b19","state":"in-community-band"},
|
|
4546
|
+
{"key":"L0047","section":"Leaderboard","text":"Leaderboard","placement":"unplaced"},
|
|
4547
|
+
{"key":"L0048","section":"Leaderboard","text":"Everyone","placement":"unplaced"},
|
|
4548
|
+
{"key":"L0049","section":"Leaderboard","text":"Engineers","placement":"unplaced"},
|
|
4549
|
+
{"key":"L0050","section":"Leaderboard","text":"Artists","placement":"unplaced"},
|
|
4550
|
+
{"key":"L0051","section":"Leaderboard","text":"Ideators","placement":"unplaced"},
|
|
4551
|
+
{"key":"L0052","section":"Leaderboard","text":"Designers","placement":"unplaced"},
|
|
4552
|
+
{"key":"L0053","section":"Leaderboard","text":"Last 7 days","placement":"placed","file":"modules/public-landing/public/community.html","line":186,"string_id":"fc3582ac098d"},
|
|
4553
|
+
{"key":"L0054","section":"Leaderboard","text":"Last 30 days","placement":"placed","file":"modules/public-landing/public/community.html","line":187,"string_id":"52f6b5974994"},
|
|
4554
|
+
{"key":"L0055","section":"Leaderboard","text":"Past year","placement":"placed","file":"modules/public-landing/public/community.html","line":188,"string_id":"42a9479b375c"},
|
|
4555
|
+
{"key":"L0056","section":"Leaderboard","text":"All time","placement":"placed","file":"modules/public-landing/public/community.html","line":189,"string_id":"23c761dcff62"},
|
|
4556
|
+
{"key":"L0057","section":"Leaderboard","text":"Credits earned in the last 30 days, across every project.","placement":"unplaced","state":"out-30d"},
|
|
4557
|
+
{"key":"L0058","section":"Leaderboard","text":"{{Currency}} earned across every project, since each builder started.","placement":"placed","file":"modules/public-landing/public/community.html","line":193,"string_id":"f81129627f7b"},
|
|
4558
|
+
{"key":"L0059","section":"Leaderboard","text":"Recruit to","placement":"unplaced","state":"in-owner-two"},
|
|
4559
|
+
{"key":"L0060","section":"Leaderboard","text":"Recruit opens its hall with their name filled in, and you send the invite there.","placement":"unplaced","state":"in-owner-two"},
|
|
4560
|
+
{"key":"L0061","section":"Leaderboard","text":"Recruit opens {…}’s hall with their name filled in, and you send the invite there.","placement":"unplaced","state":"in-owner"},
|
|
4561
|
+
{"key":"L0062","section":"Leaderboard","text":"No builders on the leaderboard yet.","placement":"unplaced","state":"out-empty"},
|
|
4562
|
+
{"key":"L0063","section":"Leaderboard","text":"212 works shipped · 64 karma","placement":"unplaced"},
|
|
4563
|
+
{"key":"L0064","section":"Leaderboard","text":"Recruit","placement":"unplaced","state":"in-owner","occurrences":6},
|
|
4564
|
+
{"key":"L0065","section":"Leaderboard","text":"131 works shipped · 40 karma","placement":"unplaced"},
|
|
4565
|
+
{"key":"L0066","section":"Leaderboard","text":"19 works shipped · 9 karma","placement":"unplaced","state":"out-30d"},
|
|
4566
|
+
{"key":"L0067","section":"Leaderboard","text":"11 works shipped · 4 karma","placement":"unplaced","state":"out-30d"},
|
|
4567
|
+
{"key":"L0068","section":"Leaderboard","text":"77 works shipped · 52 karma","placement":"unplaced"},
|
|
4568
|
+
{"key":"L0069","section":"Leaderboard","text":"31 works shipped · 18 karma","placement":"unplaced"},
|
|
4569
|
+
{"key":"L0070","section":"Leaderboard","text":"12 works shipped · 7 karma","placement":"unplaced"},
|
|
4570
|
+
{"key":"L0071","section":"Leaderboard","text":"1 work shipped · 0 karma","placement":"unplaced"},
|
|
4571
|
+
{"key":"L0072","section":"Leaderboard","text":"A project reports a builder’s numbers when they sign in or ship there, so a window counts work when it was reported, not when it was done.","placement":"placed","file":"modules/public-landing/public/community.html","line":199,"string_id":"8d79db29b7d6"}
|
|
4566
4572
|
]
|
|
4567
4573
|
},
|
|
4568
4574
|
{
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_": "The community leaderboard for a builder who owns two projects (task 1002292): GET /my-projects answers Mercury and Tidepool (fixtures/my-projects-owner-two.json), so a labelled \"Recruit to\" choice sits above the rows, and picking Tidepool re-points every row's Recruit link at Tidepool's hall invite box.",
|
|
3
|
+
"page": "/community",
|
|
4
|
+
"surface": "public-landing",
|
|
5
|
+
"modes": ["dark"],
|
|
6
|
+
"modeQuery": false,
|
|
7
|
+
"stub": { "fixtures": { "my-projects": "my-projects-owner-two" } },
|
|
8
|
+
"ignoreRequests": ["/api/(gds|bongos)/me$", "/me/guild-", "/scouting$"],
|
|
9
|
+
"ignoreConsole": ["/api/(gds|bongos)/me", "/scouting", "\\b40[13]\\b", "Unauthorized", "Forbidden"],
|
|
10
|
+
"ignoreControls": [".vh"],
|
|
11
|
+
"states": {
|
|
12
|
+
"in-owner-two": { "auth": true, "actions": [["wait", 600]], "expect": { "visible": ["#boardFor", "#boardForPick"], "value": [["#boardForPick", "0"]], "count": [["#boardForPick option", 2], ["#boardList a.commRecruit", 6]], "href": [["#boardList .commRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } },
|
|
13
|
+
"in-owner-two-picked": { "auth": true, "actions": [["wait", 600], ["select", "#boardForPick", "1"], ["wait", 200]], "expect": { "value": [["#boardForPick", "1"]], "href": [["#boardList .commRow:first-child .commRecruit", "https://tidepool.example.test/builders/watch?invite=priyanair"]], "attr": [["#boardList .commRow:first-child .commRecruit", "aria-label", "Recruit Priya Nair to Tidepool (opens in a new tab)"]] } }
|
|
14
|
+
},
|
|
15
|
+
"reducedMotion": { "auth": true, "actions": [["wait", 600]] }
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_": "The community pages for a project owner (task 1002292; spec D6, owner 2026-10-27): GET /my-projects answers one owned project (fixtures/my-projects-owner.json), so every leaderboard and search row carries a Recruit link to Mercury's hall invite box with the GitHub login filled in, and a line above the rows says what it opens. The rows are the ones everyone sees.",
|
|
3
|
+
"page": "/community",
|
|
4
|
+
"surface": "public-landing",
|
|
5
|
+
"modes": ["dark"],
|
|
6
|
+
"modeQuery": false,
|
|
7
|
+
"stub": { "fixtures": { "my-projects": "my-projects-owner" } },
|
|
8
|
+
"ignoreRequests": ["/api/(gds|bongos)/me$", "/me/guild-", "/scouting$"],
|
|
9
|
+
"ignoreConsole": ["/api/(gds|bongos)/me", "/scouting", "\\b40[13]\\b", "Unauthorized", "Forbidden"],
|
|
10
|
+
"ignoreControls": [".vh"],
|
|
11
|
+
"states": {
|
|
12
|
+
"in-owner": { "auth": true, "actions": [["wait", 600]], "expect": { "visible": ["#board", "#boardFor", "#who"], "hidden": ["#find", "#recruit", "#boardFailed"], "count": [["#boardList .commRow", 6], ["#boardList a.commRecruit", 6]], "text": [["#boardFor", "Recruit opens Mercury’s hall with their name filled in, and you send the invite there."], ["#boardList .commRow:first-child .commRecruit", "Recruit"]], "href": [["#boardList .commRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } },
|
|
13
|
+
"in-owner-find": { "auth": true, "url": "/community/find", "actions": [["wait", 600], ["fill", "#findQ", "pri"], ["click", "#findBtn"], ["wait", 300]], "expect": { "visible": ["#find", "#findFor"], "hidden": ["#board", "#recruit"], "count": [["#findList .mineRow", 2], ["#findList .mineRow__actions a.commRecruit", 2]], "href": [["#findList .mineRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } }
|
|
14
|
+
},
|
|
15
|
+
"reducedMotion": { "auth": true, "actions": [["wait", 600]] }
|
|
16
|
+
}
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
their own. The one viewer-relative page is the recruiter list: drawn only from a 200 of
|
|
17
17
|
GET /scouting, whose door (a project owner, or project.curate) is the server's, never
|
|
18
18
|
this page's (scouting-authz.js). A 401 or 403 draws no row.
|
|
19
|
+
THE RECRUIT DOOR (task 1002292; spec D6, owner 2026-10-27): a project OWNER (GET
|
|
20
|
+
/my-projects `owned`) gets a Recruit link on each leaderboard and search row. The hub
|
|
21
|
+
cannot read a project's project.recruit, which lives on that project (ADR 0335 D1), so
|
|
22
|
+
ownership stands in. The link only opens the project's own hall invite box with the
|
|
23
|
+
login filled in (ADR 0353); the project decides. The rows themselves never change.
|
|
19
24
|
Hub-only, like /account: platform-server.js serves /community only where
|
|
20
25
|
platform-identity is on. noindex until the SEO goal decides (owner, 2026-10-27).
|
|
21
26
|
Server-stamped like the footer doors: {{…}} tokens filled by landingPage(). -->
|
|
@@ -69,19 +74,29 @@
|
|
|
69
74
|
.connAv{width:36px;height:36px;border-radius:50%;flex:none;object-fit:cover;background:color-mix(in srgb,var(--ink) 12%,transparent);}
|
|
70
75
|
.commRow .mineRow__name,.connWho .mineRow__name{overflow-wrap:anywhere;}
|
|
71
76
|
/* the two dropdowns (the window, the search's craft): the field's pill */
|
|
72
|
-
.commWhen select,.commFind select{flex:0 1 auto;min-height:44px;padding:0 14px;font:inherit;font-size:14.5px;color:var(--ink);
|
|
77
|
+
.commWhen select,.commFind select,.commFor select{flex:0 1 auto;min-height:44px;padding:0 14px;font:inherit;font-size:14.5px;color:var(--ink);
|
|
73
78
|
background:var(--bg-card);border:1px solid var(--ctl-line);border-radius:var(--radius-pill);cursor:pointer;}
|
|
74
|
-
.commWhen select:focus-visible,.commFind input:focus-visible,.commFind select:focus-visible{outline:2px solid var(--focus);outline-offset:3px;box-shadow:0 0 0 8px var(--bg);}
|
|
79
|
+
.commWhen select:focus-visible,.commFind input:focus-visible,.commFind select:focus-visible,.commFor select:focus-visible{outline:2px solid var(--focus);outline-offset:3px;box-shadow:0 0 0 8px var(--bg);}
|
|
75
80
|
#findStatus{margin-top:8px;}
|
|
81
|
+
/* the Recruit door, a project owner's only (task 1002292): what it opens, or which
|
|
82
|
+
project it recruits to; then a fifth column after the credits, where your own row
|
|
83
|
+
keeps an invisible twin so every row's credits line up */
|
|
84
|
+
.commFor{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;margin:6px 0 4px;max-width:62ch;font-size:13.5px;line-height:1.5;color:var(--ink-soft);}
|
|
85
|
+
#findFor{margin-top:12px;}
|
|
86
|
+
.commRows.canRecruit .commRow{grid-template-columns:3ch 36px minmax(0,1fr) auto auto;}
|
|
87
|
+
.commGap{visibility:hidden;}
|
|
76
88
|
/* the recruiter list, signed out: the account page's door */
|
|
77
89
|
.commDoor{padding:8px 0 10px;max-width:62ch;}
|
|
78
90
|
.commDoor p{margin:0 0 18px;font-size:15px;line-height:1.55;color:var(--ink-soft);}
|
|
79
91
|
.commDoor .gh{width:18px;height:18px;fill:currentColor;}
|
|
80
92
|
.commDoor .btn{text-transform:none;}
|
|
81
93
|
@media (max-width:480px){
|
|
82
|
-
.commRow{grid-template-columns:3ch 32px minmax(0,1fr) auto;gap:0 10px;}
|
|
94
|
+
.commRow,.commRows.canRecruit .commRow{grid-template-columns:3ch 32px minmax(0,1fr) auto;gap:0 10px;}
|
|
83
95
|
.commRow .connAv{width:32px;height:32px;}
|
|
84
96
|
.commNum{font-size:19px;}
|
|
97
|
+
/* no room for a fifth column: Recruit drops under the name, as a row's actions do */
|
|
98
|
+
.commRow .commRecruit{grid-column:3/-1;justify-self:start;margin-top:8px;}
|
|
99
|
+
.commGap{display:none;}
|
|
85
100
|
}
|
|
86
101
|
</style>
|
|
87
102
|
</head>
|
|
@@ -176,6 +191,7 @@
|
|
|
176
191
|
</div>
|
|
177
192
|
</div>
|
|
178
193
|
<p class="commNote" id="boardNote">{{Currency}} earned across every project, since each builder started.</p>
|
|
194
|
+
<div class="commFor" id="boardFor" hidden></div>
|
|
179
195
|
<p class="commMsg" id="boardLoading" role="status">Reading the leaderboard…</p>
|
|
180
196
|
<p class="projMsg err" id="boardFailed" role="alert" hidden></p>
|
|
181
197
|
<p class="commMsg" id="boardEmpty" hidden></p>
|
|
@@ -201,6 +217,7 @@
|
|
|
201
217
|
</select>
|
|
202
218
|
<button id="findBtn" type="submit" class="btn small">Search</button>
|
|
203
219
|
</form>
|
|
220
|
+
<div class="commFor" id="findFor" hidden></div>
|
|
204
221
|
<p class="projMsg" id="findStatus" role="status" aria-live="polite"></p>
|
|
205
222
|
<ul class="mineRows" id="findList"></ul>
|
|
206
223
|
</section>
|
|
@@ -259,8 +276,9 @@
|
|
|
259
276
|
var UNIT = $('boardList').getAttribute('data-unit') || 'credits';
|
|
260
277
|
|
|
261
278
|
/* THREE THINGS THESE PAGES MUST NOT DO (ADR 0217 D1, ADR 0337 D4.1, ADR 0255):
|
|
262
|
-
1. differ for a viewer anywhere but the recruiter list
|
|
263
|
-
search
|
|
279
|
+
1. differ for a viewer anywhere but the recruiter list and the Recruit door — the
|
|
280
|
+
leaderboard and the search rows come from viewer-independent reads, and a
|
|
281
|
+
project owner only gains a link on each (task 1002292, spec D6);
|
|
264
282
|
2. draw a recruiter row from anything but a 200 of GET /scouting, or draw more of a
|
|
265
283
|
name-only row than its name, face and login;
|
|
266
284
|
3. re-rank, re-filter or re-count what the server sent — rows are drawn in the
|
|
@@ -317,6 +335,36 @@
|
|
|
317
335
|
return arr(list).map(function (d) { return CRAFT_WORD[d] || String(d); }).join(' · ');
|
|
318
336
|
}
|
|
319
337
|
|
|
338
|
+
// ── the Recruit door: a project owner's link on each row (task 1002292) ─────
|
|
339
|
+
// Who sees it is GET /my-projects' `owned` (owner, 2026-10-27): the hub cannot read a
|
|
340
|
+
// project's project.recruit. Where it goes is invite-notices.js hallInviteUrl's shape,
|
|
341
|
+
// the project's hall invite box, which only fills the name in; the project decides.
|
|
342
|
+
var recruit = { to: [], pick: 0, me: '' };
|
|
343
|
+
function originOf(raw) {
|
|
344
|
+
try {
|
|
345
|
+
var u = new URL(String(raw));
|
|
346
|
+
return (u.protocol === 'https:' || u.protocol === 'http:') ? u.origin : '';
|
|
347
|
+
} catch (e) { return ''; }
|
|
348
|
+
}
|
|
349
|
+
// `keepPlace`: a board row keeps an invisible twin on your own row, so its credits line up
|
|
350
|
+
function recruitCell(r, keepPlace) {
|
|
351
|
+
var p = recruit.to[recruit.pick];
|
|
352
|
+
if (!p) return null;
|
|
353
|
+
var login = String(r.github_login || '');
|
|
354
|
+
if (!login || login.toLowerCase() === recruit.me) {
|
|
355
|
+
if (!keepPlace) return null;
|
|
356
|
+
var gap = el('span', 'btn small ghost commRecruit commGap', 'Recruit');
|
|
357
|
+
gap.setAttribute('aria-hidden', 'true');
|
|
358
|
+
return gap;
|
|
359
|
+
}
|
|
360
|
+
var a = el('a', 'btn small ghost commRecruit', 'Recruit');
|
|
361
|
+
a.setAttribute('href', p.origin + '/builders/watch?invite=' + encodeURIComponent(login));
|
|
362
|
+
a.setAttribute('target', '_blank');
|
|
363
|
+
a.setAttribute('rel', 'noopener');
|
|
364
|
+
a.setAttribute('aria-label', 'Recruit ' + (r.display_name || r.handle || login) + ' to ' + p.name + ' (opens in a new tab)');
|
|
365
|
+
return a;
|
|
366
|
+
}
|
|
367
|
+
|
|
320
368
|
// ── the leaderboard ─────────────────────────────────────────────────────────
|
|
321
369
|
var board = { window: 'all', craft: '' };
|
|
322
370
|
var boardSeq = 0;
|
|
@@ -338,6 +386,8 @@
|
|
|
338
386
|
credits.appendChild(el('span', 'commNum', num(r.credits).toLocaleString()));
|
|
339
387
|
credits.appendChild(el('span', 'commUnit', UNIT));
|
|
340
388
|
li.appendChild(credits);
|
|
389
|
+
var door = recruitCell(r, true);
|
|
390
|
+
if (door) li.appendChild(door);
|
|
341
391
|
return li;
|
|
342
392
|
}
|
|
343
393
|
function emptyText() {
|
|
@@ -345,8 +395,11 @@
|
|
|
345
395
|
if (board.window === 'all') return 'No ' + who + ' on the leaderboard yet.';
|
|
346
396
|
return 'No ' + who + ' earned ' + UNIT + ' in this window yet.';
|
|
347
397
|
}
|
|
398
|
+
var boardShown = null; // the last board drawn, redrawn when the Recruit door changes
|
|
348
399
|
function paintBoard(results) {
|
|
349
400
|
var list = $('boardList');
|
|
401
|
+
boardShown = results;
|
|
402
|
+
list.className = 'commRows' + (recruit.to.length ? ' canRecruit' : '');
|
|
350
403
|
list.textContent = '';
|
|
351
404
|
results.forEach(function (r) { if (r) list.appendChild(boardRow(r)); });
|
|
352
405
|
$('boardEmpty').textContent = list.children.length ? '' : emptyText();
|
|
@@ -366,6 +419,7 @@
|
|
|
366
419
|
if (seq !== boardSeq) return; // a later pick answered first; its rows win
|
|
367
420
|
$('boardLoading').hidden = true;
|
|
368
421
|
if (!r.ok) {
|
|
422
|
+
boardShown = null;
|
|
369
423
|
$('boardList').textContent = '';
|
|
370
424
|
$('boardEmpty').hidden = true;
|
|
371
425
|
$('boardFailed').textContent = failText(r.status, 'The leaderboard');
|
|
@@ -403,23 +457,35 @@
|
|
|
403
457
|
if (c) main.appendChild(el('p', 'mineRow__hint', c));
|
|
404
458
|
who.appendChild(main);
|
|
405
459
|
li.appendChild(who);
|
|
460
|
+
var door = recruitCell(r, false);
|
|
461
|
+
if (door) {
|
|
462
|
+
var acts = el('div', 'mineRow__actions');
|
|
463
|
+
acts.appendChild(door);
|
|
464
|
+
li.appendChild(acts);
|
|
465
|
+
}
|
|
406
466
|
return li;
|
|
407
467
|
}
|
|
468
|
+
var found = null; // the last results drawn, redrawn when the Recruit door changes
|
|
469
|
+
function paintFound(results) {
|
|
470
|
+
var list = $('findList');
|
|
471
|
+
found = results;
|
|
472
|
+
list.textContent = '';
|
|
473
|
+
if (results) results.forEach(function (p) { if (p) list.appendChild(findRow(p)); });
|
|
474
|
+
}
|
|
408
475
|
function find() {
|
|
409
476
|
var q = String($('findQ').value || '').trim();
|
|
410
477
|
var craft = $('findCraft').value || '';
|
|
411
478
|
var list = $('findList');
|
|
412
|
-
if (q.length < QUERY_MIN) {
|
|
413
|
-
if (q.length > QUERY_MAX) {
|
|
479
|
+
if (q.length < QUERY_MIN) { paintFound(null); say('Type at least ' + QUERY_MIN + ' letters of a name.', 'err'); return Promise.resolve(); }
|
|
480
|
+
if (q.length > QUERY_MAX) { paintFound(null); say('A search is at most ' + QUERY_MAX + ' characters.', 'err'); return Promise.resolve(); }
|
|
414
481
|
var btn = $('findBtn');
|
|
415
482
|
btn.disabled = true;
|
|
416
483
|
say('Searching…');
|
|
417
484
|
var path = '/community/search?q=' + encodeURIComponent(q) + (craft ? '&discipline=' + encodeURIComponent(craft) : '');
|
|
418
485
|
return read(path).then(function (r) {
|
|
419
486
|
btn.disabled = false;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
arr(r.data.results).forEach(function (p) { if (p) list.appendChild(findRow(p)); });
|
|
487
|
+
if (!r.ok) { paintFound(null); say(failText(r.status, 'The search'), 'err'); return; }
|
|
488
|
+
paintFound(arr(r.data.results));
|
|
423
489
|
var n = list.children.length;
|
|
424
490
|
say(n ? plural(n, 'builder') + ' found.' : 'No builder by that name' + (craft ? ' in that role' : '') + '.');
|
|
425
491
|
});
|
|
@@ -449,6 +515,51 @@
|
|
|
449
515
|
});
|
|
450
516
|
}
|
|
451
517
|
|
|
518
|
+
// ── the Recruit door's line, and the rows redrawn with it ───────────────────
|
|
519
|
+
function repaintRows() {
|
|
520
|
+
if (boardShown) paintBoard(boardShown);
|
|
521
|
+
if (found) paintFound(found);
|
|
522
|
+
}
|
|
523
|
+
// One project: what Recruit opens. Several: which one it recruits to, drawn once, so a
|
|
524
|
+
// pick redraws only the rows and the choice keeps the focus.
|
|
525
|
+
function paintFor(box) {
|
|
526
|
+
box.textContent = '';
|
|
527
|
+
box.hidden = false;
|
|
528
|
+
if (recruit.to.length === 1) {
|
|
529
|
+
box.textContent = 'Recruit opens ' + recruit.to[0].name + '’s hall with their name filled in, and you send the invite there.';
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
var id = box.id + 'Pick';
|
|
533
|
+
var label = el('label', null, 'Recruit to');
|
|
534
|
+
label.setAttribute('for', id);
|
|
535
|
+
var pick = el('select', 'commForPick');
|
|
536
|
+
pick.id = id;
|
|
537
|
+
recruit.to.forEach(function (p, i) { var o = el('option', null, p.name); o.value = String(i); pick.appendChild(o); });
|
|
538
|
+
pick.value = String(recruit.pick);
|
|
539
|
+
pick.addEventListener('change', function () {
|
|
540
|
+
var i = Number(pick.value);
|
|
541
|
+
if (!recruit.to[i] || i === recruit.pick) return;
|
|
542
|
+
recruit.pick = i;
|
|
543
|
+
repaintRows();
|
|
544
|
+
});
|
|
545
|
+
box.appendChild(label);
|
|
546
|
+
box.appendChild(pick);
|
|
547
|
+
box.appendChild(el('span', null, 'Recruit opens its hall with their name filled in, and you send the invite there.'));
|
|
548
|
+
}
|
|
549
|
+
// A failed or empty read is no door at all: viewing never waits on it.
|
|
550
|
+
function loadOwned(me, box) {
|
|
551
|
+
return read('/my-projects').then(function (r) {
|
|
552
|
+
if (!r.ok) return;
|
|
553
|
+
recruit.me = String(me.github_login || '').toLowerCase();
|
|
554
|
+
recruit.to = arr(r.data.owned).map(function (p) {
|
|
555
|
+
return { name: String((p && (p.name || p.client_id)) || 'your project'), origin: originOf(p && p.origin) };
|
|
556
|
+
}).filter(function (p) { return p.origin; });
|
|
557
|
+
if (!recruit.to.length) return;
|
|
558
|
+
paintFor(box);
|
|
559
|
+
repaintRows();
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
|
|
452
563
|
// ── the sub-page the path names: shown, named, marked current, and read ──────
|
|
453
564
|
var VIEW = viewOf(window.location.pathname);
|
|
454
565
|
var view = VIEWS[VIEW];
|
|
@@ -461,6 +572,7 @@
|
|
|
461
572
|
$('signinTop').setAttribute('href', '/api/bongos/auth/web/start?return=' + view.path + '&repos=1');
|
|
462
573
|
if (VIEW === 'leaderboard') loadBoard();
|
|
463
574
|
if (VIEW === 'recruiters') bar.ready.then(function (me) { if (me) loadRecruit(); else showRecruit('recruitDoor'); });
|
|
575
|
+
else bar.ready.then(function (me) { if (me) loadOwned(me, $(VIEW === 'find' ? 'findFor' : 'boardFor')); });
|
|
464
576
|
})();
|
|
465
577
|
</script>
|
|
466
578
|
<script src="/assets/invite-badge.js"></script>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"_":"GET /my-projects for a builder who owns TWO projects (task 1002292): the community pages' Recruit door asks which project it recruits to.","owned":[{"client_id":"mercury","name":"Mercury","origin":"https://mercury.example.test","hall_origin":null,"membership_kind":"owner","joined_at":"2026-08-01T10:00:00.000Z","last_active":"2026-10-20T18:00:00.000Z"},{"client_id":"tidepool","name":"Tidepool","origin":"https://tidepool.example.test","hall_origin":null,"membership_kind":"owner","joined_at":"2026-09-02T10:00:00.000Z","last_active":"2026-10-24T18:00:00.000Z"}],"building":[],"applied":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"_":"GET /my-projects for a builder who owns ONE project (task 1002292): the community pages' Recruit door shows on every row and opens Mercury's hall invite box.","owned":[{"client_id":"mercury","name":"Mercury","origin":"https://mercury.example.test","hall_origin":null,"membership_kind":"owner","joined_at":"2026-08-01T10:00:00.000Z","last_active":"2026-10-20T18:00:00.000Z"}],"building":[{"client_id":"otb","name":"Example World","origin":"https://example.com","hall_origin":"https://builders.example.com","membership_kind":"member","joined_at":"2026-07-20T10:00:00.000Z","last_active":"2026-08-27T18:00:00.000Z"}],"applied":[]}
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.12",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.23.
|
|
9
|
+
"version": "1.23.12",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.12",
|
|
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",
|
package/release-notes.json
CHANGED
|
@@ -10453,5 +10453,11 @@
|
|
|
10453
10453
|
"id": "1004256",
|
|
10454
10454
|
"text": "Signed-in builders now find 'Builders you may know' in the Community menu; it opens their suggestions on the Connections page, which says so plainly when there's no one to suggest yet."
|
|
10455
10455
|
}
|
|
10456
|
+
],
|
|
10457
|
+
"1.23.12": [
|
|
10458
|
+
{
|
|
10459
|
+
"id": "1002292",
|
|
10460
|
+
"text": "Project owners can now press Recruit next to any builder on the community leaderboard or search, which opens their project's invite page with that builder's name already filled in."
|
|
10461
|
+
}
|
|
10456
10462
|
]
|
|
10457
10463
|
}
|
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.23.
|
|
84
|
+
const CORE_VERSION = '1.23.12'; // 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');
|