@go-labs-sg/gosh 1.1.0 → 1.3.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 CHANGED
@@ -110,6 +110,53 @@ Commands use `--input '<json>'` for the exact validated tRPC input object. This
110
110
 
111
111
  The command registry exposes the supported GOSH tRPC procedures across organizer and global-admin operations, organization invitations and membership, player workflows, public results/login procedures, uploads, and realtime subscriptions. Update the registry alongside API changes, then run `bun --filter @go-labs-sg/gosh generate:commands` from the repository root to regenerate the manifest, reference, and typed operations.
112
112
 
113
+ ### Messages after submitting
114
+
115
+ `gosh mission create` and `gosh mission update` accept optional `revealMessage`
116
+ plain text (up to 2,000 characters, with line breaks) in `--input`. It is hidden
117
+ from players until their team/player has a submission, regardless of review
118
+ status. Skipping a mission does not reveal it. The player submit response includes
119
+ `revealMessage`, including already-completed submissions; station and map reads
120
+ include it only on submitted missions.
121
+
122
+ ```bash
123
+ gosh mission create \
124
+ --input '{"stationId":"station-id","name":"Pavilion materials","type":"FILL_IN_THE_BLANK","points":10,"correctAnswer":"grocery bags","revealMessage":"The pavilion is clad with grocery bags.\nNotice how everyday materials are reused."}' \
125
+ --target station-id \
126
+ --allow-state-change
127
+ ```
128
+
129
+ For updates, send the existing mission editor fields (including option IDs and
130
+ answer keys) together with `missionId` and `revealMessage`. Omitting
131
+ `revealMessage` preserves it; `"revealMessage":""` clears it. The message is
132
+ display-only and can change during a live event without changing grading or
133
+ saved playthroughs. Templates, station clones and event versions preserve it.
134
+
135
+ ### Multiple accepted text answers
136
+
137
+ Fill-in-the-blank missions accept the primary `correctAnswer` or any of up to 50
138
+ `acceptedAnswers` (each trimmed, non-empty and at most 200 characters). Case and
139
+ repeated whitespace are ignored; no fuzzy or partial matching is used. Duplicate
140
+ alternatives are removed after normalization. Alternatives require a primary
141
+ answer and cannot be used for other mission types.
142
+
143
+ ```bash
144
+ gosh mission create --input '{"stationId":"station-id","name":"Climbing plants","type":"FILL_IN_THE_BLANK","correctAnswer":"Mesh","acceptedAnswers":["Trellis","Scaffolding"]}'
145
+ gosh mission update --input '{"missionId":"mission-id","name":"Climbing plants","type":"FILL_IN_THE_BLANK","correctAnswer":"Mesh","acceptedAnswers":["Trellis","Frame","Scaffolding"]}'
146
+ ```
147
+
148
+ When updating, omit `acceptedAnswers` to preserve the saved list or pass `[]` to
149
+ clear it. Alternative-answer changes affect future submissions only: stored
150
+ answers and awarded points are never re-graded. Existing restrictions on changing
151
+ the primary answer, mission type and choice options after submissions still apply.
152
+ Templates, station clones and saved event versions preserve alternatives. Answer
153
+ keys are visible to authorized admins/reviewers, never in player mission reads.
154
+
155
+ Deploy prerequisite: apply the additive GOSH database schema changes for both
156
+ `Mission.acceptedAnswers` and `GoshTemplateMission.acceptedAnswers`, each defaulting
157
+ to `[]`, before deploying the updated server. Older event snapshots restore an
158
+ empty list. Client generation alone does not apply these database changes.
159
+
113
160
  ### Templates and organization scope
114
161
 
115
162
  Template commands use the selected organization as their scope. Provide its ID in
@@ -199,9 +246,22 @@ and missions stay editable after play starts: each edit re-syncs every started
199
246
  team's saved progress in the same transaction. Played stations keep their
200
247
  progress and order, while unplayed stations follow the new route. An edit that
201
248
  would remove the station a team is in the middle of fails with a conflict and
