@go-labs-sg/gosh 1.0.0 → 1.1.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
@@ -65,6 +65,17 @@ Before requesting approval, login verifies write/read/delete capability with a u
65
65
 
66
66
  See the [shared authentication contract](../../cli-auth/README.md) for recovery and verification limits.
67
67
 
68
+ ## Realtime watch reconciliation
69
+
70
+ `gosh player watch` and `gosh submission watch` continue to emit newline-delimited
71
+ JSON. On a v2-enabled server, process-local changes can arrive immediately;
72
+ cross-process changes are reconciled through the existing 15-second resync
73
+ cadence while a watch is active. A player `resync` message or submission
74
+ `resynced: true` message means fetch the current authorized state again, not that
75
+ a complete business-event replay was delivered. Command names, arguments and
76
+ permission checks are unchanged. Browser clients use scoped v2 subscriptions
77
+ instead of this compatibility cadence.
78
+
68
79
  ## Authentication
69
80
 
70
81
  ```bash
@@ -183,10 +194,14 @@ value in that template team's `order` field:
183
194
  Events default to `OPEN` progression, which keeps the existing open-play flow.
184
195
  Sequential progression starts each team or individual on an ordered station
185
196
  route. Group routing is available only for `TEAM` play mode. Create teams and
186
- assign them to routing groups before launching the event; sequential setup
187
- freezes when play starts. Grouped OPEN events lock only a started team's group
188
- assignment, a started group's route and the gameplay settings. A group shares its ordered station route, while each team keeps
189
- independent progress through that route.
197
+ assign them to routing groups before launching the event. Routes, stations
198
+ and missions stay editable after play starts: each edit re-syncs every started
199
+ team's saved progress in the same transaction. Played stations keep their
200
+ progress and order, while unplayed stations follow the new route. An edit that
201
+ 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.
190
205
 
191
206
  Configure gameplay, then manage the event's routing groups and their complete
192
207
  station lists:
@@ -281,7 +296,7 @@ gosh player mission skip \
281
296
  ```
282
297
 
283
298
  Player actions require event enrollment and the configured team submission
284
- permissions. A skipped mission is irreversible and earns zero points; it resolves only that mission,
299
+ permissions. A player cannot undo a skip: it earns zero points and resolves only that mission,
285
300
  preserves points from the station's other submitted missions, and advances the
286
301
  route once all station missions are submitted or skipped. The station timer
287
302
  runs from check-in/start through the final mission submission or skip. It
@@ -289,6 +304,34 @@ measures mission work only: travel between stations and staff review time are
289
304
  excluded. Existing leaderboard and results commands include the resulting
290
305
  timing information.
291
306
 
307
+ A host with `reviewSubmissions` can reopen one submitted or skipped mission for
308
+ a team (`teamId`) or individual player (`eventPlayerId`) on a fixed-order route
309
+ while the event is live:
310
+
311
+ ```bash
312
+ gosh mission reopen \
313
+ --input '{"eventId":"event-id","missionId":"mission-1","teamId":"team-1"}' \
314
+ --target team-1 \
315
+ --allow-state-change
316
+ ```
317
+
318
+ The earlier submission's points keep counting until the team submits again;
319
+ then only the new submission counts, up or down. Station times and the team's
320
+ finish time are kept, and a finished station accepts the reopened mission
321
+ until it is resolved. Pending submissions must be reviewed first, and a
322
+ reopened mission that still holds earlier points cannot be skipped.
323
+
324
+ When reviewing, pass the submission's `updatedAt` from the review queue as
325
+ `expectedUpdatedAt`. If the team resubmitted after you read it, the review is
326
+ refused with `CONFLICT` instead of scoring the new answer blind:
327
+
328
+ ```bash
329
+ gosh submission review \
330
+ --input '{"eventId":"event-id","organizationId":"org-id","submissionId":"submission-1","status":"APPROVED","expectedUpdatedAt":"2026-10-14T07:00:00.000Z"}' \
331
+ --target submission-1 \
332
+ --allow-state-change
333
+ ```
334
+
292
335
  ### Artwork requirements (no login required)
