@bongos/core 1.20.48 → 1.20.50
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 +84 -54
- package/.claude/skills/new-project/SKILL.md +5 -0
- package/clients/bongos-client/index.d.ts +1 -1
- package/docs/api/openapi.json +3 -0
- package/docs/api-reference.md +1 -1
- package/docs/copy-inventory.md +434 -400
- package/docs/copy-registry.json +816 -508
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +11 -2
- package/docs/page-readings.json +733 -690
- package/modules/hall-ui/public/criterion-uat-ui.js +280 -0
- package/modules/hall-ui/public/goal-map.html +5 -3
- package/modules/hall-ui/public/goals-page.js +23 -44
- package/modules/hall-ui/public/goals-render.js +24 -15
- package/modules/hall-ui/public/goals.css +45 -0
- package/modules/hall-ui/public/goals.html +5 -2
- package/modules/hall-ui/public/goals.states.json +38 -0
- package/modules/hall-ui/public/sky-data.js +9 -1
- package/modules/hall-ui/public/sky-interaction.js +1 -1
- package/modules/hall-ui/public/sky-panel.js +1 -1
- package/modules/hall-ui/public/thinking.html +5 -3
- package/modules/lifecycle/done-when.js +3 -1
- package/modules/lifecycle/sky.js +23 -8
- package/modules/platform-identity/routes/sso.js +5 -0
- package/modules/provisioning/migrations/provisioning_033_terms_ack.sql +33 -0
- package/modules/provisioning/onboard-plan.js +5 -0
- package/modules/provisioning/provisioning.js +7 -4
- package/modules/provisioning/routes/provisioning.js +3 -3
- package/modules/provisioning/terms-ack.js +36 -0
- package/modules/public-landing/public/projects.html +226 -77
- package/modules/public-landing/public/projects.probes.json +8 -2
- package/modules/public-landing/public/projects.states.json +16 -12
- package/modules/ui-design/kit/serve.js +6 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/scripts/hall-preview/server.js +2 -0
- package/src/module-api.js +1 -1
- package/tests/claim_action.mjs +6 -1
- package/tests/criterion_uat_ui.mjs +113 -0
- package/tests/goal_criterion_confirm_ui.mjs +188 -91
- package/tests/goal_map_page.mjs +2 -1
- package/tests/hall_sky.mjs +16 -0
- package/tests/helpers.mjs +3 -1
- package/tests/projects_hub.mjs +4 -2
- package/tests/projects_hub_app_status.mjs +1 -1
- package/tests/projects_hub_app_step.mjs +9 -9
- package/tests/projects_hub_module_picker.mjs +7 -7
- package/tests/projects_hub_pre_uat.mjs +4 -1
- package/tests/provisioning_terms_ack.mjs +216 -0
- package/tests/sky_read.mjs +7 -1
- package/tests/wizard_draft_resume.mjs +4 -4
- package/tests/wizard_front_door.mjs +271 -0
- package/tests/wizard_intent_resume.mjs +31 -19
|
@@ -159,10 +159,16 @@
|
|
|
159
159
|
"steps": [["wait",900],["click","[data-disc-ask]"],["wait",200],["fill","#mDiscName","old-lantern"],["wait",100],["click","[data-disc-yes]"],["wait",900]],
|
|
160
160
|
"expect": {"text":[["#mDisc .addr","This project is being disconnected."],["#mName","old-lantern"]],"hidden":["#mDiscName","[data-disc-ask]"]} },
|
|
161
161
|
{ "name": "the wizard driver (task 1003346): name, type, about, home (fresh; the stub grants repo access, so the new repository is named from the project), address (the handle's verdict), the review as a ledger, then the filing — the done panel with the standup rail and the human steps", "auth": true, "width": 1440, "url": "/projects?view=new",
|
|
162
|
-
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400],["click","#doCreate"],["wait",1500]],
|
|
162
|
+
"steps": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400],["click","#doCreate"],["wait",1500]],
|
|
163
163
|
"expect": {"visible":["#panel-done","#liveProgress .prog","#liveProgress .prog .stages li.now","#humanSteps li"],"hidden":["#panel-review","#panel-name"],"text":[["#done-h","The drums are rolling"]],"attr":[["#panel-done","class","panel on"]]} },
|
|
164
|
+
{ "name": "the front door (task 1004417): Proceed is refused until the terms are ticked, the fork's demo door says the demo is not open yet, and Begin planet creation goes on to the name step with the rail back", "auth": true, "width": 1440, "url": "/projects?view=new",
|
|
165
|
+
"steps": [["wait",600],["click","#panel-terms button[type=submit]"],["wait",300],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#wizDemo"],["wait",200],["click","#panel-fork button[type=submit]"],["wait",400]],
|
|
166
|
+
"expect": {"visible":["#panel-name","#view-new .steps","#view-new .steps li.now"],"hidden":["#panel-fork","#panel-terms"],"attr":[["#wizDemo","aria-expanded","true"],["#view-new .steps li.now","data-step","3"]]} },
|
|
167
|
+
{ "name": "the front door at 390: the fork's two doors stack inside one pill and the walk still reaches the name step", "auth": true, "width": 390, "url": "/projects?view=new",
|
|
168
|
+
"steps": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400]],
|
|
169
|
+
"expect": {"visible":["#panel-fork",".doorPill","#wizDemo","#panel-fork button[type=submit]"],"hidden":["#view-new .steps"]} },
|
|
164
170
|
{ "name": "the wizard driver at 390: the rail folds to two rows of three and the walk still reaches the review", "auth": true, "width": 390, "url": "/projects?view=new",
|
|
165
|
-
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400]],
|
|
171
|
+
"steps": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400]],
|
|
166
172
|
"expect": {"visible":["#panel-review","#reviewList li","#doCreate"],"hidden":["#panel-address"],"text":[["#rev-h","Ready to roll"]]} }
|
|
167
173
|
]
|
|
168
174
|
}
|
|
@@ -35,19 +35,23 @@
|
|
|
35
35
|
"in-manage-gone": { "auth": true, "url": "/projects?view=manage&id=104", "expect": { "visible": ["#mMain", "#mActs"], "hidden": ["#mErr", "#mAddress"], "text": [["#mName", "old-lantern"]] } },
|
|
36
36
|
"in-manage-missing": { "auth": true, "url": "/projects?view=manage&id=999", "expect": { "visible": ["#mMissing"], "hidden": ["#mMain", "#mGate"] } },
|
|
37
37
|
"out-manage": { "auth": false, "url": "/projects?view=manage&id=101", "expect": { "visible": ["#mGate"], "hidden": ["#mMain", "#mMissing"] } },
|
|
38
|
-
"in-new": { "auth": true, "url": "/projects?view=new", "expect": { "hidden": ["#qWrap"] } },
|
|
38
|
+
"in-new": { "auth": true, "url": "/projects?view=new", "expect": { "visible": ["#panel-terms", "#termsAck"], "hidden": ["#qWrap", "#view-new .steps", "#panel-name"] } },
|
|
39
|
+
"in-new-terms-refused": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#panel-terms button[type=submit]"],["wait",300]], "expect": {"visible":["#panel-terms","#h-terms"],"hidden":["#panel-fork"],"text":[["#h-terms","Tick the box to go on. It’s how your project records that you acknowledged the terms."]]} },
|
|
40
|
+
"in-new-fork": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-fork",".doorPill","#wizDemo",".forkStage",".forkRoutes"],"hidden":["#panel-terms","#view-new .steps","#demoSoon",".bongoCell"]} },
|
|
41
|
+
"in-new-fork-demo": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#wizDemo"],["wait",200]], "expect": {"visible":["#panel-fork","#demoSoon"],"attr":[["#wizDemo","aria-expanded","true"]]} },
|
|
42
|
+
"in-new-name": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-name","#newName","#view-new .steps"],"hidden":["#panel-fork","#panel-terms"]} },
|
|
39
43
|
"out-new": { "auth": false, "url": "/projects?view=new", "expect": { "hidden": ["#qWrap"] } },
|
|
40
|
-
"in-new-type": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-type"],"hidden":["#panel-name","#qWrap"]} },
|
|
41
|
-
"in-new-about": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-detail"],"hidden":["#panel-type","#qWrap"]} },
|
|
42
|
-
"in-new-modules": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900]], "expect": {"visible":["#panel-modules","#modQ","#modCards .tpill[aria-pressed=\"true\"]","#modCoreNote"],"hidden":["#panel-detail","#qWrap"]} },
|
|
43
|
-
"in-new-modules-search": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["fill","#modQ","discord"],["wait",200]], "expect": {"visible":["#panel-modules","#modQ"],"value":[["#modQ","discord"]],"count":[["#modCards .tpill",1],["#modCards .tpill[data-mod=\"discord\"]",1]],"text":[["#modFilterNote","Showing 1 of 3. 2 extras are switched on, including any this search is hiding."]]} },
|
|
44
|
-
"in-new-home": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-home"],"hidden":["#panel-detail","#qWrap"]} },
|
|
45
|
-
"in-new-address": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-address"],"hidden":["#panel-home","#qWrap"]} },
|
|
46
|
-
"in-new-app": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-app","#appOpts","#appOptRender"],"hidden":["#panel-address","#panel-review","#qWrap"]} },
|
|
47
|
-
"in-new-app-render": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#appOptRender input"],["wait",300]], "expect": {"visible":["#panel-app","#renderSetup","#f-renderKey","#renderCheck"],"hidden":["#renderWs","#renderSvc","#renderNew"]} },
|
|
48
|
-
"in-new-review": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-review","#reviewList li"],"hidden":["#panel-address","#qWrap"]} },
|
|
49
|
-
"in-new-done": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400],["click","#doCreate"],["wait",1500]], "expect": {"visible":["#panel-done","#liveProgress .prog","#humanSteps li"],"hidden":["#panel-review","#qWrap"]} },
|
|
50
|
-
"in-new-resume-offer": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400],["click","#doCreate"],["wait",1500],["click","#projTrig"],["wait",350],["click","#menuProjects [data-nav=\"new\"]"],["wait",500]], "expect": {"visible":["#panel-
|
|
44
|
+
"in-new-type": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-type"],"hidden":["#panel-name","#qWrap"]} },
|
|
45
|
+
"in-new-about": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-detail"],"hidden":["#panel-type","#qWrap"]} },
|
|
46
|
+
"in-new-modules": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900]], "expect": {"visible":["#panel-modules","#modQ","#modCards .tpill[aria-pressed=\"true\"]","#modCoreNote"],"hidden":["#panel-detail","#qWrap"]} },
|
|
47
|
+
"in-new-modules-search": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["fill","#modQ","discord"],["wait",200]], "expect": {"visible":["#panel-modules","#modQ"],"value":[["#modQ","discord"]],"count":[["#modCards .tpill",1],["#modCards .tpill[data-mod=\"discord\"]",1]],"text":[["#modFilterNote","Showing 1 of 3. 2 extras are switched on, including any this search is hiding."]]} },
|
|
48
|
+
"in-new-home": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-home"],"hidden":["#panel-detail","#qWrap"]} },
|
|
49
|
+
"in-new-address": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-address"],"hidden":["#panel-home","#qWrap"]} },
|
|
50
|
+
"in-new-app": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-app","#appOpts","#appOptRender"],"hidden":["#panel-address","#panel-review","#qWrap"]} },
|
|
51
|
+
"in-new-app-render": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#appOptRender input"],["wait",300]], "expect": {"visible":["#panel-app","#renderSetup","#f-renderKey","#renderCheck"],"hidden":["#renderWs","#renderSvc","#renderNew"]} },
|
|
52
|
+
"in-new-review": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400]], "expect": {"visible":["#panel-review","#reviewList li"],"hidden":["#panel-address","#qWrap"]} },
|
|
53
|
+
"in-new-done": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400],["click","#doCreate"],["wait",1500]], "expect": {"visible":["#panel-done","#liveProgress .prog","#humanSteps li"],"hidden":["#panel-review","#qWrap"]} },
|
|
54
|
+
"in-new-resume-offer": { "auth": true, "url": "/projects?view=new", "actions": [["wait",600],["click","#termsAck"],["click","#panel-terms button[type=submit]"],["wait",400],["click","#panel-fork button[type=submit]"],["wait",400],["fill","#newName","Mercury"],["click","#panel-name button[type=submit]"],["wait",400],["click","#typeCards .tpill[data-type=\"game\"]"],["click","#panel-type button[type=submit]"],["wait",400],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#teamCards .tpill[data-team=\"small-team\"]"],["click","#panel-detail button[type=submit]"],["wait",900],["click","#panel-modules button[type=submit]"],["wait",400],["click","#panel-home button[type=submit]"],["wait",400],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#panel-address button[type=submit]"],["wait",400],["click","#panel-app button[type=submit]"],["wait",400],["click","#doCreate"],["wait",1500],["click","#projTrig"],["wait",350],["click","#menuProjects [data-nav=\"new\"]"],["wait",500]], "expect": {"visible":["#panel-terms","#wizResume","#wizResumeGo"],"hidden":["#panel-done","#panel-name"],"text":[["#wizResumeName","Mercury"]]} },
|
|
51
55
|
"out-map-projects": { "auth": false, "actions": [["click", "#projTrig"], ["wait", 350]], "expect": { "expanded": true, "hidden": ["#menuProjects [data-nav=\"mine\"]"] } },
|
|
52
56
|
"card": { "auth": true, "actions": [["dispatchClick", "#orbField a.worldOrb[data-origin=\"https://example.com\"]"], ["wait", 900]], "expect": { "dialog": true, "hasClass": [["#projCard", "has-art"]], "visible": ["#cardArt", "#cardFaces", "#cardBuildersFig", "#cardShippedFig", "#cardOpen", "#cardHall"], "text": [["#cardBuilders", "11"], ["#cardShipped", "0"], ["#cardRel", "you build here"], ["#cardRuns", "example.com"], ["#cardFaces .facesMore", "+6"]], "count": [["#cardFaces img", 5]], "href": [["#cardHall", "https://builders.example.com/"]] } },
|
|
53
57
|
"card-noart": { "auth": true, "actions": [["dispatchClick", "#orbField a.worldOrb[data-origin=\"https://emersonian-circles.cloudbongos.com\"]"], ["wait", 600]], "expect": { "dialog": true, "hasClass": [["#projCard", "has-art", false]], "hidden": ["#cardArt", "#cardFaces", "#cardHall"], "visible": ["#cardBuildersFig", "#cardShippedFig", "#cardOpen"], "text": [["#cardShipped", "30+"], ["#cardRel", "you build here"]] } },
|
|
@@ -393,6 +393,12 @@ const server = http.createServer((req, res) => {
|
|
|
393
393
|
const all = JSON.parse(fs.readFileSync(path.join(FIXTURES, 'provisioning-instance-render.json'), 'utf8'));
|
|
394
394
|
return json(res, 200, all[appRead[1]] || { ok: true, app: null, env_vars: [], values_held: false });
|
|
395
395
|
}
|
|
396
|
+
// the done panel's invite step (R28, ADR 0251) asks who is worth inviting; the stub
|
|
397
|
+
// gives the route's own "nobody to look for" answer, so a render that lingers on the
|
|
398
|
+
// done panel pictures that branch instead of a 404 (found by task 1004417's render)
|
|
399
|
+
if (/^\/provisioning\/instances\/\d+\/invite-suggestions$/.test(rest) && req.method === 'GET') {
|
|
400
|
+
return AUTH ? json(res, 200, { suggested: [], seeking: null, reason: null }) : json(res, 401, UNAUTH);
|
|
401
|
+
}
|
|
396
402
|
const one = rest.match(/^\/provisioning\/instances\/(\d+)(\/settings)?$/);
|
|
397
403
|
if (one && req.method === 'GET') return AUTH ? instances(res, one[1], !!one[2]) : json(res, 401, UNAUTH);
|
|
398
404
|
// the hub's own cross-project surface (task 1003774): the requested/leave/
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.50",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.20.
|
|
9
|
+
"version": "1.20.50",
|
|
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.20.
|
|
3
|
+
"version": "1.20.50",
|
|
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
|
@@ -8401,5 +8401,17 @@
|
|
|
8401
8401
|
"id": "1004422",
|
|
8402
8402
|
"text": "While a new project is being founded, its builders hall now shows a clear \"project founding mode\" band at the top and dims the rooms that open later. A hall that isn't being founded stays exactly as it was."
|
|
8403
8403
|
}
|
|
8404
|
+
],
|
|
8405
|
+
"1.20.49": [
|
|
8406
|
+
{
|
|
8407
|
+
"id": "1004402",
|
|
8408
|
+
"text": "A goal's page now shows where each checklist item really stands: Awaiting UAT, Satisfied, or Closed before UAT, with a Backend-only tag where there is nothing to record. The old Confirm button is gone. Instead, an item whose w"
|
|
8409
|
+
}
|
|
8410
|
+
],
|
|
8411
|
+
"1.20.50": [
|
|
8412
|
+
{
|
|
8413
|
+
"id": "1004417",
|
|
8414
|
+
"text": "Starting a new project now begins with two decisions before any setup. First screen, \"anything you want to make\": the founder ticks that they can sign legally for the platform and acknowledge the terms, with a link to read the"
|
|
8415
|
+
}
|
|
8404
8416
|
]
|
|
8405
8417
|
}
|
|
@@ -105,6 +105,8 @@ const FIXTURE_FALLBACKS = [
|
|
|
105
105
|
[/^goals\/\d+\/dependency-forest$/, 'goals__dependency-forest'],
|
|
106
106
|
[/^goals\/\d+\/requests$/, 'goals__requests'],
|
|
107
107
|
[/^goals\/\d+$/, 'goals__detail'],
|
|
108
|
+
// a criterion's UAT panel (task 1004402): one Awaiting UAT reading serves any id.
|
|
109
|
+
[/^done-when\/\d+\/uat$/, 'done-when__uat'],
|
|
108
110
|
[/^tasks\/\d+$/, 'tasks__detail'],
|
|
109
111
|
// the #/idea/N + #/blocker/N deep-link overlay (task-detail.js) — one record
|
|
110
112
|
// fixture serves any id so the overlay seam assertion renders real content.
|
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.20.
|
|
78
|
+
const CORE_VERSION = '1.20.50'; // 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');
|
package/tests/claim_action.mjs
CHANGED
|
@@ -401,8 +401,13 @@ await test('the cache-bust moved on every page whose script changed', () => {
|
|
|
401
401
|
['goals.html', ['goals-render.js', 'goals-page.js']],
|
|
402
402
|
]) {
|
|
403
403
|
const html = read('modules', 'hall-ui', 'public', page);
|
|
404
|
+
// The invariant is "busted AT OR AFTER the claim-action change", not the
|
|
405
|
+
// literal stamp: a later change to the same script bumps it again (task
|
|
406
|
+
// 1004402 did), and a pin on the string would fail that correct bump.
|
|
404
407
|
for (const s of scripts) {
|
|
405
|
-
|
|
408
|
+
const m = new RegExp(s.replace('.', '\\.') + '\\?v=(\\d{4}-\\d{2}-\\d{2})').exec(html);
|
|
409
|
+
assert.ok(m, `${page}: ${s} carries no dated cache-bust`);
|
|
410
|
+
assert.ok(m[1] >= '2026-09-26', `${page}: ${s} not busted since the claim-action change (${m[1]})`);
|
|
406
411
|
}
|
|
407
412
|
}
|
|
408
413
|
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// tests/criterion_uat_ui.mjs — the hall's criterion UAT helpers (task 1004402,
|
|
2
|
+
// ADR 0351), DB-free and DOM-free. The page-level wiring is driven for real in
|
|
3
|
+
// tests/goal_criterion_confirm_ui.mjs; this file pins the vocabulary and the
|
|
4
|
+
// panel's variations.
|
|
5
|
+
//
|
|
6
|
+
// 1. The labels equal the server's (modules/lifecycle/criterion-uat.js
|
|
7
|
+
// stateLabel), so the hall, /status and /goal-uat say the same thing. The
|
|
8
|
+
// browser cannot require server code, so this is the lockstep.
|
|
9
|
+
// 2. The backend-only switch appears only where it can work: an OPEN criterion,
|
|
10
|
+
// in the full view, for a reviewer, on a server that knows the rule.
|
|
11
|
+
// 3. The panel asks for what the server will require and nothing else: the
|
|
12
|
+
// attestation only where the site cannot read its own deploy; no file field
|
|
13
|
+
// on a backend-only criterion; no form for a viewer who cannot sign.
|
|
14
|
+
// 4. A stale sign-off is said to no longer count, never shown as the UAT.
|
|
15
|
+
//
|
|
16
|
+
// Run: node tests/criterion_uat_ui.mjs
|
|
17
|
+
|
|
18
|
+
import { strict as assert } from 'node:assert';
|
|
19
|
+
import { createRequire } from 'node:module';
|
|
20
|
+
import { makeRunner } from './helpers.mjs';
|
|
21
|
+
|
|
22
|
+
const require = createRequire(import.meta.url);
|
|
23
|
+
const ui = require('../modules/hall-ui/public/criterion-uat-ui.js');
|
|
24
|
+
const server = require('../modules/lifecycle/criterion-uat.js');
|
|
25
|
+
const { test, summary } = makeRunner();
|
|
26
|
+
|
|
27
|
+
await test('LABELS: every server state has the same words in the hall', () => {
|
|
28
|
+
for (const state of Object.values(server.UAT_STATES)) {
|
|
29
|
+
assert.equal(ui.STATE_LABELS[state], server.stateLabel(state), state);
|
|
30
|
+
}
|
|
31
|
+
assert.equal(Object.keys(ui.STATE_LABELS).length, Object.values(server.UAT_STATES).length, 'no hall-only state');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
await test('STATE: an older server with no uat_state reads plainly and never as a UAT state', () => {
|
|
35
|
+
assert.equal(ui.stateOf({ satisfied: true }), 'legacy_satisfied');
|
|
36
|
+
assert.equal(ui.stateOf({ satisfied: false }), 'open');
|
|
37
|
+
assert.equal(ui.badgesHtml({ satisfied: true }), '');
|
|
38
|
+
assert.equal(ui.actionHtml({ id: 1, satisfied: true }, { canReview: true, full: true }), '');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
await test('BACKEND-ONLY SWITCH: only on an OPEN criterion, in the full view, for a reviewer', () => {
|
|
42
|
+
const open = { id: 9, uat_state: 'open', satisfied: false };
|
|
43
|
+
assert.match(ui.actionHtml(open, { canReview: true, full: true }), /data-uat-backend="9" data-on="1"/);
|
|
44
|
+
assert.match(ui.actionHtml({ ...open, backend_only: true }, { canReview: true, full: true }), /data-on="0"[^>]*>Not backend-only/);
|
|
45
|
+
assert.equal(ui.actionHtml(open, { canReview: true, full: false }), '', 'not in the capped band: it is an authoring act');
|
|
46
|
+
assert.equal(ui.actionHtml(open, { canReview: false, full: true }), '');
|
|
47
|
+
assert.doesNotMatch(ui.actionHtml({ id: 9, uat_state: 'awaiting_uat' }, { canReview: true, full: true }), /data-uat-backend/,
|
|
48
|
+
'once awaiting, the server refuses it, so the page does not offer it');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const VIEW = (over = {}) => ({
|
|
52
|
+
criterion: { id: 42 },
|
|
53
|
+
uat_state: 'awaiting_uat',
|
|
54
|
+
backend_only: false,
|
|
55
|
+
checks: { code: true, live: { available: false }, uat: null, stale_uat: null },
|
|
56
|
+
...over,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
await test('PANEL: a site that cannot read its deploy asks for the attestation; one that can, does not', () => {
|
|
60
|
+
const blind = ui.panelHtml(VIEW(), { apiBase: '/api/bongos', canReview: true });
|
|
61
|
+
assert.match(blind, /data-uat-attest="42"/);
|
|
62
|
+
assert.match(blind, /data-uat-file="42"/);
|
|
63
|
+
const seeing = ui.panelHtml(VIEW({ checks: { code: true, live: { available: true, live: true }, uat: null } }), { apiBase: '/api/bongos', canReview: true });
|
|
64
|
+
assert.doesNotMatch(seeing, /data-uat-attest/);
|
|
65
|
+
assert.match(seeing, /Running on the live site\./);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await test('PANEL: not live yet names the tasks, in plain words', () => {
|
|
69
|
+
const html = ui.panelHtml(VIEW({ checks: { code: true, live: { available: true, live: false, not_live: [{ task_id: '12' }] }, uat: null } }), { apiBase: '', canReview: true });
|
|
70
|
+
assert.match(html, /not on the live site yet \(#12\)/);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
await test('PANEL: a backend-only criterion has no file field and asks how it was checked', () => {
|
|
74
|
+
const html = ui.panelHtml(VIEW({ backend_only: true }), { apiBase: '', canReview: true });
|
|
75
|
+
assert.doesNotMatch(html, /data-uat-file/);
|
|
76
|
+
assert.match(html, /How you checked it/);
|
|
77
|
+
assert.match(html, />Sign off</);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
await test('PANEL: a viewer who cannot sign sees the checks and no form', () => {
|
|
81
|
+
const html = ui.panelHtml(VIEW(), { apiBase: '', canReview: false });
|
|
82
|
+
assert.match(html, /uat-checks/);
|
|
83
|
+
assert.doesNotMatch(html, /data-uat-form/);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await test('PANEL: a stale sign-off is said to no longer count, and its recording still plays', () => {
|
|
87
|
+
const stale = { kind: 'uat', signed_off_by_login: 'ana', created_at: '2026-09-20T10:00:00Z', recording_file: 'uat-42-0123456789abcdef.mp4' };
|
|
88
|
+
const html = ui.panelHtml(VIEW({ checks: { code: true, live: { available: false }, uat: null, stale_uat: stale } }), { apiBase: '/api/bongos', canReview: true });
|
|
89
|
+
assert.match(html, /no longer counts: more work shipped after it/);
|
|
90
|
+
assert.match(html, /<video class="uat-video" controls preload="metadata" src="\/api\/bongos\/criterion-uats\/recordings\/uat-42-0123456789abcdef\.mp4">/);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
await test('PANEL: a closed criterion shows who signed it and when, and offers no form', () => {
|
|
94
|
+
const html = ui.panelHtml(VIEW({ uat_state: 'satisfied_uat', checks: { code: true, live: null, uat: { kind: 'uat', signed_off_by_login: 'ana', created_at: '2026-09-28T10:00:00Z', note: 'made a rank' } } }), { apiBase: '', canReview: true });
|
|
95
|
+
assert.match(html, /Tried on the live site by ana/);
|
|
96
|
+
assert.match(html, /made a rank/);
|
|
97
|
+
assert.doesNotMatch(html, /data-uat-form/);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await test('ESCAPING: a note or a login can never become markup', () => {
|
|
101
|
+
const html = ui.panelHtml(VIEW({ uat_state: 'satisfied_uat', checks: { code: true, uat: { kind: 'uat', signed_off_by_login: '<b>x</b>', created_at: '2026-09-28', note: '"><script>alert(1)</script>' } } }), { apiBase: '', canReview: false });
|
|
102
|
+
assert.doesNotMatch(html, /<script>|<b>x<\/b>/);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await test('REFUSALS: the server\'s sentence wins; the fallbacks are plain words', () => {
|
|
106
|
+
assert.equal(ui.refusalText({ error: { code: 'work_not_live', message: 'Some of this work is not deployed yet.' } }, 409), 'Some of this work is not deployed yet.');
|
|
107
|
+
assert.match(ui.refusalText({}, 413), /100 MB cap/);
|
|
108
|
+
assert.match(ui.refusalText(null, 500), /did not go through \(500\)/);
|
|
109
|
+
assert.equal(ui.checkFile({ type: 'video/webm', size: 5 }), null);
|
|
110
|
+
assert.equal(ui.checkFile(null), 'Choose the recording first.');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
summary();
|