@go-labs-sg/gosh 1.3.0 → 1.5.0
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/README.md +90 -2
- package/command-manifest.json +97 -3
- package/command-reference.md +83 -3
- package/dist/index.js +60 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -157,6 +157,42 @@ Deploy prerequisite: apply the additive GOSH database schema changes for both
|
|
|
157
157
|
to `[]`, before deploying the updated server. Older event snapshots restore an
|
|
158
158
|
empty list. Client generation alone does not apply these database changes.
|
|
159
159
|
|
|
160
|
+
### Number range answers
|
|
161
|
+
|
|
162
|
+
Fill-in-the-blank missions can accept any number in an inclusive range instead
|
|
163
|
+
of text answers. Set `config.numberRange` with `min` and `max` (`min` must be
|
|
164
|
+
less than or equal to `max`). Players must answer with a number such as `55`,
|
|
165
|
+
`55.5`, `-3` or `1,000`; anything that is not a number is marked incorrect.
|
|
166
|
+
Ranges cannot be combined with `acceptedAnswers` and are only available for
|
|
167
|
+
fill-in-the-blank missions.
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
gosh mission create --input '{"stationId":"station-id","name":"Guess the height","type":"FILL_IN_THE_BLANK","config":{"numberRange":{"min":50,"max":60}}}'
|
|
171
|
+
gosh mission update --input '{"missionId":"mission-id","name":"Guess the height","type":"FILL_IN_THE_BLANK","config":null,"correctAnswer":"55"}'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
When updating, omit `config` to keep the saved range or pass `null` to switch
|
|
175
|
+
back to text answers. Players see a number input but never the range itself.
|
|
176
|
+
|
|
177
|
+
Rollout gate: the stored `correctAnswer` (`"50-60"`) is a display key, not a
|
|
178
|
+
safe fallback. A server without number-range support grades it as plain text,
|
|
179
|
+
so it accepts the literal `50-60` and rejects an in-range `55`, and its
|
|
180
|
+
template, clone and version writers drop `config`. Apply the additive
|
|
181
|
+
`Mission.config` and `GoshTemplateMission.config` columns, finish rolling out
|
|
182
|
+
the server everywhere, then create range missions.
|
|
183
|
+
|
|
184
|
+
Rollback: a range mission that has submissions cannot be switched back to text.
|
|
185
|
+
The answer-key lock in `mission update` rejects that edit on purpose, so stored
|
|
186
|
+
answers and points stay consistent. Do not loosen or bypass it. Instead:
|
|
187
|
+
|
|
188
|
+
- Unused range missions (no submissions) and templates can be switched back to
|
|
189
|
+
text answers or removed before a rollback.
|
|
190
|
+
- Used range missions: do not roll the server back past number-range support
|
|
191
|
+
while those events are live. Fix forward on a compatible build (any build
|
|
192
|
+
with number-range grading), or keep the previous image ready only for
|
|
193
|
+
events with no range missions. A lossless rollback for used range missions
|
|
194
|
+
needs its own approved plan; a normal edit cannot do it.
|
|
195
|
+
|
|
160
196
|
### Templates and organization scope
|
|
161
197
|
|
|
162
198
|
Template commands use the selected organization as their scope. Provide its ID in
|
|
@@ -264,11 +300,15 @@ gosh team create \
|
|
|
264
300
|
```
|
|
265
301
|
|
|
266
302
|
Configure gameplay, then manage the event's routing groups and their complete
|
|
267
|
-
station lists
|
|
303
|
+
station lists. `requireLocationOnSubmit` (default false) makes players at a
|
|
304
|
+
location-locked station check in again within the last two minutes before each
|
|
305
|
+
answer or upload is accepted, not only once at check-in. A fresh QR scan counts
|
|
306
|
+
at stations that also accept QR. It stays editable during live play; omit it,
|
|
307
|
+
or `allowStationSkipping`, to keep the event's current value.
|
|
268
308
|
|
|
269
309
|
```bash
|
|
270
310
|
gosh event set-gameplay \
|
|
271
|
-
--input '{"eventId":"event-id","progression":"SEQUENTIAL","groupRoutingEnabled":true,"allowMissionSkipping":true}' \
|
|
311
|
+
--input '{"eventId":"event-id","progression":"SEQUENTIAL","groupRoutingEnabled":true,"allowMissionSkipping":true,"allowStationSkipping":false,"requireLocationOnSubmit":true}' \
|
|
272
312
|
--target event-id \
|
|
273
313
|
--allow-state-change
|
|
274
314
|
|
|
@@ -381,6 +421,46 @@ finish time are kept, and a finished station accepts the reopened mission
|
|
|
381
421
|
until it is resolved. Pending submissions must be reviewed first, and a
|
|
382
422
|
reopened mission that still holds earlier points cannot be skipped.
|
|
383
423
|
|
|
424
|
+
#### Skipping a station
|
|
425
|
+
|
|
426
|
+
When the event's `allowStationSkipping` gameplay setting is on, a player who
|
|
427
|
+
can submit for their team can skip their current station. Check-in is not
|
|
428
|
+
required, so a team that cannot pass geolock can still move on:
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
gosh player station skip \
|
|
432
|
+
--input '{"eventId":"event-id","stationId":"station-2"}' \
|
|
433
|
+
--target station-2 \
|
|
434
|
+
--allow-state-change
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
A host with `reviewSubmissions` can skip a team's (`teamId`) or individual
|
|
438
|
+
player's (`eventPlayerId`) current station, or one open mission on it, while
|
|
439
|
+
the event is live. This works whatever the player setting is. Check the route
|
|
440
|
+
first, then pass an optional reason:
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
gosh route progress --input '{"eventId":"event-id","teamId":"team-1"}'
|
|
444
|
+
|
|
445
|
+
gosh route skip-station \
|
|
446
|
+
--input '{"eventId":"event-id","teamId":"team-1","stationId":"station-2","reason":"Location closed"}' \
|
|
447
|
+
--target team-1 \
|
|
448
|
+
--allow-state-change
|
|
449
|
+
|
|
450
|
+
gosh route skip-mission \
|
|
451
|
+
--input '{"eventId":"event-id","teamId":"team-1","missionId":"mission-3","reason":"Prop missing"}' \
|
|
452
|
+
--target team-1 \
|
|
453
|
+
--allow-state-change
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Only the current station can be skipped, so route order stays intact. Its
|
|
457
|
+
open missions score zero, the station completes (a stop nobody started records
|
|
458
|
+
zero time), and the next stop unlocks immediately; skipping the last stop
|
|
459
|
+
finishes the route. A station with a reopened mission that still holds earlier
|
|
460
|
+
points cannot be skipped until it is resubmitted or reviewed. Who skipped and
|
|
461
|
+
why appears in `route progress`, the activity log, and the results export's
|
|
462
|
+
`skips.csv`.
|
|
463
|
+
|
|
384
464
|
When reviewing, pass the submission's `updatedAt` from the review queue as
|
|
385
465
|
`expectedUpdatedAt`. If the team resubmitted after you read it, the review is
|
|
386
466
|
refused with `CONFLICT` instead of scoring the new answer blind:
|
|
@@ -513,6 +593,14 @@ gosh submission watch --input '{"organizationId":"acme","eventId":"event-id"}'
|
|
|
513
593
|
|
|
514
594
|
Global admins can list users, change global roles, and ban or unban accounts under `gosh admin users …`. Banning an account atomically revokes its active browser and CLI sessions.
|
|
515
595
|
|
|
596
|
+
Global admins can read every post-event experience review across organizations under `gosh admin reviews …`. `list` returns newest-first `{ items, pageInfo }` cursor pages (`limit` 1 to 100, default 25; pass `pageInfo.nextCursor` back as `cursor`), `count` returns the total, average rating and 5 to 1 star distribution, `filter-options` lists the organizations and events that have reviews, and `export` returns every matching row (up to 10,000). All four accept the same optional filters: `rating` (1 to 5), `organizationId`, `eventId`, `comment` (`with` or `without`) and `q` (comment, participant or event search):
|
|
597
|
+
|
|
598
|
+
```bash
|
|
599
|
+
gosh admin reviews list --input '{"rating":1,"limit":50}'
|
|
600
|
+
gosh admin reviews count --input '{"comment":"with"}'
|
|
601
|
+
gosh admin reviews export --input '{"organizationId":"org-id"}'
|
|
602
|
+
```
|
|
603
|
+
|
|
516
604
|
## Mutation safety
|
|
517
605
|
|
|
518
606
|
Mutations require `--target` to exactly match an identifier in `--input` (such as an `eventId`, `stationId`, slug, or name), binding the confirmation to the payload. In non-interactive automation, every applicable effect flag is also required:
|
package/command-manifest.json
CHANGED
|
@@ -791,7 +791,7 @@
|
|
|
791
791
|
"path": ["mission", "create"],
|
|
792
792
|
"procedure": "event.createMission",
|
|
793
793
|
"requiresAuth": true,
|
|
794
|
-
"summary": "Create a mission in a station. Fill-in-the-blank inputs support correctAnswer and acceptedAnswers (up to 50 alternatives). Optional revealMessage (up to 2,000 characters) is shown only after submitting.",
|
|
794
|
+
"summary": "Create a mission in a station. Fill-in-the-blank inputs support correctAnswer and acceptedAnswers (up to 50 alternatives), or config.numberRange {min,max} to accept any number in that inclusive range instead. Optional revealMessage (up to 2,000 characters) is shown only after submitting.",
|
|
795
795
|
"targetKeys": [
|
|
796
796
|
"id",
|
|
797
797
|
"memberId",
|
|
@@ -823,7 +823,7 @@
|
|
|
823
823
|
"path": ["mission", "update"],
|
|
824
824
|
"procedure": "event.updateMission",
|
|
825
825
|
"requiresAuth": true,
|
|
826
|
-
"summary": "Update a mission. Fill-in-the-blank inputs support acceptedAnswers; omit to preserve or pass [] to clear. Existing submissions are not re-graded. Edit revealMessage during live play; omit it to preserve or use an empty string to clear.",
|
|
826
|
+
"summary": "Update a mission. Fill-in-the-blank inputs support acceptedAnswers; omit to preserve or pass [] to clear. Set config.numberRange {min,max} for a numeric range answer; omit config to preserve or pass null to return to text answers. Existing submissions are not re-graded. Edit revealMessage during live play; omit it to preserve or use an empty string to clear.",
|
|
827
827
|
"targetKeys": [
|
|
828
828
|
"id",
|
|
829
829
|
"memberId",
|
|
@@ -921,6 +921,15 @@
|
|
|
921
921
|
"requiresAuth": true,
|
|
922
922
|
"summary": "List teams and their current members."
|
|
923
923
|
},
|
|
924
|
+
{
|
|
925
|
+
"effects": [],
|
|
926
|
+
"input": "json",
|
|
927
|
+
"operation": "query",
|
|
928
|
+
"path": ["route", "progress"],
|
|
929
|
+
"procedure": "team.getRouteProgress",
|
|
930
|
+
"requiresAuth": true,
|
|
931
|
+
"summary": "Show a team's (teamId) or individual player's (eventPlayerId) sequential route: stops, mission statuses, and who skipped what and why."
|
|
932
|
+
},
|
|
924
933
|
{
|
|
925
934
|
"effects": [],
|
|
926
935
|
"input": "json",
|
|
@@ -1161,7 +1170,7 @@
|
|
|
1161
1170
|
"path": ["event", "set-gameplay"],
|
|
1162
1171
|
"procedure": "team.setGameplaySettings",
|
|
1163
1172
|
"requiresAuth": true,
|
|
1164
|
-
"summary": "Set open or sequential progression, group routing, and per-mission skipping before play starts.",
|
|
1173
|
+
"summary": "Set open or sequential progression, group routing, and per-mission skipping before play starts. Station skipping and requireLocationOnSubmit stay editable live.",
|
|
1165
1174
|
"targetKeys": ["eventId"]
|
|
1166
1175
|
},
|
|
1167
1176
|
{
|
|
@@ -1660,6 +1669,26 @@
|
|
|
1660
1669
|
"name"
|
|
1661
1670
|
]
|
|
1662
1671
|
},
|
|
1672
|
+
{
|
|
1673
|
+
"effects": ["state-change"],
|
|
1674
|
+
"input": "json",
|
|
1675
|
+
"operation": "mutation",
|
|
1676
|
+
"path": ["route", "skip-station"],
|
|
1677
|
+
"procedure": "team.skipStation",
|
|
1678
|
+
"requiresAuth": true,
|
|
1679
|
+
"summary": "Skip a team's (teamId) or individual player's (eventPlayerId) current station on a fixed-order route while the event is live, with an optional reason. Its open missions score zero and the next stop unlocks; works whatever the player skipping setting is.",
|
|
1680
|
+
"targetKeys": ["teamId", "eventPlayerId", "stationId"]
|
|
1681
|
+
},
|
|
1682
|
+
{
|
|
1683
|
+
"effects": ["state-change"],
|
|
1684
|
+
"input": "json",
|
|
1685
|
+
"operation": "mutation",
|
|
1686
|
+
"path": ["route", "skip-mission"],
|
|
1687
|
+
"procedure": "team.skipMission",
|
|
1688
|
+
"requiresAuth": true,
|
|
1689
|
+
"summary": "Skip one open mission at a team's (teamId) or individual player's (eventPlayerId) current station for zero points, with an optional reason. Completes the station when it was the last open mission.",
|
|
1690
|
+
"targetKeys": ["teamId", "eventPlayerId", "missionId"]
|
|
1691
|
+
},
|
|
1663
1692
|
{
|
|
1664
1693
|
"effects": ["state-change"],
|
|
1665
1694
|
"input": "json",
|
|
@@ -1906,6 +1935,16 @@
|
|
|
1906
1935
|
"name"
|
|
1907
1936
|
]
|
|
1908
1937
|
},
|
|
1938
|
+
{
|
|
1939
|
+
"effects": ["state-change"],
|
|
1940
|
+
"input": "json",
|
|
1941
|
+
"operation": "mutation",
|
|
1942
|
+
"path": ["event", "update-survey"],
|
|
1943
|
+
"procedure": "event.updateSurveySettings",
|
|
1944
|
+
"requiresAuth": true,
|
|
1945
|
+
"summary": "Set the player survey: built-in, external link, or off, plus its copy and Google review prompt.",
|
|
1946
|
+
"targetKeys": ["eventId"]
|
|
1947
|
+
},
|
|
1909
1948
|
{
|
|
1910
1949
|
"effects": ["state-change"],
|
|
1911
1950
|
"input": "json",
|
|
@@ -2161,6 +2200,15 @@
|
|
|
2161
2200
|
"requiresAuth": true,
|
|
2162
2201
|
"summary": "Get a playable station."
|
|
2163
2202
|
},
|
|
2203
|
+
{
|
|
2204
|
+
"effects": [],
|
|
2205
|
+
"input": "json",
|
|
2206
|
+
"operation": "query",
|
|
2207
|
+
"path": ["player", "station", "presence"],
|
|
2208
|
+
"procedure": "event.getPlayerStationPresence",
|
|
2209
|
+
"requiresAuth": true,
|
|
2210
|
+
"summary": "Check whether a location is within a station's submit range when the event asks players to stay at the station to submit. Returns a state and rounded distance, never coordinates."
|
|
2211
|
+
},
|
|
2164
2212
|
{
|
|
2165
2213
|
"effects": [],
|
|
2166
2214
|
"input": "none",
|
|
@@ -2451,6 +2499,16 @@
|
|
|
2451
2499
|
"summary": "Permanently skip one unresolved mission for zero points when enabled; retain other points and elapsed station time.",
|
|
2452
2500
|
"targetKeys": ["missionId"]
|
|
2453
2501
|
},
|
|
2502
|
+
{
|
|
2503
|
+
"effects": ["state-change"],
|
|
2504
|
+
"input": "json",
|
|
2505
|
+
"operation": "mutation",
|
|
2506
|
+
"path": ["player", "station", "skip"],
|
|
2507
|
+
"procedure": "event.skipStation",
|
|
2508
|
+
"requiresAuth": true,
|
|
2509
|
+
"summary": "Skip your current sequential station for zero points when the event allows station skipping. No check-in is needed; its missions cannot be played later.",
|
|
2510
|
+
"targetKeys": ["stationId"]
|
|
2511
|
+
},
|
|
2454
2512
|
{
|
|
2455
2513
|
"effects": ["state-change"],
|
|
2456
2514
|
"input": "json",
|
|
@@ -3120,6 +3178,42 @@
|
|
|
3120
3178
|
"name"
|
|
3121
3179
|
]
|
|
3122
3180
|
},
|
|
3181
|
+
{
|
|
3182
|
+
"effects": [],
|
|
3183
|
+
"input": "json",
|
|
3184
|
+
"operation": "query",
|
|
3185
|
+
"path": ["admin", "reviews", "list"],
|
|
3186
|
+
"procedure": "review.listAdmin",
|
|
3187
|
+
"requiresAuth": true,
|
|
3188
|
+
"summary": "List experience reviews across all events as a global admin. Input: optional rating, organizationId, eventId, comment (with|without), q, plus limit, cursor and direction; returns { items, pageInfo }."
|
|
3189
|
+
},
|
|
3190
|
+
{
|
|
3191
|
+
"effects": [],
|
|
3192
|
+
"input": "json",
|
|
3193
|
+
"operation": "query",
|
|
3194
|
+
"path": ["admin", "reviews", "count"],
|
|
3195
|
+
"procedure": "review.getAdminSummary",
|
|
3196
|
+
"requiresAuth": true,
|
|
3197
|
+
"summary": "Count experience reviews for the given filters, with average rating and 5 to 1 star distribution."
|
|
3198
|
+
},
|
|
3199
|
+
{
|
|
3200
|
+
"effects": [],
|
|
3201
|
+
"input": "none",
|
|
3202
|
+
"operation": "query",
|
|
3203
|
+
"path": ["admin", "reviews", "filter-options"],
|
|
3204
|
+
"procedure": "review.listAdminFilterOptions",
|
|
3205
|
+
"requiresAuth": true,
|
|
3206
|
+
"summary": "List organizations and events that have experience reviews."
|
|
3207
|
+
},
|
|
3208
|
+
{
|
|
3209
|
+
"effects": [],
|
|
3210
|
+
"input": "json",
|
|
3211
|
+
"operation": "query",
|
|
3212
|
+
"path": ["admin", "reviews", "export"],
|
|
3213
|
+
"procedure": "review.exportAdmin",
|
|
3214
|
+
"requiresAuth": true,
|
|
3215
|
+
"summary": "Export every experience review matching the filters as rows (capped at 10,000)."
|
|
3216
|
+
},
|
|
3123
3217
|
{
|
|
3124
3218
|
"path": ["assets", "requirements"],
|
|
3125
3219
|
"operation": "local",
|
package/command-reference.md
CHANGED
|
@@ -332,7 +332,7 @@ Reorder shared stations, or a selected team's station route when scopeTeamId is
|
|
|
332
332
|
|
|
333
333
|
## `gosh mission create`
|
|
334
334
|
|
|
335
|
-
Create a mission in a station. Fill-in-the-blank inputs support correctAnswer and acceptedAnswers (up to 50 alternatives). Optional revealMessage (up to 2,000 characters) is shown only after submitting.
|
|
335
|
+
Create a mission in a station. Fill-in-the-blank inputs support correctAnswer and acceptedAnswers (up to 50 alternatives), or config.numberRange {min,max} to accept any number in that inclusive range instead. Optional revealMessage (up to 2,000 characters) is shown only after submitting.
|
|
336
336
|
|
|
337
337
|
- Authentication: browser-authenticated CLI session required
|
|
338
338
|
- Input: `--input '<json>'` required
|
|
@@ -340,7 +340,7 @@ Create a mission in a station. Fill-in-the-blank inputs support correctAnswer an
|
|
|
340
340
|
|
|
341
341
|
## `gosh mission update`
|
|
342
342
|
|
|
343
|
-
Update a mission. Fill-in-the-blank inputs support acceptedAnswers; omit to preserve or pass [] to clear. Existing submissions are not re-graded. Edit revealMessage during live play; omit it to preserve or use an empty string to clear.
|
|
343
|
+
Update a mission. Fill-in-the-blank inputs support acceptedAnswers; omit to preserve or pass [] to clear. Set config.numberRange {min,max} for a numeric range answer; omit config to preserve or pass null to return to text answers. Existing submissions are not re-graded. Edit revealMessage during live play; omit it to preserve or use an empty string to clear.
|
|
344
344
|
|
|
345
345
|
- Authentication: browser-authenticated CLI session required
|
|
346
346
|
- Input: `--input '<json>'` required
|
|
@@ -370,6 +370,14 @@ List teams and their current members.
|
|
|
370
370
|
- Input: `--input '<json>'` required
|
|
371
371
|
- Effects: read-only
|
|
372
372
|
|
|
373
|
+
## `gosh route progress`
|
|
374
|
+
|
|
375
|
+
Show a team's (teamId) or individual player's (eventPlayerId) sequential route: stops, mission statuses, and who skipped what and why.
|
|
376
|
+
|
|
377
|
+
- Authentication: browser-authenticated CLI session required
|
|
378
|
+
- Input: `--input '<json>'` required
|
|
379
|
+
- Effects: read-only
|
|
380
|
+
|
|
373
381
|
## `gosh team station-routes`
|
|
374
382
|
|
|
375
383
|
List each team's linked stations and team-specific route order.
|
|
@@ -436,7 +444,7 @@ Replace a team's linked station route and set its order.
|
|
|
436
444
|
|
|
437
445
|
## `gosh event set-gameplay`
|
|
438
446
|
|
|
439
|
-
Set open or sequential progression, group routing, and per-mission skipping before play starts.
|
|
447
|
+
Set open or sequential progression, group routing, and per-mission skipping before play starts. Station skipping and requireLocationOnSubmit stay editable live.
|
|
440
448
|
|
|
441
449
|
- Authentication: browser-authenticated CLI session required
|
|
442
450
|
- Input: `--input '<json>'` required
|
|
@@ -650,6 +658,22 @@ Review a mission submission.
|
|
|
650
658
|
- Input: `--input '<json>'` required
|
|
651
659
|
- Effects: state-change
|
|
652
660
|
|
|
661
|
+
## `gosh route skip-station`
|
|
662
|
+
|
|
663
|
+
Skip a team's (teamId) or individual player's (eventPlayerId) current station on a fixed-order route while the event is live, with an optional reason. Its open missions score zero and the next stop unlocks; works whatever the player skipping setting is.
|
|
664
|
+
|
|
665
|
+
- Authentication: browser-authenticated CLI session required
|
|
666
|
+
- Input: `--input '<json>'` required
|
|
667
|
+
- Effects: state-change
|
|
668
|
+
|
|
669
|
+
## `gosh route skip-mission`
|
|
670
|
+
|
|
671
|
+
Skip one open mission at a team's (teamId) or individual player's (eventPlayerId) current station for zero points, with an optional reason. Completes the station when it was the last open mission.
|
|
672
|
+
|
|
673
|
+
- Authentication: browser-authenticated CLI session required
|
|
674
|
+
- Input: `--input '<json>'` required
|
|
675
|
+
- Effects: state-change
|
|
676
|
+
|
|
653
677
|
## `gosh mission reopen`
|
|
654
678
|
|
|
655
679
|
Reopen a submitted or skipped mission for one team (teamId) or player (eventPlayerId) on a fixed-order route. Earlier points count until they resubmit; then only the new submission counts. Finish times are kept.
|
|
@@ -786,6 +810,14 @@ Update event branding.
|
|
|
786
810
|
- Input: `--input '<json>'` required
|
|
787
811
|
- Effects: state-change
|
|
788
812
|
|
|
813
|
+
## `gosh event update-survey`
|
|
814
|
+
|
|
815
|
+
Set the player survey: built-in, external link, or off, plus its copy and Google review prompt.
|
|
816
|
+
|
|
817
|
+
- Authentication: browser-authenticated CLI session required
|
|
818
|
+
- Input: `--input '<json>'` required
|
|
819
|
+
- Effects: state-change
|
|
820
|
+
|
|
789
821
|
## `gosh station update-availability`
|
|
790
822
|
|
|
791
823
|
Update station availability.
|
|
@@ -890,6 +922,14 @@ Get a playable station.
|
|
|
890
922
|
- Input: `--input '<json>'` required
|
|
891
923
|
- Effects: read-only
|
|
892
924
|
|
|
925
|
+
## `gosh player station presence`
|
|
926
|
+
|
|
927
|
+
Check whether a location is within a station's submit range when the event asks players to stay at the station to submit. Returns a state and rounded distance, never coordinates.
|
|
928
|
+
|
|
929
|
+
- Authentication: browser-authenticated CLI session required
|
|
930
|
+
- Input: `--input '<json>'` required
|
|
931
|
+
- Effects: read-only
|
|
932
|
+
|
|
893
933
|
## `gosh player events`
|
|
894
934
|
|
|
895
935
|
List events joined by the current user.
|
|
@@ -1002,6 +1042,14 @@ Permanently skip one unresolved mission for zero points when enabled; retain oth
|
|
|
1002
1042
|
- Input: `--input '<json>'` required
|
|
1003
1043
|
- Effects: state-change
|
|
1004
1044
|
|
|
1045
|
+
## `gosh player station skip`
|
|
1046
|
+
|
|
1047
|
+
Skip your current sequential station for zero points when the event allows station skipping. No check-in is needed; its missions cannot be played later.
|
|
1048
|
+
|
|
1049
|
+
- Authentication: browser-authenticated CLI session required
|
|
1050
|
+
- Input: `--input '<json>'` required
|
|
1051
|
+
- Effects: state-change
|
|
1052
|
+
|
|
1005
1053
|
## `gosh player mission submit`
|
|
1006
1054
|
|
|
1007
1055
|
Submit a mission response and return revealMessage, including already-completed submissions.
|
|
@@ -1244,6 +1292,38 @@ Unban a user.
|
|
|
1244
1292
|
- Input: `--input '<json>'` required
|
|
1245
1293
|
- Effects: state-change
|
|
1246
1294
|
|
|
1295
|
+
## `gosh admin reviews list`
|
|
1296
|
+
|
|
1297
|
+
List experience reviews across all events as a global admin. Input: optional rating, organizationId, eventId, comment (with|without), q, plus limit, cursor and direction; returns { items, pageInfo }.
|
|
1298
|
+
|
|
1299
|
+
- Authentication: browser-authenticated CLI session required
|
|
1300
|
+
- Input: `--input '<json>'` required
|
|
1301
|
+
- Effects: read-only
|
|
1302
|
+
|
|
1303
|
+
## `gosh admin reviews count`
|
|
1304
|
+
|
|
1305
|
+
Count experience reviews for the given filters, with average rating and 5 to 1 star distribution.
|
|
1306
|
+
|
|
1307
|
+
- Authentication: browser-authenticated CLI session required
|
|
1308
|
+
- Input: `--input '<json>'` required
|
|
1309
|
+
- Effects: read-only
|
|
1310
|
+
|
|
1311
|
+
## `gosh admin reviews filter-options`
|
|
1312
|
+
|
|
1313
|
+
List organizations and events that have experience reviews.
|
|
1314
|
+
|
|
1315
|
+
- Authentication: browser-authenticated CLI session required
|
|
1316
|
+
- Input: none
|
|
1317
|
+
- Effects: read-only
|
|
1318
|
+
|
|
1319
|
+
## `gosh admin reviews export`
|
|
1320
|
+
|
|
1321
|
+
Export every experience review matching the filters as rows (capped at 10,000).
|
|
1322
|
+
|
|
1323
|
+
- Authentication: browser-authenticated CLI session required
|
|
1324
|
+
- Input: `--input '<json>'` required
|
|
1325
|
+
- Effects: read-only
|
|
1326
|
+
|
|
1247
1327
|
## `gosh assets requirements`
|
|
1248
1328
|
|
|
1249
1329
|
Show upload limits and separate artwork recommendations without login or network access.
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
35
35
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
36
36
|
var __require = import.meta.require;
|
|
37
37
|
|
|
38
|
-
// ../../../node_modules/.bun/dotenv@18.0.
|
|
38
|
+
// ../../../node_modules/.bun/dotenv@18.0.9/node_modules/dotenv/dist/index.cjs
|
|
39
39
|
var require_dist = __commonJS(function(exports, module) {
|
|
40
40
|
var j = (e, n) => () => {
|
|
41
41
|
try {
|
|
@@ -367,7 +367,7 @@ var require_dist = __commonJS(function(exports, module) {
|
|
|
367
367
|
}
|
|
368
368
|
function Ee(e) {
|
|
369
369
|
let n = J(), t = { encoding: n.encoding || "utf8", quiet: n.quiet, debug: n.debug === true, override: n.override === true, fast: n.fast === true, paths: [".env"], defaultPath: true };
|
|
370
|
-
return n.path
|
|
370
|
+
return n.path && (t.paths = [n.path], t.defaultPath = false), e.pathSet && (t.paths = e.paths, t.defaultPath = false), e.quiet != null && (t.quiet = e.quiet), e.debug != null && (t.debug = e.debug), e.override != null && (t.override = e.override), e.fast != null && (t.fast = e.fast), t;
|
|
371
371
|
}
|
|
372
372
|
function be(e) {
|
|
373
373
|
let n = {}, t = [], o = { override: e.override, debug: e.debug };
|
|
@@ -7452,6 +7452,10 @@ var typedOperations = {
|
|
|
7452
7452
|
kind: "query",
|
|
7453
7453
|
invoke: (client, input) => client.team.list.query(input)
|
|
7454
7454
|
},
|
|
7455
|
+
"team.getRouteProgress": {
|
|
7456
|
+
kind: "query",
|
|
7457
|
+
invoke: (client, input) => client.team.getRouteProgress.query(input)
|
|
7458
|
+
},
|
|
7455
7459
|
"team.getStationRoutes": {
|
|
7456
7460
|
kind: "query",
|
|
7457
7461
|
invoke: (client, input) => client.team.getStationRoutes.query(input)
|
|
@@ -7592,6 +7596,14 @@ var typedOperations = {
|
|
|
7592
7596
|
kind: "mutation",
|
|
7593
7597
|
invoke: (client, input) => client.event.reviewSubmission.mutate(input)
|
|
7594
7598
|
},
|
|
7599
|
+
"team.skipStation": {
|
|
7600
|
+
kind: "mutation",
|
|
7601
|
+
invoke: (client, input) => client.team.skipStation.mutate(input)
|
|
7602
|
+
},
|
|
7603
|
+
"team.skipMission": {
|
|
7604
|
+
kind: "mutation",
|
|
7605
|
+
invoke: (client, input) => client.team.skipMission.mutate(input)
|
|
7606
|
+
},
|
|
7595
7607
|
"event.reopenMission": {
|
|
7596
7608
|
kind: "mutation",
|
|
7597
7609
|
invoke: (client, input) => client.event.reopenMission.mutate(input)
|
|
@@ -7660,6 +7672,10 @@ var typedOperations = {
|
|
|
7660
7672
|
kind: "mutation",
|
|
7661
7673
|
invoke: (client, input) => client.event.updateBranding.mutate(input)
|
|
7662
7674
|
},
|
|
7675
|
+
"event.updateSurveySettings": {
|
|
7676
|
+
kind: "mutation",
|
|
7677
|
+
invoke: (client, input) => client.event.updateSurveySettings.mutate(input)
|
|
7678
|
+
},
|
|
7663
7679
|
"event.updateStationAvailability": {
|
|
7664
7680
|
kind: "mutation",
|
|
7665
7681
|
invoke: (client, input) => client.event.updateStationAvailability.mutate(input)
|
|
@@ -7712,6 +7728,10 @@ var typedOperations = {
|
|
|
7712
7728
|
kind: "query",
|
|
7713
7729
|
invoke: (client, input) => client.event.getPlayerStation.query(input)
|
|
7714
7730
|
},
|
|
7731
|
+
"event.getPlayerStationPresence": {
|
|
7732
|
+
kind: "query",
|
|
7733
|
+
invoke: (client, input) => client.event.getPlayerStationPresence.query(input)
|
|
7734
|
+
},
|
|
7715
7735
|
"event.listJoined": {
|
|
7716
7736
|
kind: "query",
|
|
7717
7737
|
invoke: (client, input) => client.event.listJoined.query(input)
|
|
@@ -7768,6 +7788,10 @@ var typedOperations = {
|
|
|
7768
7788
|
kind: "mutation",
|
|
7769
7789
|
invoke: (client, input) => client.event.skipMission.mutate(input)
|
|
7770
7790
|
},
|
|
7791
|
+
"event.skipStation": {
|
|
7792
|
+
kind: "mutation",
|
|
7793
|
+
invoke: (client, input) => client.event.skipStation.mutate(input)
|
|
7794
|
+
},
|
|
7771
7795
|
"event.submitMission": {
|
|
7772
7796
|
kind: "mutation",
|
|
7773
7797
|
invoke: (client, input) => client.event.submitMission.mutate(input)
|
|
@@ -7895,6 +7919,22 @@ var typedOperations = {
|
|
|
7895
7919
|
"user.unban": {
|
|
7896
7920
|
kind: "mutation",
|
|
7897
7921
|
invoke: (client, input) => client.user.unban.mutate(input)
|
|
7922
|
+
},
|
|
7923
|
+
"review.listAdmin": {
|
|
7924
|
+
kind: "query",
|
|
7925
|
+
invoke: (client, input) => client.review.listAdmin.query(input)
|
|
7926
|
+
},
|
|
7927
|
+
"review.getAdminSummary": {
|
|
7928
|
+
kind: "query",
|
|
7929
|
+
invoke: (client, input) => client.review.getAdminSummary.query(input)
|
|
7930
|
+
},
|
|
7931
|
+
"review.listAdminFilterOptions": {
|
|
7932
|
+
kind: "query",
|
|
7933
|
+
invoke: (client, input) => client.review.listAdminFilterOptions.query(input)
|
|
7934
|
+
},
|
|
7935
|
+
"review.exportAdmin": {
|
|
7936
|
+
kind: "query",
|
|
7937
|
+
invoke: (client, input) => client.review.exportAdmin.query(input)
|
|
7898
7938
|
}
|
|
7899
7939
|
};
|
|
7900
7940
|
|
|
@@ -7950,6 +7990,7 @@ var defaultMutationTargetKeys = [
|
|
|
7950
7990
|
var mutationTargetKeys = {
|
|
7951
7991
|
"team.updateRoutingGroupRelease": ["groupId", "eventId"],
|
|
7952
7992
|
"team.setGameplaySettings": ["eventId"],
|
|
7993
|
+
"event.updateSurveySettings": ["eventId"],
|
|
7953
7994
|
"team.createRoutingGroup": ["eventId"],
|
|
7954
7995
|
"team.renameRoutingGroup": ["groupId"],
|
|
7955
7996
|
"team.deleteRoutingGroup": ["groupId"],
|
|
@@ -7959,6 +8000,9 @@ var mutationTargetKeys = {
|
|
|
7959
8000
|
"team.resolveRsvpCheckInReview": ["linkId"],
|
|
7960
8001
|
"event.startStation": ["stationId"],
|
|
7961
8002
|
"event.skipMission": ["missionId"],
|
|
8003
|
+
"event.skipStation": ["stationId"],
|
|
8004
|
+
"team.skipStation": ["teamId", "eventPlayerId", "stationId"],
|
|
8005
|
+
"team.skipMission": ["teamId", "eventPlayerId", "missionId"],
|
|
7962
8006
|
"event.reopenMission": ["teamId", "eventPlayerId", "missionId"],
|
|
7963
8007
|
"event.create": ["organizationId", "name"],
|
|
7964
8008
|
"event.createFromTemplate": ["organizationId", "templateId"],
|
|
@@ -8051,11 +8095,12 @@ var commands = [
|
|
|
8051
8095
|
mutation(["station", "clone"], "event.cloneStation", "Clone a station and its missions.", ["state-change"]),
|
|
8052
8096
|
mutation(["station", "archive"], "event.archiveStation", "Archive a station.", ["state-change", "delete"]),
|
|
8053
8097
|
mutation(["station", "reorder"], "event.reorderStations", "Reorder shared stations, or a selected team's station route when scopeTeamId is supplied.", ["state-change"]),
|
|
8054
|
-
mutation(["mission", "create"], "event.createMission", "Create a mission in a station. Fill-in-the-blank inputs support correctAnswer and acceptedAnswers (up to 50 alternatives). Optional revealMessage (up to 2,000 characters) is shown only after submitting.", ["state-change"]),
|
|
8055
|
-
mutation(["mission", "update"], "event.updateMission", "Update a mission. Fill-in-the-blank inputs support acceptedAnswers; omit to preserve or pass [] to clear. Existing submissions are not re-graded. Edit revealMessage during live play; omit it to preserve or use an empty string to clear.", ["state-change"]),
|
|
8098
|
+
mutation(["mission", "create"], "event.createMission", "Create a mission in a station. Fill-in-the-blank inputs support correctAnswer and acceptedAnswers (up to 50 alternatives), or config.numberRange {min,max} to accept any number in that inclusive range instead. Optional revealMessage (up to 2,000 characters) is shown only after submitting.", ["state-change"]),
|
|
8099
|
+
mutation(["mission", "update"], "event.updateMission", "Update a mission. Fill-in-the-blank inputs support acceptedAnswers; omit to preserve or pass [] to clear. Set config.numberRange {min,max} for a numeric range answer; omit config to preserve or pass null to return to text answers. Existing submissions are not re-graded. Edit revealMessage during live play; omit it to preserve or use an empty string to clear.", ["state-change"]),
|
|
8056
8100
|
mutation(["mission", "archive"], "event.archiveMission", "Archive a mission.", ["state-change", "delete"]),
|
|
8057
8101
|
mutation(["mission", "reorder"], "event.reorderMissions", "Reorder missions within a station.", ["state-change"]),
|
|
8058
8102
|
query(["team", "list"], "team.list", "List teams and their current members."),
|
|
8103
|
+
query(["route", "progress"], "team.getRouteProgress", "Show a team's (teamId) or individual player's (eventPlayerId) sequential route: stops, mission statuses, and who skipped what and why."),
|
|
8059
8104
|
query(["team", "station-routes"], "team.getStationRoutes", "List each team's linked stations and team-specific route order."),
|
|
8060
8105
|
mutation(["team", "create"], "team.create", "Create a team.", [
|
|
8061
8106
|
"state-change"
|
|
@@ -8068,7 +8113,7 @@ var commands = [
|
|
|
8068
8113
|
mutation(["team", "set-play-mode"], "team.setPlayMode", "Change an event between individual and team play.", ["state-change"]),
|
|
8069
8114
|
mutation(["team", "set-submission-access"], "team.setSubmissionAccess", "Change who can submit missions in team play.", ["state-change"]),
|
|
8070
8115
|
mutation(["team", "set-station-routes"], "team.setStationRoutes", "Replace a team's linked station route and set its order.", ["state-change"]),
|
|
8071
|
-
mutation(["event", "set-gameplay"], "team.setGameplaySettings", "Set open or sequential progression, group routing, and per-mission skipping before play starts.", ["state-change"]),
|
|
8116
|
+
mutation(["event", "set-gameplay"], "team.setGameplaySettings", "Set open or sequential progression, group routing, and per-mission skipping before play starts. Station skipping and requireLocationOnSubmit stay editable live.", ["state-change"]),
|
|
8072
8117
|
query(["routing-group", "list"], "team.listRoutingGroups", "List an event's routing groups, ordered stations, and assigned teams."),
|
|
8073
8118
|
query(["routing-group", "release-history"], "team.listRoutingGroupReleaseHistory", "Show a routing group's five most recent release changes with actor, action and before/after UTC values."),
|
|
8074
8119
|
mutation(["routing-group", "release"], "team.updateRoutingGroupRelease", "Schedule (future releaseAt ISO timestamp with offset), CLEAR schedule, HOLD, RELEASE_SCHEDULED_HOLD (keep schedule), or RELEASE_NOW for a routing group. After a group starts, only HOLD and RELEASE_SCHEDULED_HOLD are accepted. Requires launchEvent permission.", ["state-change"]),
|
|
@@ -8098,6 +8143,8 @@ var commands = [
|
|
|
8098
8143
|
mutation(["reward", "update"], "event.updateReward", "Update an event reward.", ["state-change"]),
|
|
8099
8144
|
mutation(["score", "adjust"], "event.createScoreAdjustment", "Create a manual score adjustment.", ["state-change"]),
|
|
8100
8145
|
mutation(["submission", "review"], "event.reviewSubmission", "Review a mission submission.", ["state-change"]),
|
|
8146
|
+
mutation(["route", "skip-station"], "team.skipStation", "Skip a team's (teamId) or individual player's (eventPlayerId) current station on a fixed-order route while the event is live, with an optional reason. Its open missions score zero and the next stop unlocks; works whatever the player skipping setting is.", ["state-change"]),
|
|
8147
|
+
mutation(["route", "skip-mission"], "team.skipMission", "Skip one open mission at a team's (teamId) or individual player's (eventPlayerId) current station for zero points, with an optional reason. Completes the station when it was the last open mission.", ["state-change"]),
|
|
8101
8148
|
mutation(["mission", "reopen"], "event.reopenMission", "Reopen a submitted or skipped mission for one team (teamId) or player (eventPlayerId) on a fixed-order route. Earlier points count until they resubmit; then only the new submission counts. Finish times are kept.", ["state-change"]),
|
|
8102
8149
|
mutation(["results-share", "regenerate"], "event.regenerateResultsPortalShare", "Create a new results portal share token.", ["state-change"]),
|
|
8103
8150
|
mutation(["results-share", "revoke"], "event.revokeResultsPortalShare", "Revoke the current results portal share token.", ["state-change", "delete"]),
|
|
@@ -8115,6 +8162,7 @@ var commands = [
|
|
|
8115
8162
|
query(["results-share", "get"], "event.getResultsPortalShare", "Get the current results portal share."),
|
|
8116
8163
|
mutation(["event", "update-access"], "event.updateAccess", "Update event access rules.", ["state-change"]),
|
|
8117
8164
|
mutation(["event", "update-branding"], "event.updateBranding", "Update event branding.", ["state-change"]),
|
|
8165
|
+
mutation(["event", "update-survey"], "event.updateSurveySettings", "Set the player survey: built-in, external link, or off, plus its copy and Google review prompt.", ["state-change"]),
|
|
8118
8166
|
mutation(["station", "update-availability"], "event.updateStationAvailability", "Update station availability.", ["state-change"]),
|
|
8119
8167
|
mutation(["station", "update-image"], "event.updateStationImage", "Update a station image.", ["state-change"]),
|
|
8120
8168
|
mutation(["station", "update-location"], "event.updateStationLocation", "Update station location and geofence settings.", ["state-change"]),
|
|
@@ -8128,6 +8176,7 @@ var commands = [
|
|
|
8128
8176
|
query(["player", "map"], "event.getPlayerMap", "Get the player event map."),
|
|
8129
8177
|
query(["player", "shell"], "event.getPlayerShell", "Get the player application shell."),
|
|
8130
8178
|
query(["player", "station"], "event.getPlayerStation", "Get a playable station."),
|
|
8179
|
+
query(["player", "station", "presence"], "event.getPlayerStationPresence", "Check whether a location is within a station's submit range when the event asks players to stay at the station to submit. Returns a state and rounded distance, never coordinates."),
|
|
8131
8180
|
query(["player", "events"], "event.listJoined", "List events joined by the current user.", { input: "none" }),
|
|
8132
8181
|
query(["player", "broadcasts"], "event.listPlayerBroadcasts", "List broadcasts visible to the current player."),
|
|
8133
8182
|
query(["player", "broadcast"], "event.getPlayerBroadcast", "Get one broadcast visible to the current player."),
|
|
@@ -8144,6 +8193,7 @@ var commands = [
|
|
|
8144
8193
|
mutation(["player", "station-qr-check-in"], "event.createStationQrCheckInProof", "Check in to a station with its scanned QR or manual code.", ["state-change"]),
|
|
8145
8194
|
mutation(["player", "station", "start"], "event.startStation", "Start the current sequential station's shared mission timer and reveal its missions; required check-in still applies.", ["state-change"]),
|
|
8146
8195
|
mutation(["player", "mission", "skip"], "event.skipMission", "Permanently skip one unresolved mission for zero points when enabled; retain other points and elapsed station time.", ["state-change"]),
|
|
8196
|
+
mutation(["player", "station", "skip"], "event.skipStation", "Skip your current sequential station for zero points when the event allows station skipping. No check-in is needed; its missions cannot be played later.", ["state-change"]),
|
|
8147
8197
|
mutation(["player", "mission", "submit"], "event.submitMission", "Submit a mission response and return revealMessage, including already-completed submissions.", ["state-change"]),
|
|
8148
8198
|
query(["public", "event-login"], "event.getPublicLoginDetails", "Get public event login details.", { requiresAuth: false }),
|
|
8149
8199
|
query(["public", "results"], "event.getResultsPortal", "Get a shared public results portal.", { requiresAuth: false }),
|
|
@@ -8175,7 +8225,11 @@ var commands = [
|
|
|
8175
8225
|
mutation(["admin", "users", "ban"], "user.ban", "Ban a user and revoke their sessions and API keys.", ["state-change", "delete"]),
|
|
8176
8226
|
mutation(["admin", "users", "unban"], "user.unban", "Unban a user.", [
|
|
8177
8227
|
"state-change"
|
|
8178
|
-
])
|
|
8228
|
+
]),
|
|
8229
|
+
query(["admin", "reviews", "list"], "review.listAdmin", "List experience reviews across all events as a global admin. Input: optional rating, organizationId, eventId, comment (with|without), q, plus limit, cursor and direction; returns { items, pageInfo }."),
|
|
8230
|
+
query(["admin", "reviews", "count"], "review.getAdminSummary", "Count experience reviews for the given filters, with average rating and 5 to 1 star distribution."),
|
|
8231
|
+
query(["admin", "reviews", "filter-options"], "review.listAdminFilterOptions", "List organizations and events that have experience reviews.", { input: "none" }),
|
|
8232
|
+
query(["admin", "reviews", "export"], "review.exportAdmin", "Export every experience review matching the filters as rows (capped at 10,000).")
|
|
8179
8233
|
];
|
|
8180
8234
|
var commandManifest = commands.map((command) => ({
|
|
8181
8235
|
effects: command.effects,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@go-labs-sg/gosh",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "GOSH CLI for organizers and AI agents — manage organizations, events, teams, stations, missions, templates, and live operations through the GOSH API.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@trpc/client": "^11.19.0",
|
|
22
|
-
"dotenv": "^18.0.
|
|
22
|
+
"dotenv": "^18.0.9",
|
|
23
23
|
"superjson": "^2.2.6"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|