gogcli-mcp-classroom 2.28.0 → 2.29.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.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
10
- "version": "2.28.0"
10
+ "version": "2.29.0"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "gogcli (Classroom)",
16
16
  "source": "./",
17
17
  "description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
18
- "version": "2.28.0",
18
+ "version": "2.29.0",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gogcli-mcp-classroom",
3
3
  "displayName": "gogcli (Classroom)",
4
- "version": "2.28.0",
4
+ "version": "2.29.0",
5
5
  "description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/dist/index.js CHANGED
@@ -31323,6 +31323,56 @@ function redactSecrets(text) {
31323
31323
  return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JWT_RE, "[REDACTED]");
31324
31324
  }
31325
31325
 
31326
+ // ../../node_modules/@chrischall/mcp-utils/dist/response/view.js
31327
+ function minifiedResult(data) {
31328
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31329
+ }
31330
+
31331
+ // ../../node_modules/@chrischall/mcp-utils/dist/response/media.js
31332
+ var MEDIA_NOUN = "(?:avatar|tall_avatar|cover_photo|cover_image|picture|photo|thumbnail|thumb|image|icon|banner|profile_pic(?:ture)?|logo)";
31333
+ var MEDIA_KEY = new RegExp(`^${MEDIA_NOUN}s?(?:(?:link|uri|url)s?)?$`, "i");
31334
+ var MEDIA_URL = /^https?:\/\/[^\s]+?\.(png|jpe?g|gif|webp|svg|avif|bmp|ico)([?#]|$)/i;
31335
+ function stripMediaUrls(value, opts = {}) {
31336
+ const keep = new Set((opts.keep ?? []).map((k) => k.toLowerCase()));
31337
+ const drop = (opts.drop ?? []).map((rule) => typeof rule === "string" ? rule.toLowerCase() : new RegExp(rule.source, rule.flags));
31338
+ return walk(value, keep, drop);
31339
+ }
31340
+ function alsoDrop(key, drop) {
31341
+ const lower = key.toLowerCase();
31342
+ for (const rule of drop) {
31343
+ if (typeof rule === "string") {
31344
+ if (rule === lower)
31345
+ return true;
31346
+ continue;
31347
+ }
31348
+ rule.lastIndex = 0;
31349
+ if (rule.test(key))
31350
+ return true;
31351
+ }
31352
+ return false;
31353
+ }
31354
+ function walk(value, keep, drop) {
31355
+ if (Array.isArray(value))
31356
+ return value.map((v) => walk(v, keep, drop));
31357
+ if (value === null || typeof value !== "object")
31358
+ return value;
31359
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
31360
+ return value;
31361
+ const out = {};
31362
+ for (const [key, v] of Object.entries(value)) {
31363
+ if (keep.has(key.toLowerCase())) {
31364
+ out[key] = v;
31365
+ continue;
31366
+ }
31367
+ if (MEDIA_KEY.test(key) || alsoDrop(key, drop))
31368
+ continue;
31369
+ if (typeof v === "string" && MEDIA_URL.test(v))
31370
+ continue;
31371
+ out[key] = walk(v, keep, drop);
31372
+ }
31373
+ return out;
31374
+ }
31375
+
31326
31376
  // ../../node_modules/@chrischall/mcp-utils/dist/response/index.js
31327
31377
  function rawTextResult(text) {
31328
31378
  return { content: [{ type: "text", text }] };
@@ -31842,11 +31892,11 @@ function parseTimestampValue(key, value, assumeNaiveIn) {
31842
31892
  }
31843
31893
  return null;
31844
31894
  }
31845
- function walk(node, tz, naiveTz) {
31895
+ function walk2(node, tz, naiveTz) {
31846
31896
  let changed = false;
31847
31897
  if (Array.isArray(node)) {
31848
31898
  for (const item of node) {
31849
- if (walk(item, tz, naiveTz)) changed = true;
31899
+ if (walk2(item, tz, naiveTz)) changed = true;
31850
31900
  }
31851
31901
  return changed;
31852
31902
  }
@@ -31855,7 +31905,7 @@ function walk(node, tz, naiveTz) {
31855
31905
  for (const key of Object.keys(obj)) {
31856
31906
  const value = obj[key];
31857
31907
  if (value !== null && typeof value === "object") {
31858
- if (walk(value, tz, naiveTz)) changed = true;
31908
+ if (walk2(value, tz, naiveTz)) changed = true;
31859
31909
  continue;
31860
31910
  }
31861
31911
  if (ZONE_NAME_KEYS.has(key) || !TIMESTAMP_KEYS.has(key)) continue;
@@ -31881,7 +31931,7 @@ function normalizeTimestamps(text, tz = displayTimeZone(), naiveTz = naiveSource
31881
31931
  } catch {
31882
31932
  return text;
31883
31933
  }
31884
- if (!walk(parsed, tz, naiveTz)) return text;
31934
+ if (!walk2(parsed, tz, naiveTz)) return text;
31885
31935
  return JSON.stringify(parsed, null, detectIndent(text));
31886
31936
  }
31887
31937
 
@@ -32017,10 +32067,38 @@ ${accounts || "(none)"}${hint}`);
32017
32067
  return errorResult(`${errText}${hint}`);
32018
32068
  }
32019
32069
  }
32070
+ function minifiedOrRawText(text, stripMedia = false) {
32071
+ const trimmed = text.trim();
32072
+ if (trimmed === "" || !/^[[{]/.test(trimmed)) return rawTextResult(text);
32073
+ try {
32074
+ const parsed = JSON.parse(trimmed);
32075
+ return minifiedResult(stripMedia ? stripMediaUrls(parsed) : parsed);
32076
+ } catch {
32077
+ return rawTextResult(text);
32078
+ }
32079
+ }
32080
+ function isRejectedFieldMask(err) {
32081
+ return /invalidParameter|invalid field selection/i.test(String(err));
32082
+ }
32083
+ async function runProjected(args, options) {
32084
+ const { fieldsMask } = options;
32085
+ if (!fieldsMask) return run(args, options);
32086
+ try {
32087
+ return await run([...args, `--fields=${fieldsMask}`], options);
32088
+ } catch (err) {
32089
+ if (!isRejectedFieldMask(err)) throw err;
32090
+ process.stderr.write(
32091
+ `gogcli-mcp: Google rejected the compact field mask (${fieldsMask}); retrying unprojected
32092
+ `
32093
+ );
32094
+ return run(args, options);
32095
+ }
32096
+ }
32020
32097
  async function runOrDiagnose(args, options) {
32021
32098
  try {
32022
- const raw = await run(args, options);
32023
- return rawTextResult(options.lossless ? raw : stripConsumedPageToken(normalizeTimestamps(raw)));
32099
+ const raw = await runProjected(args, options);
32100
+ if (options.lossless) return rawTextResult(raw);
32101
+ return minifiedOrRawText(stripConsumedPageToken(normalizeTimestamps(raw)), options.stripMedia);
32024
32102
  } catch (err) {
32025
32103
  return diagnose(err);
32026
32104
  }
@@ -32647,7 +32725,7 @@ var failIfNotEmptyParam = external_exports.boolean().optional().describe(
32647
32725
  );
32648
32726
 
32649
32727
  // ../gogcli-mcp/src/server.ts
32650
- var VERSION = true ? "2.28.0" : "0.0.0";
32728
+ var VERSION = true ? "2.29.0" : "0.0.0";
32651
32729
 
32652
32730
  // ../gogcli-mcp/src/auth-log.ts
32653
32731
  var FAILURES = /* @__PURE__ */ new Set([
package/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "manifest_version": "0.3",
4
4
  "name": "gogcli-mcp-classroom",
5
5
  "display_name": "gogcli (Classroom)",
6
- "version": "2.28.0",
6
+ "version": "2.29.0",
7
7
  "description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
8
8
  "author": {
9
9
  "name": "Chris Hall",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-classroom",
3
- "version": "2.28.0",
3
+ "version": "2.29.0",
4
4
  "mcpName": "io.github.chrischall/gogcli-mcp-classroom",
5
5
  "description": "Extended Google Classroom MCP server via gogcli — auth + full Classroom support",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
@@ -24,7 +24,7 @@
24
24
  "test:coverage": "vitest run --coverage"
25
25
  },
26
26
  "dependencies": {
27
- "@chrischall/mcp-utils": "^0.17.1",
27
+ "@chrischall/mcp-utils": "^0.23.0",
28
28
  "@modelcontextprotocol/sdk": "^1.30.0",
29
29
  "zod": "^4.4.3"
30
30
  },
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "source": "github",
8
8
  "subfolder": "packages/gogcli-mcp-classroom"
9
9
  },
10
- "version": "2.28.0",
10
+ "version": "2.29.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "gogcli-mcp-classroom",
15
- "version": "2.28.0",
15
+ "version": "2.29.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },