@bongos/core 1.24.10 → 1.24.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bongos-core.json +171 -86
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +12 -0
- package/clients/bongos-client/index.cjs +12 -0
- package/clients/bongos-client/index.d.ts +18 -1
- package/clients/bongos-client/index.mjs +12 -0
- package/docs/api/openapi.json +304 -5
- package/docs/api-reference.md +14 -4
- package/docs/architecture.md +4 -0
- package/docs/copy-inventory.md +154 -76
- package/docs/copy-registry.json +923 -125
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +68 -4
- package/docs/page-readings.json +873 -819
- package/modules/government/decision-rules.js +1 -0
- package/modules/hall-ui/public/ai-studio.html +1 -1
- package/modules/hall-ui/public/atlas.html +1 -1
- package/modules/hall-ui/public/blockers.html +1 -1
- package/modules/hall-ui/public/board-room.html +1 -1
- package/modules/hall-ui/public/city.html +1 -1
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/commands.html +1 -1
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/craft-mode.js +2 -2
- package/modules/hall-ui/public/deploy.html +1 -1
- package/modules/hall-ui/public/diagrams.html +1 -1
- package/modules/hall-ui/public/drachmae.html +1 -1
- package/modules/hall-ui/public/fleet.html +1 -1
- package/modules/hall-ui/public/gate.html +1 -1
- package/modules/hall-ui/public/goal-map.html +1 -1
- package/modules/hall-ui/public/goals.html +1 -1
- package/modules/hall-ui/public/government.html +1 -1
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/ideas.html +1 -1
- package/modules/hall-ui/public/index.html +1 -1
- package/modules/hall-ui/public/market-watch-item.html +83 -0
- package/modules/hall-ui/public/market-watch-item.js +150 -0
- package/modules/hall-ui/public/market-watch-item.states.json +143 -0
- package/modules/hall-ui/public/market-watch-lib.js +243 -0
- package/modules/hall-ui/public/market-watch-rules.html +1 -1
- package/modules/hall-ui/public/market-watch-settings.html +1 -1
- package/modules/hall-ui/public/market-watch.css +169 -0
- package/modules/hall-ui/public/market-watch.html +111 -0
- package/modules/hall-ui/public/market-watch.js +129 -0
- package/modules/hall-ui/public/market-watch.states.json +14 -0
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/my-agents.html +1 -1
- package/modules/hall-ui/public/primer.html +1 -1
- package/modules/hall-ui/public/profile.html +1 -1
- package/modules/hall-ui/public/project-settings.css +12 -0
- package/modules/hall-ui/public/project-settings.html +1 -1
- package/modules/hall-ui/public/project-settings.js +63 -1
- package/modules/hall-ui/public/ranks.html +1 -1
- package/modules/hall-ui/public/roadmap.html +1 -1
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/sessions.html +1 -1
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell.js +3 -2
- package/modules/hall-ui/public/street.html +1 -1
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/task.js +34 -1
- package/modules/hall-ui/public/thinking.html +1 -1
- package/modules/hall-ui/public/tweak-editor.html +1 -1
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/hall-ui/records/market-watch.md +40 -0
- package/modules/lifecycle/migrations/lifecycle_018_pay_terms.sql +64 -0
- package/modules/lifecycle/pay-terms.js +171 -0
- package/modules/lifecycle/routes/project-settings.js +94 -0
- package/modules/lifecycle/routes/task-write-routes.js +35 -4
- package/modules/market-watch/db.js +10 -8
- package/modules/market-watch/module.json +2 -1
- package/modules/market-watch/pages.js +323 -0
- package/modules/market-watch/proposals.js +66 -4
- package/modules/market-watch/routes/pages.js +116 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/scripts/bongos/government-walk.js +1 -0
- package/scripts/bongos/run-unit-tests.js +4 -0
- package/scripts/bongos/start.js +42 -2
- package/src/bongos/module-scope-map.js +1 -0
- package/src/module-api.js +1 -1
- package/tests/fixtures/market-watch-seed-rows.cjs +60 -0
- package/tests/government_act_alone_buildings.mjs +1 -0
- package/tests/hall_nav.mjs +4 -1
- package/tests/hall_page_gate_map.mjs +4 -0
- package/tests/market_watch_module.mjs +2 -1
- package/tests/market_watch_pages.mjs +356 -0
- package/tests/market_watch_rules.mjs +63 -3
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/patch_gate_ordering.mjs +3 -0
- package/tests/pay_terms.mjs +254 -0
- package/tests/pay_terms_db.mjs +86 -0
- package/tests/project_settings_page.mjs +25 -6
|
@@ -67,6 +67,7 @@ const AREAS = Object.freeze([
|
|
|
67
67
|
'PATCH /project-settings/rot-days',
|
|
68
68
|
'PATCH /project-settings/ship-mode',
|
|
69
69
|
'PATCH /project-settings/tweak-autopickup',
|
|
70
|
+
'PATCH /project-settings/pay-terms', // task 1004990: the project's standing pay terms
|
|
70
71
|
'PATCH /work-categories/:id',
|
|
71
72
|
// task 1004941: the owner approving a Market Watch proposal (a passed
|
|
72
73
|
// matter approves it through the market_watch_proposal act instead)
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
89
89
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
90
90
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
91
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
91
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
92
92
|
<script src="/builders/palette.js" defer></script>
|
|
93
93
|
<script src="/builders/tweak-editor-lib.js?v=2026-09-28-tw23"></script>
|
|
94
94
|
<script src="/builders/studio-lib.js?v=2026-10-09-day"></script>
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
93
93
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
94
94
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
95
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
95
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
96
96
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
97
97
|
<script src="/builders/palette.js" defer></script>
|
|
98
98
|
<script src="/builders/atlas.js?v=2026-09-02-index" defer></script>
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
62
62
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
63
63
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
64
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
64
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
65
65
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
66
66
|
<script src="/builders/palette.js" defer></script>
|
|
67
67
|
<!-- the branding pack's currency label, loaded BEFORE blockers.js. -->
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
62
62
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
63
63
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
64
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
64
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
65
65
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
66
66
|
<script src="/builders/palette.js" defer></script>
|
|
67
67
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
109
109
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab" defer></script>
|
|
110
110
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch" defer></script>
|
|
111
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch" defer></script>
|
|
111
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages" defer></script>
|
|
112
112
|
<script src="/builders/palette.js" defer></script>
|
|
113
113
|
<script src="/builders/gov-living.js?v=2026-10-09-positions1" defer></script>
|
|
114
114
|
<script src="/builders/gov-feeds.js?v=2026-10-09-living3" defer></script>
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
163
163
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
164
164
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
165
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
165
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
166
166
|
<script src="/builders/palette.js" defer></script>
|
|
167
167
|
<script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
|
|
168
168
|
<script src="/builders/collab.js?v=2026-09-24-archive"></script>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
55
55
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
56
56
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
57
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
57
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
58
58
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
59
59
|
<script src="/builders/palette.js" defer></script>
|
|
60
60
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -180,7 +180,7 @@
|
|
|
180
180
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
181
181
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
182
182
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
183
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
183
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
184
184
|
<script src="/builders/palette.js" defer></script>
|
|
185
185
|
<script src="/builders/hall-kit.js"></script>
|
|
186
186
|
<script src="/builders/copy-desk.js?v=2026-09-01-redesign"></script>
|
|
@@ -103,9 +103,9 @@
|
|
|
103
103
|
var MODE_TABS = {
|
|
104
104
|
building: ['home', 'roadmap', 'goals', 'goal-map', 'work', 'blockers', 'thinking', 'studio',
|
|
105
105
|
'standing',
|
|
106
|
-
'primer', 'ranks', 'economy', 'commands', 'diagrams', 'atlas', 'modules', 'apidocs'],
|
|
106
|
+
'primer', 'ranks', 'economy', 'commands', 'diagrams', 'atlas', 'modules', 'apidocs', 'market-watch'],
|
|
107
107
|
artistry: ['studio', 'goals', 'thinking'],
|
|
108
|
-
ideating: ['goal-map', 'thinking', 'goals'],
|
|
108
|
+
ideating: ['goal-map', 'thinking', 'goals', 'market-watch'],
|
|
109
109
|
governing: ['city', 'blockers', 'board-room',
|
|
110
110
|
'watch', 'gate', 'sessions', 'project-settings', 'deploy', 'fleet', 'market-watch-settings', 'government'],
|
|
111
111
|
};
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
80
80
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
81
81
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
82
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
82
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
83
83
|
<script src="/builders/palette.js" defer></script>
|
|
84
84
|
<script src="/builders/hall-kit.js"></script>
|
|
85
85
|
<!-- the shared ask card the move is drawn with (task 1004829) -->
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
98
98
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
99
99
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
100
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
100
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
101
101
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
102
102
|
<script src="/builders/palette.js" defer></script>
|
|
103
103
|
<script src="/builders/diagram-viewer.js?v=2026-06-14-diagviewer-1" defer></script>
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
98
98
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
99
99
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
100
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
100
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
101
101
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
102
102
|
<script src="/builders/palette.js" defer></script>
|
|
103
103
|
<script src="/builders/md-reader.js?v=2026-09-02-mdreader-2"></script>
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
59
59
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
60
60
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
61
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
61
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
62
62
|
<script src="/builders/palette.js" defer></script>
|
|
63
63
|
<script src="/builders/hall-kit.js"></script>
|
|
64
64
|
<script src="/builders/fleet-costs.js"></script>
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
66
66
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
67
67
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
68
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
68
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
69
69
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
70
70
|
<script src="/builders/palette.js" defer></script>
|
|
71
71
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
141
141
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
142
142
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
143
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
143
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
144
144
|
<script src="/builders/palette.js" defer></script>
|
|
145
145
|
|
|
146
146
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
245
245
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
246
246
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
247
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
247
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
248
248
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
249
249
|
<script src="/builders/palette.js" defer></script>
|
|
250
250
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
156
156
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
157
157
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
158
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
158
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
159
159
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
160
160
|
<script src="/builders/palette.js" defer></script>
|
|
161
161
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
54
54
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
55
55
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
56
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
56
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
57
57
|
<script src="/builders/palette.js" defer></script>
|
|
58
58
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N overlay, so a ref
|
|
59
59
|
written inside an idea's own prose keeps resolving from this page. -->
|
|
@@ -228,7 +228,7 @@
|
|
|
228
228
|
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
229
229
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
230
230
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch"></script>
|
|
231
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch"></script>
|
|
231
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
232
232
|
<script src="/builders/palette.js" defer></script>
|
|
233
233
|
<!-- task 1004727: the ONE karma vote control every task/idea list renders -->
|
|
234
234
|
<script src="/builders/vote-control.js"></script>
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
<script src="/builders/welcome-boot.js?v=2026-10-23-city1" defer></script>
|
|
120
120
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab" defer></script>
|
|
121
121
|
<script src="/builders/craft-mode.js?v=2026-10-30-market-watch" defer></script>
|
|
122
|
-
<script src="/builders/shell.js?v=2026-10-30-market-watch" defer></script>
|
|
122
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages" defer></script>
|
|
123
123
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
124
124
|
<script src="/builders/palette.js" defer></script>
|
|
125
125
|
<!-- task 2166: the shared component kit (window.OTBKit) — pager/ledger/rail.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Market Watch item — {{worldName}}</title>
|
|
7
|
+
<meta name="description" content="One tracked competitor, partner or topic: its card, its scores over time and its sourced case file.">
|
|
8
|
+
<link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
|
|
9
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
|
|
12
|
+
<link rel="stylesheet" href="/builders/market-watch.css">
|
|
13
|
+
</head>
|
|
14
|
+
<body data-page="market-watch-item" data-page-title="Market Watch">
|
|
15
|
+
|
|
16
|
+
<div class="app">
|
|
17
|
+
<aside class="app-sidebar" id="app-sidebar" aria-label="Primary"></aside>
|
|
18
|
+
<div class="app-scrim" id="app-scrim" hidden></div>
|
|
19
|
+
<div class="app-body">
|
|
20
|
+
<header class="app-topbar" id="app-topbar"></header>
|
|
21
|
+
<div class="app-content">
|
|
22
|
+
<!-- The page's one h1, for screen readers: no page shows its head (task 1004836). -->
|
|
23
|
+
<div class="page-head page-head--room">
|
|
24
|
+
<h1 class="page-head__h" id="mw-h1">Market Watch item</h1>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<main id="hall-main">
|
|
28
|
+
<a class="mw-back" href="/market-watch">‹ Market Watch</a>
|
|
29
|
+
<p class="mw-quiet" id="mw-loading">Loading the case file…</p>
|
|
30
|
+
|
|
31
|
+
<section class="mw-panel mw-off" id="mw-off" hidden>
|
|
32
|
+
<span class="mw-label">market watch</span>
|
|
33
|
+
<p>Market Watch is off on this project.</p>
|
|
34
|
+
<p class="mw-quiet">An owner can turn it on from <a href="/modules">Modules</a>.</p>
|
|
35
|
+
</section>
|
|
36
|
+
|
|
37
|
+
<section class="mw-panel mw-off" id="mw-fail" hidden>
|
|
38
|
+
<p id="mw-fail-text">Could not read this item. Try reloading the page.</p>
|
|
39
|
+
</section>
|
|
40
|
+
|
|
41
|
+
<div class="mw-wrap" id="mw-wrap" hidden>
|
|
42
|
+
<aside class="mw-card" id="mw-card" aria-label="The item card"></aside>
|
|
43
|
+
<section>
|
|
44
|
+
<div class="mw-sec"><span class="mw-label">why it's on the watch</span><div class="mw-panel mw-why" id="mw-why"></div></div>
|
|
45
|
+
<div class="mw-sec" id="mw-facts-sec"><span class="mw-label">known facts</span><div class="mw-panel mw-facts" id="mw-facts"></div></div>
|
|
46
|
+
<div class="mw-sec"><span class="mw-label" id="mw-logl">case file</span>
|
|
47
|
+
<div class="mw-filter" id="mw-filter"></div>
|
|
48
|
+
<div class="mw-panel mw-log">
|
|
49
|
+
<table>
|
|
50
|
+
<thead><tr>
|
|
51
|
+
<th data-s="found" aria-sort="descending"><button type="button">found</button></th>
|
|
52
|
+
<th class="mw-c-run" data-s="run"><button type="button">run</button></th>
|
|
53
|
+
<th data-s="type"><button type="button">type</button></th>
|
|
54
|
+
<th data-s="takeaway"><button type="button">takeaway</button></th>
|
|
55
|
+
<th class="mw-c-conf" data-s="confidence"><button type="button">conf.</button></th>
|
|
56
|
+
<th><span>source</span></th>
|
|
57
|
+
</tr></thead>
|
|
58
|
+
<tbody id="mw-log"></tbody>
|
|
59
|
+
</table>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</section>
|
|
63
|
+
</div>
|
|
64
|
+
</main>
|
|
65
|
+
|
|
66
|
+
<footer class="app-foot" id="app-foot"></footer>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<dialog class="mw-dialog" id="mw-propose" aria-label="Propose a change"></dialog>
|
|
72
|
+
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
73
|
+
|
|
74
|
+
<script src="/builders/dom-utils.js?v=2026-10-25-escape"></script>
|
|
75
|
+
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
76
|
+
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
77
|
+
<script src="/builders/shell.js?v=2026-10-30-market-watch-pages"></script>
|
|
78
|
+
<script src="/builders/palette.js" defer></script>
|
|
79
|
+
<script src="/builders/hall-kit.js"></script>
|
|
80
|
+
<script src="/builders/market-watch-lib.js"></script>
|
|
81
|
+
<script src="/builders/market-watch-item.js"></script>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// market-watch-item.js — one tracked item, the dossier (task 1004939; design of record
|
|
2
|
+
// docs/design/mocks/market-watch/item.html, option B). The item is a card that levels up
|
|
3
|
+
// run by run; beside it, why it is watched, its facts and its sortable case file.
|
|
4
|
+
//
|
|
5
|
+
// One read, GET /market-watch/items/:id (every signed-in member). The buttons:
|
|
6
|
+
// Propose a change re-score, move between partner and competitor, add a source, or
|
|
7
|
+
// correct an entry, each with a one-line reason → a proposal row
|
|
8
|
+
// Stop tracking a one-line reason → a remove_item proposal (the government decides)
|
|
9
|
+
// Pin this viewer's own shortcut on the Market Watch home (localStorage)
|
|
10
|
+
(() => {
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const MW = window.OTBMarketWatch;
|
|
14
|
+
const esc = MW.esc;
|
|
15
|
+
const $ = (id) => document.getElementById(id);
|
|
16
|
+
const toast = (m) => (window.OTB && window.OTB.toast ? window.OTB.toast(m, { duration: 2400, clear: true }) : null);
|
|
17
|
+
let VIEW = null;
|
|
18
|
+
let SORT = { key: 'found', dir: -1 };
|
|
19
|
+
let TYPE = ''; // the case file's type filter: '' is every type
|
|
20
|
+
|
|
21
|
+
function show(id) {
|
|
22
|
+
$('mw-loading').hidden = true;
|
|
23
|
+
for (const k of ['mw-off', 'mw-fail', 'mw-wrap']) $(k).hidden = k !== id;
|
|
24
|
+
}
|
|
25
|
+
function fail(msg) { $('mw-fail-text').textContent = msg; show('mw-fail'); }
|
|
26
|
+
function moduleOff() {
|
|
27
|
+
const m = window.__MODULES__;
|
|
28
|
+
return !!(m && m.enabled && 'market-watch' in m.enabled && m.enabled['market-watch'] !== true);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function shortName(name) { return String(name).replace(/\s*\(.*\)\s*$/, '') || String(name); }
|
|
32
|
+
|
|
33
|
+
function renderCard(v) {
|
|
34
|
+
const it = v.item;
|
|
35
|
+
const o = v.overall;
|
|
36
|
+
const last = o.latest;
|
|
37
|
+
const word = it.kind === 'partner' ? 'fit' : 'likeness';
|
|
38
|
+
const runs = v.runs.length;
|
|
39
|
+
const solid = v.entries.filter((e) => e.confidence === 3).length;
|
|
40
|
+
const pinned = MW.pins.has(it.id);
|
|
41
|
+
$('mw-card').innerHTML = `<div class="mw-holo"><span class="mw-holo__kind">${esc(it.kind)}</span><span class="mw-holo__ini" aria-hidden="true">${esc(MW.initials(it.name))}</span><div class="mw-holo__nm" title="${esc(it.name)}">${esc(it.name)}</div></div>
|
|
42
|
+
<div class="mw-lvl"><div class="mw-ring" style="--p:${last == null ? 0 : Math.round((last / 10) * 100)}"><b>${last == null ? '–' : esc(last)}</b></div>
|
|
43
|
+
<div class="mw-one"><div class="mw-vtag">Level ${esc(it.level)}</div><div class="mw-quiet">${word} ${o.first == null ? '–' : esc(o.first)} → ${last == null ? '–' : esc(last)} over ${runs} ${runs === 1 ? 'run' : 'runs'}</div></div>
|
|
44
|
+
<div style="margin-left:auto">${MW.spark(o.series, 60, 26, `${word} over the runs`)}</div></div>
|
|
45
|
+
<div class="mw-stats">${v.dimensions.map((d) => `<div class="mw-st">${window.OTBKit.barSeriesHtml([{ label: d.label, value: d.latest == null ? 0 : d.latest, valueLabel: d.latest == null ? '–' : d.latest }], { max: 10, tone: 'neutral', valueWidth: '24px' })}${MW.spark(d.series, 70, 20, `${d.label} over the runs`)}</div>`).join('')}</div>
|
|
46
|
+
<div class="mw-badges"><span class="mw-bdg${it.streak > 1 ? ' mw-bdg--hot' : ''}">${esc(it.streak)}-run streak</span><span class="mw-bdg">◆ ${solid} solid ${solid === 1 ? 'find' : 'finds'}</span>${v.moved ? `<span class="mw-bdg">↗ ${v.moved} ${v.moved === 1 ? 'score' : 'scores'} moved</span>` : ''}${v.open_proposals ? `<span class="mw-bdg mw-bdg--hot">${v.open_proposals} open ${v.open_proposals === 1 ? 'proposal' : 'proposals'}</span>` : ''}</div>
|
|
47
|
+
<div class="mw-acts"><button class="btn mw-wide" type="button" data-act="propose">propose a change</button><button class="btn btn--ghost" type="button" data-act="pin" aria-pressed="${pinned}">${pinned ? 'pinned' : 'pin'}</button><button class="btn btn--ghost" type="button" data-act="stop"${it.status !== 'active' ? ' disabled' : ''}>stop tracking</button></div>`;
|
|
48
|
+
$('mw-card').querySelectorAll('[data-act]').forEach((b) => b.addEventListener('click', () => act(b.dataset.act, b)));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function act(a, btn) {
|
|
52
|
+
const it = VIEW.item;
|
|
53
|
+
if (a === 'pin') {
|
|
54
|
+
const on = MW.pins.toggle(it);
|
|
55
|
+
btn.setAttribute('aria-pressed', String(on));
|
|
56
|
+
btn.textContent = on ? 'pinned' : 'pin';
|
|
57
|
+
toast(on ? `${shortName(it.name)} pinned to the top of Market Watch` : 'Unpinned');
|
|
58
|
+
} else if (a === 'stop') {
|
|
59
|
+
MW.openPropose('stop', { item: it }, () => toast(`Asked the government to stop tracking ${shortName(it.name)}`));
|
|
60
|
+
} else if (a === 'propose') {
|
|
61
|
+
MW.openPropose('change', { item: it, dimensions: VIEW.dimensions, entries: VIEW.entries }, () => {
|
|
62
|
+
toast('Proposal sent to the project government');
|
|
63
|
+
VIEW.open_proposals += 1;
|
|
64
|
+
renderCard(VIEW);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function renderSides(v) {
|
|
70
|
+
const it = v.item;
|
|
71
|
+
const added = it.added_via === 'seed' ? 'the 2026-10-28 research' : it.added_via === 'run' ? 'a weekly run' : it.added_via === 'proposal' ? 'an approved proposal' : 'a member';
|
|
72
|
+
$('mw-why').innerHTML = `${esc(it.why_tracked || 'No reason recorded yet.')}<small>${it.description ? `${esc(it.description)} · ` : ''}added by ${esc(added)}</small>`;
|
|
73
|
+
const rows = MW.factRows(it.facts);
|
|
74
|
+
if (it.category) rows.unshift(['Category', it.category]);
|
|
75
|
+
const site = it.url ? `<div class="mw-f"><span>Site</span><a class="mw-src" href="${MW.safeHref(it.url)}" target="_blank" rel="noopener noreferrer">${esc(String(it.url).replace(/^https?:\/\//, ''))} ↗</a></div>` : '';
|
|
76
|
+
$('mw-facts').innerHTML = rows.map(([k, val]) => `<div class="mw-f"><span>${esc(k)}</span><span class="mw-one" title="${esc(val)}">${esc(val)}</span></div>`).join('') + site;
|
|
77
|
+
$('mw-facts-sec').hidden = !rows.length && !site;
|
|
78
|
+
$('mw-logl').textContent = `case file · ${v.entries.length} ${v.entries.length === 1 ? 'entry' : 'entries'}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function cmp(a, b) {
|
|
82
|
+
const k = SORT.key;
|
|
83
|
+
if (k === 'found') return (a.found_on < b.found_on ? -1 : a.found_on > b.found_on ? 1 : 0) || (a.id - b.id);
|
|
84
|
+
if (k === 'run') return ((a.run ?? -1) - (b.run ?? -1)) || (a.id - b.id);
|
|
85
|
+
if (k === 'confidence') return (a.confidence - b.confidence) || (a.id - b.id);
|
|
86
|
+
return String(a[k] || '').localeCompare(String(b[k] || '')) || (a.id - b.id);
|
|
87
|
+
}
|
|
88
|
+
function drawLog() {
|
|
89
|
+
const rows = VIEW.entries.filter((e) => !TYPE || e.type === TYPE).sort((a, b) => (Number(b.pinned) - Number(a.pinned)) || SORT.dir * cmp(a, b));
|
|
90
|
+
$('mw-log').innerHTML = rows.length ? rows.map((e) => `<tr class="${e.pinned ? 'pin' : ''}">
|
|
91
|
+
<td class="mw-date">${esc(MW.fmtDay(e.found_on))}</td>
|
|
92
|
+
<td class="mw-c-run mw-run">${e.run == null ? '–' : `run ${esc(e.run)}`}</td>
|
|
93
|
+
<td>${MW.typePill(e.type)}</td>
|
|
94
|
+
<td class="mw-tk"><div class="mw-one" title="${esc(e.takeaway)}">${esc(e.takeaway)}</div></td>
|
|
95
|
+
<td class="mw-c-conf">${MW.confDots(e.confidence)}</td>
|
|
96
|
+
<td><a class="mw-src" href="${MW.safeHref(e.source_url)}" target="_blank" rel="noopener noreferrer">${esc(e.source_label || 'source')} ↗</a></td></tr>`).join('')
|
|
97
|
+
: `<tr><td colspan="6" class="mw-quiet">${TYPE ? `No ${esc(TYPE)} entries yet.` : 'Nothing found on it yet.'}</td></tr>`;
|
|
98
|
+
}
|
|
99
|
+
function wireSort() {
|
|
100
|
+
document.querySelectorAll('.mw-log th[data-s] button').forEach((b) => {
|
|
101
|
+
b.addEventListener('click', () => {
|
|
102
|
+
const th = b.closest('th');
|
|
103
|
+
const key = th.dataset.s;
|
|
104
|
+
SORT = SORT.key === key ? { key, dir: -SORT.dir } : { key, dir: key === 'type' || key === 'takeaway' ? 1 : -1 };
|
|
105
|
+
document.querySelectorAll('.mw-log th').forEach((x) => x.removeAttribute('aria-sort'));
|
|
106
|
+
th.setAttribute('aria-sort', SORT.dir < 0 ? 'descending' : 'ascending');
|
|
107
|
+
drawLog();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function load() {
|
|
113
|
+
if (moduleOff()) return show('mw-off');
|
|
114
|
+
const id = new URLSearchParams(window.location.search).get('id') || '';
|
|
115
|
+
if (!/^[1-9]\d{0,17}$/.test(id)) return fail('No item was named. Open one from the Market Watch home.');
|
|
116
|
+
let res;
|
|
117
|
+
try {
|
|
118
|
+
res = await fetch(`/api/bongos/market-watch/items/${id}`, { credentials: 'same-origin' });
|
|
119
|
+
} catch (e) {
|
|
120
|
+
return fail('Could not reach the server.');
|
|
121
|
+
}
|
|
122
|
+
if (res.status === 401) { window.location.assign(`/api/bongos/auth/web/start?return=${encodeURIComponent(window.location.pathname + window.location.search)}`); return; }
|
|
123
|
+
const data = await res.json().catch(() => null);
|
|
124
|
+
if (res.status === 404) {
|
|
125
|
+
const code = data && data.error && data.error.code;
|
|
126
|
+
return code === 'item_not_found' ? fail('That item is not tracked on this project.') : show('mw-off');
|
|
127
|
+
}
|
|
128
|
+
if (!res.ok || !data) return fail('Could not read this item. Try reloading the page.');
|
|
129
|
+
VIEW = data;
|
|
130
|
+
$('mw-h1').textContent = data.item.name;
|
|
131
|
+
document.title = `${data.item.name} — ${document.title.split(' — ').pop()}`;
|
|
132
|
+
show('mw-wrap');
|
|
133
|
+
renderCard(VIEW);
|
|
134
|
+
renderSides(VIEW);
|
|
135
|
+
drawLog();
|
|
136
|
+
wireSort();
|
|
137
|
+
// Filter the case file by type: the kit's filter bar, one select, kept in the URL.
|
|
138
|
+
const types = ['insight', 'news', 'datapoint'];
|
|
139
|
+
window.OTBKit.makeFilterBar({
|
|
140
|
+
mount: $('mw-filter'),
|
|
141
|
+
url: true,
|
|
142
|
+
primary: [{ id: 'type', label: 'type', options: [{ value: '', label: 'every type' }, ...types.map((t) => ({ value: t, label: t }))] }],
|
|
143
|
+
onChange: (v) => { TYPE = types.includes(v.type) ? v.type : ''; drawLog(); },
|
|
144
|
+
});
|
|
145
|
+
const pre = new URLSearchParams(window.location.search).get('type');
|
|
146
|
+
if (types.includes(pre)) { TYPE = pre; drawLog(); }
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
document.addEventListener('DOMContentLoaded', load);
|
|
150
|
+
})();
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_": "MARKET WATCH ITEM, the dossier (task 1004939; design of record docs/design/mocks/market-watch/item.html, option B). One read, GET /market-watch/items/:id. Against the kit's own stub it 404s with no item code, which the page reads as the module being off. The populated card and case file need the hall-preview harness with the module reported on; its market-watch__items__4.json (GitHub Copilot coding agent) and market-watch__items__37.json (NLnet Foundation) fixtures were built from the committed 2026-10-28 seed through the real shapes:\n\n node scripts/hall-preview/server.js --port 4639 --fixture-me --modules-on market-watch\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/market-watch-item.states.json --base-in http://localhost:4639 --base-out http://localhost:4639",
|
|
3
|
+
"page": "/builders/market-watch-item?id=4",
|
|
4
|
+
"surface": "hall-ui",
|
|
5
|
+
"stub": {
|
|
6
|
+
"prefix": "/builders/"
|
|
7
|
+
},
|
|
8
|
+
"modeQuery": false,
|
|
9
|
+
"ignoreRequests": [
|
|
10
|
+
"/api/(gds|bongos)/"
|
|
11
|
+
],
|
|
12
|
+
"ignoreConsole": [
|
|
13
|
+
"/api/(gds|bongos)/",
|
|
14
|
+
"\\b401\\b",
|
|
15
|
+
"\\b403\\b",
|
|
16
|
+
"\\b404\\b",
|
|
17
|
+
"\\b501\\b",
|
|
18
|
+
"Unauthorized",
|
|
19
|
+
"Forbidden",
|
|
20
|
+
"Not Found",
|
|
21
|
+
"Not Implemented",
|
|
22
|
+
"load failed"
|
|
23
|
+
],
|
|
24
|
+
"states": {
|
|
25
|
+
"dossier": {
|
|
26
|
+
"auth": true,
|
|
27
|
+
"actions": [
|
|
28
|
+
[
|
|
29
|
+
"wait",
|
|
30
|
+
900
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
"clickIfVisible",
|
|
34
|
+
"[data-craft-close]"
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
"wait",
|
|
38
|
+
200
|
|
39
|
+
]
|
|
40
|
+
],
|
|
41
|
+
"expect": {
|
|
42
|
+
"visible": [
|
|
43
|
+
"#mw-wrap",
|
|
44
|
+
"#mw-card .mw-ring"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"out": {
|
|
49
|
+
"auth": false,
|
|
50
|
+
"actions": [
|
|
51
|
+
[
|
|
52
|
+
"wait",
|
|
53
|
+
600
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
"clickIfVisible",
|
|
57
|
+
"[data-craft-close]"
|
|
58
|
+
]
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"propose": {
|
|
62
|
+
"auth": true,
|
|
63
|
+
"_": "Propose a change open: the four kinds, the score picker for a re-score, and the one-line reason.",
|
|
64
|
+
"actions": [
|
|
65
|
+
[
|
|
66
|
+
"wait",
|
|
67
|
+
900
|
|
68
|
+
],
|
|
69
|
+
[
|
|
70
|
+
"clickIfVisible",
|
|
71
|
+
"[data-craft-close]"
|
|
72
|
+
],
|
|
73
|
+
[
|
|
74
|
+
"wait",
|
|
75
|
+
200
|
|
76
|
+
],
|
|
77
|
+
[
|
|
78
|
+
"click",
|
|
79
|
+
"[data-act=\"propose\"]"
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"wait",
|
|
83
|
+
300
|
|
84
|
+
]
|
|
85
|
+
],
|
|
86
|
+
"expect": {
|
|
87
|
+
"visible": [
|
|
88
|
+
"#mw-propose form"
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"filtered": {
|
|
93
|
+
"auth": true,
|
|
94
|
+
"_": "The case file filtered to one type through the kit filter bar (insight): one row on the seeded Copilot item.",
|
|
95
|
+
"actions": [
|
|
96
|
+
[
|
|
97
|
+
"wait",
|
|
98
|
+
900
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
"clickIfVisible",
|
|
102
|
+
"[data-craft-close]"
|
|
103
|
+
],
|
|
104
|
+
[
|
|
105
|
+
"wait",
|
|
106
|
+
200
|
|
107
|
+
],
|
|
108
|
+
[
|
|
109
|
+
"select",
|
|
110
|
+
"#type",
|
|
111
|
+
"insight"
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
"wait",
|
|
115
|
+
300
|
|
116
|
+
]
|
|
117
|
+
],
|
|
118
|
+
"expect": {
|
|
119
|
+
"visible": [
|
|
120
|
+
"#mw-filter select",
|
|
121
|
+
"#mw-log tr"
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"reducedMotion": {
|
|
127
|
+
"auth": true,
|
|
128
|
+
"actions": [
|
|
129
|
+
[
|
|
130
|
+
"wait",
|
|
131
|
+
900
|
|
132
|
+
],
|
|
133
|
+
[
|
|
134
|
+
"clickIfVisible",
|
|
135
|
+
"[data-craft-close]"
|
|
136
|
+
],
|
|
137
|
+
[
|
|
138
|
+
"wait",
|
|
139
|
+
200
|
|
140
|
+
]
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
}
|