202
- changes nothing. A started team's group assignment, team creation, play mode
203
- and progression settings stay locked. A group shares its ordered station route,
204
- while each team keeps independent progress through that route.
249
+ changes nothing. A started team's group assignment, play mode and progression
250
+ settings stay locked. A group shares its ordered station route, while each team
251
+ keeps independent progress through that route.
252
+
253
+ Late teams can join a live group-routed event. `team create` must then include
254
+ a `groupId`, so the team starts on that group's route behind its release gate
255
+ (a held or scheduled group stays closed to it). Restoring an archived team
256
+ while group routing is live works only if the team never played and still has
257
+ a group. Without group routing, team creation still locks once play starts.
258
+
259
+ ```bash
260
+ gosh team create \
261
+ --input '{"eventId":"event-id","name":"Walk-in team","groupId":"group-id"}' \
262
+ --target event-id \
263
+ --allow-state-change
264
+ ```
205
265
 
206
266
  Configure gameplay, then manage the event's routing groups and their complete
207
267
  station lists:
@@ -332,6 +392,44 @@ gosh submission review \
332
392
  --allow-state-change
333
393
  ```
334
394
 
395
+ ### RSVP check-in teams
396
+
397
+ An RSVP form can create a GOSH team on its first successful check-in. RSVP
398
+ signs the request; GOSH creates the team from the registration's emails (the
399
+ first email is the captain, the rest are members), picks the least-loaded
400
+ route group that still has room, and returns the route. This also works
401
+ while the event is live, so a newly checked-in team can start playing.
402
+
403
+ The binding is off by default. Set the signing secret in the GOSH environment
404
+ as `GOSH_RSVP_CHECK_IN_WEBHOOK_SECRETS=<keyId>:whsec_...` (comma separated
405
+ during rotation). The secret is never stored in the binding.
406
+
407
+ ```bash
408
+ gosh rsvp-check-in binding set \
409
+ --input '{"eventId":"event-id","sourceOrganizationId":"rsvp-org-id","sourceEventId":"rsvp-event-id","sourceFormId":"rsvp-form-id","keyId":"farm-2026","enabled":true,"groups":[{"groupId":"group-a","teamCapacity":125},{"groupId":"group-b","teamCapacity":125},{"groupId":"group-c","teamCapacity":125},{"groupId":"group-d","teamCapacity":125}],"totalTeamCapacity":500,"maxRosterSize":2}' \
410
+ --target event-id \
411
+ --allow-state-change
412
+ gosh rsvp-check-in binding get --input '{"eventId":"event-id"}'
413
+ gosh rsvp-check-in links list --input '{"eventId":"event-id","filter":"REVIEW"}'
414
+ ```
415
+
416
+ - Group load counts every non-archived team in the group, including teams
417
+ assigned by hand. While the binding is enabled, `routing-group assign-team`
418
+ and restoring an archived team are refused if they would exceed a group's
419
+ capacity or the total limit.
420
+ - Groups with equal load are filled in the order listed in `groups`.
421
+ - When every route is full, GOSH creates no team and RSVP shows
422
+ `CAPACITY_FULL`. The attendee stays checked in.
423
+ - Email addresses are matched case-insensitively. Repeated addresses are
424
+ counted once. An invalid address, a suspended account, a player removed
425
+ from the event, or a player already on another team rejects the whole
426
+ team, and nothing is created.
427
+ - New accounts are not marked verified, and GOSH sends no email. Players sign
428
+ in later with the normal email code.
429
+ - Undoing the last RSVP check-in keeps the team and route but flags the team
430
+ for review. Clear the flag with `gosh rsvp-check-in review resolve`. A later
431
+ check-in reuses the same team.
432
+
335
433
  ### Artwork requirements (no login required)
336
434
 
337
435
  Read the bundled upload policy before preparing station, mission, or branding artwork:
@@ -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.",
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.",
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.",
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.",
827
827
  "targetKeys": [
828
828
  "id",
829
829
  "memberId",
@@ -1239,9 +1239,47 @@
1239
1239
  "path": ["routing-group", "assign-team"],
1240
1240
  "procedure": "team.assignTeamRoutingGroup",
1241
1241
  "requiresAuth": true,
1242
- "summary": "Assign a team to a routing group, or clear its assignment with groupId null, before play starts.",
1242
+ "summary": "Assign a team to a routing group, or clear its assignment with groupId null, before play starts. Groups covered by an enabled RSVP check-in binding reject moves that exceed their team capacity.",
1243
1243
  "targetKeys": ["teamId"]
1244
1244
  },
1245
+ {
1246
+ "effects": [],
1247
+ "input": "json",
1248
+ "operation": "query",
1249
+ "path": ["rsvp-check-in", "binding", "get"],
1250
+ "procedure": "team.getRsvpCheckInBinding",
1251
+ "requiresAuth": true,
1252
+ "summary": "Show the RSVP check-in team binding for an event: source RSVP organization/event/form, key ID, enabled flag, ordered routing groups with team capacity and current load, total limit and roster size limit. Secrets are never stored or shown. Requires editSetup."
1253
+ },
1254
+ {
1255
+ "effects": ["state-change"],
1256
+ "input": "json",
1257
+ "operation": "mutation",
1258
+ "path": ["rsvp-check-in", "binding", "set"],
1259
+ "procedure": "team.upsertRsvpCheckInBinding",
1260
+ "requiresAuth": true,
1261
+ "summary": "Create or replace the RSVP check-in team binding: {eventId, sourceOrganizationId, sourceEventId, sourceFormId, keyId, enabled, groups:[{groupId, teamCapacity}] in tie-break order, totalTeamCapacity, maxRosterSize}. Disabled by default; the signing secret is set in the GOSH_RSVP_CHECK_IN_WEBHOOK_SECRETS environment variable under keyId. Requires launchEvent.",
1262
+ "targetKeys": ["eventId", "sourceFormId"]
1263
+ },
1264
+ {
1265
+ "effects": [],
1266
+ "input": "json",
1267
+ "operation": "query",
1268
+ "path": ["rsvp-check-in", "links", "list"],
1269
+ "procedure": "team.listRsvpCheckInLinks",
1270
+ "requiresAuth": true,
1271
+ "summary": "List RSVP registrations linked to check-in teams with route, applied revision, review flag and rejection code. filter ALL, REVIEW (undone check-ins) or REJECTED. Requires editSetup."
1272
+ },
1273
+ {
1274
+ "effects": ["state-change"],
1275
+ "input": "json",
1276
+ "operation": "mutation",
1277
+ "path": ["rsvp-check-in", "review", "resolve"],
1278
+ "procedure": "team.resolveRsvpCheckInReview",
1279
+ "requiresAuth": true,
1280
+ "summary": "Clear the review flag on an RSVP check-in team after crew follow-up. The team and its route are unchanged. Requires editSetup.",
1281
+ "targetKeys": ["linkId"]
1282
+ },
1245
1283
  {
1246
1284
  "effects": [],
1247
1285
  "input": "json",
@@ -1964,6 +2002,79 @@
1964
2002
  "name"
1965
2003
  ]
1966
2004
  },
2005
+ {
2006
+ "effects": ["state-change"],
2007
+ "input": "json",
2008
+ "operation": "mutation",
2009
+ "path": ["station", "update-check-in"],
2010
+ "procedure": "event.updateStationCheckIn",
2011
+ "requiresAuth": true,
2012
+ "summary": "Set how players unlock a station: open, location, QR, or both.",
2013
+ "targetKeys": [
2014
+ "id",
2015
+ "memberId",
2016
+ "invitationId",
2017
+ "broadcastId",
2018
+ "rewardId",
2019
+ "submissionId",
2020
+ "participantId",
2021
+ "participantIds",
2022
+ "missionId",
2023
+ "stationId",
2024
+ "teamId",
2025
+ "templateId",
2026
+ "eventId",
2027
+ "organizationId",
2028
+ "userId",
2029
+ "key",
2030
+ "uploadId",
2031
+ "email",
2032
+ "joinCode",
2033
+ "slug",
2034
+ "name"
2035
+ ]
2036
+ },
2037
+ {
2038
+ "effects": [],
2039
+ "input": "json",
2040
+ "operation": "query",
2041
+ "path": ["station", "qr-codes"],
2042
+ "procedure": "event.getStationQrCodes",
2043
+ "requiresAuth": true,
2044
+ "summary": "List printable QR codes and manual codes for QR-enabled stations."
2045
+ },
2046
+ {
2047
+ "effects": ["state-change"],
2048
+ "input": "json",
2049
+ "operation": "mutation",
2050
+ "path": ["station", "regenerate-qr"],
2051
+ "procedure": "event.regenerateStationQr",
2052
+ "requiresAuth": true,
2053
+ "summary": "Regenerate a station QR. Earlier prints stop working.",
2054
+ "targetKeys": [
2055
+ "id",
2056
+ "memberId",
2057
+ "invitationId",
2058
+ "broadcastId",
2059
+ "rewardId",
2060
+ "submissionId",
2061
+ "participantId",
2062
+ "participantIds",
2063
+ "missionId",
2064
+ "stationId",
2065
+ "teamId",
2066
+ "templateId",
2067
+ "eventId",
2068
+ "organizationId",
2069
+ "userId",
2070
+ "key",
2071
+ "uploadId",
2072
+ "email",
2073
+ "joinCode",
2074
+ "slug",
2075
+ "name"
2076
+ ]
2077
+ },
1967
2078
  {
1968
2079
  "effects": ["state-change"],
1969
2080
  "input": "json",
@@ -2288,6 +2399,38 @@
2288
2399
  "name"
2289
2400
  ]
2290
2401
  },
2402
+ {
2403
+ "effects": ["state-change"],
2404
+ "input": "json",
2405
+ "operation": "mutation",
2406
+ "path": ["player", "station-qr-check-in"],
2407
+ "procedure": "event.createStationQrCheckInProof",
2408
+ "requiresAuth": true,
2409
+ "summary": "Check in to a station with its scanned QR or manual code.",
2410
+ "targetKeys": [
2411
+ "id",
2412
+ "memberId",
2413
+ "invitationId",
2414
+ "broadcastId",
2415
+ "rewardId",
2416
+ "submissionId",
2417
+ "participantId",
2418
+ "participantIds",
2419
+ "missionId",
2420
+ "stationId",
2421
+ "teamId",
2422
+ "templateId",
2423
+ "eventId",
2424
+ "organizationId",
2425
+ "userId",
2426
+ "key",
2427
+ "uploadId",
2428
+ "email",
2429
+ "joinCode",
2430
+ "slug",
2431
+ "name"
2432
+ ]
2433
+ },
2291
2434
  {
2292
2435
  "effects": ["state-change"],
2293
2436
  "input": "json",
@@ -2315,7 +2458,7 @@
2315
2458
  "path": ["player", "mission", "submit"],
2316
2459
  "procedure": "event.submitMission",
2317
2460
  "requiresAuth": true,
2318
- "summary": "Submit a mission response.",
2461
+ "summary": "Submit a mission response and return revealMessage, including already-completed submissions.",
2319
2462
  "targetKeys": [
2320
2463
  "id",
2321
2464
  "memberId",
@@ -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.
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.
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.
340
340
 
341
341
  ## `gosh mission update`
342
342
 
343
- Update a mission.
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.
344
344
 
345
345
  - Authentication: browser-authenticated CLI session required
346
346
  - Input: `--input '<json>'` required
@@ -500,7 +500,39 @@ Replace a group's complete station route in the supplied order before play start
500
500
 
501
501
  ## `gosh routing-group assign-team`
502
502
 
503
- Assign a team to a routing group, or clear its assignment with groupId null, before play starts.
503
+ Assign a team to a routing group, or clear its assignment with groupId null, before play starts. Groups covered by an enabled RSVP check-in binding reject moves that exceed their team capacity.
504
+
505
+ - Authentication: browser-authenticated CLI session required
506
+ - Input: `--input '<json>'` required
507
+ - Effects: state-change
508
+
509
+ ## `gosh rsvp-check-in binding get`
510
+
511
+ Show the RSVP check-in team binding for an event: source RSVP organization/event/form, key ID, enabled flag, ordered routing groups with team capacity and current load, total limit and roster size limit. Secrets are never stored or shown. Requires editSetup.
512
+
513
+ - Authentication: browser-authenticated CLI session required
514
+ - Input: `--input '<json>'` required
515
+ - Effects: read-only
516
+
517
+ ## `gosh rsvp-check-in binding set`
518
+
519
+ Create or replace the RSVP check-in team binding: {eventId, sourceOrganizationId, sourceEventId, sourceFormId, keyId, enabled, groups:[{groupId, teamCapacity}] in tie-break order, totalTeamCapacity, maxRosterSize}. Disabled by default; the signing secret is set in the GOSH_RSVP_CHECK_IN_WEBHOOK_SECRETS environment variable under keyId. Requires launchEvent.
520
+
521
+ - Authentication: browser-authenticated CLI session required
522
+ - Input: `--input '<json>'` required
523
+ - Effects: state-change
524
+
525
+ ## `gosh rsvp-check-in links list`
526
+
527
+ List RSVP registrations linked to check-in teams with route, applied revision, review flag and rejection code. filter ALL, REVIEW (undone check-ins) or REJECTED. Requires editSetup.
528
+
529
+ - Authentication: browser-authenticated CLI session required
530
+ - Input: `--input '<json>'` required
531
+ - Effects: read-only
532
+
533
+ ## `gosh rsvp-check-in review resolve`
534
+
535
+ Clear the review flag on an RSVP check-in team after crew follow-up. The team and its route are unchanged. Requires editSetup.
504
536
 
505
537
  - Authentication: browser-authenticated CLI session required
506
538
  - Input: `--input '<json>'` required
@@ -778,6 +810,30 @@ Update station location and geofence settings.
778
810
  - Input: `--input '<json>'` required
779
811
  - Effects: state-change
780
812
 
813
+ ## `gosh station update-check-in`
814
+
815
+ Set how players unlock a station: open, location, QR, or both.
816
+
817
+ - Authentication: browser-authenticated CLI session required
818
+ - Input: `--input '<json>'` required
819
+ - Effects: state-change
820
+
821
+ ## `gosh station qr-codes`
822
+
823
+ List printable QR codes and manual codes for QR-enabled stations.
824
+
825
+ - Authentication: browser-authenticated CLI session required
826
+ - Input: `--input '<json>'` required
827
+ - Effects: read-only
828
+
829
+ ## `gosh station regenerate-qr`
830
+
831
+ Regenerate a station QR. Earlier prints stop working.
832
+
833
+ - Authentication: browser-authenticated CLI session required
834
+ - Input: `--input '<json>'` required
835
+ - Effects: state-change
836
+
781
837
  ## `gosh event save-as-template`
782
838
 
783
839
  Save an event as a template.
@@ -922,6 +978,14 @@ Create an expiring station check-in proof.
922
978
  - Input: `--input '<json>'` required
923
979
  - Effects: state-change
924
980
 
981
+ ## `gosh player station-qr-check-in`
982
+
983
+ Check in to a station with its scanned QR or manual code.
984
+
985
+ - Authentication: browser-authenticated CLI session required
986
+ - Input: `--input '<json>'` required
987
+ - Effects: state-change
988
+
925
989
  ## `gosh player station start`
926
990
 
927
991
  Start the current sequential station's shared mission timer and reveal its missions; required check-in still applies.
@@ -940,7 +1004,7 @@ Permanently skip one unresolved mission for zero points when enabled; retain oth
940
1004
 
941
1005
  ## `gosh player mission submit`
942
1006
 
943
- Submit a mission response.
1007
+ Submit a mission response and return revealMessage, including already-completed submissions.
944
1008
 
945
1009
  - Authentication: browser-authenticated CLI session required
946
1010
  - Input: `--input '<json>'` required
package/dist/index.js CHANGED
@@ -7520,6 +7520,22 @@ var typedOperations = {
7520
7520
  kind: "mutation",
7521
7521
  invoke: (client, input) => client.team.assignTeamRoutingGroup.mutate(input)
7522
7522
  },
7523
+ "team.getRsvpCheckInBinding": {
7524
+ kind: "query",
7525
+ invoke: (client, input) => client.team.getRsvpCheckInBinding.query(input)
7526
+ },
7527
+ "team.upsertRsvpCheckInBinding": {
7528
+ kind: "mutation",
7529
+ invoke: (client, input) => client.team.upsertRsvpCheckInBinding.mutate(input)
7530
+ },
7531
+ "team.listRsvpCheckInLinks": {
7532
+ kind: "query",
7533
+ invoke: (client, input) => client.team.listRsvpCheckInLinks.query(input)
7534
+ },
7535
+ "team.resolveRsvpCheckInReview": {
7536
+ kind: "mutation",
7537
+ invoke: (client, input) => client.team.resolveRsvpCheckInReview.mutate(input)
7538
+ },
7523
7539
  "template.list": {
7524
7540
  kind: "query",
7525
7541
  invoke: (client, input) => client.template.list.query(input)
@@ -7656,6 +7672,18 @@ var typedOperations = {
7656
7672
  kind: "mutation",
7657
7673
  invoke: (client, input) => client.event.updateStationLocation.mutate(input)
7658
7674
  },
7675
+ "event.updateStationCheckIn": {
7676
+ kind: "mutation",
7677
+ invoke: (client, input) => client.event.updateStationCheckIn.mutate(input)
7678
+ },
7679
+ "event.getStationQrCodes": {
7680
+ kind: "query",
7681
+ invoke: (client, input) => client.event.getStationQrCodes.query(input)
7682
+ },
7683
+ "event.regenerateStationQr": {
7684
+ kind: "mutation",
7685
+ invoke: (client, input) => client.event.regenerateStationQr.mutate(input)
7686
+ },
7659
7687
  "event.saveAsTemplate": {
7660
7688
  kind: "mutation",
7661
7689
  invoke: (client, input) => client.event.saveAsTemplate.mutate(input)
@@ -7728,6 +7756,10 @@ var typedOperations = {
7728
7756
  kind: "mutation",
7729
7757
  invoke: (client, input) => client.event.createStationCheckInProof.mutate(input)
7730
7758
  },
7759
+ "event.createStationQrCheckInProof": {
7760
+ kind: "mutation",
7761
+ invoke: (client, input) => client.event.createStationQrCheckInProof.mutate(input)
7762
+ },
7731
7763
  "event.startStation": {
7732
7764
  kind: "mutation",
7733
7765
  invoke: (client, input) => client.event.startStation.mutate(input)
@@ -7923,6 +7955,8 @@ var mutationTargetKeys = {
7923
7955
  "team.deleteRoutingGroup": ["groupId"],
7924
7956
  "team.setRoutingGroupStations": ["groupId"],
7925
7957
  "team.assignTeamRoutingGroup": ["teamId"],
7958
+ "team.upsertRsvpCheckInBinding": ["eventId", "sourceFormId"],
7959
+ "team.resolveRsvpCheckInReview": ["linkId"],
7926
7960
  "event.startStation": ["stationId"],
7927
7961
  "event.skipMission": ["missionId"],
7928
7962
  "event.reopenMission": ["teamId", "eventPlayerId", "missionId"],
@@ -8017,10 +8051,8 @@ var commands = [
8017
8051
  mutation(["station", "clone"], "event.cloneStation", "Clone a station and its missions.", ["state-change"]),
8018
8052
  mutation(["station", "archive"], "event.archiveStation", "Archive a station.", ["state-change", "delete"]),
8019
8053
  mutation(["station", "reorder"], "event.reorderStations", "Reorder shared stations, or a selected team's station route when scopeTeamId is supplied.", ["state-change"]),
8020
- mutation(["mission", "create"], "event.createMission", "Create a mission in a station.", ["state-change"]),
8021
- mutation(["mission", "update"], "event.updateMission", "Update a mission.", [
8022
- "state-change"
8023
- ]),
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"]),
8024
8056
  mutation(["mission", "archive"], "event.archiveMission", "Archive a mission.", ["state-change", "delete"]),
8025
8057
  mutation(["mission", "reorder"], "event.reorderMissions", "Reorder missions within a station.", ["state-change"]),
8026
8058
  query(["team", "list"], "team.list", "List teams and their current members."),
@@ -8044,7 +8076,11 @@ var commands = [
8044
8076
  mutation(["routing-group", "rename"], "team.renameRoutingGroup", "Rename an event's routing group before play starts.", ["state-change"]),
8045
8077
  mutation(["routing-group", "delete"], "team.deleteRoutingGroup", "Delete an unassigned routing group before play starts.", ["state-change", "delete"]),
8046
8078
  mutation(["routing-group", "set-stations"], "team.setRoutingGroupStations", "Replace a group's complete station route in the supplied order before play starts.", ["state-change"]),
8047
- mutation(["routing-group", "assign-team"], "team.assignTeamRoutingGroup", "Assign a team to a routing group, or clear its assignment with groupId null, before play starts.", ["state-change"]),
8079
+ mutation(["routing-group", "assign-team"], "team.assignTeamRoutingGroup", "Assign a team to a routing group, or clear its assignment with groupId null, before play starts. Groups covered by an enabled RSVP check-in binding reject moves that exceed their team capacity.", ["state-change"]),
8080
+ query(["rsvp-check-in", "binding", "get"], "team.getRsvpCheckInBinding", "Show the RSVP check-in team binding for an event: source RSVP organization/event/form, key ID, enabled flag, ordered routing groups with team capacity and current load, total limit and roster size limit. Secrets are never stored or shown. Requires editSetup."),
8081
+ mutation(["rsvp-check-in", "binding", "set"], "team.upsertRsvpCheckInBinding", "Create or replace the RSVP check-in team binding: {eventId, sourceOrganizationId, sourceEventId, sourceFormId, keyId, enabled, groups:[{groupId, teamCapacity}] in tie-break order, totalTeamCapacity, maxRosterSize}. Disabled by default; the signing secret is set in the GOSH_RSVP_CHECK_IN_WEBHOOK_SECRETS environment variable under keyId. Requires launchEvent.", ["state-change"]),
8082
+ query(["rsvp-check-in", "links", "list"], "team.listRsvpCheckInLinks", "List RSVP registrations linked to check-in teams with route, applied revision, review flag and rejection code. filter ALL, REVIEW (undone check-ins) or REJECTED. Requires editSetup."),
8083
+ mutation(["rsvp-check-in", "review", "resolve"], "team.resolveRsvpCheckInReview", "Clear the review flag on an RSVP check-in team after crew follow-up. The team and its route are unchanged. Requires editSetup.", ["state-change"]),
8048
8084
  query(["template", "list"], "template.list", "List templates visible in an organization; global admins can include every organization."),
8049
8085
  query(["template", "get"], "template.getById", "Get a template visible in the requested organization; global admins can get any template."),
8050
8086
  mutation(["template", "create"], "template.create", "Create an organization template, including shared stations with optional per-team route order.", ["state-change"]),
@@ -8082,6 +8118,9 @@ var commands = [
8082
8118
  mutation(["station", "update-availability"], "event.updateStationAvailability", "Update station availability.", ["state-change"]),
8083
8119
  mutation(["station", "update-image"], "event.updateStationImage", "Update a station image.", ["state-change"]),
8084
8120
  mutation(["station", "update-location"], "event.updateStationLocation", "Update station location and geofence settings.", ["state-change"]),
8121
+ mutation(["station", "update-check-in"], "event.updateStationCheckIn", "Set how players unlock a station: open, location, QR, or both.", ["state-change"]),
8122
+ query(["station", "qr-codes"], "event.getStationQrCodes", "List printable QR codes and manual codes for QR-enabled stations."),
8123
+ mutation(["station", "regenerate-qr"], "event.regenerateStationQr", "Regenerate a station QR. Earlier prints stop working.", ["state-change"]),
8085
8124
  mutation(["event", "save-as-template"], "event.saveAsTemplate", "Save an event as a template.", ["state-change"]),
8086
8125
  query(["player", "event"], "event.getJoinDetails", "Get the current player's event details."),
8087
8126
  query(["player", "leaderboard", "page"], "event.getPaginatedPlayerLeaderboard", "Get a page of the player leaderboard."),
@@ -8102,9 +8141,10 @@ var commands = [
8102
8141
  mutation(["player", "display-name", "update"], "event.updatePlayerDisplayName", "Update the player's display name.", ["state-change"]),
8103
8142
  mutation(["player", "resolve-join-code"], "event.resolveJoinCode", "Resolve an event or team join code.", []),
8104
8143
  mutation(["player", "station-check-in"], "event.createStationCheckInProof", "Create an expiring station check-in proof.", ["state-change"]),
8144
+ mutation(["player", "station-qr-check-in"], "event.createStationQrCheckInProof", "Check in to a station with its scanned QR or manual code.", ["state-change"]),
8105
8145
  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"]),
8106
8146
  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"]),
8107
- mutation(["player", "mission", "submit"], "event.submitMission", "Submit a mission response.", ["state-change"]),
8147
+ mutation(["player", "mission", "submit"], "event.submitMission", "Submit a mission response and return revealMessage, including already-completed submissions.", ["state-change"]),
8108
8148
  query(["public", "event-login"], "event.getPublicLoginDetails", "Get public event login details.", { requiresAuth: false }),
8109
8149
  query(["public", "results"], "event.getResultsPortal", "Get a shared public results portal.", { requiresAuth: false }),
8110
8150
  mutation(["public", "request-login-code"], "event.requestLoginEmailOtp", "Send an event login email code.", ["email", "external-write"], { requiresAuth: false }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-labs-sg/gosh",
3
- "version": "1.1.0",
3
+ "version": "1.3.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",