@bongos/core 1.21.171 → 1.21.172
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 +18 -18
- package/docs/copy-inventory.md +10 -9
- package/docs/copy-registry.json +19 -10
- package/docs/module-api-changelog.md +2 -0
- package/docs/page-readings.json +1 -1
- package/modules/copy-desk/page-status.js +34 -0
- package/modules/copy-desk/tests/copy_page_next.mjs +30 -2
- package/modules/hall-ui/public/studio-lib.js +13 -1
- package/modules/hall-ui/public/studio.js +9 -1
- 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/hall_studio_home.mjs +24 -0
package/.bongos-core.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.21.
|
|
6
|
-
"core_contract": "1.21.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.21.172",
|
|
6
|
+
"core_contract": "1.21.172",
|
|
7
|
+
"source_commit": "a5b5fc89c2bddcd402af46f6271b80c329759d8f",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-10-23T17:
|
|
9
|
+
"built_at": "2026-10-23T17:54:54.483Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 609,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 3831,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "3f3467a2aa833a4abbd6faf317d2656fb98738368a7376cdd163964d5f34a529",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -2412,12 +2412,12 @@
|
|
|
2412
2412
|
{
|
|
2413
2413
|
"path": "docs/copy-inventory.md",
|
|
2414
2414
|
"mode": "0000644",
|
|
2415
|
-
"sha256": "
|
|
2415
|
+
"sha256": "eec10b588ffe284a8e52e0f5e167b24ffee253b336454d980906d1d299f789c2"
|
|
2416
2416
|
},
|
|
2417
2417
|
{
|
|
2418
2418
|
"path": "docs/copy-registry.json",
|
|
2419
2419
|
"mode": "0000644",
|
|
2420
|
-
"sha256": "
|
|
2420
|
+
"sha256": "f537f321c123a47d6c8a7e026293bac969b79ab648462f1fbaa51929c8282584"
|
|
2421
2421
|
},
|
|
2422
2422
|
{
|
|
2423
2423
|
"path": "docs/design/apex-pass-2-direction.md",
|
|
@@ -2927,7 +2927,7 @@
|
|
|
2927
2927
|
{
|
|
2928
2928
|
"path": "docs/module-api-changelog.md",
|
|
2929
2929
|
"mode": "0000644",
|
|
2930
|
-
"sha256": "
|
|
2930
|
+
"sha256": "af6395d2e0df7248fff770ebe525441b4af0ba73ff474328bfb69ace36f3180b"
|
|
2931
2931
|
},
|
|
2932
2932
|
{
|
|
2933
2933
|
"path": "docs/modules-contract.md",
|
|
@@ -3017,7 +3017,7 @@
|
|
|
3017
3017
|
{
|
|
3018
3018
|
"path": "docs/page-readings.json",
|
|
3019
3019
|
"mode": "0000644",
|
|
3020
|
-
"sha256": "
|
|
3020
|
+
"sha256": "4a1fa9bbf1b952ebabc5587a38f634de6fdee2678ba6b9c8ef6a6e0862dff820"
|
|
3021
3021
|
},
|
|
3022
3022
|
{
|
|
3023
3023
|
"path": "docs/project-context.template.md",
|
|
@@ -4487,7 +4487,7 @@
|
|
|
4487
4487
|
{
|
|
4488
4488
|
"path": "modules/copy-desk/page-status.js",
|
|
4489
4489
|
"mode": "0000644",
|
|
4490
|
-
"sha256": "
|
|
4490
|
+
"sha256": "59a1cf0aeee19aee9595ab59b08bae6423bd98a60743eb3edec89e0dbe799c69"
|
|
4491
4491
|
},
|
|
4492
4492
|
{
|
|
4493
4493
|
"path": "modules/copy-desk/pages.js",
|
|
@@ -4552,7 +4552,7 @@
|
|
|
4552
4552
|
{
|
|
4553
4553
|
"path": "modules/copy-desk/tests/copy_page_next.mjs",
|
|
4554
4554
|
"mode": "0000644",
|
|
4555
|
-
"sha256": "
|
|
4555
|
+
"sha256": "29faf19e0c0c99cb749a048d4fb73c33dfdd9e363ee46fa6e00465b286cfb096"
|
|
4556
4556
|
},
|
|
4557
4557
|
{
|
|
4558
4558
|
"path": "modules/copy-desk/tests/copy_page_status.mjs",
|
|
@@ -6627,7 +6627,7 @@
|
|
|
6627
6627
|
{
|
|
6628
6628
|
"path": "modules/hall-ui/public/studio-lib.js",
|
|
6629
6629
|
"mode": "0000644",
|
|
6630
|
-
"sha256": "
|
|
6630
|
+
"sha256": "e8ff3230c35edc9315fa850f3875cdebb0d6f776a6d51a9b6cba18c0dd0ae303"
|
|
6631
6631
|
},
|
|
6632
6632
|
{
|
|
6633
6633
|
"path": "modules/hall-ui/public/studio.css",
|
|
@@ -6642,7 +6642,7 @@
|
|
|
6642
6642
|
{
|
|
6643
6643
|
"path": "modules/hall-ui/public/studio.js",
|
|
6644
6644
|
"mode": "0000644",
|
|
6645
|
-
"sha256": "
|
|
6645
|
+
"sha256": "2b1adabd2d219c418ea335ad348668df75cc1f49673df3c5472c4107e8595691"
|
|
6646
6646
|
},
|
|
6647
6647
|
{
|
|
6648
6648
|
"path": "modules/hall-ui/public/studio.states.json",
|
|
@@ -10602,12 +10602,12 @@
|
|
|
10602
10602
|
{
|
|
10603
10603
|
"path": "package-lock.json",
|
|
10604
10604
|
"mode": "0000644",
|
|
10605
|
-
"sha256": "
|
|
10605
|
+
"sha256": "11e80d0bbd4cbe40847b4b7b3185243caca27ca1eb62a23d16af9244aedf7d5f"
|
|
10606
10606
|
},
|
|
10607
10607
|
{
|
|
10608
10608
|
"path": "package.json",
|
|
10609
10609
|
"mode": "0000644",
|
|
10610
|
-
"sha256": "
|
|
10610
|
+
"sha256": "ac557c163c39ef7b845595788a40b41a256fa82143a06632ac9a0805479a8285"
|
|
10611
10611
|
},
|
|
10612
10612
|
{
|
|
10613
10613
|
"path": "public-docs/index.html",
|
|
@@ -10627,7 +10627,7 @@
|
|
|
10627
10627
|
{
|
|
10628
10628
|
"path": "release-notes.json",
|
|
10629
10629
|
"mode": "0000644",
|
|
10630
|
-
"sha256": "
|
|
10630
|
+
"sha256": "a0f68aef51f5fbd8e741303c53f90c1342c0c9cc19f99d8c9de37fce33edb894"
|
|
10631
10631
|
},
|
|
10632
10632
|
{
|
|
10633
10633
|
"path": "scripts/cron/style_guide_audit.sh",
|
|
@@ -13017,7 +13017,7 @@
|
|
|
13017
13017
|
{
|
|
13018
13018
|
"path": "src/module-api.js",
|
|
13019
13019
|
"mode": "0000644",
|
|
13020
|
-
"sha256": "
|
|
13020
|
+
"sha256": "d91f9c6725d2c369f3af694a4e9b1ecada83994a2208961414c7814f0bf65b48"
|
|
13021
13021
|
},
|
|
13022
13022
|
{
|
|
13023
13023
|
"path": "src/module-loader/catalog.js",
|
|
@@ -15772,7 +15772,7 @@
|
|
|
15772
15772
|
{
|
|
15773
15773
|
"path": "tests/hall_studio_home.mjs",
|
|
15774
15774
|
"mode": "0000644",
|
|
15775
|
-
"sha256": "
|
|
15775
|
+
"sha256": "2f8bb467008b2a8007627a50e7b9432924364688c24f9a2d8ef38f8966034fef"
|
|
15776
15776
|
},
|
|
15777
15777
|
{
|
|
15778
15778
|
"path": "tests/hall_studio_world.mjs",
|
package/docs/copy-inventory.md
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
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
|
-
**
|
|
7
|
+
**2794 strings** across 3 surfaces · 2375 distinct pieces of copy · 2794 certain, 0 heuristic · 243 shown in more than one place.
|
|
8
8
|
|
|
9
9
|
## Surfaces
|
|
10
10
|
|
|
11
11
|
| surface | lives at | files | strings |
|
|
12
12
|
|---|---|---|---|
|
|
13
|
-
| `builders-hall` | `modules/hall-ui/public` | 150 |
|
|
13
|
+
| `builders-hall` | `modules/hall-ui/public` | 150 | 1974 |
|
|
14
14
|
| `status-dashboard` | `modules/status-ui/public` | 4 | 100 |
|
|
15
15
|
| `landing` | `modules/public-landing/public` | 9 | 720 |
|
|
16
16
|
|
|
@@ -78,7 +78,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
78
78
|
| `8226c979db4d` | 3x | Not now | modules/hall-ui/public/collab.js:668, modules/hall-ui/public/paintbrush.js:119, modules/hall-ui/public/paintbrush.js:183 |
|
|
79
79
|
| … | | _203 more in the JSON registry_ | |
|
|
80
80
|
|
|
81
|
-
## `builders-hall` —
|
|
81
|
+
## `builders-hall` — 1974 strings
|
|
82
82
|
|
|
83
83
|
| id | conf | text | where |
|
|
84
84
|
|---|---|---|---|
|
|
@@ -590,9 +590,9 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
590
590
|
| `320a0516a33e` | certain | Goals seeded — awaiting kickoff | `modules/hall-ui/public/roadmap.js:271` |
|
|
591
591
|
| `bba4caf837e9` | certain | Goals — {{worldName}} | `modules/hall-ui/public/goals.html:6` |
|
|
592
592
|
| `bba4caf837e9` | certain | Goals — {{worldName}} | `modules/hall-ui/public/goals.html:6` |
|
|
593
|
-
| `d0f76a295d09` | certain | Good afternoon. | `modules/hall-ui/public/studio.js:
|
|
593
|
+
| `d0f76a295d09` | certain | Good afternoon. | `modules/hall-ui/public/studio.js:968` |
|
|
594
594
|
| `80fd51db38d7` | certain | Good evening. | `modules/hall-ui/public/studio.html:101` |
|
|
595
|
-
| `36083f00396d` | certain | Good morning. | `modules/hall-ui/public/studio.js:
|
|
595
|
+
| `36083f00396d` | certain | Good morning. | `modules/hall-ui/public/studio.js:967` |
|
|
596
596
|
| `cab3de254155` | certain | Government — {{worldName}} | `modules/hall-ui/public/government.html:6` |
|
|
597
597
|
| `cab3de254155` | certain | Government — {{worldName}} | `modules/hall-ui/public/government.html:6` |
|
|
598
598
|
| `24d58d284952` | certain | Grades across all recent shipped work — a rolling aggregate. | `modules/hall-ui/public/watch.html:86` |
|
|
@@ -778,6 +778,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
778
778
|
| `9dacaf382dc8` | certain | More ways to open the page | `modules/hall-ui/public/tweak-editor.html:59` |
|
|
779
779
|
| `46fea78f33c6` | certain | Most recent first. Each load of this page is itself recorded in the audit log, and so is every transcript {…} | `modules/hall-ui/public/sessions.js:445` |
|
|
780
780
|
| `f14a91b3f625` | certain | Most recent first. Each row is one recorded work session; every id on it opens its record. | `modules/hall-ui/public/sessions.html:56` |
|
|
781
|
+
| `2d5aea02c40e` | certain | Most words to write | `modules/hall-ui/public/studio.js:737` |
|
|
781
782
|
| `e52ae74f0052` | certain | Move to goal | `modules/hall-ui/public/task.js:562` |
|
|
782
783
|
| `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:569` |
|
|
783
784
|
| `e77d5f3beaef` | certain | Move to {…} | `modules/hall-ui/public/deploy.js:731` |
|
|
@@ -861,7 +862,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
861
862
|
| `d5cf262e671d` | certain | Nobody is writing this page. Take it, and every line here is yours to type over. | `modules/hall-ui/public/tweak-editor.js:314` |
|
|
862
863
|
| `91c409a4aea5` | certain | Nobody vouched for this name — anyone can file a request naming anyone. Confirm who is asking before you admit | `modules/hall-ui/public/watch.js:397` |
|
|
863
864
|
| `4016b9cf8d57` | certain | None of your asks have been settled yet. | `modules/hall-ui/public/collab.html:134` |
|
|
864
|
-
| `2dd1beb3b2ab` | certain | None yet. A signed-in builder on the live site sees a Review button in its top bar; what they write lands here | `modules/hall-ui/public/studio.js:
|
|
865
|
+
| `2dd1beb3b2ab` | certain | None yet. A signed-in builder on the live site sees a Review button in its top bar; what they write lands here | `modules/hall-ui/public/studio.js:746` |
|
|
865
866
|
| `36c97d6094bf` | certain | None yet. Yours will be the first. | `modules/hall-ui/public/lightbulb.js:94` |
|
|
866
867
|
| `36c97d6094bf` | certain | None yet. Yours will be the first. | `modules/hall-ui/public/page-notes.js:177` |
|
|
867
868
|
| `7b915c25289b` | certain | None. Governing is held, not picked: you steer your own agents. | `modules/hall-ui/public/my-agents.js:371` |
|
|
@@ -1106,7 +1107,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
1106
1107
|
| `f1b2b158c3b1` | certain | Review quality | `modules/hall-ui/public/watch.html:85` |
|
|
1107
1108
|
| `4e062d4f8d69` | certain | Reviews by builder | `modules/hall-ui/public/watch.html:78` |
|
|
1108
1109
|
| `5c233879ce4e` | certain | Reviews from before Tweak Mode | `modules/hall-ui/public/studio.html:165` |
|
|
1109
|
-
| `4c112975a739` | certain | Rewrite it in the editor | `modules/hall-ui/public/studio.js:
|
|
1110
|
+
| `4c112975a739` | certain | Rewrite it in the editor | `modules/hall-ui/public/studio.js:843` |
|
|
1110
1111
|
| `c56d9a6451a7` | certain | Rewrite them in the tweak editor | `modules/hall-ui/public/paintbrush.js:252` |
|
|
1111
1112
|
| `f7ed4ba07178` | certain | Roadmap — {{worldName}} | `modules/hall-ui/public/roadmap.html:6` |
|
|
1112
1113
|
| `f7ed4ba07178` | certain | Roadmap — {{worldName}} | `modules/hall-ui/public/roadmap.html:6` |
|
|
@@ -1383,7 +1384,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
1383
1384
|
| `2287c62afcdd` | certain | The street | `modules/hall-ui/public/street.html:103` |
|
|
1384
1385
|
| `fdc4b3013936` | certain | The street — {{worldName}} | `modules/hall-ui/public/street.html:6` |
|
|
1385
1386
|
| `fdc4b3013936` | certain | The street — {{worldName}} | `modules/hall-ui/public/street.html:6` |
|
|
1386
|
-
| `d00666a91ac4` | certain | The studio page is yours, but its words could not be read just now. Open it in the editor. | `modules/hall-ui/public/studio.js:
|
|
1387
|
+
| `d00666a91ac4` | certain | The studio page is yours, but its words could not be read just now. Open it in the editor. | `modules/hall-ui/public/studio.js:914` |
|
|
1387
1388
|
| `7d016f4a65bf` | certain | The system is mid-build. These diagrams deliberately separate what stands today from what is yet planned, so t | `modules/hall-ui/public/diagrams.html:40` |
|
|
1388
1389
|
| `599fd0e82d1c` | certain | The task board — all work | `modules/hall-ui/public/studio.html:178` |
|
|
1389
1390
|
| `198ba9353bf6` | certain | The task feed did not answer. Nothing on the record has changed, only the read failed. Try again in a moment, | `modules/hall-ui/public/task.js:1015` |
|
|
@@ -1836,7 +1837,7 @@ Identical copy within one surface. Sometimes right (a repeated button), sometime
|
|
|
1836
1837
|
| `1e737a57eb20` | certain | start governing | `modules/hall-ui/public/city.html:99` |
|
|
1837
1838
|
| `e294c3429c2e` | certain | strong at {…} | `modules/hall-ui/public/modules.js:340` |
|
|
1838
1839
|
| `0215b2cdca8c` | certain | submit for review | `modules/hall-ui/public/modules.js:286` |
|
|
1839
|
-
| `43e6f1592ae3` | certain | submit it in the editor | `modules/hall-ui/public/studio.js:
|
|
1840
|
+
| `43e6f1592ae3` | certain | submit it in the editor | `modules/hall-ui/public/studio.js:844` |
|
|
1840
1841
|
| `9ec19e32f86f` | certain | submit page | `modules/hall-ui/public/tweak-editor.html:68` |
|
|
1841
1842
|
| `da30b952a60b` | certain | system / unattributed | `modules/hall-ui/public/goals-page.js:284` |
|
|
1842
1843
|
| `da30b952a60b` | certain | system / unattributed | `modules/hall-ui/public/work.js:581` |
|
package/docs/copy-registry.json
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"generator": "scripts/gds/copy-inventory.js",
|
|
4
4
|
"goal": 1000074,
|
|
5
5
|
"counts": {
|
|
6
|
-
"strings":
|
|
7
|
-
"unique_ids":
|
|
8
|
-
"certain":
|
|
6
|
+
"strings": 2794,
|
|
7
|
+
"unique_ids": 2375,
|
|
8
|
+
"certain": 2794,
|
|
9
9
|
"heuristic": 0,
|
|
10
10
|
"duplicate_ids": 243
|
|
11
11
|
},
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"builders-hall": {
|
|
14
14
|
"at": "modules/hall-ui/public",
|
|
15
15
|
"files": 150,
|
|
16
|
-
"strings":
|
|
16
|
+
"strings": 1974
|
|
17
17
|
},
|
|
18
18
|
"status-dashboard": {
|
|
19
19
|
"at": "modules/status-ui/public",
|
|
@@ -7223,7 +7223,7 @@
|
|
|
7223
7223
|
"surface": "builders-hall",
|
|
7224
7224
|
"text": "Good afternoon.",
|
|
7225
7225
|
"file": "modules/hall-ui/public/studio.js",
|
|
7226
|
-
"line":
|
|
7226
|
+
"line": 968,
|
|
7227
7227
|
"origin": "js-text-assign",
|
|
7228
7228
|
"confidence": "certain"
|
|
7229
7229
|
},
|
|
@@ -7241,7 +7241,7 @@
|
|
|
7241
7241
|
"surface": "builders-hall",
|
|
7242
7242
|
"text": "Good morning.",
|
|
7243
7243
|
"file": "modules/hall-ui/public/studio.js",
|
|
7244
|
-
"line":
|
|
7244
|
+
"line": 967,
|
|
7245
7245
|
"origin": "js-text-assign",
|
|
7246
7246
|
"confidence": "certain"
|
|
7247
7247
|
},
|
|
@@ -8910,6 +8910,15 @@
|
|
|
8910
8910
|
"origin": "html-text",
|
|
8911
8911
|
"confidence": "certain"
|
|
8912
8912
|
},
|
|
8913
|
+
{
|
|
8914
|
+
"id": "2d5aea02c40e",
|
|
8915
|
+
"surface": "builders-hall",
|
|
8916
|
+
"text": "Most words to write",
|
|
8917
|
+
"file": "modules/hall-ui/public/studio.js",
|
|
8918
|
+
"line": 737,
|
|
8919
|
+
"origin": "js-markup",
|
|
8920
|
+
"confidence": "certain"
|
|
8921
|
+
},
|
|
8913
8922
|
{
|
|
8914
8923
|
"id": "e52ae74f0052",
|
|
8915
8924
|
"surface": "builders-hall",
|
|
@@ -9662,7 +9671,7 @@
|
|
|
9662
9671
|
"surface": "builders-hall",
|
|
9663
9672
|
"text": "None yet. A signed-in builder on the live site sees a Review button in its top bar; what they write lands here.",
|
|
9664
9673
|
"file": "modules/hall-ui/public/studio.js",
|
|
9665
|
-
"line":
|
|
9674
|
+
"line": 746,
|
|
9666
9675
|
"origin": "js-markup",
|
|
9667
9676
|
"confidence": "certain"
|
|
9668
9677
|
},
|
|
@@ -11867,7 +11876,7 @@
|
|
|
11867
11876
|
"surface": "builders-hall",
|
|
11868
11877
|
"text": "Rewrite it in the editor",
|
|
11869
11878
|
"file": "modules/hall-ui/public/studio.js",
|
|
11870
|
-
"line":
|
|
11879
|
+
"line": 843,
|
|
11871
11880
|
"origin": "js-markup",
|
|
11872
11881
|
"confidence": "certain"
|
|
11873
11882
|
},
|
|
@@ -14360,7 +14369,7 @@
|
|
|
14360
14369
|
"surface": "builders-hall",
|
|
14361
14370
|
"text": "The studio page is yours, but its words could not be read just now. Open it in the editor.",
|
|
14362
14371
|
"file": "modules/hall-ui/public/studio.js",
|
|
14363
|
-
"line":
|
|
14372
|
+
"line": 914,
|
|
14364
14373
|
"origin": "js-text-assign",
|
|
14365
14374
|
"confidence": "certain"
|
|
14366
14375
|
},
|
|
@@ -18437,7 +18446,7 @@
|
|
|
18437
18446
|
"surface": "builders-hall",
|
|
18438
18447
|
"text": "submit it in the editor",
|
|
18439
18448
|
"file": "modules/hall-ui/public/studio.js",
|
|
18440
|
-
"line":
|
|
18449
|
+
"line": 844,
|
|
18441
18450
|
"origin": "js-markup",
|
|
18442
18451
|
"confidence": "certain"
|
|
18443
18452
|
},
|
|
@@ -3179,5 +3179,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
3179
3179
|
landed since 1.21.169 with no explicit bump. run 39994339257. (task 1002620)
|
|
3180
3180
|
1.21.171 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3181
3181
|
landed since 1.21.170 with no explicit bump. run 39996371081. (task 1002620)
|
|
3182
|
+
1.21.172 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
3183
|
+
landed since 1.21.171 with no explicit bump. run 39998870016. (task 1002620)
|
|
3182
3184
|
---------------------------------------------------------------------------
|
|
3183
3185
|
```
|
package/docs/page-readings.json
CHANGED
|
@@ -3978,7 +3978,7 @@
|
|
|
3978
3978
|
"surface": "builders",
|
|
3979
3979
|
"title": "Studio",
|
|
3980
3980
|
"states_read": ["home","out","flow","flow-pick","status","words-offer","words-edit","reviews","full","full-back","approvals","approvals-before","approvals-phone","approvals-note","approved","sent-back"],
|
|
3981
|
-
"files_hash": "
|
|
3981
|
+
"files_hash": "b9928eadcd3c7524",
|
|
3982
3982
|
"reading_hash": "55e9090fdd96a979",
|
|
3983
3983
|
"counts": {"lines":30,"placed":16,"shared":6,"unplaced":8},
|
|
3984
3984
|
"omitted": {"data":4},
|
|
@@ -242,6 +242,32 @@ function changelogFor(rounds) {
|
|
|
242
242
|
// Composition.
|
|
243
243
|
// ---------------------------------------------------------------------------
|
|
244
244
|
|
|
245
|
+
// task 1004670: how much text a page shows, the measure the worst-pages report
|
|
246
|
+
// and the copy queue rank by. Distinct non-shared lines of its reading: shell
|
|
247
|
+
// text every page carries is no page's own work, and a line a page repeats in
|
|
248
|
+
// several states is written once. null when the page has not been read.
|
|
249
|
+
function textLinesOf(readingPage) {
|
|
250
|
+
if (!readingPage || !Array.isArray(readingPage.lines)) return null;
|
|
251
|
+
return new Set(readingPage.lines.filter((l) => l && l.placement !== 'shared').map((l) => String(l.text))).size;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// The worst-pages report (task 1004670): the pages with the most text first,
|
|
255
|
+
// each with its status, so the copy queue's priority is visible in the Studio.
|
|
256
|
+
const WORST_PAGES = 5;
|
|
257
|
+
function worstPagesFor(inventory, rIdx, list) {
|
|
258
|
+
const byId = new Map(list.map((p) => [p.id, p]));
|
|
259
|
+
return ((inventory && inventory.pages) || [])
|
|
260
|
+
.filter((p) => p && p.id)
|
|
261
|
+
.map((p, i) => ({ p, i, n: textLinesOf(rIdx.get(p.id)) }))
|
|
262
|
+
.filter((x) => x.n != null && x.n > 0)
|
|
263
|
+
.sort((a, b) => b.n - a.n || a.i - b.i)
|
|
264
|
+
.slice(0, WORST_PAGES)
|
|
265
|
+
.map(({ p, n }) => ({
|
|
266
|
+
page_id: p.id, title: p.title || p.id, surface: p.surface, path: p.path || null,
|
|
267
|
+
text_lines: n, status_label: (byId.get(p.id) || {}).status_label || null,
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
|
|
245
271
|
function readingIndex(readings) {
|
|
246
272
|
const m = new Map();
|
|
247
273
|
for (const p of (readings && readings.pages) || []) if (p && p.id) m.set(p.id, p);
|
|
@@ -393,6 +419,7 @@ function composePages({ inventory, readings, tasks, now = Date.now() }) {
|
|
|
393
419
|
surfaces,
|
|
394
420
|
totals: { tweaked, total: list.length, line: `${tweaked} of ${list.length} pages tweaked` },
|
|
395
421
|
in_flight: inFlightFor(list, byPage, now instanceof Date ? now.getTime() : Number(now)),
|
|
422
|
+
worst_pages: worstPagesFor(inventory, rIdx, list),
|
|
396
423
|
};
|
|
397
424
|
}
|
|
398
425
|
|
|
@@ -575,6 +602,8 @@ function candidateFor({ page, rounds, readingPage, readingsOk, ask, builderId, a
|
|
|
575
602
|
askers,
|
|
576
603
|
oldest_ask_at: ask ? iso(ask.oldest_ask_at) : null,
|
|
577
604
|
changed_lines: changedLines,
|
|
605
|
+
// task 1004670: more text ranks a page higher within its tier.
|
|
606
|
+
text_lines: textLinesOf(readingPage) || 0,
|
|
578
607
|
drift_known: drift.known,
|
|
579
608
|
count: counts.count,
|
|
580
609
|
status_label: counts.status_label,
|
|
@@ -594,6 +623,9 @@ function compareCandidates(a, b) {
|
|
|
594
623
|
if (at !== bt) return at - bt;
|
|
595
624
|
}
|
|
596
625
|
if (a.tier === 'changed' && a.changed_lines !== b.changed_lines) return b.changed_lines - a.changed_lines;
|
|
626
|
+
// task 1004670: within a tier, the page with the most text leads (the
|
|
627
|
+
// worst-pages report's measure), then the inventory's own order.
|
|
628
|
+
if (a.text_lines !== b.text_lines) return b.text_lines - a.text_lines;
|
|
597
629
|
return a._base - b._base;
|
|
598
630
|
}
|
|
599
631
|
|
|
@@ -922,6 +954,8 @@ module.exports = {
|
|
|
922
954
|
roundState,
|
|
923
955
|
changelogFor,
|
|
924
956
|
composePages,
|
|
957
|
+
textLinesOf,
|
|
958
|
+
WORST_PAGES,
|
|
925
959
|
composePage,
|
|
926
960
|
lastRoundShippedAt,
|
|
927
961
|
composeTally,
|
|
@@ -92,11 +92,12 @@ const order = (out) => [out.recommended, ...out.alternatives].filter(Boolean).ma
|
|
|
92
92
|
const EXPECTED = [
|
|
93
93
|
'builders:work', 'landing:privacy', 'builders:tasks',
|
|
94
94
|
'builders:goals', 'status:board',
|
|
95
|
-
|
|
95
|
+
// task 1004670: within a tier the page with the most text leads, then surface order.
|
|
96
|
+
'landing:index', 'status:explore', 'builders:ideas',
|
|
96
97
|
'landing:projects',
|
|
97
98
|
];
|
|
98
99
|
|
|
99
|
-
await test('the order on the fixture: asked, changed, untweaked (
|
|
100
|
+
await test('the order on the fixture: asked, changed, untweaked (most text first), tweaked last', () => {
|
|
100
101
|
const out = next(F.ALICE.id);
|
|
101
102
|
assert.deepEqual(order(out), EXPECTED);
|
|
102
103
|
assert.deepEqual([...new Set([out.recommended, ...out.alternatives].map((c) => c.tier))], ['asked', 'changed', 'untweaked', 'tweaked']);
|
|
@@ -180,5 +181,32 @@ await test('nothing left to take: recommended is null, never a held page', () =>
|
|
|
180
181
|
assert.equal(out.skipped.length, 2);
|
|
181
182
|
});
|
|
182
183
|
|
|
184
|
+
// task 1004670: the worst-pages report. Pages with the most text lead the copy
|
|
185
|
+
// queue within their tier, and the Studio's page list names the worst ones.
|
|
186
|
+
await test('more text leads within a tier; shell text and repeats do not count', () => {
|
|
187
|
+
const L = (text, placement = 'placed') => ({ key: 'k', section: 's', text, placement });
|
|
188
|
+
const inventory = { surfaces: [{ id: 'landing' }], pages: [
|
|
189
|
+
{ id: 'landing:a', surface: 'landing', title: 'A', path: '/a', files: [] },
|
|
190
|
+
{ id: 'landing:b', surface: 'landing', title: 'B', path: '/b', files: [] },
|
|
191
|
+
{ id: 'landing:c', surface: 'landing', title: 'C', path: '/c', files: [] },
|
|
192
|
+
] };
|
|
193
|
+
const readings = { pages: [
|
|
194
|
+
{ id: 'landing:a', reading_hash: 'a', lines: [L('one'), L('Skip', 'shared'), L('Nav', 'shared'), L('Footer', 'shared')] },
|
|
195
|
+
{ id: 'landing:b', reading_hash: 'b', lines: [L('one'), L('two'), L('three'), L('two')] },
|
|
196
|
+
{ id: 'landing:c', reading_hash: 'c', lines: [L('one'), L('two')] },
|
|
197
|
+
] };
|
|
198
|
+
assert.equal(status.textLinesOf(readings.pages[0]), 1, 'shared shell text is no page\'s own');
|
|
199
|
+
assert.equal(status.textLinesOf(readings.pages[1]), 3, 'a repeated line is written once');
|
|
200
|
+
assert.equal(status.textLinesOf(null), null);
|
|
201
|
+
const out = status.composeNext({ inventory, readings, tasks: [], asks: [], builderId: F.ALICE.id, alternatives: 9 });
|
|
202
|
+
assert.deepEqual(order(out), ['landing:b', 'landing:c', 'landing:a']);
|
|
203
|
+
assert.deepEqual([out.recommended.text_lines, out.recommended.tier], [3, 'untweaked']);
|
|
204
|
+
|
|
205
|
+
const pagesOut = status.composePages({ inventory, readings, tasks: [] });
|
|
206
|
+
assert.deepEqual(pagesOut.worst_pages.map((w) => [w.page_id, w.text_lines, w.status_label]),
|
|
207
|
+
[['landing:b', 3, 'Untweaked'], ['landing:c', 2, 'Untweaked'], ['landing:a', 1, 'Untweaked']]);
|
|
208
|
+
assert.deepEqual(status.composePages({ inventory, readings: null, tasks: [] }).worst_pages, [], 'unread pages are not ranked');
|
|
209
|
+
});
|
|
210
|
+
|
|
183
211
|
console.log(`\ncopy_page_next: ${passed} passed, ${failed} failed`);
|
|
184
212
|
if (failed) process.exit(1);
|
|
@@ -171,6 +171,18 @@
|
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
// The worst-pages report (task 1004670): the pages with the most text, from
|
|
175
|
+
// the server's own list, most first. The panel only words the count.
|
|
176
|
+
function worstRows(pages) {
|
|
177
|
+
return ((pages && pages.worst_pages) || []).map((p) => ({
|
|
178
|
+
page_id: p.page_id,
|
|
179
|
+
title: titleOf(p),
|
|
180
|
+
surface: surfaceWord(p.surface),
|
|
181
|
+
size: `${num(p.text_lines)} ${num(p.text_lines) === 1 ? 'line' : 'lines'} of text`,
|
|
182
|
+
status: p.status_label || '',
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
|
|
174
186
|
function askedLine(n) {
|
|
175
187
|
const v = num(n);
|
|
176
188
|
if (v <= 0) return '';
|
|
@@ -241,7 +253,7 @@
|
|
|
241
253
|
|
|
242
254
|
const api = {
|
|
243
255
|
STUDIO_PAGE, PAGE_ID_RE, SURFACE_WORDS, surfaceWord, titleOf, numberWords, tallyParts, resumeDetail,
|
|
244
|
-
subParts, flowDetail, statusDetail, apexHost, landingHost, surfaceRows, inFlightRows, askedLine, pickLabel, matchLine, claimWords,
|
|
256
|
+
subParts, flowDetail, statusDetail, apexHost, landingHost, surfaceRows, inFlightRows, worstRows, askedLine, pickLabel, matchLine, claimWords,
|
|
245
257
|
skyAt, dayPart, STOCK_GREETING, clockGreets,
|
|
246
258
|
};
|
|
247
259
|
if (typeof window !== 'undefined') window.OTBStudioLib = api;
|
|
@@ -727,7 +727,15 @@
|
|
|
727
727
|
<span class="st-flight__state">${escapeHtml(f.state)}${f.age ? ` · ${escapeHtml(f.age)}` : ''}${f.stuck ? ' · stuck' : ''}</span>
|
|
728
728
|
</li>`).join('');
|
|
729
729
|
const inFlight = flight ? `<h3 class="st-flight__head">Where your pages are</h3><ul class="st-flights">${flight}</ul>` : '';
|
|
730
|
-
|
|
730
|
+
// task 1004670: the worst-pages report, the pages with the most text first.
|
|
731
|
+
const worst = lib.worstRows(home.pages).map((w) => `
|
|
732
|
+
<li class="st-flight">
|
|
733
|
+
<a class="st-flight__page" href="${escapeHtml(editorHref(w.page_id))}">${escapeHtml(w.title)}</a>
|
|
734
|
+
<span class="st-flight__where">${escapeHtml(w.surface)}</span>
|
|
735
|
+
<span class="st-flight__state">${escapeHtml(w.size)}${w.status ? ` · ${escapeHtml(w.status.toLowerCase())}` : ''}</span>
|
|
736
|
+
</li>`).join('');
|
|
737
|
+
const worstList = worst ? `<h3 class="st-flight__head">Most words to write</h3><ul class="st-flights st-worst">${worst}</ul>` : '';
|
|
738
|
+
return `<ul class="st-surfaces">${rows}</ul>${asked ? `<p class="st-asked">${escapeHtml(asked)}</p>` : ''}${inFlight}${worstList}`;
|
|
731
739
|
}
|
|
732
740
|
|
|
733
741
|
function siteHtml() {
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.172",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.21.
|
|
9
|
+
"version": "1.21.172",
|
|
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.21.
|
|
3
|
+
"version": "1.21.172",
|
|
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
|
@@ -10100,5 +10100,11 @@
|
|
|
10100
10100
|
"id": "1004781",
|
|
10101
10101
|
"text": "Credit figures in the hall now show money that was actually paid. A finished task shows its real payout instead of the old guess, so goal totals, member stats and the goal map stop adding up estimates as if they were earnings."
|
|
10102
10102
|
}
|
|
10103
|
+
],
|
|
10104
|
+
"1.21.172": [
|
|
10105
|
+
{
|
|
10106
|
+
"id": "1004670",
|
|
10107
|
+
"text": "The Studio now shows which pages have the most words to write: a short list of the five pages with the most text, each with how many lines it has and whether it has been tweaked, linked straight to the editor. The suggested ne"
|
|
10108
|
+
}
|
|
10103
10109
|
]
|
|
10104
10110
|
}
|
package/src/module-api.js
CHANGED
|
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
75
75
|
// MAJOR (see allowBoxScope below): passes the request through untouched.
|
|
76
76
|
function deprecatedNoopMiddleware(_req, _res, next) { next(); }
|
|
77
77
|
|
|
78
|
-
const CORE_VERSION = '1.21.
|
|
78
|
+
const CORE_VERSION = '1.21.172'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
79
79
|
|
|
80
80
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
81
81
|
// Usage: const log = api.logger('discord'); log.info('mounted');
|
|
@@ -360,6 +360,30 @@ try {
|
|
|
360
360
|
assert.ok(!s.html.classList.contains('st-open'));
|
|
361
361
|
});
|
|
362
362
|
|
|
363
|
+
// task 1004670: the worst-pages report, through the real composer into the
|
|
364
|
+
// real Studio panel: the pages with the most text, most first.
|
|
365
|
+
await test('Most words to write: the worst-pages report, most text first, linked to the editor', async () => {
|
|
366
|
+
const T = (key, text) => ({ key, section: 's', text, placement: 'placed' });
|
|
367
|
+
const readings = { pages: INV.pages.map((p, i) => ({ id: p.id, reading_hash: `r${i}`, lines: Array.from({ length: i + 2 }, (_, k) => T(`L${k}`, `${p.id} line ${k}`)) })) };
|
|
368
|
+
const pagesWithReadings = ps.composePages({ inventory: INV, readings, tasks: TASKS });
|
|
369
|
+
assert.ok(pagesWithReadings.worst_pages.length >= 1);
|
|
370
|
+
const top = pagesWithReadings.worst_pages[0];
|
|
371
|
+
assert.equal(top.page_id, INV.pages[INV.pages.length - 1].id, 'the page with the most text leads');
|
|
372
|
+
const rows = lib.worstRows(pagesWithReadings);
|
|
373
|
+
assert.equal(rows[0].size, `${top.text_lines} lines of text`);
|
|
374
|
+
const s = bootStudio({ answers: { ...HOME, 'GET /copy-desk/pages': ok(pagesWithReadings) } });
|
|
375
|
+
await s.settle();
|
|
376
|
+
await s.click('st-status');
|
|
377
|
+
const body = s.el('st-panel-body').innerHTML;
|
|
378
|
+
assert.match(body, /Most words to write/);
|
|
379
|
+
assert.match(body, new RegExp(`${top.text_lines} lines of text`));
|
|
380
|
+
assert.match(body, new RegExp(`href="/builders/tweak-editor\\?page=${top.page_id}"`));
|
|
381
|
+
const plain = bootStudio({ answers: HOME });
|
|
382
|
+
await plain.settle();
|
|
383
|
+
await plain.click('st-status');
|
|
384
|
+
assert.doesNotMatch(plain.el('st-panel-body').innerHTML, /Most words to write/, 'no readings, no report');
|
|
385
|
+
});
|
|
386
|
+
|
|
363
387
|
await test('the studio\'s words: a first click offers the studio page, and nothing is taken until the artist says so', async () => {
|
|
364
388
|
const s = bootStudio({ answers: { ...HOME, 'GET /copy-desk/pages/builders:studio/draft': ok(studioRead({ held: false })) } });
|
|
365
389
|
await s.settle();
|