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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +85 -7
- package/manifest.json +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
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
|
|
32023
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
10
|
+
"version": "2.29.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp-classroom",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.29.0",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|