293
336
 
294
337
  Read the bundled upload policy before preparing station, mission, or branding artwork:
@@ -1622,6 +1622,16 @@
1622
1622
  "name"
1623
1623
  ]
1624
1624
  },
1625
+ {
1626
+ "effects": ["state-change"],
1627
+ "input": "json",
1628
+ "operation": "mutation",
1629
+ "path": ["mission", "reopen"],
1630
+ "procedure": "event.reopenMission",
1631
+ "requiresAuth": true,
1632
+ "summary": "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.",
1633
+ "targetKeys": ["teamId", "eventPlayerId", "missionId"]
1634
+ },
1625
1635
  {
1626
1636
  "effects": ["state-change"],
1627
1637
  "input": "json",
@@ -618,6 +618,14 @@ Review a mission submission.
618
618
  - Input: `--input '<json>'` required
619
619
  - Effects: state-change
620
620
 
621
+ ## `gosh mission reopen`
622
+
623
+ 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.
624
+
625
+ - Authentication: browser-authenticated CLI session required
626
+ - Input: `--input '<json>'` required
627
+ - Effects: state-change
628
+
621
629
  ## `gosh results-share regenerate`
622
630
 
623
631
  Create a new results portal share token.
package/dist/index.js CHANGED
@@ -35,16 +35,16 @@ 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.7/node_modules/dotenv/dist/index.cjs
38
+ // ../../../node_modules/.bun/dotenv@18.0.8/node_modules/dotenv/dist/index.cjs
39
39
  var require_dist = __commonJS(function(exports, module) {
40
- var k = (e, n) => () => {
40
+ var j = (e, n) => () => {
41
41
  try {
42
42
  return n || e((n = { exports: {} }).exports, n), n.exports;
43
43
  } catch (t) {
44
44
  throw n = 0, t;
45
45
  }
46
46
  };
47
- var I = k((xe, U) => {
47
+ var k = j((xe, U) => {
48
48
  function G(e) {
49
49
  return typeof e == "string" ? !["false", "0", "no", "off", ""].includes(e.toLowerCase()) : !!e;
50
50
  }
@@ -58,8 +58,8 @@ var require_dist = __commonJS(function(exports, module) {
58
58
  }
59
59
  U.exports = { parseBoolean: G, optionsFromEnv: Y };
60
60
  });
61
- var N = k((ye, x) => {
62
- var z = __require("fs"), S = __require("path"), Z = __require("os"), { URL: ee, fileURLToPath: te } = __require("url"), { parseBoolean: $, optionsFromEnv: B } = I(), re = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg, b = new Uint8Array(256);
61
+ var N = j((ye, x) => {
62
+ var z = __require("fs"), I = __require("path"), Z = __require("os"), { URL: ee, fileURLToPath: te } = __require("url"), { parseBoolean: $, optionsFromEnv: B } = k(), re = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg, b = new Uint8Array(256);
63
63
  for (let e = 48;e <= 57; e++)
64
64
  b[e] = 1;
65
65
  for (let e = 65;e <= 90; e++)
@@ -124,7 +124,7 @@ var require_dist = __commonJS(function(exports, module) {
124
124
  r++;
125
125
  continue;
126
126
  }
127
- let p = t.slice(l, r), f = r;
127
+ let h = t.slice(l, r), f = r;
128
128
  if (r >= o && (d = 0), w(d))
129
129
  do
130
130
  r++, d = r < o ? t.charCodeAt(r) : 0;
@@ -141,8 +141,8 @@ var require_dist = __commonJS(function(exports, module) {
141
141
  let c = r, a = r;
142
142
  for (;a < o && w(t.charCodeAt(a)); )
143
143
  a++;
144
- let h = t.charCodeAt(a), g, y = false;
145
- if (h === 39 || h === 34 || h === 96) {
144
+ let g = t.charCodeAt(a), p, y = false;
145
+ if (g === 39 || g === 34 || g === 96) {
146
146
  let v = t[a], u = t.indexOf(v, a + 1), m = -1, C = -1;
147
147
  for (;u !== -1; ) {
148
148
  let O = t.charCodeAt(u - 1) === 92, E = u + 1;
@@ -153,7 +153,7 @@ var require_dist = __commonJS(function(exports, module) {
153
153
  u = t.indexOf(v, u + 1);
154
154
  }
155
155
  if (m !== -1) {
156
- if (g = t.slice(a + 1, m), r = C, t.charCodeAt(r) === 35)
156
+ if (p = t.slice(a + 1, m), r = C, t.charCodeAt(r) === 35)
157
157
  for (;r < o && !q(t.charCodeAt(r)); )
158
158
  r++;
159
159
  y = true;
@@ -175,12 +175,12 @@ var require_dist = __commonJS(function(exports, module) {
175
175
  for (;C > m && w(t.charCodeAt(C - 1)); )
176
176
  C--;
177
177
  let O = t.charCodeAt(m);
178
- if (C - m >= 2 && (O === 39 || O === 34 || O === 96) && t.charCodeAt(C - 1) === O ? g = t.slice(m + 1, C - 1) : g = t.slice(m, C), r = u, u < v)
178
+ if (p = t.slice(m, C), p.includes("\u2028") || p.includes("\u2029") ? p = p.replace(/^(['"`])([\s\S]*)\1$/mg, "$2") : C - m >= 2 && (O === 39 || O === 34 || O === 96) && t.charCodeAt(C - 1) === O && (p = t.slice(m + 1, C - 1)), r = u, u < v)
179
179
  for (;r < o && !q(t.charCodeAt(r)); )
180
180
  r++;
181
181
  }
182
- h === 34 && (y || a < r) && g.indexOf("\\") !== -1 && (g = g.replace(/\\n/g, `
183
- `).replace(/\\r/g, "\r")), n[p] = g;
182
+ g === 34 && (y || a < r) && p.indexOf("\\") !== -1 && (p = p.replace(/\\n/g, `
183
+ `).replace(/\\r/g, "\r")), n[h] = p;
184
184
  }
185
185
  return n;
186
186
  }
@@ -194,7 +194,7 @@ var require_dist = __commonJS(function(exports, module) {
194
194
  console.error(`\u25C7 ${e}`);
195
195
  }
196
196
  function V(e) {
197
- return e[0] === "~" ? S.join(Z.homedir(), e.slice(1)) : e;
197
+ return e[0] === "~" ? I.join(Z.homedir(), e.slice(1)) : e;
198
198
  }
199
199
  function ce(e = {}) {
200
200
  let n = { ...e };
@@ -204,7 +204,7 @@ var require_dist = __commonJS(function(exports, module) {
204
204
  }
205
205
  function ae(e) {
206
206
  e = ce(e);
207
- let n = S.resolve(process.cwd(), ".env"), t = "utf8", o = process.env;
207
+ let n = I.resolve(process.cwd(), ".env"), t = "utf8", o = process.env;
208
208
  e && e.processEnv != null && (o = e.processEnv);
209
209
  let r = $(e && e.debug);
210
210
  e && e.encoding ? t = e.encoding : r && T("no encoding is specified (UTF-8 is used by default)");
@@ -225,15 +225,15 @@ var require_dist = __commonJS(function(exports, module) {
225
225
  } catch (a) {
226
226
  r && T(`failed to load ${c} ${a.message}`), i = a;
227
227
  }
228
- let p = A.populate(o, l, e), f = $(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(o).quiet);
228
+ let h = A.populate(o, l, e), f = $(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(o).quiet);
229
229
  if (r || !f) {
230
- let c = Object.keys(p).length, a = [];
231
- for (let h of s)
230
+ let c = Object.keys(h).length, a = [];
231
+ for (let g of s)
232
232
  try {
233
- let g = S.relative(process.cwd(), h instanceof ee ? te(h) : h);
234
- a.push(g);
235
- } catch (g) {
236
- r && T(`failed to load ${h} ${g.message}`), i = g;
233
+ let p = I.relative(process.cwd(), g instanceof ee ? te(g) : g);
234
+ a.push(p);
235
+ } catch (p) {
236
+ r && T(`failed to load ${g} ${p.message}`), i = p;
237
237
  }
238
238
  ie(`injected env (${c}) from ${a.join(",")}`);
239
239
  }
@@ -259,7 +259,7 @@ var require_dist = __commonJS(function(exports, module) {
259
259
  x.exports.populate = A.populate;
260
260
  x.exports = A;
261
261
  });
262
- var M = k((Te, W) => {
262
+ var M = j((Te, W) => {
263
263
  var _ = __require("child_process"), ue = __require("fs"), L = __require("path");
264
264
  function de(e) {
265
265
  let n = ['"'], t = 0;
@@ -291,10 +291,10 @@ var require_dist = __commonJS(function(exports, module) {
291
291
  let o = (P(n, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean), s = o.some((l) => e.toLowerCase().endsWith(l.toLowerCase())) ? ["", ...o] : [...o, ""], i = /[\\/]/.test(e) ? [t] : [t, ...(P(n, "PATH") || "").split(";")];
292
292
  for (let l of i)
293
293
  for (let d of s) {
294
- let p = L.resolve(t, l.replace(/^"|"$/g, ""), e + d);
294
+ let h = L.resolve(t, l.replace(/^"|"$/g, ""), e + d);
295
295
  try {
296
- if (ue.statSync(p).isFile())
297
- return p;
296
+ if (ue.statSync(h).isFile())
297
+ return h;
298
298
  } catch {}
299
299
  }
300
300
  }
@@ -312,18 +312,18 @@ var require_dist = __commonJS(function(exports, module) {
312
312
  }
313
313
  W.exports = he;
314
314
  });
315
- var X = k(($e, F) => {
316
- var ge = __require("fs"), me = __require("os"), Q = __require("path"), ve = __require("child_process"), Ce = M(), R = N(), { optionsFromEnv: J } = I();
315
+ var X = j(($e, F) => {
316
+ var ge = __require("fs"), me = __require("os"), Q = __require("path"), ve = __require("child_process"), Ce = M(), R = N(), { optionsFromEnv: J } = k();
317
317
  function D() {
318
318
  console.log(["Usage: dotenv run [--help] [-q|--quiet] [--debug] [--override] [--fast] [-f|--file <paths>] [--] <command> [args...]", "", "Run a command with environment variables from a .env file.", "Place dotenv options before the command; all following arguments go to the command.", "", "Options:", " -f, --file <paths> .env paths, comma-separated or repeated (default: .env)", " -q, --quiet suppress the injected env message", " --debug enable debug logging", " --override override existing environment variables", " --fast use the faster character-scanner parser", "", "Environment variables (DOTENV_CONFIG_* names remain as fallbacks):", " DOTENV_PATH, DOTENV_ENCODING, DOTENV_QUIET,", " DOTENV_DEBUG, DOTENV_OVERRIDE,", " DOTENV_FAST"].join(`
319
319
  `));
320
320
  }
321
321
  function we(e) {
322
322
  let n = [], t = false, o, r, s, i, l = -1;
323
- for (let p = 0;p < e.length; p++) {
324
- let f = e[p];
323
+ for (let h = 0;h < e.length; h++) {
324
+ let f = e[h];
325
325
  if (f === "--") {
326
- l = p + 1;
326
+ l = h + 1;
327
327
  break;
328
328
  }
329
329
  if (f === "--help" || f === "-h")
@@ -345,18 +345,18 @@ var require_dist = __commonJS(function(exports, module) {
345
345
  continue;
346
346
  }
347
347
  if (f === "-f" || f === "--file" || f.startsWith("-f=") || f.startsWith("--file=")) {
348
- let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), h = c === -1 ? e[++p] : f.slice(c + 1);
349
- if (!h || h === "--")
348
+ let c = f.indexOf("="), a = c === -1 ? f : f.slice(0, c), g = c === -1 ? e[++h] : f.slice(c + 1);
349
+ if (!g || g === "--")
350
350
  return { error: `${a} requires a path` };
351
- let g = h.split(",").map((y) => y.trim()).filter(Boolean);
352
- if (g.length === 0)
351
+ let p = g.split(",").map((y) => y.trim()).filter(Boolean);
352
+ if (p.length === 0)
353
353
  return { error: `${a} requires a path` };
354
- n.push(...g), t = true;
354
+ n.push(...p), t = true;
355
355
  continue;
356
356
  }
357
357
  if (f.startsWith("-"))
358
358
  return { error: `unknown option: ${f}` };
359
- l = p;
359
+ l = h;
360
360
  break;
361
361
  }
362
362
  let d = l === -1 ? [] : e.slice(l);
@@ -410,15 +410,15 @@ var require_dist = __commonJS(function(exports, module) {
410
410
  try {
411
411
  let c = be(o);
412
412
  if (!(o.quiet == null ? J().quiet : o.quiet)) {
413
- let h = `\u25C7 injected env (${Object.keys(c.injected).length})`;
414
- c.loadedPaths.length > 0 && (h += ` from ${c.loadedPaths.join(", ")}`), console.error(h);
413
+ let g = `\u25C7 injected env (${Object.keys(c.injected).length})`;
414
+ c.loadedPaths.length > 0 && (g += ` from ${c.loadedPaths.join(", ")}`), console.error(g);
415
415
  }
416
416
  } catch (c) {
417
417
  console.error(`dotenv: ${c.message}`), process.exitCode = 1;
418
418
  return;
419
419
  }
420
420
  let r = !!process.stdin.isTTY, s = process.platform !== "win32" && !r, i = Ce(t.command[0], t.command.slice(1), { stdio: "inherit", detached: s }), l = new Map, d = 0;
421
- function p(c) {
421
+ function h(c) {
422
422
  if (!(!i.pid || i.exitCode !== null || i.signalCode !== null)) {
423
423
  if (process.platform === "win32") {
424
424
  ve.spawnSync("taskkill", ["/pid", String(i.pid), "/T", "/F"], { stdio: "ignore" });
@@ -442,11 +442,11 @@ var require_dist = __commonJS(function(exports, module) {
442
442
  if (d++, r && process.platform !== "win32" && d === 1)
443
443
  return;
444
444
  if (d > 1) {
445
- p(d === 2 ? "SIGTERM" : "SIGKILL");
445
+ h(d === 2 ? "SIGTERM" : "SIGKILL");
446
446
  return;
447
447
  }
448
448
  }
449
- p(c);
449
+ h(c);
450
450
  };
451
451
  l.set(c, a), process.on(c, a);
452
452
  }
@@ -459,13 +459,13 @@ var require_dist = __commonJS(function(exports, module) {
459
459
  F.exports = K;
460
460
  F === __require.main && K(process.argv.slice(2));
461
461
  });
462
- var j = N();
462
+ var S = N();
463
463
  var qe = X();
464
- module.exports = j;
465
- module.exports.config = j.config;
466
- module.exports.configDotenv = j.configDotenv;
467
- module.exports.parse = j.parse;
468
- module.exports.populate = j.populate;
464
+ module.exports = S;
465
+ module.exports.config = S.config;
466
+ module.exports.configDotenv = S.configDotenv;
467
+ module.exports.parse = S.parse;
468
+ module.exports.populate = S.populate;
469
469
  });
470
470
 
471
471
  // src/load-env.ts
@@ -515,7 +515,7 @@ var createPkcePair = () => {
515
515
  verifier
516
516
  };
517
517
  };
518
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/util.js
518
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/util.js
519
519
  function getEnumValues(entries) {
520
520
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
521
521
  const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
@@ -861,6 +861,18 @@ function prefixIssues(path, issues) {
861
861
  function unwrapMessage(message) {
862
862
  return typeof message === "string" ? message : message?.message;
863
863
  }
864
+ function sizeCaps(defChecks) {
865
+ const caps = [];
866
+ for (const ch of defChecks ?? []) {
867
+ const d = ch._zod.def;
868
+ if (!/_(length|size)$|_equals$/.test(d.check))
869
+ break;
870
+ const max = d.maximum ?? d.length ?? d.size;
871
+ if (max >= 0)
872
+ caps.push([max, ch]);
873
+ }
874
+ return caps;
875
+ }
864
876
  function attachSchema(issues, start, inst) {
865
877
  var _a;
866
878
  for (let i = start;i < issues.length; i++) {
@@ -1058,7 +1070,7 @@ function constantCatch(value) {
1058
1070
  return fn;
1059
1071
  }
1060
1072
 
1061
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/core.js
1073
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/core.js
1062
1074
  var _a;
1063
1075
  var _zodDesc = { value: undefined, enumerable: false };
1064
1076
  var _E = "captureStackTrace" in Error ? Error : null;
@@ -1176,7 +1188,7 @@ function config2(newConfig) {
1176
1188
  Object.assign(globalConfig, newConfig);
1177
1189
  return globalConfig;
1178
1190
  }
1179
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/errors.js
1191
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/errors.js
1180
1192
  function _getMessage() {
1181
1193
  const internals = this._zod;
1182
1194
  internals.message ?? (internals.message = JSON.stringify(internals.def, jsonStringifyReplacer, 2));
@@ -1291,7 +1303,7 @@ function formatError(error, mapper = (issue) => issue.message) {
1291
1303
  return fieldErrors;
1292
1304
  }
1293
1305
 
1294
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/parse.js
1306
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/parse.js
1295
1307
  function finalizeParams(callee, params) {
1296
1308
  return { callee: params?.callee ?? callee, Err: params?.Err };
1297
1309
  }
@@ -1438,7 +1450,7 @@ var _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => {
1438
1450
  var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
1439
1451
  return _safeParseAsync(_Err)(schema, value, _ctx);
1440
1452
  };
1441
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/regexes.js
1453
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/regexes.js
1442
1454
  var cuid = /^[cC][0-9a-z]{6,}$/;
1443
1455
  var cuid2 = /^[0-9a-z]+$/;
1444
1456
  var ulid = /^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/;
@@ -1496,7 +1508,7 @@ var _null = /^null$/i;
1496
1508
  var lowercase = /^[^A-Z]*$/;
1497
1509
  var uppercase = /^[^a-z]*$/;
1498
1510
 
1499
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/checks.js
1511
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/checks.js
1500
1512
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
1501
1513
  var _a;
1502
1514
  inst._zod ?? (inst._zod = {});
@@ -1812,7 +1824,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
1812
1824
  };
1813
1825
  });
1814
1826
 
1815
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/doc.js
1827
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/doc.js
1816
1828
  class Doc {
1817
1829
  constructor(args = [], closed = {}) {
1818
1830
  this.content = [];
@@ -1854,14 +1866,14 @@ ${content.join(`
1854
1866
  }
1855
1867
  }
1856
1868
 
1857
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/versions.js
1869
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/versions.js
1858
1870
  var version = {
1859
1871
  major: 4,
1860
1872
  minor: 6,
1861
- patch: 5
1873
+ patch: 7
1862
1874
  };
1863
1875
 
1864
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/schemas.js
1876
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/schemas.js
1865
1877
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
1866
1878
  var _a;
1867
1879
  inst ?? (inst = {});
@@ -2427,6 +2439,29 @@ var $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
2427
2439
  return payload;
2428
2440
  };
2429
2441
  });
2442
+ function capSize(inst, size) {
2443
+ const caps = sizeCaps(inst._zod.def.checks);
2444
+ if (!caps.length)
2445
+ return;
2446
+ const cap = Math.min(...caps.map((c) => c[0]));
2447
+ const parse = inst._zod.parse;
2448
+ inst._zod.parse = (payload, ctx) => {
2449
+ const n = size(payload.value);
2450
+ if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
2451
+ for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
2452
+ if (n > max && ch._zod.def.when(payload)) {
2453
+ const start = payload.issues.length;
2454
+ ch._zod.check(payload);
2455
+ payload.issues[start].continue = false;
2456
+ attachSchema(payload.issues, start, inst);
2457
+ return payload;
2458
+ }
2459
+ }
2460
+ }
2461
+ return parse(payload, ctx);
2462
+ };
2463
+ }
2464
+ var arraySize = (input) => Array.isArray(input) ? input.length : -1;
2430
2465
  function handleArrayResult(result, final, index) {
2431
2466
  if (result.issues.length) {
2432
2467
  final.issues.push(...prefixIssues(index, result.issues));
@@ -2470,6 +2505,7 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
2470
2505
  }
2471
2506
  return payload;
2472
2507
  };
2508
+ capSize(inst, arraySize);
2473
2509
  });
2474
2510
  function handlePropertyResult(result, final, key, input, optin, optout) {
2475
2511
  const isPresent = key in input;
@@ -3252,7 +3288,7 @@ function handleRefineResult(result, payload, input, inst) {
3252
3288
  payload.issues.push(issue(_iss));
3253
3289
  }
3254
3290
  }
3255
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/memoizer.js
3291
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/memoizer.js
3256
3292
  class $ZodCyclicError extends Error {
3257
3293
  constructor() {
3258
3294
  super(`Cannot parse a reference cycle that closes through a transform`);
@@ -3521,7 +3557,7 @@ function isBackEdge(ctx, value) {
3521
3557
  const backEdges = ctx[STATE]?.backEdges;
3522
3558
  return backEdges !== undefined && isRef(value) && backEdges.has(value);
3523
3559
  }
3524
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/locales/en.js
3560
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/locales/en.js
3525
3561
  var error = () => {
3526
3562
  const Sizable = {
3527
3563
  string: { unit: "characters", verb: "to have" },
@@ -3643,7 +3679,7 @@ function en_default() {
3643
3679
  localeError: error()
3644
3680
  };
3645
3681
  }
3646
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/registries.js
3682
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/registries.js
3647
3683
  var _a2;
3648
3684
  class $ZodRegistry {
3649
3685
  constructor() {
@@ -3690,7 +3726,7 @@ function registry() {
3690
3726
  }
3691
3727
  (_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
3692
3728
  var globalRegistry = globalThis.__zod_globalRegistry;
3693
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/api.js
3729
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/api.js
3694
3730
  function snapshotChecks(def) {
3695
3731
  if (def.checks)
3696
3732
  def.checks = [...def.checks];
@@ -4144,7 +4180,7 @@ function _check(fn, params) {
4144
4180
  ch._zod.check = fn;
4145
4181
  return ch;
4146
4182
  }
4147
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/to-json-schema.js
4183
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/to-json-schema.js
4148
4184
  function assignProps(target, ...sources) {
4149
4185
  for (const source of sources) {
4150
4186
  for (const key of Reflect.ownKeys(source)) {
@@ -4667,7 +4703,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
4667
4703
  extractDefs(ctx, schema);
4668
4704
  return finalize(ctx, schema);
4669
4705
  };
4670
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/json-schema-processors.js
4706
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/core/json-schema-processors.js
4671
4707
  var narrowMin = (agg, key, value) => {
4672
4708
  if (agg[key] === undefined || value > agg[key])
4673
4709
  agg[key] = value;
@@ -5096,7 +5132,7 @@ var optionalProcessor = (schema, ctx, _json, params) => {
5096
5132
  const seen = ctx.seen.get(schema);
5097
5133
  seen.ref = def.innerType;
5098
5134
  };
5099
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/errors.js
5135
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/errors.js
5100
5136
  var _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
5101
5137
  function _lazyMethod(proto, key, make) {
5102
5138
  Object.defineProperty(proto, key, {
@@ -5141,7 +5177,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, undefi
5141
5177
  Parent: Error
5142
5178
  });
5143
5179
 
5144
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/parse.js
5180
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/parse.js
5145
5181
  var parse2 = /* @__PURE__ */ _parse(ZodRealError);
5146
5182
  var parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
5147
5183
  var safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -5155,7 +5191,7 @@ var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
5155
5191
  var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
5156
5192
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
5157
5193
 
5158
- // ../../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/schemas.js
5194
+ // ../../../node_modules/.bun/zod@4.6.7/node_modules/zod/v4/classic/schemas.js
5159
5195
  function _ensureDefaultLocale() {
5160
5196
  if (!globalConfig.localeError)
5161
5197
  config2(en_default());
@@ -7540,6 +7576,10 @@ var typedOperations = {
7540
7576
  kind: "mutation",
7541
7577
  invoke: (client, input) => client.event.reviewSubmission.mutate(input)
7542
7578
  },
7579
+ "event.reopenMission": {
7580
+ kind: "mutation",
7581
+ invoke: (client, input) => client.event.reopenMission.mutate(input)
7582
+ },
7543
7583
  "event.regenerateResultsPortalShare": {
7544
7584
  kind: "mutation",
7545
7585
  invoke: (client, input) => client.event.regenerateResultsPortalShare.mutate(input)
@@ -7885,6 +7925,7 @@ var mutationTargetKeys = {
7885
7925
  "team.assignTeamRoutingGroup": ["teamId"],
7886
7926
  "event.startStation": ["stationId"],
7887
7927
  "event.skipMission": ["missionId"],
7928
+ "event.reopenMission": ["teamId", "eventPlayerId", "missionId"],
7888
7929
  "event.create": ["organizationId", "name"],
7889
7930
  "event.createFromTemplate": ["organizationId", "templateId"],
7890
7931
  "event.requestLoginEmailOtp": ["eventId", "email"],
@@ -8021,6 +8062,7 @@ var commands = [
8021
8062
  mutation(["reward", "update"], "event.updateReward", "Update an event reward.", ["state-change"]),
8022
8063
  mutation(["score", "adjust"], "event.createScoreAdjustment", "Create a manual score adjustment.", ["state-change"]),
8023
8064
  mutation(["submission", "review"], "event.reviewSubmission", "Review a mission submission.", ["state-change"]),
8065
+ 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"]),
8024
8066
  mutation(["results-share", "regenerate"], "event.regenerateResultsPortalShare", "Create a new results portal share token.", ["state-change"]),
8025
8067
  mutation(["results-share", "revoke"], "event.revokeResultsPortalShare", "Revoke the current results portal share token.", ["state-change", "delete"]),
8026
8068
  query(["event", "analytics-shell"], "event.getAdminAnalyticsShell", "Get the organizer analytics shell."),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-labs-sg/gosh",
3
- "version": "1.0.0",
3
+ "version": "1.1.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.7",
22
+ "dotenv": "^18.0.8",
23
23
  "superjson": "^2.2.6"
24
24
  },
25
25
  "engines": {