@bongos/core 1.19.1066 → 1.19.1068

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.
@@ -2619,5 +2619,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
2619
2619
  landed since 1.19.1064 with no explicit bump. run 36451089716. (task 1002620)
2620
2620
  1.19.1066 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2621
2621
  landed since 1.19.1065 with no explicit bump. run 36454504693. (task 1002620)
2622
+ 1.19.1067 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2623
+ landed since 1.19.1066 with no explicit bump. run 36458843914. (task 1002620)
2624
+ 1.19.1068 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2625
+ landed since 1.19.1067 with no explicit bump. run 36467481353. (task 1002620)
2622
2626
  ---------------------------------------------------------------------------
2623
2627
  ```
@@ -13,7 +13,7 @@
13
13
  "pages": 38,
14
14
  "surfaces": 3,
15
15
  "with_states": 31,
16
- "states": 161
16
+ "states": 167
17
17
  },
18
18
  "surfaces": [
19
19
  {
@@ -850,14 +850,22 @@
850
850
  "modules/hall-ui/public/hall-kit.js",
851
851
  "modules/hall-ui/public/approval-queue-lib.js",
852
852
  "modules/hall-ui/public/approval-queue.js",
853
+ "modules/hall-ui/public/tweak-editor-lib.js",
854
+ "modules/hall-ui/public/studio-lib.js",
853
855
  "modules/hall-ui/public/studio.js"
854
856
  ],
855
857
  "states_files": [
856
858
  "modules/hall-ui/public/studio.states.json"
857
859
  ],
858
860
  "states": [
859
- "focus",
861
+ "home",
860
862
  "out",
863
+ "flow",
864
+ "flow-pick",
865
+ "status",
866
+ "words-offer",
867
+ "words-edit",
868
+ "reviews",
861
869
  "full",
862
870
  "full-back",
863
871
  "approvals",
@@ -5,7 +5,7 @@
5
5
  "adr": "0341 D3",
6
6
  "reread": "node scripts/gds/page-reader.js --stale",
7
7
  "how": ["Generated by node scripts/gds/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":38,"lines":3659,"placed":1139,"shared":247,"unplaced":2273,"omitted_data":2015},
8
+ "counts": {"pages":38,"lines":3683,"placed":1156,"shared":245,"unplaced":2282,"omitted_data":2025},
9
9
  "pages": [
10
10
  {
11
11
  "id": "builders:atlas",
@@ -2650,58 +2650,82 @@
2650
2650
  "id": "builders:studio",
2651
2651
  "surface": "builders",
2652
2652
  "title": "Studio",
2653
- "states_read": ["focus","out","full","full-back","approvals","approvals-before","approvals-phone","approvals-note","approved","sent-back"],
2654
- "files_hash": "e1041dfa74aca8dd",
2655
- "reading_hash": "e52bb7163191d85a",
2656
- "counts": {"lines":45,"placed":23,"shared":5,"unplaced":17},
2657
- "omitted": {"data":7},
2653
+ "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"],
2654
+ "files_hash": "f2dec3a598d97cc4",
2655
+ "reading_hash": "80b6c61d91869b36",
2656
+ "counts": {"lines":69,"placed":40,"shared":3,"unplaced":26},
2657
+ "omitted": {"data":17},
2658
2658
  "notes": [],
2659
2659
  "lines": [
2660
2660
  {"key":"L0001","section":"skip link","text":"Skip to content","placement":"shared","file":"modules/hall-ui/public/shell.js","line":776,"string_id":"87cee78ca134"},
2661
- {"key":"L0002","section":"top bar","text":"Studio","placement":"shared"},
2662
- {"key":"L0003","section":"top bar","text":"Jump to…","placement":"shared","file":"modules/hall-ui/public/shell.js","line":496,"string_id":"eba610d25523"},
2663
- {"key":"L0004","section":"top bar","text":"Ctrl K","placement":"shared"},
2664
- {"key":"L0005","section":"page top","text":"artist mode","placement":"placed","file":"modules/hall-ui/public/studio.html","line":43,"string_id":"520853131591"},
2665
- {"key":"L0006","section":"Good morning, {…}","text":"Good morning, {…}","placement":"unplaced"},
2666
- {"key":"L0007","section":"Good morning, {…}","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9"},
2667
- {"key":"L0008","section":"Good morning, {…}","text":"Approval queue","placement":"placed","file":"modules/hall-ui/public/studio.html","line":55,"string_id":"20c98a4b630f"},
2668
- {"key":"L0009","section":"Good morning, {…}","text":"1 page applied, waiting for you","placement":"unplaced","state":"approved"},
2669
- {"key":"L0010","section":"Good morning, {…}","text":"2 pages applied, waiting for you","placement":"unplaced"},
2670
- {"key":"L0011","section":"Good morning, {…}","text":"to tend now · {…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":215,"string_id":"1b88ce51fd84"},
2671
- {"key":"L0012","section":"The copy and visuals that {…} in task #1899","text":"The copy and visuals that {…} in task #1899","placement":"unplaced"},
2672
- {"key":"L0013","section":"The copy and visuals that {…} in task #1899","text":"It shipped and it is live. Say what you see — your review coaches the grader and never blocks what shipped.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":213,"string_id":"a28aa368453f"},
2673
- {"key":"L0014","section":"The copy and visuals that {…} in task #1899","text":"What you saw","placement":"placed","file":"modules/hall-ui/public/studio.js","line":173,"string_id":"1d5bfd09068c"},
2674
- {"key":"L0015","section":"The copy and visuals that {…} in task #1899","text":"— your words, in your voice. Needed for a note or a follow-up.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":173,"string_id":"d3afa6d6dd9e"},
2675
- {"key":"L0016","section":"The copy and visuals that {…} in task #1899","text":"The headline lands, but the sub-line reads like a brochure.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":173,"string_id":"027e9420daa2","attr":"placeholder"},
2676
- {"key":"L0017","section":"The copy and visuals that {…} in task #1899","text":"Looks good","placement":"placed","file":"modules/hall-ui/public/studio.js","line":173,"string_id":"73677b6839d7"},
2677
- {"key":"L0018","section":"The copy and visuals that {…} in task #1899","text":"Note it","placement":"placed","file":"modules/hall-ui/public/studio.js","line":173,"string_id":"73c72974f4f9"},
2678
- {"key":"L0019","section":"The copy and visuals that {…} in task #1899","text":"Needs work","placement":"placed","file":"modules/hall-ui/public/studio.js","line":173,"string_id":"3970d299c95a"},
2679
- {"key":"L0020","section":"The copy and visuals that {…} in task #1899","text":"Open this review","placement":"placed","file":"modules/hall-ui/public/studio.js","line":215,"string_id":"1cb80282de09"},
2680
- {"key":"L0021","section":"The copy and visuals that {…} in task #1899","text":"Let it be for now","placement":"placed","file":"modules/hall-ui/public/studio.js","line":215,"string_id":"d6a78b9e5368"},
2681
- {"key":"L0022","section":"The copy and visuals that {…} in task #1899","text":"and {…} more waiting{…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":288,"string_id":"d86265f99668"},
2682
- {"key":"L0023","section":"The copy and visuals that {…} in task #1899","text":"The copy desk — every flagged string","placement":"placed","file":"modules/hall-ui/public/studio.html","line":76,"string_id":"2dc061096c48"},
2683
- {"key":"L0024","section":"The copy and visuals that {…} in task #1899","text":"The task board — all work","placement":"placed","file":"modules/hall-ui/public/studio.html","line":77,"string_id":"599fd0e82d1c"},
2684
- {"key":"L0025","section":"footer","text":"Sign out","placement":"shared","file":"modules/hall-ui/public/shell.js","line":473,"string_id":"1883ad7f07fc"},
2685
- {"key":"L0026","section":"The copy and visuals that {…} in task #1899","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","state":"approvals"},
2686
- {"key":"L0027","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"Home","placement":"unplaced","state":"approvals"},
2687
- {"key":"L0028","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"· {…} · 3 lines rewritten, applied · 1 not applied","placement":"unplaced","state":"approvals"},
2688
- {"key":"L0029","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"before","placement":"unplaced","state":"approvals"},
2689
- {"key":"L0030","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"after","placement":"unplaced","state":"approvals"},
2690
- {"key":"L0031","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"close","placement":"unplaced","state":"approvals"},
2691
- {"key":"L0032","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"desktop","placement":"unplaced","state":"approvals"},
2692
- {"key":"L0033","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"phone","placement":"unplaced","state":"approvals"},
2693
- {"key":"L0034","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"light","placement":"unplaced","state":"approvals"},
2694
- {"key":"L0035","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"dark","placement":"unplaced","state":"approvals"},
2695
- {"key":"L0036","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"{…} project{…}","placement":"placed","file":"modules/hall-ui/public/fleet.js","line":39,"string_id":"771bef3d31b5","state":"approvals-before","occurrences":12},
2696
- {"key":"L0037","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"not applied: the page no longer shows it","placement":"unplaced","state":"approvals"},
2697
- {"key":"L0038","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"Sent back with your note. It comes back to the queue once it is re-applied.","placement":"unplaced","state":"sent-back"},
2698
- {"key":"L0039","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"Approved. It ships now, and Home reads text tweaked 3x. Next in the queue: Contact.","placement":"unplaced","state":"approved"},
2699
- {"key":"L0040","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"open {…}","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":156,"string_id":"9a803563c948","state":"approved"},
2700
- {"key":"L0041","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"approve and ship","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":165,"string_id":"ac37199ccdbb","state":"approvals"},
2701
- {"key":"L0042","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"The hero line is too long on a phone.","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":167,"string_id":"f08587a38a2a","attr":"placeholder","state":"approvals-note"},
2702
- {"key":"L0043","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"send","placement":"unplaced","state":"approvals-note"},
2703
- {"key":"L0044","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"send it back","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":172,"string_id":"92775a3d8d0d","state":"approvals"},
2704
- {"key":"L0045","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"highlighted: the words you changed","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":161,"string_id":"c2267f78f931","state":"approvals"}
2661
+ {"key":"L0002","section":"top bar","text":"Jump to…","placement":"shared","file":"modules/hall-ui/public/shell.js","line":496,"string_id":"eba610d25523"},
2662
+ {"key":"L0003","section":"top bar","text":"Ctrl K","placement":"shared"},
2663
+ {"key":"L0004","section":"page top","text":"{{worldName}} · studio","placement":"placed","file":"modules/hall-ui/public/studio.html","line":79,"string_id":"3d8611c2e79d"},
2664
+ {"key":"L0005","section":"page top","text":"pages tweaked","placement":"placed","file":"modules/hall-ui/public/studio.html","line":83,"string_id":"271de72308a4"},
2665
+ {"key":"L0006","section":"page top","text":"this week","placement":"placed","file":"modules/hall-ui/public/studio.html","line":85,"string_id":"130c3731ad83"},
2666
+ {"key":"L0007","section":"Good evening.","text":"Good evening.","placement":"placed","file":"modules/hall-ui/public/studio.html","line":95,"string_id":"80fd51db38d7"},
2667
+ {"key":"L0008","section":"Good evening.","text":"{…}, on the {…} page, is where you left it. {…} of its {…} lines are yours so far.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":656,"string_id":"7763e6f28c67","state":"words-edit","occurrences":2},
2668
+ {"key":"L0009","section":"Good evening.","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","state":"words-edit","occurrences":4},
2669
+ {"key":"L0010","section":"Good evening.","text":"submit it in the editor","placement":"placed","file":"modules/hall-ui/public/studio.js","line":797,"string_id":"43e6f1592ae3","state":"words-edit"},
2670
+ {"key":"L0011","section":"Good evening.","text":"click any words here to rewrite them","placement":"placed","file":"modules/hall-ui/public/studio.html","line":97,"string_id":"8d46c902a9d5"},
2671
+ {"key":"L0012","section":"Good evening.","text":"These words are the studio page itself. Take the page, type over them here, and submit it from the editor when you are done.","placement":"placed","file":"modules/hall-ui/public/studio.html","line":100,"string_id":"d6b9826f1bd3","state":"words-offer"},
2672
+ {"key":"L0013","section":"Good evening.","text":"take the studio page","placement":"placed","file":"modules/hall-ui/public/studio.html","line":103,"string_id":"357cc737dd98","state":"words-offer"},
2673
+ {"key":"L0014","section":"Good evening.","text":"not now","placement":"placed","file":"modules/hall-ui/public/studio.html","line":104,"string_id":"c04e4491af67","state":"words-offer"},
2674
+ {"key":"L0015","section":"Good evening.","text":"Resume","placement":"unplaced"},
2675
+ {"key":"L0016","section":"Good evening.","text":"Tweak/CopyWrite Flow","placement":"placed","file":"modules/hall-ui/public/studio.html","line":117,"string_id":"18801fb6845f"},
2676
+ {"key":"L0017","section":"Good evening.","text":"next up: {…} — {…}","placement":"unplaced"},
2677
+ {"key":"L0018","section":"Good evening.","text":"Approval queue","placement":"placed","file":"modules/hall-ui/public/studio.html","line":121,"string_id":"20c98a4b630f"},
2678
+ {"key":"L0019","section":"Good evening.","text":"1 page applied, waiting for you","placement":"unplaced","state":"approved"},
2679
+ {"key":"L0020","section":"Good evening.","text":"2 pages applied, waiting for you","placement":"unplaced"},
2680
+ {"key":"L0021","section":"Good evening.","text":"Artist Review Status","placement":"placed","file":"modules/hall-ui/public/studio.html","line":125,"string_id":"4d3b1bcae3eb"},
2681
+ {"key":"L0022","section":"Good evening.","text":"1 review from before Tweak Mode still waits","placement":"unplaced"},
2682
+ {"key":"L0023","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"Home","placement":"unplaced","state":"approvals"},
2683
+ {"key":"L0024","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"· {…} · 3 lines rewritten, applied · 1 not applied","placement":"unplaced","state":"approvals"},
2684
+ {"key":"L0025","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"before","placement":"unplaced","state":"approvals"},
2685
+ {"key":"L0026","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"after","placement":"unplaced","state":"approvals"},
2686
+ {"key":"L0027","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"close","placement":"unplaced","state":"approvals"},
2687
+ {"key":"L0028","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"desktop","placement":"unplaced","state":"approvals"},
2688
+ {"key":"L0029","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"phone","placement":"unplaced","state":"approvals"},
2689
+ {"key":"L0030","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"light","placement":"unplaced","state":"approvals"},
2690
+ {"key":"L0031","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"dark","placement":"unplaced","state":"approvals"},
2691
+ {"key":"L0032","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"{…} project{…}","placement":"placed","file":"modules/hall-ui/public/fleet.js","line":39,"string_id":"771bef3d31b5","state":"approvals-before","occurrences":12},
2692
+ {"key":"L0033","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"not applied: the page no longer shows it","placement":"unplaced","state":"approvals"},
2693
+ {"key":"L0034","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"Sent back with your note. It comes back to the queue once it is re-applied.","placement":"unplaced","state":"sent-back"},
2694
+ {"key":"L0035","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"Approved. It ships now, and Home reads text tweaked 3x. Next in the queue: {…}.","placement":"unplaced","state":"approved"},
2695
+ {"key":"L0036","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"open {…}","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":156,"string_id":"9a803563c948","state":"approved"},
2696
+ {"key":"L0037","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"approve and ship","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":165,"string_id":"ac37199ccdbb","state":"approvals"},
2697
+ {"key":"L0038","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"The hero line is too long on a phone.","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":167,"string_id":"f08587a38a2a","attr":"placeholder","state":"approvals-note"},
2698
+ {"key":"L0039","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"send","placement":"unplaced","state":"approvals-note"},
2699
+ {"key":"L0040","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"send it back","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":172,"string_id":"92775a3d8d0d","state":"approvals"},
2700
+ {"key":"L0041","section":"Home · {…} · 3 lines rewritten, applied · 1 not applied","text":"highlighted: the words you changed","placement":"placed","file":"modules/hall-ui/public/approval-queue.js","line":161,"string_id":"c2267f78f931","state":"approvals"},
2701
+ {"key":"L0042","section":"Reviews from before Tweak Mode","text":"Reviews from before Tweak Mode","placement":"placed","file":"modules/hall-ui/public/studio.html","line":153,"string_id":"5c233879ce4e","state":"reviews"},
2702
+ {"key":"L0043","section":"Reviews from before Tweak Mode","text":"close","placement":"unplaced","state":"reviews"},
2703
+ {"key":"L0044","section":"Reviews from before Tweak Mode","text":"Each was filed when a ship changed copy or visuals. No new ones arrive; answer these and the door goes.","placement":"placed","file":"modules/hall-ui/public/studio.html","line":156,"string_id":"3f7d82a0d9b1","state":"reviews"},
2704
+ {"key":"L0045","section":"Reviews from before Tweak Mode","text":"to tend now · {…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":233,"string_id":"1b88ce51fd84","state":"reviews"},
2705
+ {"key":"L0046","section":"The copy and visuals that {…} in task #1899","text":"The copy and visuals that {…} in task #1899","placement":"unplaced","state":"reviews"},
2706
+ {"key":"L0047","section":"The copy and visuals that {…} in task #1899","text":"It shipped and it is live. Say what you see — your review coaches the grader and never blocks what shipped.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":231,"string_id":"a28aa368453f","state":"reviews"},
2707
+ {"key":"L0048","section":"The copy and visuals that {…} in task #1899","text":"What you saw","placement":"placed","file":"modules/hall-ui/public/studio.js","line":191,"string_id":"1d5bfd09068c","state":"reviews"},
2708
+ {"key":"L0049","section":"The copy and visuals that {…} in task #1899","text":"— your words, in your voice. Needed for a note or a follow-up.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":191,"string_id":"d3afa6d6dd9e","state":"reviews"},
2709
+ {"key":"L0050","section":"The copy and visuals that {…} in task #1899","text":"The headline lands, but the sub-line reads like a brochure.","placement":"placed","file":"modules/hall-ui/public/studio.js","line":191,"string_id":"027e9420daa2","attr":"placeholder","state":"reviews"},
2710
+ {"key":"L0051","section":"The copy and visuals that {…} in task #1899","text":"Looks good","placement":"placed","file":"modules/hall-ui/public/studio.js","line":191,"string_id":"73677b6839d7","state":"reviews"},
2711
+ {"key":"L0052","section":"The copy and visuals that {…} in task #1899","text":"Note it","placement":"placed","file":"modules/hall-ui/public/studio.js","line":191,"string_id":"73c72974f4f9","state":"reviews"},
2712
+ {"key":"L0053","section":"The copy and visuals that {…} in task #1899","text":"Needs work","placement":"placed","file":"modules/hall-ui/public/studio.js","line":191,"string_id":"3970d299c95a","state":"reviews"},
2713
+ {"key":"L0054","section":"The copy and visuals that {…} in task #1899","text":"Open this review","placement":"placed","file":"modules/hall-ui/public/studio.js","line":233,"string_id":"1cb80282de09","state":"reviews"},
2714
+ {"key":"L0055","section":"The copy and visuals that {…} in task #1899","text":"Let it be for now","placement":"placed","file":"modules/hall-ui/public/studio.js","line":233,"string_id":"d6a78b9e5368","state":"reviews"},
2715
+ {"key":"L0056","section":"The copy and visuals that {…} in task #1899","text":"and {…} more waiting{…}","placement":"placed","file":"modules/hall-ui/public/studio.js","line":311,"string_id":"d86265f99668","state":"reviews"},
2716
+ {"key":"L0057","section":"The copy and visuals that {…} in task #1899","text":"The copy desk — every flagged string","placement":"placed","file":"modules/hall-ui/public/studio.html","line":165,"string_id":"2dc061096c48","state":"reviews"},
2717
+ {"key":"L0058","section":"The copy and visuals that {…} in task #1899","text":"The task board — all work","placement":"placed","file":"modules/hall-ui/public/studio.html","line":166,"string_id":"599fd0e82d1c","state":"reviews"},
2718
+ {"key":"L0059","section":"Artist Review Status","text":"Artist Review Status","placement":"placed","file":"modules/hall-ui/public/studio.html","line":125,"string_id":"4d3b1bcae3eb","state":"status"},
2719
+ {"key":"L0060","section":"Artist Review Status","text":"close","placement":"unplaced","state":"status"},
2720
+ {"key":"L0061","section":"Artist Review Status","text":"localhost:3000","placement":"unplaced","state":"status"},
2721
+ {"key":"L0062","section":"Artist Review Status","text":"{…} of {…}","placement":"placed","file":"modules/hall-ui/public/sky-panel.js","line":120,"string_id":"73c1372b43d9","state":"status","occurrences":3},
2722
+ {"key":"L0063","section":"Artist Review Status","text":"where the work happens","placement":"unplaced","state":"status"},
2723
+ {"key":"L0064","section":"Artist Review Status","text":"the {…} dashboard","placement":"unplaced","state":"status"},
2724
+ {"key":"L0065","section":"Artist Review Status","text":"2 pages have been {…} for. They come up first in the {…}.","placement":"unplaced","state":"status"},
2725
+ {"key":"L0066","section":"Tweak/CopyWrite Flow","text":"Tweak/CopyWrite Flow","placement":"placed","file":"modules/hall-ui/public/studio.html","line":117,"string_id":"18801fb6845f","state":"flow"},
2726
+ {"key":"L0067","section":"Tweak/CopyWrite Flow","text":"close","placement":"unplaced","state":"flow"},
2727
+ {"key":"L0068","section":"Tweak/CopyWrite Flow","text":"take it","placement":"placed","file":"modules/hall-ui/public/studio.js","line":685,"string_id":"70bbd20d223f","state":"flow"},
2728
+ {"key":"L0069","section":"Tweak/CopyWrite Flow","text":"pick another","placement":"placed","file":"modules/hall-ui/public/studio.js","line":682,"string_id":"b6ceacaad5e5","state":"flow"}
2705
2729
  ]
2706
2730
  },
2707
2731
  {
@@ -0,0 +1,207 @@
1
+ // studio-lib.js — the studio home's pure half (task 1003971 / BV2.TW16, goal
2
+ // 1000095; ADR 0341 D2, D5, D8 and D11; docs/design/mocks/tweak-mode/Main.dc.html).
3
+ //
4
+ // The studio is the artist's lofi home: the night room, a greeting whose words
5
+ // are editable where they stand, the tally in the corner, Resume, and three
6
+ // quick actions that open glass panels in place. Every word it says about the
7
+ // ledger is a pure function of the four reads it makes, so a test imports this
8
+ // file and runs the real rules:
9
+ //
10
+ // tallyParts(tally) the corner pill: credits, pages tweaked, this week
11
+ // resumeDetail(resume, c) "Home · landing · 12 of 38 lines"
12
+ // subParts(resume, c) the sub-line's parts ("Home", "landing", "Twelve", …)
13
+ // flowDetail(next) "next up: Projects — 2 people asked for it"
14
+ // statusDetail(pages) "6 of 37 pages tweaked"
15
+ // surfaceRows(pages, host) Artist Review Status: one row per surface
16
+ // landingHost(origin, host) the landing surface's address for that list
17
+ // askedLine(n) "4 pages have been asked for. …"
18
+ // pickLabel(candidate) a "pick another" chip: "Work · builders hall"
19
+ // matchLine(text, lines) which line of the studio's own reading a word on
20
+ // the page is, so an in-place edit names its key
21
+ // claimWords(code, detail) a refused claim, in words
22
+ //
23
+ // Node-require-safe (the tweak-editor-lib.js pattern): assignment is the only
24
+ // eval-time side effect, and only when a window exists.
25
+ (() => {
26
+ 'use strict';
27
+
28
+ const editorLib = (typeof window !== 'undefined' && window.OTBTweakEditor)
29
+ || (typeof require === 'function' ? require('./tweak-editor-lib.js') : null);
30
+
31
+ // The studio's own page id (docs/page-inventory.json). Its words are a tweak
32
+ // of this page like any other (ADR 0341 D2), never a live edit.
33
+ const STUDIO_PAGE = 'builders:studio';
34
+ const PAGE_ID_RE = /^[a-z0-9-]+:[a-z0-9-]+$/;
35
+
36
+ // A surface as the artboard says it in a line ("Home · landing · …").
37
+ const SURFACE_WORDS = Object.freeze({ landing: 'landing', builders: 'builders hall', status: 'status' });
38
+ function surfaceWord(id) { return SURFACE_WORDS[id] || String(id || ''); }
39
+
40
+ // What each surface is, under its name in Artist Review Status (the
41
+ // artboard's words). The landing surface is the instance's own address.
42
+ const SURFACE_WHERE = Object.freeze({ builders: 'where the work happens', status: 'the public dashboard' });
43
+
44
+ function titleOf(page) {
45
+ if (editorLib && typeof editorLib.displayTitle === 'function') return editorLib.displayTitle(page);
46
+ return String((page && (page.title || page.page_id)) || '');
47
+ }
48
+
49
+ function num(n) { const v = Number(n); return Number.isFinite(v) ? v : 0; }
50
+
51
+ // The artboard writes its counts in words ("Twelve of its thirty-eight lines").
52
+ const ONES = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
53
+ 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
54
+ const TENS = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
55
+ function numberWords(n, { capital = false, zero = 'none' } = {}) {
56
+ const v = Math.floor(num(n));
57
+ let out;
58
+ if (v === 0) out = zero;
59
+ else if (v < 0 || v > 999) out = String(v);
60
+ else if (v < 20) out = ONES[v];
61
+ else if (v < 100) out = TENS[Math.floor(v / 10)] + (v % 10 ? `-${ONES[v % 10]}` : '');
62
+ else {
63
+ const rest = v % 100;
64
+ out = `${ONES[Math.floor(v / 100)]} hundred${rest ? ` and ${numberWords(rest)}` : ''}`;
65
+ }
66
+ return capital ? out.charAt(0).toUpperCase() + out.slice(1) : out;
67
+ }
68
+
69
+ // The corner pill. "+38" this week, the artboard's sign; a quiet week is 0.
70
+ function tallyParts(tally) {
71
+ if (!tally) return null;
72
+ const week = num(tally.this_week);
73
+ return { credits: String(num(tally.credits)), pages: String(num(tally.pages_tweaked)), week: week > 0 ? `+${week}` : String(week) };
74
+ }
75
+
76
+ // Resume's second line. `counter` is the editor read's { changed, total }.
77
+ // Each sentence is ONE template literal, so the copy registry places the
78
+ // whole line the page shows (and an in-place tweak of it names one string).
79
+ function resumeDetail(resume, counter) {
80
+ if (!resume) return '';
81
+ const title = titleOf(resume);
82
+ const surface = surfaceWord(resume.surface);
83
+ if (!counter || !num(counter.total)) return `${title} · ${surface}`;
84
+ return `${title} · ${surface} · ${num(counter.changed)} of ${num(counter.total)} lines`;
85
+ }
86
+
87
+ // The greeting's sub-line, when the artist holds a page: its parts, in the
88
+ // artboard's words ("Twelve", "thirty-eight"). Null otherwise: the page's own
89
+ // sentence (studio.html) stands. The SENTENCE is written where studio.js
90
+ // assigns it, because the sub-line is one of the studio's own editable lines,
91
+ // and the copy registry places a line at its textContent assignment: a
92
+ // sentence built in here would read as unplaced, and an in-place tweak of it
93
+ // could not name its string.
94
+ function subParts(resume, counter) {
95
+ if (!resume) return null;
96
+ const counted = !!counter && num(counter.total) > 0;
97
+ return {
98
+ title: titleOf(resume),
99
+ surface: surfaceWord(resume.surface),
100
+ counted,
101
+ changed: counted ? numberWords(counter.changed, { capital: true }) : '',
102
+ total: counted ? numberWords(counter.total) : '',
103
+ };
104
+ }
105
+
106
+ function flowDetail(next) {
107
+ const rec = next && next.recommended;
108
+ if (rec) return `next up: ${titleOf(rec)} — ${rec.why}`;
109
+ if (next) return 'every page is taken for now';
110
+ return 'the next page to tweak';
111
+ }
112
+
113
+ function statusDetail(pages) {
114
+ const t = pages && pages.totals;
115
+ return t && t.line ? t.line : 'how far each surface has come';
116
+ }
117
+
118
+ // The instance's own address, from the hall's host (tweak-editor-lib liveUrl's
119
+ // rule: the hall answers at builders.<apex>).
120
+ function apexHost(host) {
121
+ return String(host || '').replace(/^(builders|status)\./, '');
122
+ }
123
+
124
+ // The landing surface's address, as Artist Review Status names it
125
+ // ("cloudbongos.com"): the instance's own public origin, which the server
126
+ // stamps into the page from the branding pack, else the hall's host without
127
+ // its builders. prefix. An unstamped token ({{…}}) is no address.
128
+ function landingHost(stampedOrigin, host) {
129
+ const o = String(stampedOrigin || '').trim();
130
+ if (o && !/\{\{/.test(o)) return o.replace(/^[a-z]+:\/\//i, '').replace(/\/+$/, '');
131
+ return apexHost(host);
132
+ }
133
+
134
+ // Artist Review Status: landing, builders hall, status, each "N of M tweaked"
135
+ // (ADR 0341 D8). The bar is one value against that surface's page count.
136
+ function surfaceRows(pages, host) {
137
+ return ((pages && pages.surfaces) || []).map((s) => {
138
+ const total = num(s.total);
139
+ const done = num(s.tweaked);
140
+ return {
141
+ id: s.id,
142
+ name: s.label || s.id,
143
+ where: s.id === 'landing' ? (host || 'the public site') : (SURFACE_WHERE[s.id] || ''),
144
+ count: s.line || `${done} of ${total} tweaked`,
145
+ pct: total > 0 ? Math.max(3, Math.min(100, Math.round((100 * done) / total))) : 3,
146
+ };
147
+ });
148
+ }
149
+
150
+ function askedLine(n) {
151
+ const v = num(n);
152
+ if (v <= 0) return '';
153
+ return v === 1
154
+ ? '1 page has been asked for. It comes up first in the Tweak/CopyWrite Flow.'
155
+ : `${v} pages have been asked for. They come up first in the Tweak/CopyWrite Flow.`;
156
+ }
157
+
158
+ // A "pick another" chip names the page and its surface (the artboard's label).
159
+ function pickLabel(c) {
160
+ return `${titleOf(c)} · ${surfaceWord(c && c.surface)}`;
161
+ }
162
+
163
+ // Which reading line a word on the page IS. A reading line's text carries
164
+ // {…} for each hole the page fills in (the registry's convention), so each
165
+ // hole matches any run of words. The most specific match wins (the most
166
+ // literal characters), and a line that is only holes never matches anything.
167
+ const HOLE = '{…}';
168
+ function tidy(s) { return String(s == null ? '' : s).replace(/\s+/g, ' ').trim(); }
169
+ function escapeRe(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
170
+ function matchLine(text, lines) {
171
+ const want = tidy(text);
172
+ if (!want) return null;
173
+ let best = null;
174
+ let bestLit = 0;
175
+ for (const l of lines || []) {
176
+ if (!l || typeof l.text !== 'string' || l.placement === 'shared') continue;
177
+ const parts = tidy(l.text).split(HOLE);
178
+ const literal = parts.join('').trim().length;
179
+ // A line mostly made of holes ("{…} of {…}") would match almost any
180
+ // sentence; its own words must be at least half of what the page shows.
181
+ if (!literal || literal * 2 < want.length) continue;
182
+ const re = new RegExp(`^${parts.map(escapeRe).join('.+?')}$`);
183
+ if (re.test(want) && literal > bestLit) { best = l; bestLit = literal; }
184
+ }
185
+ return best;
186
+ }
187
+
188
+ // A refused claim, in the artist's words. The server's own sentence
189
+ // (what_this_means) wins where it has one.
190
+ function claimWords(code, detail) {
191
+ const d = detail || {};
192
+ const holder = d.holder && (d.holder.login || d.holder.name);
193
+ if (code === 'page_held') return `${holder || 'Another artist'} is tweaking this page right now.`;
194
+ if (code === 'not_an_artist') return 'Only an artist can take a page. Your craft is set in Settings.';
195
+ if (d.what_this_means) return d.what_this_means;
196
+ if (code === 'page_in_flight') return 'This page is on its way to the site. It comes back to you to approve.';
197
+ if (code === 'no_open_version') return 'No version is being built right now, so there is nowhere for a page to land.';
198
+ return 'That page could not be taken just now. Nothing changed.';
199
+ }
200
+
201
+ const api = {
202
+ STUDIO_PAGE, PAGE_ID_RE, SURFACE_WORDS, surfaceWord, titleOf, numberWords, tallyParts, resumeDetail,
203
+ subParts, flowDetail, statusDetail, apexHost, landingHost, surfaceRows, askedLine, pickLabel, matchLine, claimWords,
204
+ };
205
+ if (typeof window !== 'undefined') window.OTBStudioLib = api;
206
+ if (typeof module !== 'undefined' && module.exports) module.exports = api;
207
+ })();