@lukeguo12210/canvas-cli 0.0.6 → 0.0.8
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 +8 -2
- package/dist/bin/canvas.js +74 -4
- package/dist/bin/canvas.js.map +1 -1
- package/package.json +1 -1
- package/skills/canvas-courses/SKILL.md +11 -0
- package/skills/canvas-files/SKILL.md +1 -0
- package/skills/canvas-pages/SKILL.md +1 -0
- package/skills/canvas-shared/SKILL.md +6 -2
- package/skills/canvas-shared/references/auth.md +29 -14
- package/skills/canvas-shared/references/output.md +1 -1
package/README.md
CHANGED
|
@@ -80,6 +80,7 @@ canvas auth login
|
|
|
80
80
|
|
|
81
81
|
# Agent/non-interactive auth
|
|
82
82
|
canvas auth schools search "Columbia"
|
|
83
|
+
canvas auth login --school "Columbia"
|
|
83
84
|
canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
|
|
84
85
|
|
|
85
86
|
# 2. List courses
|
|
@@ -134,7 +135,11 @@ The login flow will:
|
|
|
134
135
|
4. Store the token locally.
|
|
135
136
|
5. Run a lightweight context bootstrap.
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
Agents can complete setup with a token the user provides:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
canvas auth login --school "Berkeley" --token "paste-token-here"
|
|
142
|
+
```
|
|
138
143
|
|
|
139
144
|
## Command System
|
|
140
145
|
|
|
@@ -151,6 +156,7 @@ canvas review pack --course-id <course-id> --out ./review/<course> --include-all
|
|
|
151
156
|
|
|
152
157
|
```bash
|
|
153
158
|
canvas auth login
|
|
159
|
+
canvas auth login --school "Berkeley"
|
|
154
160
|
canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
|
|
155
161
|
canvas auth login --school-url https://courseworks2.columbia.edu --school-name "Columbia University (CourseWorks)" --token "paste-token-here"
|
|
156
162
|
canvas auth schools search "Columbia"
|
|
@@ -211,7 +217,7 @@ MVP raw API access is GET-only.
|
|
|
211
217
|
|
|
212
218
|
## Security & Privacy
|
|
213
219
|
|
|
214
|
-
- Tokens are local
|
|
220
|
+
- Tokens are stored in the local Canvas CLI config after auth.
|
|
215
221
|
- Logs and errors redact `Authorization`, `access_token`, `token`, and bearer values.
|
|
216
222
|
- The MVP refuses Canvas write methods.
|
|
217
223
|
- Review packs exclude grades, submissions, conversations, and group member lists by default.
|
package/dist/bin/canvas.js
CHANGED
|
@@ -613,9 +613,13 @@ function positionalArgs(argv) {
|
|
|
613
613
|
}
|
|
614
614
|
|
|
615
615
|
// src/commands/auth.ts
|
|
616
|
-
var TOKEN_PURPOSE = "
|
|
616
|
+
var TOKEN_PURPOSE = "canvas-cli";
|
|
617
617
|
async function handleAuthCommand(argv, options) {
|
|
618
618
|
const [subcommand] = argv;
|
|
619
|
+
if (!subcommand || subcommand === "--help" || subcommand === "-h" || subcommand === "help") {
|
|
620
|
+
process.stdout.write(authHelpText());
|
|
621
|
+
return 0;
|
|
622
|
+
}
|
|
619
623
|
if (subcommand === "login") {
|
|
620
624
|
return authLogin(argv.slice(1), options);
|
|
621
625
|
}
|
|
@@ -641,6 +645,32 @@ async function handleAuthCommand(argv, options) {
|
|
|
641
645
|
);
|
|
642
646
|
return 1;
|
|
643
647
|
}
|
|
648
|
+
function authHelpText() {
|
|
649
|
+
return `canvas auth \u2014 authenticate and inspect Canvas login state.
|
|
650
|
+
|
|
651
|
+
USAGE:
|
|
652
|
+
canvas auth <command> [options]
|
|
653
|
+
|
|
654
|
+
COMMANDS:
|
|
655
|
+
login Interactive Canvas PAT setup
|
|
656
|
+
login --school <query> Non-interactive login with a school search
|
|
657
|
+
login --school-url <url> Non-interactive login with a custom Canvas URL
|
|
658
|
+
schools search <query> Search supported Canvas school URLs
|
|
659
|
+
status Show redacted auth status
|
|
660
|
+
logout Remove local Canvas auth config
|
|
661
|
+
|
|
662
|
+
TOKEN OPTIONS:
|
|
663
|
+
--token <PAT> Use a token provided by the user
|
|
664
|
+
--token-env <ENV> Read token from an environment variable
|
|
665
|
+
--token-stdin Read token from stdin
|
|
666
|
+
|
|
667
|
+
EXAMPLES:
|
|
668
|
+
canvas auth schools search "Berkeley" --format json
|
|
669
|
+
canvas auth login --school "Berkeley"
|
|
670
|
+
canvas auth login --school "Berkeley" --token-env CANVAS_TOKEN
|
|
671
|
+
canvas auth login --school-url https://bcourses.berkeley.edu --school-name "UC Berkeley" --token "paste-token-here"
|
|
672
|
+
`;
|
|
673
|
+
}
|
|
644
674
|
async function authLogin(argv, options) {
|
|
645
675
|
const io = createPrompt();
|
|
646
676
|
try {
|
|
@@ -649,6 +679,20 @@ async function authLogin(argv, options) {
|
|
|
649
679
|
const settingsUrl = `${school.url}/profile/settings`;
|
|
650
680
|
const providedToken = await tokenFromArgs(argv);
|
|
651
681
|
let token = providedToken;
|
|
682
|
+
if (!token && nonInteractive) {
|
|
683
|
+
await writeOutput(
|
|
684
|
+
{
|
|
685
|
+
ok: true,
|
|
686
|
+
data: tokenSetupForSchool(school),
|
|
687
|
+
meta: {
|
|
688
|
+
command: "auth login",
|
|
689
|
+
mode: "token-setup"
|
|
690
|
+
}
|
|
691
|
+
},
|
|
692
|
+
options
|
|
693
|
+
);
|
|
694
|
+
return 0;
|
|
695
|
+
}
|
|
652
696
|
if (!token) {
|
|
653
697
|
process.stdout.write(tokenInstructions(school, settingsUrl));
|
|
654
698
|
await io.question("Press Enter to open Canvas settings in your browser...");
|
|
@@ -868,6 +912,32 @@ async function tokenFromArgs(argv) {
|
|
|
868
912
|
}
|
|
869
913
|
return void 0;
|
|
870
914
|
}
|
|
915
|
+
function tokenSetupForSchool(school) {
|
|
916
|
+
const settingsUrl = `${school.url}/profile/settings`;
|
|
917
|
+
const schoolArg = JSON.stringify(school.name);
|
|
918
|
+
return {
|
|
919
|
+
requiresToken: true,
|
|
920
|
+
message: `Open ${school.name}'s Canvas settings, create a new access token with purpose "${TOKEN_PURPOSE}", then send the token back so I can finish connecting Canvas.`,
|
|
921
|
+
school: {
|
|
922
|
+
name: school.name,
|
|
923
|
+
baseUrl: school.url,
|
|
924
|
+
settingsUrl
|
|
925
|
+
},
|
|
926
|
+
tokenPurpose: TOKEN_PURPOSE,
|
|
927
|
+
steps: [
|
|
928
|
+
`Open ${settingsUrl}`,
|
|
929
|
+
'Click "+ New Access Token"',
|
|
930
|
+
`Use "${TOKEN_PURPOSE}" as the purpose`,
|
|
931
|
+
"Generate the token and copy it",
|
|
932
|
+
"Send the token back, or put it in CANVAS_TOKEN"
|
|
933
|
+
],
|
|
934
|
+
nextCommands: {
|
|
935
|
+
directToken: `canvas auth login --school ${schoolArg} --token "paste-token-here"`,
|
|
936
|
+
envToken: `CANVAS_TOKEN="paste-token-here" canvas auth login --school ${schoolArg} --token-env CANVAS_TOKEN`,
|
|
937
|
+
stdinToken: `printf '%s' "paste-token-here" | canvas auth login --school ${schoolArg} --token-stdin`
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
}
|
|
871
941
|
async function promptCustomSchool(io) {
|
|
872
942
|
const name = await io.question("School display name: ");
|
|
873
943
|
const url = await io.question("Canvas base URL: ");
|
|
@@ -887,9 +957,9 @@ async function readStdin() {
|
|
|
887
957
|
}
|
|
888
958
|
function tokenInstructions(school, settingsUrl) {
|
|
889
959
|
return `
|
|
890
|
-
|
|
960
|
+
Let's connect ${school.name} to Canvas CLI.
|
|
891
961
|
|
|
892
|
-
1.
|
|
962
|
+
1. Open ${settingsUrl}
|
|
893
963
|
2. Click "+ New Access Token"
|
|
894
964
|
3. Enter "${TOKEN_PURPOSE}" as the purpose
|
|
895
965
|
4. Optionally set an expiration date
|
|
@@ -2407,7 +2477,7 @@ DIRECT INSTALLER:
|
|
|
2407
2477
|
}
|
|
2408
2478
|
|
|
2409
2479
|
// src/bin/canvas.ts
|
|
2410
|
-
var VERSION = "0.0.
|
|
2480
|
+
var VERSION = "0.0.8";
|
|
2411
2481
|
function helpText() {
|
|
2412
2482
|
return `canvas \u2014 Canvas LMS CLI for students and agents.
|
|
2413
2483
|
|
package/dist/bin/canvas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/redaction.ts","../../src/core/output.ts","../../src/core/errors.ts","../../src/core/pagination.ts","../../src/core/canvas-client.ts","../../src/core/config-store.ts","../../src/core/paths.ts","../../src/core/browser.ts","../../src/core/prompt.ts","../../src/registry/schools.ts","../../src/workflows/context-bootstrap.ts","../../src/commands/shared.ts","../../src/commands/auth.ts","../../src/commands/api.ts","../../src/commands/assignments.ts","../../src/commands/config.ts","../../src/commands/courses.ts","../../src/commands/files.ts","../../src/commands/me.ts","../../src/commands/modules.ts","../../src/commands/pages.ts","../../src/commands/review.ts","../../src/commands/tabs.ts","../../src/commands/skills.ts","../../src/bin/canvas.ts"],"sourcesContent":["const REDACTED = \"[REDACTED]\";\n\nconst SECRET_KEY_PATTERN = /(^|[_-])(authorization|access[_-]?token|token|api[_-]?key|secret)$/i;\nconst BEARER_PATTERN = /Bearer\\s+[A-Za-z0-9._~+/=-]+/gi;\nconst QUERY_SECRET_PATTERN = /([?&](?:access_token|token|api_key|verifier|code)=)[^&#\\s]+/gi;\n\nexport function redactSecrets(value: unknown): unknown {\n if (typeof value === \"string\") {\n return redactString(value);\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => redactSecrets(item));\n }\n\n if (value && typeof value === \"object\") {\n const output: Record<string, unknown> = {};\n for (const [key, nested] of Object.entries(value)) {\n output[key] = SECRET_KEY_PATTERN.test(key) ? REDACTED : redactSecrets(nested);\n }\n return output;\n }\n\n return value;\n}\n\nexport function redactString(value: string): string {\n return value\n .replace(BEARER_PATTERN, `Bearer ${REDACTED}`)\n .replace(QUERY_SECRET_PATTERN, `$1${REDACTED}`);\n}\n\nexport function redactedValue(): string {\n return REDACTED;\n}\n","import { redactSecrets } from \"./redaction.js\";\n\nexport type OutputFormat = \"json\" | \"pretty\" | \"table\" | \"ndjson\";\n\nexport type Success<T> = {\n ok: true;\n data: T;\n meta?: Record<string, unknown>;\n};\n\nexport type Failure = {\n ok: false;\n error: {\n code: string;\n message: string;\n status?: number;\n retryable: boolean;\n };\n};\n\nexport type ResultEnvelope<T> = Success<T> | Failure;\n\nexport function formatOutput<T>(\n result: ResultEnvelope<T>,\n options: { format?: OutputFormat } = {}\n): string {\n const format = options.format ?? \"json\";\n const safeResult = redactSecrets(result) as ResultEnvelope<T>;\n\n if (format === \"json\") {\n return `${JSON.stringify(safeResult, null, 2)}\\n`;\n }\n\n if (format === \"ndjson\") {\n return `${JSON.stringify(safeResult)}\\n`;\n }\n\n if (!safeResult.ok) {\n const status = safeResult.error.status ? ` (${safeResult.error.status})` : \"\";\n return `Error ${safeResult.error.code}${status}: ${safeResult.error.message}\\n`;\n }\n\n if (format === \"table\") {\n return tableOutput(safeResult.data);\n }\n\n return prettyOutput(safeResult.data);\n}\n\nexport async function writeOutput<T>(\n result: ResultEnvelope<T>,\n options: { format?: OutputFormat } = {}\n): Promise<void> {\n const stream = result.ok ? process.stdout : process.stderr;\n stream.write(formatOutput(result, options));\n}\n\nfunction prettyOutput(data: unknown): string {\n if (typeof data === \"string\") {\n return `${data}\\n`;\n }\n return `${JSON.stringify(data, null, 2)}\\n`;\n}\n\nfunction tableOutput(data: unknown): string {\n if (!Array.isArray(data)) {\n return prettyOutput(data);\n }\n\n if (data.length === 0) {\n return \"\\n\";\n }\n\n const rows = data.filter((row): row is Record<string, unknown> => {\n return row !== null && typeof row === \"object\" && !Array.isArray(row);\n });\n\n if (rows.length === 0) {\n return prettyOutput(data);\n }\n\n const columns = Object.keys(rows[0] ?? {});\n const widths = columns.map((column) =>\n Math.max(column.length, ...rows.map((row) => String(row[column] ?? \"\").length))\n );\n\n const line = (values: string[]) =>\n `${values.map((value, index) => value.padEnd(widths[index] ?? value.length)).join(\" \")}\\n`;\n\n let output = line(columns);\n output += line(widths.map((width) => \"-\".repeat(width)));\n for (const row of rows) {\n output += line(columns.map((column) => String(row[column] ?? \"\")));\n }\n return output;\n}\n","export class CanvasCliError extends Error {\n readonly code: string;\n readonly status?: number;\n readonly retryable: boolean;\n\n constructor(\n code: string,\n message: string,\n options: { status?: number; retryable?: boolean; cause?: unknown } = {}\n ) {\n super(message, { cause: options.cause });\n this.name = \"CanvasCliError\";\n this.code = code;\n this.status = options.status;\n this.retryable = options.retryable ?? false;\n }\n}\n\nexport function toErrorEnvelope(error: unknown) {\n if (error instanceof CanvasCliError) {\n return {\n ok: false as const,\n error: {\n code: error.code,\n message: error.message,\n status: error.status,\n retryable: error.retryable\n }\n };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return {\n ok: false as const,\n error: {\n code: \"UNEXPECTED_ERROR\",\n message,\n retryable: false\n }\n };\n}\n","export type LinkRelation = \"current\" | \"next\" | \"prev\" | \"first\" | \"last\";\n\nexport type ParsedLinks = Partial<Record<LinkRelation, string>>;\n\nexport function parseLinkHeader(header: string | null | undefined): ParsedLinks {\n if (!header) {\n return {};\n }\n\n const links: ParsedLinks = {};\n for (const part of splitHeader(header)) {\n const match = part.match(/^\\s*<([^>]+)>\\s*;\\s*rel=\"([^\"]+)\"\\s*$/i);\n if (!match) {\n continue;\n }\n const [, url, rel] = match;\n if (isLinkRelation(rel)) {\n links[rel] = url;\n }\n }\n return links;\n}\n\nfunction splitHeader(header: string): string[] {\n const parts: string[] = [];\n let current = \"\";\n let inQuotes = false;\n\n for (const char of header) {\n if (char === \"\\\"\") {\n inQuotes = !inQuotes;\n }\n if (char === \",\" && !inQuotes) {\n parts.push(current);\n current = \"\";\n continue;\n }\n current += char;\n }\n\n if (current.trim()) {\n parts.push(current);\n }\n\n return parts;\n}\n\nfunction isLinkRelation(value: string): value is LinkRelation {\n return [\"current\", \"next\", \"prev\", \"first\", \"last\"].includes(value);\n}\n","import { CanvasCliError } from \"./errors.js\";\nimport { parseLinkHeader } from \"./pagination.js\";\nimport { redactSecrets } from \"./redaction.js\";\n\nexport type CanvasClientOptions = {\n baseUrl: string;\n token: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type RequestOptions = {\n query?: Record<string, string | number | boolean | Array<string | number | boolean> | undefined>;\n pageAll?: boolean;\n pageLimit?: number;\n};\n\nexport type CanvasResponse<T> = {\n data: T;\n meta: {\n request: {\n method: \"GET\";\n path: string;\n };\n pagination: {\n pagesFetched: number;\n hasNext: boolean;\n };\n };\n};\n\nexport type CanvasDownload = {\n data: Uint8Array;\n contentType?: string;\n filename?: string;\n meta: {\n request: {\n method: \"GET\";\n url: string;\n };\n };\n};\n\nexport class CanvasClient {\n private readonly baseUrl: string;\n private readonly token: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: CanvasClientOptions) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl);\n this.token = options.token;\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n async get<T>(path: string, options: RequestOptions = {}): Promise<CanvasResponse<T>> {\n if (!path.startsWith(\"/api/v1/\")) {\n throw new CanvasCliError(\"INVALID_API_PATH\", \"Canvas API paths must start with /api/v1/.\");\n }\n\n let nextUrl: string | null = buildUrl(this.baseUrl, path, options.query);\n const pages: unknown[] = [];\n let pagesFetched = 0;\n const pageLimit = options.pageLimit ?? 50;\n\n let hasNext = false;\n\n while (nextUrl) {\n pagesFetched += 1;\n if (pagesFetched > pageLimit) {\n throw new CanvasCliError(\n \"PAGE_LIMIT_EXCEEDED\",\n `Stopped after ${pageLimit} pages. Increase --page-limit if needed.`\n );\n }\n\n const response = await this.fetchImpl(nextUrl, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${this.token}`,\n Accept: \"application/json+canvas-string-ids\"\n }\n }).catch((error: unknown) => {\n throw new CanvasCliError(\"CANVAS_NETWORK_ERROR\", \"Could not reach Canvas.\", {\n retryable: true,\n cause: error\n });\n });\n\n if (!response.ok) {\n throw new CanvasCliError(\n mapStatusCode(response.status),\n `Canvas request failed with status ${response.status}.`,\n { status: response.status, retryable: response.status === 429 || response.status >= 500 }\n );\n }\n\n const data = (await response.json()) as unknown;\n pages.push(data);\n\n const links = parseLinkHeader(response.headers.get(\"link\"));\n hasNext = Boolean(links.next);\n nextUrl = options.pageAll ? links.next ?? null : null;\n }\n\n const merged = mergePages(pages) as T;\n return {\n data: redactSecrets(merged) as T,\n meta: {\n request: {\n method: \"GET\",\n path\n },\n pagination: {\n pagesFetched,\n hasNext\n }\n }\n };\n }\n\n async download(url: string): Promise<CanvasDownload> {\n const response = await this.fetchImpl(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${this.token}`,\n Accept: \"*/*\"\n }\n }).catch((error: unknown) => {\n throw new CanvasCliError(\"CANVAS_NETWORK_ERROR\", \"Could not reach Canvas.\", {\n retryable: true,\n cause: error\n });\n });\n\n if (!response.ok) {\n throw new CanvasCliError(\n mapStatusCode(response.status),\n `Canvas download failed with status ${response.status}.`,\n { status: response.status, retryable: response.status === 429 || response.status >= 500 }\n );\n }\n\n return {\n data: new Uint8Array(await response.arrayBuffer()),\n contentType: response.headers.get(\"content-type\") ?? undefined,\n filename: filenameFromContentDisposition(response.headers.get(\"content-disposition\")),\n meta: {\n request: {\n method: \"GET\",\n url: redactSecrets(url) as string\n }\n }\n };\n }\n}\n\nexport function normalizeBaseUrl(input: string): string {\n const trimmed = input.trim().replace(/\\/+$/, \"\");\n const url = new URL(trimmed);\n\n if (url.protocol !== \"https:\") {\n throw new CanvasCliError(\"INVALID_BASE_URL\", \"Canvas base URL must use https://.\");\n }\n\n if (url.pathname.includes(\"/api/\")) {\n throw new CanvasCliError(\"INVALID_BASE_URL\", \"Canvas base URL should not include /api/.\");\n }\n\n url.pathname = url.pathname.replace(/\\/+$/, \"\");\n url.search = \"\";\n url.hash = \"\";\n return url.toString().replace(/\\/+$/, \"\");\n}\n\nfunction buildUrl(\n baseUrl: string,\n path: string,\n query: RequestOptions[\"query\"] = {}\n): string {\n const url = new URL(path, baseUrl);\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, String(item));\n }\n continue;\n }\n url.searchParams.set(key, String(value));\n }\n return url.toString();\n}\n\nfunction mergePages(pages: unknown[]): unknown {\n if (pages.length === 1) {\n return pages[0];\n }\n\n if (pages.every(Array.isArray)) {\n return pages.flat();\n }\n\n return pages;\n}\n\nfunction mapStatusCode(status: number): string {\n if (status === 401) return \"CANVAS_UNAUTHORIZED\";\n if (status === 403) return \"CANVAS_FORBIDDEN\";\n if (status === 404) return \"CANVAS_NOT_FOUND\";\n if (status === 429) return \"CANVAS_RATE_LIMITED\";\n if (status >= 500) return \"CANVAS_SERVER_ERROR\";\n return \"CANVAS_REQUEST_FAILED\";\n}\n\nfunction filenameFromContentDisposition(header: string | null): string | undefined {\n if (!header) {\n return undefined;\n }\n const utf8Match = /filename\\*=UTF-8''([^;]+)/i.exec(header);\n if (utf8Match?.[1]) {\n return decodeURIComponent(utf8Match[1]);\n }\n const match = /filename=\"?([^\";]+)\"?/i.exec(header);\n return match?.[1];\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { CanvasCliError } from \"./errors.js\";\nimport { configPath } from \"./paths.js\";\nimport { redactSecrets } from \"./redaction.js\";\n\nexport type CanvasProfile = {\n schoolName: string;\n baseUrl: string;\n token: string;\n createdAt: string;\n validatedAt?: string;\n user?: {\n id?: string;\n name?: string;\n };\n};\n\nexport type CanvasConfig = {\n version: 1;\n activeProfile: string;\n profiles: Record<string, CanvasProfile>;\n};\n\nexport class ConfigStore {\n constructor(private readonly filePath = configPath()) {}\n\n async read(): Promise<CanvasConfig | null> {\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n return JSON.parse(raw) as CanvasConfig;\n } catch (error) {\n if (isNotFound(error)) {\n return null;\n }\n throw error;\n }\n }\n\n async write(config: CanvasConfig): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true, mode: 0o700 });\n await writeFile(this.filePath, `${JSON.stringify(config, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: 0o600\n });\n }\n\n async remove(): Promise<void> {\n await rm(this.filePath, { force: true });\n }\n\n async readRedacted(): Promise<CanvasConfig | null> {\n const config = await this.read();\n return config ? (redactSecrets(config) as CanvasConfig) : null;\n }\n\n async activeProfile(): Promise<CanvasProfile> {\n const config = await this.read();\n if (!config) {\n throw new CanvasCliError(\"NO_AUTH_CONFIG\", \"No Canvas auth config found. Run canvas auth login.\");\n }\n\n const profile = config.profiles[config.activeProfile];\n if (!profile) {\n throw new CanvasCliError(\n \"NO_ACTIVE_PROFILE\",\n `Active Canvas profile not found: ${config.activeProfile}`\n );\n }\n\n return profile;\n }\n}\n\nfunction isNotFound(error: unknown): boolean {\n return Boolean(error && typeof error === \"object\" && \"code\" in error && error.code === \"ENOENT\");\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\n\nexport function canvasHome(): string {\n return process.env.CANVAS_HOME || path.join(os.homedir(), \".canvas\");\n}\n\nexport function configPath(): string {\n return path.join(canvasHome(), \"config.json\");\n}\n\nexport function contextPath(): string {\n return path.join(canvasHome(), \"context.json\");\n}\n\nexport function resolveInside(baseDir: string, targetPath: string): string {\n const resolvedBase = path.resolve(baseDir);\n const resolvedTarget = path.resolve(resolvedBase, targetPath);\n const relative = path.relative(resolvedBase, resolvedTarget);\n\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Path escapes target directory: ${targetPath}`);\n }\n\n return resolvedTarget;\n}\n","import { spawn } from \"node:child_process\";\n\nexport async function openBrowser(url: string): Promise<void> {\n const command = openCommand(url);\n const child = spawn(command.command, command.args, {\n detached: true,\n stdio: \"ignore\"\n });\n child.unref();\n}\n\nfunction openCommand(url: string): { command: string; args: string[] } {\n if (process.platform === \"darwin\") {\n return { command: \"open\", args: [url] };\n }\n if (process.platform === \"win32\") {\n return { command: \"cmd\", args: [\"/c\", \"start\", \"\", url] };\n }\n return { command: \"xdg-open\", args: [url] };\n}\n","import { createInterface } from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\n\nexport type PromptIO = {\n question(prompt: string): Promise<string>;\n close(): void;\n};\n\nexport function createPrompt(): PromptIO {\n return createInterface({ input, output });\n}\n\nexport async function promptHidden(prompt: string): Promise<string> {\n if (!process.stdin.isTTY) {\n const io = createPrompt();\n try {\n return (await io.question(prompt)).trim();\n } finally {\n io.close();\n }\n }\n\n return new Promise((resolve, reject) => {\n const stdin = process.stdin;\n const onData = (char: Buffer) => {\n const value = char.toString(\"utf8\");\n if (value === \"\\n\" || value === \"\\r\" || value === \"\\r\\n\") {\n stdin.setRawMode(false);\n stdin.pause();\n stdin.off(\"data\", onData);\n process.stdout.write(\"\\n\");\n resolve(buffer.trim());\n return;\n }\n if (value === \"\\u0003\") {\n stdin.setRawMode(false);\n stdin.pause();\n stdin.off(\"data\", onData);\n process.stdout.write(\"\\n\");\n reject(new Error(\"Prompt cancelled.\"));\n return;\n }\n if (value === \"\\u007f\") {\n buffer = buffer.slice(0, -1);\n return;\n }\n buffer += value;\n };\n\n let buffer = \"\";\n process.stdout.write(prompt);\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on(\"data\", onData);\n });\n}\n","import { normalizeBaseUrl } from \"../core/canvas-client.js\";\n\nexport type School = {\n name: string;\n url: string;\n};\n\nexport const SCHOOLS: School[] = [\n { name: \"Brown University\", url: \"https://canvas.brown.edu\" },\n { name: \"Carnegie Mellon University\", url: \"https://canvas.cmu.edu\" },\n { name: \"Columbia University (CourseWorks)\", url: \"https://courseworks2.columbia.edu\" },\n { name: \"Cornell University\", url: \"https://canvas.cornell.edu\" },\n { name: \"Dartmouth College\", url: \"https://canvas.dartmouth.edu\" },\n { name: \"Duke University\", url: \"https://go.canvas.duke.edu\" },\n { name: \"Emory University\", url: \"https://canvas.emory.edu\" },\n { name: \"Georgetown University\", url: \"https://canvas.georgetown.edu\" },\n { name: \"Georgia Institute of Technology\", url: \"https://canvas.gatech.edu\" },\n { name: \"Harvard University\", url: \"https://canvas.harvard.edu\" },\n { name: \"Massachusetts Institute of Technology (MIT)\", url: \"https://canvas.mit.edu\" },\n { name: \"Northeastern University\", url: \"https://canvas.northeastern.edu\" },\n { name: \"Northwestern University\", url: \"https://canvas.northwestern.edu\" },\n { name: \"Ohio State University\", url: \"https://canvas.osu.edu\" },\n { name: \"Pennsylvania State University\", url: \"https://canvas.psu.edu\" },\n { name: \"Princeton University\", url: \"https://canvas.princeton.edu\" },\n { name: \"Rice University\", url: \"https://canvas.rice.edu\" },\n { name: \"Stanford University\", url: \"https://canvas.stanford.edu\" },\n { name: \"Tufts University\", url: \"https://canvas.tufts.edu\" },\n { name: \"University of California, Berkeley (bCourses)\", url: \"https://bcourses.berkeley.edu\" },\n { name: \"University of California, Davis\", url: \"https://canvas.ucdavis.edu\" },\n { name: \"University of California, Irvine\", url: \"https://canvas.eee.uci.edu\" },\n { name: \"University of California, Los Angeles (Bruin Learn)\", url: \"https://bruinlearn.ucla.edu\" },\n { name: \"University of California, San Diego\", url: \"https://canvas.ucsd.edu\" },\n { name: \"University of California, Santa Barbara\", url: \"https://canvas.ucsb.edu\" },\n { name: \"University of California, Santa Cruz\", url: \"https://canvas.ucsc.edu\" },\n { name: \"University of Chicago\", url: \"https://canvas.uchicago.edu\" },\n { name: \"University of Michigan\", url: \"https://canvas.umich.edu\" },\n { name: \"University of North Carolina at Chapel Hill\", url: \"https://canvas.unc.edu\" },\n { name: \"University of Notre Dame\", url: \"https://canvas.nd.edu\" },\n { name: \"University of Pennsylvania\", url: \"https://canvas.upenn.edu\" },\n { name: \"University of Southern California\", url: \"https://canvas.usc.edu\" },\n { name: \"University of Virginia\", url: \"https://canvas.its.virginia.edu\" },\n { name: \"University of Washington\", url: \"https://canvas.uw.edu\" },\n { name: \"Yale University\", url: \"https://canvas.yale.edu\" }\n];\n\nexport function searchSchools(query: string, limit = 10): School[] {\n const normalized = query.trim().toLowerCase();\n if (!normalized) {\n return SCHOOLS.slice(0, limit);\n }\n\n return SCHOOLS.filter((school) => {\n return school.name.toLowerCase().includes(normalized) || school.url.toLowerCase().includes(normalized);\n }).slice(0, limit);\n}\n\nexport function makeCustomSchool(name: string, url: string): School {\n return {\n name: name.trim() || \"Custom Canvas School\",\n url: normalizeBaseUrl(url)\n };\n}\n","export type BootstrapSummary = {\n skipped: true;\n reason: string;\n};\n\nexport async function runPostLoginBootstrap(): Promise<BootstrapSummary> {\n return {\n skipped: true,\n reason: \"Context bootstrap is planned for Phase 4.\"\n };\n}\n","import { CanvasClient } from \"../core/canvas-client.js\";\nimport { ConfigStore, type CanvasProfile } from \"../core/config-store.js\";\n\nexport type ActiveCanvas = {\n profile: CanvasProfile;\n client: CanvasClient;\n};\n\nexport async function activeCanvas(): Promise<ActiveCanvas> {\n const profile = await new ConfigStore().activeProfile();\n return {\n profile,\n client: new CanvasClient({\n baseUrl: profile.baseUrl,\n token: profile.token\n })\n };\n}\n\nexport function flagValue(argv: string[], flag: string): string | undefined {\n const index = argv.indexOf(flag);\n if (index === -1) {\n return undefined;\n }\n return argv[index + 1];\n}\n\nexport function requiredFlag(argv: string[], flag: string, usage: string): string {\n const value = flagValue(argv, flag);\n if (!value) {\n throw new Error(usage);\n }\n return value;\n}\n\nexport function hasFlag(argv: string[], flag: string): boolean {\n return argv.includes(flag);\n}\n\nexport function csvFlag(argv: string[], flag: string): string[] | undefined {\n const raw = flagValue(argv, flag);\n if (!raw) {\n return undefined;\n }\n const values = raw\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean);\n return values.length > 0 ? values : undefined;\n}\n\nexport function pageOptions(argv: string[]): { pageAll: boolean; pageLimit?: number } {\n const pageLimitRaw = flagValue(argv, \"--page-limit\");\n return {\n pageAll: hasFlag(argv, \"--page-all\"),\n pageLimit: pageLimitRaw ? Number.parseInt(pageLimitRaw, 10) : undefined\n };\n}\n\nexport function positionalArgs(argv: string[]): string[] {\n const valueFlags = new Set([\n \"--course-id\",\n \"--module-id\",\n \"--item-id\",\n \"--assignment-id\",\n \"--quiz-id\",\n \"--topic-id\",\n \"--page\",\n \"--path\",\n \"--out\",\n \"--format\",\n \"--page-limit\",\n \"--page-size\",\n \"--page-delay\",\n \"--enrollment-state\",\n \"--state\",\n \"--include\",\n \"--params\",\n \"--bucket\",\n \"--search\",\n \"--order-by\",\n \"--sort\",\n \"--file-id\",\n \"--folder-id\",\n \"--group-id\",\n \"--content-type\",\n \"--school\",\n \"--school-query\",\n \"--school-url\",\n \"--url\",\n \"--school-name\",\n \"--name\",\n \"--token\",\n \"--token-env\"\n ]);\n const values: string[] = [];\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg.startsWith(\"--\")) {\n if (valueFlags.has(arg)) {\n index += 1;\n }\n continue;\n }\n values.push(arg);\n }\n return values;\n}\n","import { CanvasClient, normalizeBaseUrl } from \"../core/canvas-client.js\";\nimport { ConfigStore, type CanvasConfig } from \"../core/config-store.js\";\nimport { CanvasCliError, toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { openBrowser } from \"../core/browser.js\";\nimport { createPrompt, promptHidden, type PromptIO } from \"../core/prompt.js\";\nimport { makeCustomSchool, searchSchools, type School } from \"../registry/schools.js\";\nimport { runPostLoginBootstrap } from \"../workflows/context-bootstrap.js\";\nimport { flagValue, positionalArgs } from \"./shared.js\";\n\nconst TOKEN_PURPOSE = \"Hyperknow\";\n\nexport async function handleAuthCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n if (subcommand === \"login\") {\n return authLogin(argv.slice(1), options);\n }\n\n if (subcommand === \"status\") {\n return authStatus(options);\n }\n\n if (subcommand === \"schools\") {\n return authSchools(argv.slice(1), options);\n }\n\n if (subcommand === \"logout\") {\n return authLogout(options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown auth command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n}\n\nasync function authLogin(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const io = createPrompt();\n\n try {\n const nonInteractive = hasNonInteractiveLoginArgs(argv);\n const school = nonInteractive ? resolveSchoolFromArgs(argv) : await chooseSchool(io);\n const settingsUrl = `${school.url}/profile/settings`;\n\n const providedToken = await tokenFromArgs(argv);\n let token = providedToken;\n\n if (!token) {\n process.stdout.write(tokenInstructions(school, settingsUrl));\n await io.question(\"Press Enter to open Canvas settings in your browser...\");\n await openBrowser(settingsUrl);\n process.stdout.write(\"\\nWaiting for your Canvas personal access token.\\n\");\n token = await promptHidden(\"Paste token: \");\n }\n\n if (!token) {\n throw new CanvasCliError(\"EMPTY_TOKEN\", \"No token entered.\");\n }\n\n const client = new CanvasClient({ baseUrl: school.url, token });\n const user = await validateToken(client);\n const now = new Date().toISOString();\n const config: CanvasConfig = {\n version: 1,\n activeProfile: \"default\",\n profiles: {\n default: {\n schoolName: school.name,\n baseUrl: school.url,\n token,\n createdAt: now,\n validatedAt: now,\n user\n }\n }\n };\n\n await new ConfigStore().write(config);\n const bootstrap = await runPostLoginBootstrap();\n\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: true,\n school: {\n name: school.name,\n baseUrl: school.url\n },\n user,\n contextBootstrap: bootstrap,\n next: \"canvas courses list --active --page-all\"\n },\n meta: {\n command: \"auth login\"\n }\n },\n options\n );\n return 0;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n } finally {\n io.close();\n }\n}\n\nasync function authSchools(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const [subcommand] = argv;\n const query =\n subcommand === \"search\"\n ? positionalArgs(argv.slice(1)).join(\" \")\n : flagValue(argv, \"--query\") ?? positionalArgs(argv).join(\" \");\n\n await writeOutput(\n {\n ok: true,\n data: searchSchools(query).map((school) => ({\n name: school.name,\n baseUrl: school.url\n })),\n meta: {\n command: \"auth schools\",\n query\n }\n },\n options\n );\n return 0;\n}\n\nasync function authStatus(options: { format: OutputFormat }): Promise<number> {\n const store = new ConfigStore();\n const config = await store.readRedacted();\n\n if (!config) {\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: false,\n message: \"No Canvas auth config found. Run canvas auth login.\"\n },\n meta: {\n command: \"auth status\"\n }\n },\n options\n );\n return 0;\n }\n\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: true,\n activeProfile: config.activeProfile,\n profile: config.profiles[config.activeProfile]\n },\n meta: {\n command: \"auth status\"\n }\n },\n options\n );\n return 0;\n}\n\nasync function authLogout(options: { format: OutputFormat }): Promise<number> {\n await new ConfigStore().remove();\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: false,\n message: \"Canvas auth config removed.\"\n },\n meta: {\n command: \"auth logout\"\n }\n },\n options\n );\n return 0;\n}\n\nexport async function chooseSchool(\n io: PromptIO,\n write: (message: string) => void = (message) => process.stdout.write(message)\n): Promise<School> {\n write(\"Search for your school, or press Enter to browse the first matches.\\n\");\n const query = await io.question(\"School: \");\n const matches = searchSchools(query);\n\n if (matches.length === 1) {\n const school = matches[0];\n const answer = (\n await io.question(`Is this your school: ${school.name} (${school.url})? Choose: y/n `)\n )\n .trim()\n .toLowerCase();\n\n if (answer === \"y\" || answer === \"yes\") {\n return {\n name: school.name,\n url: normalizeBaseUrl(school.url)\n };\n }\n\n if (answer === \"n\" || answer === \"no\") {\n return promptCustomSchool(io);\n }\n\n throw new CanvasCliError(\"INVALID_SELECTION\", \"Please answer y or n.\");\n }\n\n for (const [index, school] of matches.entries()) {\n write(`${index + 1}. ${school.name}\\n ${school.url}\\n`);\n }\n write(`${matches.length + 1}. Not found? Add your own\\n`);\n\n const selected = Number.parseInt(await io.question(\"Choose: \"), 10);\n if (!Number.isFinite(selected) || selected < 1 || selected > matches.length + 1) {\n throw new CanvasCliError(\"INVALID_SELECTION\", \"Invalid school selection.\");\n }\n\n if (selected === matches.length + 1) {\n return promptCustomSchool(io);\n }\n\n const school = matches[selected - 1];\n return {\n name: school.name,\n url: normalizeBaseUrl(school.url)\n };\n}\n\nexport function resolveSchoolFromArgs(argv: string[]): School {\n const schoolUrl = flagValue(argv, \"--school-url\") ?? flagValue(argv, \"--url\");\n if (schoolUrl) {\n return makeCustomSchool(flagValue(argv, \"--school-name\") ?? flagValue(argv, \"--name\") ?? \"Custom Canvas School\", schoolUrl);\n }\n\n const schoolQuery = flagValue(argv, \"--school\") ?? flagValue(argv, \"--school-query\");\n if (!schoolQuery) {\n throw new CanvasCliError(\n \"MISSING_SCHOOL\",\n \"Non-interactive auth requires --school <query> or --school-url <url>.\"\n );\n }\n\n const matches = searchSchools(schoolQuery, 20);\n if (matches.length === 0) {\n throw new CanvasCliError(\n \"SCHOOL_NOT_FOUND\",\n `No Canvas school matched \"${schoolQuery}\". Use --school-url <url> for a custom Canvas URL.`\n );\n }\n\n const exact = matches.find((school) => {\n return school.name.toLowerCase() === schoolQuery.toLowerCase() || school.url.toLowerCase() === schoolQuery.toLowerCase();\n });\n\n if (exact) {\n return {\n name: exact.name,\n url: normalizeBaseUrl(exact.url)\n };\n }\n\n if (matches.length === 1) {\n const school = matches[0];\n return {\n name: school.name,\n url: normalizeBaseUrl(school.url)\n };\n }\n\n throw new CanvasCliError(\n \"AMBIGUOUS_SCHOOL\",\n `Multiple schools matched \"${schoolQuery}\": ${matches\n .map((school) => `${school.name} (${school.url})`)\n .join(\"; \")}. Use a more specific --school value or --school-url.`\n );\n}\n\nexport async function tokenFromArgs(argv: string[]): Promise<string | undefined> {\n const directToken = flagValue(argv, \"--token\");\n if (directToken) {\n return directToken.trim();\n }\n\n const envName = flagValue(argv, \"--token-env\");\n if (envName) {\n return process.env[envName]?.trim();\n }\n\n if (argv.includes(\"--token-stdin\")) {\n return readStdin().then((value) => value.trim());\n }\n\n return undefined;\n}\n\nasync function promptCustomSchool(io: PromptIO): Promise<School> {\n const name = await io.question(\"School display name: \");\n const url = await io.question(\"Canvas base URL: \");\n return makeCustomSchool(name, url);\n}\n\nfunction hasNonInteractiveLoginArgs(argv: string[]): boolean {\n return Boolean(\n flagValue(argv, \"--school\") ||\n flagValue(argv, \"--school-query\") ||\n flagValue(argv, \"--school-url\") ||\n flagValue(argv, \"--url\")\n );\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nfunction tokenInstructions(school: School, settingsUrl: string): string {\n return `\nCanvas token setup for ${school.name}\n\n1. Go to ${settingsUrl}\n2. Click \"+ New Access Token\"\n3. Enter \"${TOKEN_PURPOSE}\" as the purpose\n4. Optionally set an expiration date\n5. Click \"Generate Token\"\n6. Copy the token and paste it back here\n\n`;\n}\n\nasync function validateToken(client: CanvasClient): Promise<{ id?: string; name?: string }> {\n try {\n const response = await client.get<{ id?: string; name?: string; short_name?: string }>(\n \"/api/v1/users/self/profile\"\n );\n return {\n id: response.data.id,\n name: response.data.name ?? response.data.short_name\n };\n } catch (error) {\n if (error instanceof CanvasCliError && error.status === 404) {\n await client.get(\"/api/v1/courses\");\n return {};\n }\n throw error;\n }\n}\n","import { CanvasCliError, toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue, pageOptions, positionalArgs } from \"./shared.js\";\n\ntype QueryValue = string | number | boolean | Array<string | number | boolean> | undefined;\n\nexport async function handleApiCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"get\") {\n return await apiGet(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown api command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function apiGet(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const path = positionalArgs(argv)[0];\n if (!path) {\n throw new Error(\"Usage: canvas api get /api/v1/<path> [--params '<json>'] [--page-all]\");\n }\n if (!path.startsWith(\"/api/v1/\")) {\n throw new CanvasCliError(\"INVALID_API_PATH\", \"Raw API paths must start with /api/v1/.\");\n }\n\n const params = parseParams(flagValue(argv, \"--params\"));\n const { client, profile } = await activeCanvas();\n const response = await client.get(path, {\n query: params,\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data,\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function parseParams(raw: string | undefined): Record<string, QueryValue> {\n if (!raw) {\n return {};\n }\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new CanvasCliError(\"INVALID_PARAMS\", \"--params must be a JSON object.\");\n }\n\n const params: Record<string, QueryValue> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (value === null) {\n continue;\n }\n if (isQueryValue(value)) {\n params[key] = value;\n continue;\n }\n throw new CanvasCliError(\n \"INVALID_PARAMS\",\n `Unsupported query value for ${key}. Use string, number, boolean, or arrays of those.`\n );\n }\n return params;\n}\n\nfunction isQueryValue(value: unknown): value is QueryValue {\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(\n (item) => typeof item === \"string\" || typeof item === \"number\" || typeof item === \"boolean\"\n );\n }\n return value === undefined;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport {\n activeCanvas,\n csvFlag,\n flagValue,\n pageOptions,\n positionalArgs,\n requiredFlag\n} from \"./shared.js\";\n\nexport type CanvasAssignment = {\n id: string | number;\n name?: string;\n description?: string | null;\n due_at?: string | null;\n unlock_at?: string | null;\n lock_at?: string | null;\n points_possible?: number | null;\n grading_type?: string;\n submission_types?: string[];\n allowed_extensions?: string[];\n html_url?: string;\n assignment_group_id?: string | number;\n position?: number;\n published?: boolean;\n muted?: boolean;\n has_submitted_submissions?: boolean;\n locked_for_user?: boolean;\n lock_explanation?: string;\n needs_grading_count?: number;\n all_dates?: unknown[];\n external_tool_tag_attributes?: unknown;\n rubric?: unknown[];\n attachments?: CanvasAttachment[];\n};\n\nexport type CanvasAttachment = {\n id: string | number;\n display_name?: string;\n filename?: string;\n content_type?: string;\n url?: string;\n size?: number;\n};\n\nexport async function handleAssignmentsCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listAssignments(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showAssignment(argv.slice(1), options);\n }\n if (subcommand === \"export\") {\n return await exportAssignment(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown assignments command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listAssignments(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas assignments list --course-id <course-id>\"\n );\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasAssignment[]>(\n `/api/v1/courses/${courseId}/assignments`,\n {\n query: assignmentListQuery(argv),\n ...pageOptions(argv)\n }\n );\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeAssignment),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showAssignment(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas assignments show --course-id <course-id> --assignment-id <assignment-id>\"\n );\n const assignmentId =\n flagValue(argv, \"--assignment-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas assignments show --course-id <course-id> --assignment-id <assignment-id>\");\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasAssignment>(\n `/api/v1/courses/${courseId}/assignments/${assignmentId}`,\n { query: assignmentShowQuery(argv) }\n );\n\n await writeOutput(\n {\n ok: true,\n data: normalizeAssignment(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function exportAssignment(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas assignments export --course-id <course-id> --assignment-id <assignment-id> --out <dir>\"\n );\n const assignmentId =\n flagValue(argv, \"--assignment-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas assignments export --course-id <course-id> --assignment-id <assignment-id> --out <dir>\");\n const outDir = requiredFlag(\n argv,\n \"--out\",\n \"Usage: canvas assignments export --course-id <course-id> --assignment-id <assignment-id> --out <dir>\"\n );\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasAssignment>(\n `/api/v1/courses/${courseId}/assignments/${assignmentId}`,\n { query: { \"include[]\": [\"all_dates\", \"description\", \"submission\"] } }\n );\n const assignment = normalizeAssignment(response.data);\n\n await mkdir(outDir, { recursive: true });\n const jsonPath = join(outDir, `assignment-${assignment.id}.json`);\n const markdownPath = join(outDir, `assignment-${assignment.id}.md`);\n await writeFile(jsonPath, `${JSON.stringify(assignment, null, 2)}\\n`, \"utf8\");\n await writeFile(markdownPath, assignmentMarkdown(assignment), \"utf8\");\n\n await writeOutput(\n {\n ok: true,\n data: {\n assignment,\n written: [\n { path: jsonPath, kind: \"assignment-json\" },\n { path: markdownPath, kind: \"assignment-markdown\" }\n ]\n },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function assignmentListQuery(argv: string[]) {\n return {\n bucket: flagValue(argv, \"--bucket\"),\n search_term: flagValue(argv, \"--search\"),\n order_by: flagValue(argv, \"--order-by\"),\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function assignmentShowQuery(argv: string[]) {\n return {\n \"include[]\": csvFlag(argv, \"--include\") ?? [\"all_dates\", \"description\"]\n };\n}\n\nexport function normalizeAssignment(assignment: CanvasAssignment) {\n return {\n id: String(assignment.id),\n name: assignment.name,\n description: assignment.description,\n dueAt: assignment.due_at,\n unlockAt: assignment.unlock_at,\n lockAt: assignment.lock_at,\n pointsPossible: assignment.points_possible,\n gradingType: assignment.grading_type,\n submissionTypes: assignment.submission_types,\n allowedExtensions: assignment.allowed_extensions,\n htmlUrl: assignment.html_url,\n assignmentGroupId:\n assignment.assignment_group_id === undefined ? undefined : String(assignment.assignment_group_id),\n position: assignment.position,\n published: assignment.published,\n muted: assignment.muted,\n hasSubmittedSubmissions: assignment.has_submitted_submissions,\n lockedForUser: assignment.locked_for_user,\n lockExplanation: assignment.lock_explanation,\n needsGradingCount: assignment.needs_grading_count,\n allDates: assignment.all_dates,\n externalToolTagAttributes: assignment.external_tool_tag_attributes,\n rubric: assignment.rubric,\n attachments: assignment.attachments?.map(normalizeAttachment)\n };\n}\n\nexport function normalizeAttachment(attachment: CanvasAttachment) {\n return {\n id: String(attachment.id),\n displayName: attachment.display_name,\n filename: attachment.filename,\n contentType: attachment.content_type,\n url: attachment.url,\n size: attachment.size\n };\n}\n\nfunction assignmentMarkdown(assignment: ReturnType<typeof normalizeAssignment>): string {\n const lines = [\n `# ${assignment.name ?? `Assignment ${assignment.id}`}`,\n \"\",\n `- id: ${assignment.id}`,\n `- due: ${assignment.dueAt ?? \"none\"}`,\n `- points: ${assignment.pointsPossible ?? \"none\"}`,\n `- html: ${assignment.htmlUrl ?? \"none\"}`,\n \"\",\n \"## Description\",\n \"\",\n assignment.description ?? \"\"\n ];\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { ConfigStore } from \"../core/config-store.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\n\nexport async function handleConfigCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n if (subcommand !== \"show\") {\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown config command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n }\n\n const config = await new ConfigStore().readRedacted();\n await writeOutput(\n {\n ok: true,\n data: config ?? {\n configured: false,\n message: \"No Canvas config found. Run canvas auth login.\"\n },\n meta: {\n command: \"config show\"\n }\n },\n options\n );\n return 0;\n}\n","import { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue, hasFlag, pageOptions, positionalArgs } from \"./shared.js\";\n\nexport type CanvasCourse = {\n id: string;\n name?: string;\n course_code?: string;\n workflow_state?: string;\n enrollment_term_id?: string;\n term?: {\n id?: string;\n name?: string;\n start_at?: string;\n end_at?: string;\n };\n enrollments?: Array<{\n type?: string;\n role?: string;\n enrollment_state?: string;\n }>;\n};\n\nexport async function handleCoursesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listCourses(argv.slice(1), options);\n }\n if (subcommand === \"search\") {\n return await searchCourses(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showCourse(argv.slice(1), options);\n }\n if (subcommand === \"overview\") {\n return await overviewCourse(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown courses command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listCourses(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasCourse[]>(\"/api/v1/courses\", {\n query: courseListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeCourse),\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n}\n\nasync function searchCourses(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const query = positionalArgs(argv).join(\" \").trim();\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasCourse[]>(\"/api/v1/courses\", {\n query: courseListQuery([\"--active\"]),\n pageAll: true\n });\n\n const matches = response.data\n .map(normalizeCourse)\n .filter((course) => {\n const haystack = `${course.name ?? \"\"} ${course.courseCode ?? \"\"}`.toLowerCase();\n return haystack.includes(query.toLowerCase());\n });\n\n await writeOutput(\n {\n ok: true,\n data: matches,\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl,\n query\n }\n },\n options\n );\n return 0;\n}\n\nasync function showCourse(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = positionalArgs(argv)[0];\n if (!courseId) {\n throw new Error(\"Usage: canvas courses show <course-id>\");\n }\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasCourse>(`/api/v1/courses/${courseId}`, {\n query: {\n \"include[]\": [\"term\", \"course_image\", \"total_scores\", \"teachers\"]\n }\n });\n\n await writeOutput(\n {\n ok: true,\n data: normalizeCourse(response.data),\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n}\n\nasync function overviewCourse(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = positionalArgs(argv)[0];\n if (!courseId) {\n throw new Error(\"Usage: canvas courses overview <course-id>\");\n }\n\n const { client, profile } = await activeCanvas();\n const [course, tabs, modules, assignments] = await Promise.all([\n client.get<CanvasCourse>(`/api/v1/courses/${courseId}`, {\n query: { \"include[]\": [\"term\", \"course_image\"] }\n }),\n client.get<Array<{ id: string; label?: string; visibility?: string }>>(\n `/api/v1/courses/${courseId}/tabs`\n ),\n client.get<Array<{ id: string; name?: string; position?: number }>>(\n `/api/v1/courses/${courseId}/modules`,\n { query: { per_page: 100 } }\n ),\n client.get<Array<{ id: string; name?: string; due_at?: string }>>(\n `/api/v1/courses/${courseId}/assignments`,\n { query: { bucket: \"upcoming\", per_page: 20 } }\n )\n ]);\n\n await writeOutput(\n {\n ok: true,\n data: {\n course: normalizeCourse(course.data),\n tabs: tabs.data,\n setup: {\n hasModules: modules.data.length > 0,\n hasAssignments: assignments.data.length > 0,\n hasFilesTab: tabs.data.some((tab) => tab.id === \"files\"),\n isModuleHeavy: modules.data.length > 0\n },\n counts: {\n tabs: tabs.data.length,\n modules: modules.data.length,\n upcomingAssignments: assignments.data.length\n },\n modules: modules.data.map((module) => ({\n id: module.id,\n name: module.name,\n position: module.position\n })),\n upcomingAssignments: assignments.data.map((assignment) => ({\n id: assignment.id,\n name: assignment.name,\n dueAt: assignment.due_at\n }))\n },\n meta: {\n baseUrl: profile.baseUrl,\n request: {\n method: \"GET\",\n path: `/api/v1/courses/${courseId}/overview`\n }\n }\n },\n options\n );\n return 0;\n}\n\nexport function courseListQuery(argv: string[]) {\n return {\n enrollment_state: hasFlag(argv, \"--active\") ? \"active\" : flagValue(argv, \"--enrollment-state\"),\n state: flagValue(argv, \"--state\"),\n per_page: flagValue(argv, \"--page-size\"),\n \"include[]\": [\"term\", \"total_scores\"]\n };\n}\n\nexport function normalizeCourse(course: CanvasCourse) {\n return {\n id: String(course.id),\n name: course.name,\n courseCode: course.course_code,\n workflowState: course.workflow_state,\n enrollmentTermId: course.enrollment_term_id,\n term: course.term\n ? {\n id: course.term.id,\n name: course.term.name,\n startAt: course.term.start_at,\n endAt: course.term.end_at\n }\n : undefined,\n enrollments: course.enrollments?.map((enrollment) => ({\n type: enrollment.type,\n role: enrollment.role,\n state: enrollment.enrollment_state\n }))\n };\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { basename, join, resolve } from \"node:path\";\nimport { CanvasCliError, toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport {\n activeCanvas,\n csvFlag,\n flagValue,\n pageOptions,\n positionalArgs,\n requiredFlag\n} from \"./shared.js\";\n\nexport type CanvasFile = {\n id: string | number;\n uuid?: string;\n folder_id?: string | number;\n display_name?: string;\n filename?: string;\n content_type?: string;\n url?: string;\n size?: number;\n created_at?: string;\n updated_at?: string;\n modified_at?: string;\n unlock_at?: string | null;\n locked?: boolean;\n hidden?: boolean;\n locked_for_user?: boolean;\n lock_explanation?: string;\n thumbnail_url?: string;\n preview_url?: string;\n mime_class?: string;\n};\n\nexport type CanvasFolder = {\n id: string | number;\n name?: string;\n full_name?: string;\n context_id?: string | number;\n context_type?: string;\n parent_folder_id?: string | number | null;\n files_count?: number;\n folders_count?: number;\n position?: number;\n locked?: boolean;\n hidden?: boolean;\n locked_for_user?: boolean;\n for_submissions?: boolean;\n};\n\nexport async function handleFilesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listFiles(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showFile(argv.slice(1), options);\n }\n if (subcommand === \"download\") {\n return await downloadFile(argv.slice(1), options);\n }\n if (subcommand === \"download-linked\") {\n return await downloadLinkedFiles(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown files command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nexport async function handleFoldersCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listFolders(argv.slice(1), options);\n }\n if (subcommand === \"path\") {\n return await folderPath(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown folders command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listFiles(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const path = filesListPath(argv);\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasFile[]>(path, {\n query: filesListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeFile),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showFile(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const fileId =\n flagValue(argv, \"--file-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas files show <file-id>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasFile>(`/api/v1/files/${fileId}`, {\n query: { \"include[]\": csvFlag(argv, \"--include\") }\n });\n\n await writeOutput(\n {\n ok: true,\n data: normalizeFile(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function downloadFile(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const fileId =\n flagValue(argv, \"--file-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas files download <file-id> --out <dir>\");\n const outDir = requiredFlag(argv, \"--out\", \"Usage: canvas files download <file-id> --out <dir>\");\n const { client, profile } = await activeCanvas();\n const fileResponse = await client.get<CanvasFile>(`/api/v1/files/${fileId}`);\n const file = normalizeFile(fileResponse.data);\n if (!file.url) {\n throw new CanvasCliError(\"FILE_URL_UNAVAILABLE\", \"Canvas did not return a download URL for this file.\");\n }\n\n const download = await client.download(file.url);\n const filename = safeFilename(download.filename ?? file.displayName ?? file.filename ?? `file-${file.id}`);\n const filePath = safeJoin(outDir, filename);\n await mkdir(outDir, { recursive: true });\n await writeFile(filePath, download.data);\n\n await writeOutput(\n {\n ok: true,\n data: {\n file,\n written: {\n path: filePath,\n bytes: download.data.byteLength,\n contentType: download.contentType\n }\n },\n meta: { baseUrl: profile.baseUrl, download: download.meta }\n },\n options\n );\n return 0;\n}\n\nasync function downloadLinkedFiles(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas files download-linked --course-id <course-id> --out <dir>\"\n );\n const outDir = requiredFlag(\n argv,\n \"--out\",\n \"Usage: canvas files download-linked --course-id <course-id> --out <dir>\"\n );\n const { client, profile } = await activeCanvas();\n const [moduleItems, assignments] = await Promise.all([\n client.get<Array<{ type?: string; content_id?: string | number; title?: string }>>(\n `/api/v1/courses/${courseId}/modules/items`,\n { query: { per_page: 100 }, pageAll: true }\n ).catch(() => ({ data: [] })),\n client.get<Array<{ attachments?: CanvasFile[] }>>(`/api/v1/courses/${courseId}/assignments`, {\n query: { \"include[]\": [\"description\"], per_page: 100 },\n pageAll: true\n }).catch(() => ({ data: [] }))\n ]);\n\n const ids = new Set<string>();\n for (const item of moduleItems.data) {\n if (item.type === \"File\" && item.content_id !== undefined) {\n ids.add(String(item.content_id));\n }\n }\n for (const assignment of assignments.data) {\n for (const attachment of assignment.attachments ?? []) {\n ids.add(String(attachment.id));\n }\n }\n\n const written: Array<{ id: string; path?: string; error?: string }> = [];\n for (const id of ids) {\n try {\n const fileResponse = await client.get<CanvasFile>(`/api/v1/files/${id}`);\n const file = normalizeFile(fileResponse.data);\n if (!file.url) {\n written.push({ id, error: \"FILE_URL_UNAVAILABLE\" });\n continue;\n }\n const download = await client.download(file.url);\n const filename = safeFilename(download.filename ?? file.displayName ?? file.filename ?? `file-${id}`);\n const filePath = safeJoin(outDir, filename);\n await mkdir(outDir, { recursive: true });\n await writeFile(filePath, download.data);\n written.push({ id, path: filePath });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n written.push({ id, error: message });\n }\n }\n\n await writeOutput(\n {\n ok: true,\n data: { count: ids.size, written },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function listFolders(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas folders list --course-id <course-id>\"\n );\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasFolder[]>(`/api/v1/courses/${courseId}/folders`, {\n query: { per_page: flagValue(argv, \"--page-size\") },\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeFolder),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function folderPath(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas folders path --course-id <course-id> --path <path>\"\n );\n const folderPathValue = requiredFlag(\n argv,\n \"--path\",\n \"Usage: canvas folders path --course-id <course-id> --path <path>\"\n );\n const { client, profile } = await activeCanvas();\n const encodedPath = folderPathValue\n .split(\"/\")\n .filter(Boolean)\n .map(encodeURIComponent)\n .join(\"/\");\n const response = await client.get<CanvasFolder[]>(\n `/api/v1/courses/${courseId}/folders/by_path/${encodedPath}`\n );\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeFolder),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function filesListPath(argv: string[]): string {\n const groupId = flagValue(argv, \"--group-id\");\n if (groupId) {\n return `/api/v1/groups/${groupId}/files`;\n }\n const folderId = flagValue(argv, \"--folder-id\");\n if (folderId) {\n return `/api/v1/folders/${folderId}/files`;\n }\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas files list --course-id <course-id>\");\n return `/api/v1/courses/${courseId}/files`;\n}\n\nexport function filesListQuery(argv: string[]) {\n return {\n search_term: flagValue(argv, \"--search\"),\n sort: flagValue(argv, \"--sort\"),\n \"content_types[]\": csvFlag(argv, \"--content-type\"),\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function normalizeFile(file: CanvasFile) {\n return {\n id: String(file.id),\n uuid: file.uuid,\n folderId: file.folder_id === undefined ? undefined : String(file.folder_id),\n displayName: file.display_name,\n filename: file.filename,\n contentType: file.content_type,\n url: file.url,\n size: file.size,\n createdAt: file.created_at,\n updatedAt: file.updated_at,\n modifiedAt: file.modified_at,\n unlockAt: file.unlock_at,\n locked: file.locked,\n hidden: file.hidden,\n lockedForUser: file.locked_for_user,\n lockExplanation: file.lock_explanation,\n thumbnailUrl: file.thumbnail_url,\n previewUrl: file.preview_url,\n mimeClass: file.mime_class\n };\n}\n\nexport function normalizeFolder(folder: CanvasFolder) {\n return {\n id: String(folder.id),\n name: folder.name,\n fullName: folder.full_name,\n contextId: folder.context_id === undefined ? undefined : String(folder.context_id),\n contextType: folder.context_type,\n parentFolderId: folder.parent_folder_id === undefined ? undefined : String(folder.parent_folder_id),\n filesCount: folder.files_count,\n foldersCount: folder.folders_count,\n position: folder.position,\n locked: folder.locked,\n hidden: folder.hidden,\n lockedForUser: folder.locked_for_user,\n forSubmissions: folder.for_submissions\n };\n}\n\nfunction safeFilename(input: string): string {\n const name = basename(input).replace(/[/:\\\\]/g, \"_\").trim();\n return name || \"canvas-file\";\n}\n\nfunction safeJoin(outDir: string, filename: string): string {\n const base = resolve(outDir);\n const target = resolve(base, filename);\n if (!target.startsWith(`${base}/`) && target !== base) {\n throw new CanvasCliError(\"INVALID_OUTPUT_PATH\", \"Refusing to write outside the output directory.\");\n }\n return target;\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { CanvasClient } from \"../core/canvas-client.js\";\nimport { ConfigStore } from \"../core/config-store.js\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\n\nexport async function handleMeCommand(options: { format: OutputFormat }): Promise<number> {\n try {\n const profile = await new ConfigStore().activeProfile();\n const client = new CanvasClient({\n baseUrl: profile.baseUrl,\n token: profile.token\n });\n const response = await client.get(\"/api/v1/users/self/profile\");\n\n await writeOutput(\n {\n ok: true,\n data: response.data,\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport {\n activeCanvas,\n csvFlag,\n flagValue,\n pageOptions,\n positionalArgs,\n requiredFlag\n} from \"./shared.js\";\n\nexport type CanvasModule = {\n id: string | number;\n name?: string;\n position?: number;\n unlock_at?: string | null;\n require_sequential_progress?: boolean;\n publish_final_grade?: boolean;\n prerequisite_module_ids?: Array<string | number>;\n state?: string;\n completed_at?: string | null;\n items_count?: number;\n items_url?: string;\n items?: CanvasModuleItem[];\n};\n\nexport type CanvasModuleItem = {\n id: string | number;\n module_id?: string | number;\n title?: string;\n type?: string;\n content_id?: string | number;\n position?: number;\n indent?: number;\n page_url?: string;\n external_url?: string;\n html_url?: string;\n url?: string;\n new_tab?: boolean;\n completion_requirement?: unknown;\n content_details?: unknown;\n};\n\nexport async function handleModulesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listModules(argv.slice(1), options);\n }\n if (subcommand === \"items\") {\n return await listModuleItems(argv.slice(1), options);\n }\n if (subcommand === \"item\") {\n return await showModuleItem(argv.slice(1), options);\n }\n if (subcommand === \"export\") {\n return await exportModule(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown modules command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listModules(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas modules list --course-id <course-id>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasModule[]>(`/api/v1/courses/${courseId}/modules`, {\n query: moduleListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeModule),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function listModuleItems(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas modules items --course-id <course-id> --module-id <module-id>\"\n );\n const moduleId = requiredFlag(\n argv,\n \"--module-id\",\n \"Usage: canvas modules items --course-id <course-id> --module-id <module-id>\"\n );\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasModuleItem[]>(\n `/api/v1/courses/${courseId}/modules/${moduleId}/items`,\n {\n query: moduleItemsQuery(argv),\n ...pageOptions(argv)\n }\n );\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeModuleItem),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showModuleItem(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas modules item --course-id <course-id> --module-id <module-id> --item-id <item-id>\"\n );\n const moduleId = requiredFlag(\n argv,\n \"--module-id\",\n \"Usage: canvas modules item --course-id <course-id> --module-id <module-id> --item-id <item-id>\"\n );\n const itemId =\n flagValue(argv, \"--item-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas modules item --course-id <course-id> --module-id <module-id> --item-id <item-id>\");\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasModuleItem>(\n `/api/v1/courses/${courseId}/modules/${moduleId}/items/${itemId}`,\n { query: moduleItemsQuery(argv) }\n );\n\n await writeOutput(\n {\n ok: true,\n data: normalizeModuleItem(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function exportModule(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas modules export --course-id <course-id> --module-id <module-id> --out <dir>\"\n );\n const moduleId = requiredFlag(\n argv,\n \"--module-id\",\n \"Usage: canvas modules export --course-id <course-id> --module-id <module-id> --out <dir>\"\n );\n const outDir = requiredFlag(\n argv,\n \"--out\",\n \"Usage: canvas modules export --course-id <course-id> --module-id <module-id> --out <dir>\"\n );\n\n const { client, profile } = await activeCanvas();\n const [moduleResponse, itemsResponse] = await Promise.all([\n client.get<CanvasModule>(`/api/v1/courses/${courseId}/modules/${moduleId}`),\n client.get<CanvasModuleItem[]>(`/api/v1/courses/${courseId}/modules/${moduleId}/items`, {\n query: { \"include[]\": [\"content_details\"], per_page: 100 },\n pageAll: true\n })\n ]);\n const moduleData = normalizeModule({ ...moduleResponse.data, items: itemsResponse.data });\n\n await mkdir(outDir, { recursive: true });\n const filePath = join(outDir, `module-${moduleData.id}.json`);\n await writeFile(filePath, `${JSON.stringify(moduleData, null, 2)}\\n`, \"utf8\");\n\n await writeOutput(\n {\n ok: true,\n data: { module: moduleData, written: [{ path: filePath, kind: \"module-json\" }] },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function moduleListQuery(argv: string[]) {\n return {\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function moduleItemsQuery(argv: string[]) {\n return {\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function normalizeModule(module: CanvasModule) {\n return {\n id: String(module.id),\n name: module.name,\n position: module.position,\n state: module.state,\n unlockAt: module.unlock_at,\n completedAt: module.completed_at,\n requireSequentialProgress: module.require_sequential_progress,\n publishFinalGrade: module.publish_final_grade,\n prerequisiteModuleIds: module.prerequisite_module_ids?.map(String),\n itemsCount: module.items_count,\n itemsUrl: module.items_url,\n items: module.items?.map(normalizeModuleItem)\n };\n}\n\nexport function normalizeModuleItem(item: CanvasModuleItem) {\n return {\n id: String(item.id),\n moduleId: item.module_id === undefined ? undefined : String(item.module_id),\n title: item.title,\n type: item.type,\n contentId: item.content_id === undefined ? undefined : String(item.content_id),\n position: item.position,\n indent: item.indent,\n pageUrl: item.page_url,\n externalUrl: item.external_url,\n htmlUrl: item.html_url,\n apiUrl: item.url,\n newTab: item.new_tab,\n completionRequirement: item.completion_requirement,\n contentDetails: item.content_details\n };\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue, pageOptions, positionalArgs, requiredFlag } from \"./shared.js\";\n\nexport type CanvasPage = {\n page_id?: string | number;\n url: string;\n title?: string;\n created_at?: string;\n updated_at?: string;\n editing_roles?: string;\n last_edited_by?: unknown;\n body?: string;\n published?: boolean;\n hide_from_students?: boolean;\n front_page?: boolean;\n html_url?: string;\n locked_for_user?: boolean;\n lock_info?: unknown;\n lock_explanation?: string;\n};\n\nexport async function handlePagesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listPages(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showPage(argv.slice(1), options);\n }\n if (subcommand === \"export\") {\n return await exportPage(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown pages command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listPages(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas pages list --course-id <course-id>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasPage[]>(`/api/v1/courses/${courseId}/pages`, {\n query: pagesListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizePage),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showPage(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas pages show --course-id <course-id> --page <url>\");\n const pageUrl =\n flagValue(argv, \"--page\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas pages show --course-id <course-id> --page <url>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasPage>(\n `/api/v1/courses/${courseId}/pages/${encodeURIComponent(pageUrl)}`\n );\n\n await writeOutput(\n {\n ok: true,\n data: normalizePage(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function exportPage(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas pages export --course-id <course-id> --page <url> --out <dir>\"\n );\n const pageUrl =\n flagValue(argv, \"--page\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas pages export --course-id <course-id> --page <url> --out <dir>\");\n const outDir = requiredFlag(argv, \"--out\", \"Usage: canvas pages export --course-id <course-id> --page <url> --out <dir>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasPage>(\n `/api/v1/courses/${courseId}/pages/${encodeURIComponent(pageUrl)}`\n );\n const page = normalizePage(response.data);\n await mkdir(outDir, { recursive: true });\n const jsonPath = join(outDir, `${page.url}.json`);\n const htmlPath = join(outDir, `${page.url}.html`);\n await writeFile(jsonPath, `${JSON.stringify(page, null, 2)}\\n`, \"utf8\");\n await writeFile(htmlPath, page.body ?? \"\", \"utf8\");\n\n await writeOutput(\n {\n ok: true,\n data: {\n page,\n written: [\n { path: jsonPath, kind: \"page-json\" },\n { path: htmlPath, kind: \"page-html\" }\n ]\n },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function pagesListQuery(argv: string[]) {\n return {\n sort: flagValue(argv, \"--sort\"),\n search_term: flagValue(argv, \"--search\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function normalizePage(page: CanvasPage) {\n return {\n id: page.page_id === undefined ? undefined : String(page.page_id),\n url: page.url,\n title: page.title,\n createdAt: page.created_at,\n updatedAt: page.updated_at,\n editingRoles: page.editing_roles,\n lastEditedBy: page.last_edited_by,\n body: page.body,\n published: page.published,\n hideFromStudents: page.hide_from_students,\n frontPage: page.front_page,\n htmlUrl: page.html_url,\n lockedForUser: page.locked_for_user,\n lockInfo: page.lock_info,\n lockExplanation: page.lock_explanation\n };\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { normalizeAssignment, type CanvasAssignment } from \"./assignments.js\";\nimport { normalizeCourse, type CanvasCourse } from \"./courses.js\";\nimport { normalizeFile, type CanvasFile } from \"./files.js\";\nimport { normalizeModule, type CanvasModule } from \"./modules.js\";\nimport { normalizePage, type CanvasPage } from \"./pages.js\";\nimport { activeCanvas, hasFlag, requiredFlag } from \"./shared.js\";\nimport { normalizeTab, type CanvasTab } from \"./tabs.js\";\n\nexport async function handleReviewCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"pack\") {\n return await reviewPack(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown review command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function reviewPack(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas review pack --course-id <course-id> --out <dir>\"\n );\n const outDir = requiredFlag(argv, \"--out\", \"Usage: canvas review pack --course-id <course-id> --out <dir>\");\n const includeAllFiles = hasFlag(argv, \"--include-all-files\");\n\n const { client, profile } = await activeCanvas();\n const [course, tabs, modules, assignments, pages, files] = await Promise.all([\n client.get<CanvasCourse>(`/api/v1/courses/${courseId}`, {\n query: { \"include[]\": [\"term\", \"course_image\"] }\n }),\n client.get<CanvasTab[]>(`/api/v1/courses/${courseId}/tabs`).catch(() => ({ data: [] })),\n client\n .get<CanvasModule[]>(`/api/v1/courses/${courseId}/modules`, {\n query: { \"include[]\": [\"items\", \"content_details\"], per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] })),\n client\n .get<CanvasAssignment[]>(`/api/v1/courses/${courseId}/assignments`, {\n query: { per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] })),\n client\n .get<CanvasPage[]>(`/api/v1/courses/${courseId}/pages`, {\n query: { per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] })),\n includeAllFiles\n ? client\n .get<CanvasFile[]>(`/api/v1/courses/${courseId}/files`, {\n query: { per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] }))\n : Promise.resolve({ data: [] })\n ]);\n\n const pack = {\n generatedAt: new Date().toISOString(),\n baseUrl: profile.baseUrl,\n course: normalizeCourse(course.data),\n tabs: tabs.data.map(normalizeTab),\n modules: modules.data.map(normalizeModule),\n assignments: assignments.data.map(normalizeAssignment),\n pages: pages.data.map(normalizePage),\n files: files.data.map(normalizeFile),\n notes: [\n \"This review pack preserves Canvas IDs and visible course structure.\",\n includeAllFiles\n ? \"All visible course files metadata was included; file bytes are not downloaded by this command yet.\"\n : \"All-files metadata is omitted by default. Re-run with --include-all-files to include visible file metadata.\"\n ]\n };\n\n await mkdir(outDir, { recursive: true });\n const manifestPath = join(outDir, \"manifest.json\");\n const coursePath = join(outDir, \"course.json\");\n const modulesPath = join(outDir, \"modules.json\");\n const assignmentsPath = join(outDir, \"assignments.json\");\n const pagesPath = join(outDir, \"pages.json\");\n await Promise.all([\n writeFile(manifestPath, `${JSON.stringify(pack, null, 2)}\\n`, \"utf8\"),\n writeFile(coursePath, `${JSON.stringify(pack.course, null, 2)}\\n`, \"utf8\"),\n writeFile(modulesPath, `${JSON.stringify(pack.modules, null, 2)}\\n`, \"utf8\"),\n writeFile(assignmentsPath, `${JSON.stringify(pack.assignments, null, 2)}\\n`, \"utf8\"),\n writeFile(pagesPath, `${JSON.stringify(pack.pages, null, 2)}\\n`, \"utf8\")\n ]);\n\n await writeOutput(\n {\n ok: true,\n data: {\n course: pack.course,\n counts: {\n tabs: pack.tabs.length,\n modules: pack.modules.length,\n assignments: pack.assignments.length,\n pages: pack.pages.length,\n files: pack.files.length\n },\n written: [\n { path: manifestPath, kind: \"manifest\" },\n { path: coursePath, kind: \"course-json\" },\n { path: modulesPath, kind: \"modules-json\" },\n { path: assignmentsPath, kind: \"assignments-json\" },\n { path: pagesPath, kind: \"pages-json\" }\n ]\n },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n","import { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue } from \"./shared.js\";\n\nexport type CanvasTab = {\n id: string;\n html_url?: string;\n full_url?: string;\n position?: number;\n label?: string;\n type?: string;\n hidden?: boolean;\n visibility?: string;\n};\n\nexport async function handleTabsCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n if (subcommand !== \"list\") {\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown tabs command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n }\n\n try {\n const courseId = flagValue(argv, \"--course-id\");\n if (!courseId) {\n throw new Error(\"Usage: canvas tabs list --course-id <course-id>\");\n }\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasTab[]>(`/api/v1/courses/${courseId}/tabs`);\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeTab),\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nexport function normalizeTab(tab: CanvasTab) {\n return {\n id: tab.id,\n label: tab.label,\n type: tab.type,\n position: tab.position,\n hidden: tab.hidden,\n visibility: tab.visibility,\n htmlUrl: tab.html_url,\n fullUrl: tab.full_url\n };\n}\n","import { spawn } from \"node:child_process\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { hasFlag } from \"./shared.js\";\n\nexport const SKILLS_INSTALL_COMMAND = [\n \"npx\",\n \"skills\",\n \"add\",\n \"lukeguo12210/canvas-cli\",\n \"-g\",\n \"--skill\",\n \"*\",\n \"-y\"\n] as const;\n\nexport const SKILLS_INSTALL_DISPLAY_COMMAND = 'npx skills add lukeguo12210/canvas-cli -g --skill \"*\" -y';\n\nexport async function handleSkillsCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\" || subcommand === \"help\") {\n process.stdout.write(skillsHelpText());\n return 0;\n }\n if (subcommand === \"install\") {\n return await installSkills(argv.slice(1), options);\n }\n if (subcommand === \"command\") {\n return await printSkillsCommand(options);\n }\n if (subcommand === \"status\") {\n return await skillsStatus(options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown skills command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function installSkills(argv: string[], options: { format: OutputFormat }): Promise<number> {\n if (hasFlag(argv, \"--dry-run\") || hasFlag(argv, \"--print\")) {\n return printSkillsCommand(options);\n }\n\n const code = await run(SKILLS_INSTALL_COMMAND[0], SKILLS_INSTALL_COMMAND.slice(1));\n if (code !== 0) {\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"SKILLS_INSTALL_FAILED\",\n message: `Skills installer exited with code ${code}. Try: ${SKILLS_INSTALL_DISPLAY_COMMAND}`,\n retryable: true\n }\n },\n options\n );\n return code;\n }\n\n await writeOutput(\n {\n ok: true,\n data: {\n installed: true,\n command: SKILLS_INSTALL_DISPLAY_COMMAND,\n next: \"Restart or reload your agent so it can discover the updated Canvas skills.\"\n },\n meta: {\n command: \"skills install\"\n }\n },\n options\n );\n return 0;\n}\n\nasync function printSkillsCommand(options: { format: OutputFormat }): Promise<number> {\n await writeOutput(\n {\n ok: true,\n data: {\n command: SKILLS_INSTALL_DISPLAY_COMMAND,\n note: \"Run this to install or update all Canvas agent skills from GitHub.\"\n },\n meta: {\n command: \"skills command\"\n }\n },\n options\n );\n return 0;\n}\n\nasync function skillsStatus(options: { format: OutputFormat }): Promise<number> {\n await writeOutput(\n {\n ok: true,\n data: {\n installCommand: SKILLS_INSTALL_DISPLAY_COMMAND,\n skills: [\n \"canvas-shared\",\n \"canvas-courses\",\n \"canvas-modules\",\n \"canvas-pages\",\n \"canvas-files\",\n \"canvas-assignments\",\n \"canvas-review\"\n ],\n note: \"Use canvas skills install to install/update these skills.\"\n },\n meta: {\n command: \"skills status\"\n }\n },\n options\n );\n return 0;\n}\n\nfunction run(command: string, args: readonly string[]): Promise<number> {\n return new Promise((resolve) => {\n const child = spawn(command, [...args], {\n stdio: \"inherit\",\n shell: process.platform === \"win32\"\n });\n child.on(\"close\", (code) => resolve(code ?? 1));\n child.on(\"error\", () => resolve(1));\n });\n}\n\nexport function skillsHelpText(): string {\n return `canvas skills — install and inspect Canvas agent skills.\n\nUSAGE:\n canvas skills <command> [options]\n\nCOMMANDS:\n install Install or update all Canvas agent skills\n install --dry-run Print the install command without running it\n command Print the direct npx skills install command\n status Show bundled skill names and install command\n\nALIASES:\n canvas install-skills\n\nDIRECT INSTALLER:\n ${SKILLS_INSTALL_DISPLAY_COMMAND}\n`;\n}\n","import { writeOutput } from \"../core/output.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { handleAuthCommand } from \"../commands/auth.js\";\nimport { handleApiCommand } from \"../commands/api.js\";\nimport { handleAssignmentsCommand } from \"../commands/assignments.js\";\nimport { handleConfigCommand } from \"../commands/config.js\";\nimport { handleCoursesCommand } from \"../commands/courses.js\";\nimport { handleFilesCommand, handleFoldersCommand } from \"../commands/files.js\";\nimport { handleMeCommand } from \"../commands/me.js\";\nimport { handleModulesCommand } from \"../commands/modules.js\";\nimport { handlePagesCommand } from \"../commands/pages.js\";\nimport { handleReviewCommand } from \"../commands/review.js\";\nimport { handleSkillsCommand } from \"../commands/skills.js\";\nimport { handleTabsCommand } from \"../commands/tabs.js\";\n\nconst VERSION = \"0.0.6\";\n\nfunction helpText(): string {\n return `canvas — Canvas LMS CLI for students and agents.\n\nUSAGE:\n canvas <command> [options]\n\nCOMMANDS:\n auth login Interactive Canvas PAT setup\n auth status Show redacted auth status\n auth schools Search supported Canvas school URLs\n auth logout Remove local Canvas auth config\n config show Show redacted local config\n me Show current Canvas user profile\n courses list List active Canvas courses\n courses overview Summarize course setup\n tabs list List course tabs\n modules list List course modules\n modules items List module items\n assignments list List course assignments\n pages list List course pages\n files list List course files\n folders list List course folders\n review pack Create a local course review pack\n api get Raw read-only Canvas API GET\n skills install Install/update bundled agent skills\n install-skills Alias for skills install\n version Print CLI version\n\nFLAGS:\n -h, --help Show help\n --format <fmt> Output format: json | pretty | table | ndjson\n\nMVP STATUS:\n Read-only student commands are available for auth, courses, tabs, modules,\n assignments, pages, files, folders, review packs, and raw GET.\n`;\n}\n\nasync function main(argv: string[]): Promise<number> {\n const parsed = parseGlobalOptions(argv);\n const [command] = parsed.argv;\n\n if (!command || command === \"--help\" || command === \"-h\" || command === \"help\") {\n process.stdout.write(helpText());\n return 0;\n }\n\n if (command === \"version\" || command === \"--version\" || command === \"-v\") {\n await writeOutput(\n {\n ok: true,\n data: { version: VERSION },\n meta: { command: \"version\" }\n },\n { format: parsed.format === \"json\" ? \"json\" : \"pretty\" }\n );\n return 0;\n }\n\n if (command === \"auth\") {\n return handleAuthCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"config\") {\n return handleConfigCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"me\") {\n return handleMeCommand({ format: parsed.format });\n }\n\n if (command === \"courses\") {\n return handleCoursesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"tabs\") {\n return handleTabsCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"modules\") {\n return handleModulesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"assignments\") {\n return handleAssignmentsCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"pages\") {\n return handlePagesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"files\") {\n return handleFilesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"folders\") {\n return handleFoldersCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"review\") {\n return handleReviewCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"api\") {\n return handleApiCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"skills\" || command === \"install-skills\") {\n const skillsArgv = command === \"install-skills\" ? [\"install\", ...parsed.argv.slice(1)] : parsed.argv.slice(1);\n return handleSkillsCommand(skillsArgv, { format: parsed.format });\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown command: ${parsed.argv.join(\" \")}`,\n retryable: false\n }\n },\n { format: parsed.format }\n );\n return 1;\n}\n\nfunction parseGlobalOptions(argv: string[]): { argv: string[]; format: OutputFormat } {\n const nextArgv: string[] = [];\n let format: OutputFormat = \"json\";\n\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === \"--format\") {\n const value = argv[index + 1];\n if (isOutputFormat(value)) {\n format = value;\n index += 1;\n continue;\n }\n }\n nextArgv.push(arg);\n }\n\n return { argv: nextArgv, format };\n}\n\nfunction isOutputFormat(value: string | undefined): value is OutputFormat {\n return value === \"json\" || value === \"pretty\" || value === \"table\" || value === \"ndjson\";\n}\n\nmain(process.argv.slice(2))\n .then((code) => {\n process.exitCode = code;\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`canvas: ${message}\\n`);\n process.exitCode = 1;\n });\n"],"mappings":"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","names":["output","output","path","input","resolve","school","path","mkdir","writeFile","mkdir","writeFile","mkdir","writeFile","path","missing","mkdir","writeFile","input","mkdir","writeFile","join","missing","mkdir","join","writeFile","mkdir","writeFile","join","missing","mkdir","join","writeFile","mkdir","writeFile","join","mkdir","join","writeFile","spawn","resolve","spawn"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/redaction.ts","../../src/core/output.ts","../../src/core/errors.ts","../../src/core/pagination.ts","../../src/core/canvas-client.ts","../../src/core/config-store.ts","../../src/core/paths.ts","../../src/core/browser.ts","../../src/core/prompt.ts","../../src/registry/schools.ts","../../src/workflows/context-bootstrap.ts","../../src/commands/shared.ts","../../src/commands/auth.ts","../../src/commands/api.ts","../../src/commands/assignments.ts","../../src/commands/config.ts","../../src/commands/courses.ts","../../src/commands/files.ts","../../src/commands/me.ts","../../src/commands/modules.ts","../../src/commands/pages.ts","../../src/commands/review.ts","../../src/commands/tabs.ts","../../src/commands/skills.ts","../../src/bin/canvas.ts"],"sourcesContent":["const REDACTED = \"[REDACTED]\";\n\nconst SECRET_KEY_PATTERN = /(^|[_-])(authorization|access[_-]?token|token|api[_-]?key|secret)$/i;\nconst BEARER_PATTERN = /Bearer\\s+[A-Za-z0-9._~+/=-]+/gi;\nconst QUERY_SECRET_PATTERN = /([?&](?:access_token|token|api_key|verifier|code)=)[^&#\\s]+/gi;\n\nexport function redactSecrets(value: unknown): unknown {\n if (typeof value === \"string\") {\n return redactString(value);\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => redactSecrets(item));\n }\n\n if (value && typeof value === \"object\") {\n const output: Record<string, unknown> = {};\n for (const [key, nested] of Object.entries(value)) {\n output[key] = SECRET_KEY_PATTERN.test(key) ? REDACTED : redactSecrets(nested);\n }\n return output;\n }\n\n return value;\n}\n\nexport function redactString(value: string): string {\n return value\n .replace(BEARER_PATTERN, `Bearer ${REDACTED}`)\n .replace(QUERY_SECRET_PATTERN, `$1${REDACTED}`);\n}\n\nexport function redactedValue(): string {\n return REDACTED;\n}\n","import { redactSecrets } from \"./redaction.js\";\n\nexport type OutputFormat = \"json\" | \"pretty\" | \"table\" | \"ndjson\";\n\nexport type Success<T> = {\n ok: true;\n data: T;\n meta?: Record<string, unknown>;\n};\n\nexport type Failure = {\n ok: false;\n error: {\n code: string;\n message: string;\n status?: number;\n retryable: boolean;\n };\n};\n\nexport type ResultEnvelope<T> = Success<T> | Failure;\n\nexport function formatOutput<T>(\n result: ResultEnvelope<T>,\n options: { format?: OutputFormat } = {}\n): string {\n const format = options.format ?? \"json\";\n const safeResult = redactSecrets(result) as ResultEnvelope<T>;\n\n if (format === \"json\") {\n return `${JSON.stringify(safeResult, null, 2)}\\n`;\n }\n\n if (format === \"ndjson\") {\n return `${JSON.stringify(safeResult)}\\n`;\n }\n\n if (!safeResult.ok) {\n const status = safeResult.error.status ? ` (${safeResult.error.status})` : \"\";\n return `Error ${safeResult.error.code}${status}: ${safeResult.error.message}\\n`;\n }\n\n if (format === \"table\") {\n return tableOutput(safeResult.data);\n }\n\n return prettyOutput(safeResult.data);\n}\n\nexport async function writeOutput<T>(\n result: ResultEnvelope<T>,\n options: { format?: OutputFormat } = {}\n): Promise<void> {\n const stream = result.ok ? process.stdout : process.stderr;\n stream.write(formatOutput(result, options));\n}\n\nfunction prettyOutput(data: unknown): string {\n if (typeof data === \"string\") {\n return `${data}\\n`;\n }\n return `${JSON.stringify(data, null, 2)}\\n`;\n}\n\nfunction tableOutput(data: unknown): string {\n if (!Array.isArray(data)) {\n return prettyOutput(data);\n }\n\n if (data.length === 0) {\n return \"\\n\";\n }\n\n const rows = data.filter((row): row is Record<string, unknown> => {\n return row !== null && typeof row === \"object\" && !Array.isArray(row);\n });\n\n if (rows.length === 0) {\n return prettyOutput(data);\n }\n\n const columns = Object.keys(rows[0] ?? {});\n const widths = columns.map((column) =>\n Math.max(column.length, ...rows.map((row) => String(row[column] ?? \"\").length))\n );\n\n const line = (values: string[]) =>\n `${values.map((value, index) => value.padEnd(widths[index] ?? value.length)).join(\" \")}\\n`;\n\n let output = line(columns);\n output += line(widths.map((width) => \"-\".repeat(width)));\n for (const row of rows) {\n output += line(columns.map((column) => String(row[column] ?? \"\")));\n }\n return output;\n}\n","export class CanvasCliError extends Error {\n readonly code: string;\n readonly status?: number;\n readonly retryable: boolean;\n\n constructor(\n code: string,\n message: string,\n options: { status?: number; retryable?: boolean; cause?: unknown } = {}\n ) {\n super(message, { cause: options.cause });\n this.name = \"CanvasCliError\";\n this.code = code;\n this.status = options.status;\n this.retryable = options.retryable ?? false;\n }\n}\n\nexport function toErrorEnvelope(error: unknown) {\n if (error instanceof CanvasCliError) {\n return {\n ok: false as const,\n error: {\n code: error.code,\n message: error.message,\n status: error.status,\n retryable: error.retryable\n }\n };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return {\n ok: false as const,\n error: {\n code: \"UNEXPECTED_ERROR\",\n message,\n retryable: false\n }\n };\n}\n","export type LinkRelation = \"current\" | \"next\" | \"prev\" | \"first\" | \"last\";\n\nexport type ParsedLinks = Partial<Record<LinkRelation, string>>;\n\nexport function parseLinkHeader(header: string | null | undefined): ParsedLinks {\n if (!header) {\n return {};\n }\n\n const links: ParsedLinks = {};\n for (const part of splitHeader(header)) {\n const match = part.match(/^\\s*<([^>]+)>\\s*;\\s*rel=\"([^\"]+)\"\\s*$/i);\n if (!match) {\n continue;\n }\n const [, url, rel] = match;\n if (isLinkRelation(rel)) {\n links[rel] = url;\n }\n }\n return links;\n}\n\nfunction splitHeader(header: string): string[] {\n const parts: string[] = [];\n let current = \"\";\n let inQuotes = false;\n\n for (const char of header) {\n if (char === \"\\\"\") {\n inQuotes = !inQuotes;\n }\n if (char === \",\" && !inQuotes) {\n parts.push(current);\n current = \"\";\n continue;\n }\n current += char;\n }\n\n if (current.trim()) {\n parts.push(current);\n }\n\n return parts;\n}\n\nfunction isLinkRelation(value: string): value is LinkRelation {\n return [\"current\", \"next\", \"prev\", \"first\", \"last\"].includes(value);\n}\n","import { CanvasCliError } from \"./errors.js\";\nimport { parseLinkHeader } from \"./pagination.js\";\nimport { redactSecrets } from \"./redaction.js\";\n\nexport type CanvasClientOptions = {\n baseUrl: string;\n token: string;\n fetchImpl?: typeof fetch;\n};\n\nexport type RequestOptions = {\n query?: Record<string, string | number | boolean | Array<string | number | boolean> | undefined>;\n pageAll?: boolean;\n pageLimit?: number;\n};\n\nexport type CanvasResponse<T> = {\n data: T;\n meta: {\n request: {\n method: \"GET\";\n path: string;\n };\n pagination: {\n pagesFetched: number;\n hasNext: boolean;\n };\n };\n};\n\nexport type CanvasDownload = {\n data: Uint8Array;\n contentType?: string;\n filename?: string;\n meta: {\n request: {\n method: \"GET\";\n url: string;\n };\n };\n};\n\nexport class CanvasClient {\n private readonly baseUrl: string;\n private readonly token: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: CanvasClientOptions) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl);\n this.token = options.token;\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n async get<T>(path: string, options: RequestOptions = {}): Promise<CanvasResponse<T>> {\n if (!path.startsWith(\"/api/v1/\")) {\n throw new CanvasCliError(\"INVALID_API_PATH\", \"Canvas API paths must start with /api/v1/.\");\n }\n\n let nextUrl: string | null = buildUrl(this.baseUrl, path, options.query);\n const pages: unknown[] = [];\n let pagesFetched = 0;\n const pageLimit = options.pageLimit ?? 50;\n\n let hasNext = false;\n\n while (nextUrl) {\n pagesFetched += 1;\n if (pagesFetched > pageLimit) {\n throw new CanvasCliError(\n \"PAGE_LIMIT_EXCEEDED\",\n `Stopped after ${pageLimit} pages. Increase --page-limit if needed.`\n );\n }\n\n const response = await this.fetchImpl(nextUrl, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${this.token}`,\n Accept: \"application/json+canvas-string-ids\"\n }\n }).catch((error: unknown) => {\n throw new CanvasCliError(\"CANVAS_NETWORK_ERROR\", \"Could not reach Canvas.\", {\n retryable: true,\n cause: error\n });\n });\n\n if (!response.ok) {\n throw new CanvasCliError(\n mapStatusCode(response.status),\n `Canvas request failed with status ${response.status}.`,\n { status: response.status, retryable: response.status === 429 || response.status >= 500 }\n );\n }\n\n const data = (await response.json()) as unknown;\n pages.push(data);\n\n const links = parseLinkHeader(response.headers.get(\"link\"));\n hasNext = Boolean(links.next);\n nextUrl = options.pageAll ? links.next ?? null : null;\n }\n\n const merged = mergePages(pages) as T;\n return {\n data: redactSecrets(merged) as T,\n meta: {\n request: {\n method: \"GET\",\n path\n },\n pagination: {\n pagesFetched,\n hasNext\n }\n }\n };\n }\n\n async download(url: string): Promise<CanvasDownload> {\n const response = await this.fetchImpl(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${this.token}`,\n Accept: \"*/*\"\n }\n }).catch((error: unknown) => {\n throw new CanvasCliError(\"CANVAS_NETWORK_ERROR\", \"Could not reach Canvas.\", {\n retryable: true,\n cause: error\n });\n });\n\n if (!response.ok) {\n throw new CanvasCliError(\n mapStatusCode(response.status),\n `Canvas download failed with status ${response.status}.`,\n { status: response.status, retryable: response.status === 429 || response.status >= 500 }\n );\n }\n\n return {\n data: new Uint8Array(await response.arrayBuffer()),\n contentType: response.headers.get(\"content-type\") ?? undefined,\n filename: filenameFromContentDisposition(response.headers.get(\"content-disposition\")),\n meta: {\n request: {\n method: \"GET\",\n url: redactSecrets(url) as string\n }\n }\n };\n }\n}\n\nexport function normalizeBaseUrl(input: string): string {\n const trimmed = input.trim().replace(/\\/+$/, \"\");\n const url = new URL(trimmed);\n\n if (url.protocol !== \"https:\") {\n throw new CanvasCliError(\"INVALID_BASE_URL\", \"Canvas base URL must use https://.\");\n }\n\n if (url.pathname.includes(\"/api/\")) {\n throw new CanvasCliError(\"INVALID_BASE_URL\", \"Canvas base URL should not include /api/.\");\n }\n\n url.pathname = url.pathname.replace(/\\/+$/, \"\");\n url.search = \"\";\n url.hash = \"\";\n return url.toString().replace(/\\/+$/, \"\");\n}\n\nfunction buildUrl(\n baseUrl: string,\n path: string,\n query: RequestOptions[\"query\"] = {}\n): string {\n const url = new URL(path, baseUrl);\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, String(item));\n }\n continue;\n }\n url.searchParams.set(key, String(value));\n }\n return url.toString();\n}\n\nfunction mergePages(pages: unknown[]): unknown {\n if (pages.length === 1) {\n return pages[0];\n }\n\n if (pages.every(Array.isArray)) {\n return pages.flat();\n }\n\n return pages;\n}\n\nfunction mapStatusCode(status: number): string {\n if (status === 401) return \"CANVAS_UNAUTHORIZED\";\n if (status === 403) return \"CANVAS_FORBIDDEN\";\n if (status === 404) return \"CANVAS_NOT_FOUND\";\n if (status === 429) return \"CANVAS_RATE_LIMITED\";\n if (status >= 500) return \"CANVAS_SERVER_ERROR\";\n return \"CANVAS_REQUEST_FAILED\";\n}\n\nfunction filenameFromContentDisposition(header: string | null): string | undefined {\n if (!header) {\n return undefined;\n }\n const utf8Match = /filename\\*=UTF-8''([^;]+)/i.exec(header);\n if (utf8Match?.[1]) {\n return decodeURIComponent(utf8Match[1]);\n }\n const match = /filename=\"?([^\";]+)\"?/i.exec(header);\n return match?.[1];\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { CanvasCliError } from \"./errors.js\";\nimport { configPath } from \"./paths.js\";\nimport { redactSecrets } from \"./redaction.js\";\n\nexport type CanvasProfile = {\n schoolName: string;\n baseUrl: string;\n token: string;\n createdAt: string;\n validatedAt?: string;\n user?: {\n id?: string;\n name?: string;\n };\n};\n\nexport type CanvasConfig = {\n version: 1;\n activeProfile: string;\n profiles: Record<string, CanvasProfile>;\n};\n\nexport class ConfigStore {\n constructor(private readonly filePath = configPath()) {}\n\n async read(): Promise<CanvasConfig | null> {\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n return JSON.parse(raw) as CanvasConfig;\n } catch (error) {\n if (isNotFound(error)) {\n return null;\n }\n throw error;\n }\n }\n\n async write(config: CanvasConfig): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true, mode: 0o700 });\n await writeFile(this.filePath, `${JSON.stringify(config, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: 0o600\n });\n }\n\n async remove(): Promise<void> {\n await rm(this.filePath, { force: true });\n }\n\n async readRedacted(): Promise<CanvasConfig | null> {\n const config = await this.read();\n return config ? (redactSecrets(config) as CanvasConfig) : null;\n }\n\n async activeProfile(): Promise<CanvasProfile> {\n const config = await this.read();\n if (!config) {\n throw new CanvasCliError(\"NO_AUTH_CONFIG\", \"No Canvas auth config found. Run canvas auth login.\");\n }\n\n const profile = config.profiles[config.activeProfile];\n if (!profile) {\n throw new CanvasCliError(\n \"NO_ACTIVE_PROFILE\",\n `Active Canvas profile not found: ${config.activeProfile}`\n );\n }\n\n return profile;\n }\n}\n\nfunction isNotFound(error: unknown): boolean {\n return Boolean(error && typeof error === \"object\" && \"code\" in error && error.code === \"ENOENT\");\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\n\nexport function canvasHome(): string {\n return process.env.CANVAS_HOME || path.join(os.homedir(), \".canvas\");\n}\n\nexport function configPath(): string {\n return path.join(canvasHome(), \"config.json\");\n}\n\nexport function contextPath(): string {\n return path.join(canvasHome(), \"context.json\");\n}\n\nexport function resolveInside(baseDir: string, targetPath: string): string {\n const resolvedBase = path.resolve(baseDir);\n const resolvedTarget = path.resolve(resolvedBase, targetPath);\n const relative = path.relative(resolvedBase, resolvedTarget);\n\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Path escapes target directory: ${targetPath}`);\n }\n\n return resolvedTarget;\n}\n","import { spawn } from \"node:child_process\";\n\nexport async function openBrowser(url: string): Promise<void> {\n const command = openCommand(url);\n const child = spawn(command.command, command.args, {\n detached: true,\n stdio: \"ignore\"\n });\n child.unref();\n}\n\nfunction openCommand(url: string): { command: string; args: string[] } {\n if (process.platform === \"darwin\") {\n return { command: \"open\", args: [url] };\n }\n if (process.platform === \"win32\") {\n return { command: \"cmd\", args: [\"/c\", \"start\", \"\", url] };\n }\n return { command: \"xdg-open\", args: [url] };\n}\n","import { createInterface } from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\n\nexport type PromptIO = {\n question(prompt: string): Promise<string>;\n close(): void;\n};\n\nexport function createPrompt(): PromptIO {\n return createInterface({ input, output });\n}\n\nexport async function promptHidden(prompt: string): Promise<string> {\n if (!process.stdin.isTTY) {\n const io = createPrompt();\n try {\n return (await io.question(prompt)).trim();\n } finally {\n io.close();\n }\n }\n\n return new Promise((resolve, reject) => {\n const stdin = process.stdin;\n const onData = (char: Buffer) => {\n const value = char.toString(\"utf8\");\n if (value === \"\\n\" || value === \"\\r\" || value === \"\\r\\n\") {\n stdin.setRawMode(false);\n stdin.pause();\n stdin.off(\"data\", onData);\n process.stdout.write(\"\\n\");\n resolve(buffer.trim());\n return;\n }\n if (value === \"\\u0003\") {\n stdin.setRawMode(false);\n stdin.pause();\n stdin.off(\"data\", onData);\n process.stdout.write(\"\\n\");\n reject(new Error(\"Prompt cancelled.\"));\n return;\n }\n if (value === \"\\u007f\") {\n buffer = buffer.slice(0, -1);\n return;\n }\n buffer += value;\n };\n\n let buffer = \"\";\n process.stdout.write(prompt);\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on(\"data\", onData);\n });\n}\n","import { normalizeBaseUrl } from \"../core/canvas-client.js\";\n\nexport type School = {\n name: string;\n url: string;\n};\n\nexport const SCHOOLS: School[] = [\n { name: \"Brown University\", url: \"https://canvas.brown.edu\" },\n { name: \"Carnegie Mellon University\", url: \"https://canvas.cmu.edu\" },\n { name: \"Columbia University (CourseWorks)\", url: \"https://courseworks2.columbia.edu\" },\n { name: \"Cornell University\", url: \"https://canvas.cornell.edu\" },\n { name: \"Dartmouth College\", url: \"https://canvas.dartmouth.edu\" },\n { name: \"Duke University\", url: \"https://go.canvas.duke.edu\" },\n { name: \"Emory University\", url: \"https://canvas.emory.edu\" },\n { name: \"Georgetown University\", url: \"https://canvas.georgetown.edu\" },\n { name: \"Georgia Institute of Technology\", url: \"https://canvas.gatech.edu\" },\n { name: \"Harvard University\", url: \"https://canvas.harvard.edu\" },\n { name: \"Massachusetts Institute of Technology (MIT)\", url: \"https://canvas.mit.edu\" },\n { name: \"Northeastern University\", url: \"https://canvas.northeastern.edu\" },\n { name: \"Northwestern University\", url: \"https://canvas.northwestern.edu\" },\n { name: \"Ohio State University\", url: \"https://canvas.osu.edu\" },\n { name: \"Pennsylvania State University\", url: \"https://canvas.psu.edu\" },\n { name: \"Princeton University\", url: \"https://canvas.princeton.edu\" },\n { name: \"Rice University\", url: \"https://canvas.rice.edu\" },\n { name: \"Stanford University\", url: \"https://canvas.stanford.edu\" },\n { name: \"Tufts University\", url: \"https://canvas.tufts.edu\" },\n { name: \"University of California, Berkeley (bCourses)\", url: \"https://bcourses.berkeley.edu\" },\n { name: \"University of California, Davis\", url: \"https://canvas.ucdavis.edu\" },\n { name: \"University of California, Irvine\", url: \"https://canvas.eee.uci.edu\" },\n { name: \"University of California, Los Angeles (Bruin Learn)\", url: \"https://bruinlearn.ucla.edu\" },\n { name: \"University of California, San Diego\", url: \"https://canvas.ucsd.edu\" },\n { name: \"University of California, Santa Barbara\", url: \"https://canvas.ucsb.edu\" },\n { name: \"University of California, Santa Cruz\", url: \"https://canvas.ucsc.edu\" },\n { name: \"University of Chicago\", url: \"https://canvas.uchicago.edu\" },\n { name: \"University of Michigan\", url: \"https://canvas.umich.edu\" },\n { name: \"University of North Carolina at Chapel Hill\", url: \"https://canvas.unc.edu\" },\n { name: \"University of Notre Dame\", url: \"https://canvas.nd.edu\" },\n { name: \"University of Pennsylvania\", url: \"https://canvas.upenn.edu\" },\n { name: \"University of Southern California\", url: \"https://canvas.usc.edu\" },\n { name: \"University of Virginia\", url: \"https://canvas.its.virginia.edu\" },\n { name: \"University of Washington\", url: \"https://canvas.uw.edu\" },\n { name: \"Yale University\", url: \"https://canvas.yale.edu\" }\n];\n\nexport function searchSchools(query: string, limit = 10): School[] {\n const normalized = query.trim().toLowerCase();\n if (!normalized) {\n return SCHOOLS.slice(0, limit);\n }\n\n return SCHOOLS.filter((school) => {\n return school.name.toLowerCase().includes(normalized) || school.url.toLowerCase().includes(normalized);\n }).slice(0, limit);\n}\n\nexport function makeCustomSchool(name: string, url: string): School {\n return {\n name: name.trim() || \"Custom Canvas School\",\n url: normalizeBaseUrl(url)\n };\n}\n","export type BootstrapSummary = {\n skipped: true;\n reason: string;\n};\n\nexport async function runPostLoginBootstrap(): Promise<BootstrapSummary> {\n return {\n skipped: true,\n reason: \"Context bootstrap is planned for Phase 4.\"\n };\n}\n","import { CanvasClient } from \"../core/canvas-client.js\";\nimport { ConfigStore, type CanvasProfile } from \"../core/config-store.js\";\n\nexport type ActiveCanvas = {\n profile: CanvasProfile;\n client: CanvasClient;\n};\n\nexport async function activeCanvas(): Promise<ActiveCanvas> {\n const profile = await new ConfigStore().activeProfile();\n return {\n profile,\n client: new CanvasClient({\n baseUrl: profile.baseUrl,\n token: profile.token\n })\n };\n}\n\nexport function flagValue(argv: string[], flag: string): string | undefined {\n const index = argv.indexOf(flag);\n if (index === -1) {\n return undefined;\n }\n return argv[index + 1];\n}\n\nexport function requiredFlag(argv: string[], flag: string, usage: string): string {\n const value = flagValue(argv, flag);\n if (!value) {\n throw new Error(usage);\n }\n return value;\n}\n\nexport function hasFlag(argv: string[], flag: string): boolean {\n return argv.includes(flag);\n}\n\nexport function csvFlag(argv: string[], flag: string): string[] | undefined {\n const raw = flagValue(argv, flag);\n if (!raw) {\n return undefined;\n }\n const values = raw\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean);\n return values.length > 0 ? values : undefined;\n}\n\nexport function pageOptions(argv: string[]): { pageAll: boolean; pageLimit?: number } {\n const pageLimitRaw = flagValue(argv, \"--page-limit\");\n return {\n pageAll: hasFlag(argv, \"--page-all\"),\n pageLimit: pageLimitRaw ? Number.parseInt(pageLimitRaw, 10) : undefined\n };\n}\n\nexport function positionalArgs(argv: string[]): string[] {\n const valueFlags = new Set([\n \"--course-id\",\n \"--module-id\",\n \"--item-id\",\n \"--assignment-id\",\n \"--quiz-id\",\n \"--topic-id\",\n \"--page\",\n \"--path\",\n \"--out\",\n \"--format\",\n \"--page-limit\",\n \"--page-size\",\n \"--page-delay\",\n \"--enrollment-state\",\n \"--state\",\n \"--include\",\n \"--params\",\n \"--bucket\",\n \"--search\",\n \"--order-by\",\n \"--sort\",\n \"--file-id\",\n \"--folder-id\",\n \"--group-id\",\n \"--content-type\",\n \"--school\",\n \"--school-query\",\n \"--school-url\",\n \"--url\",\n \"--school-name\",\n \"--name\",\n \"--token\",\n \"--token-env\"\n ]);\n const values: string[] = [];\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg.startsWith(\"--\")) {\n if (valueFlags.has(arg)) {\n index += 1;\n }\n continue;\n }\n values.push(arg);\n }\n return values;\n}\n","import { CanvasClient, normalizeBaseUrl } from \"../core/canvas-client.js\";\nimport { ConfigStore, type CanvasConfig } from \"../core/config-store.js\";\nimport { CanvasCliError, toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { openBrowser } from \"../core/browser.js\";\nimport { createPrompt, promptHidden, type PromptIO } from \"../core/prompt.js\";\nimport { makeCustomSchool, searchSchools, type School } from \"../registry/schools.js\";\nimport { runPostLoginBootstrap } from \"../workflows/context-bootstrap.js\";\nimport { flagValue, positionalArgs } from \"./shared.js\";\n\nconst TOKEN_PURPOSE = \"canvas-cli\";\n\nexport async function handleAuthCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\" || subcommand === \"help\") {\n process.stdout.write(authHelpText());\n return 0;\n }\n\n if (subcommand === \"login\") {\n return authLogin(argv.slice(1), options);\n }\n\n if (subcommand === \"status\") {\n return authStatus(options);\n }\n\n if (subcommand === \"schools\") {\n return authSchools(argv.slice(1), options);\n }\n\n if (subcommand === \"logout\") {\n return authLogout(options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown auth command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n}\n\nexport function authHelpText(): string {\n return `canvas auth — authenticate and inspect Canvas login state.\n\nUSAGE:\n canvas auth <command> [options]\n\nCOMMANDS:\n login Interactive Canvas PAT setup\n login --school <query> Non-interactive login with a school search\n login --school-url <url> Non-interactive login with a custom Canvas URL\n schools search <query> Search supported Canvas school URLs\n status Show redacted auth status\n logout Remove local Canvas auth config\n\nTOKEN OPTIONS:\n --token <PAT> Use a token provided by the user\n --token-env <ENV> Read token from an environment variable\n --token-stdin Read token from stdin\n\nEXAMPLES:\n canvas auth schools search \"Berkeley\" --format json\n canvas auth login --school \"Berkeley\"\n canvas auth login --school \"Berkeley\" --token-env CANVAS_TOKEN\n canvas auth login --school-url https://bcourses.berkeley.edu --school-name \"UC Berkeley\" --token \"paste-token-here\"\n`;\n}\n\nasync function authLogin(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const io = createPrompt();\n\n try {\n const nonInteractive = hasNonInteractiveLoginArgs(argv);\n const school = nonInteractive ? resolveSchoolFromArgs(argv) : await chooseSchool(io);\n const settingsUrl = `${school.url}/profile/settings`;\n\n const providedToken = await tokenFromArgs(argv);\n let token = providedToken;\n\n if (!token && nonInteractive) {\n await writeOutput(\n {\n ok: true,\n data: tokenSetupForSchool(school),\n meta: {\n command: \"auth login\",\n mode: \"token-setup\"\n }\n },\n options\n );\n return 0;\n }\n\n if (!token) {\n process.stdout.write(tokenInstructions(school, settingsUrl));\n await io.question(\"Press Enter to open Canvas settings in your browser...\");\n await openBrowser(settingsUrl);\n process.stdout.write(\"\\nWaiting for your Canvas personal access token.\\n\");\n token = await promptHidden(\"Paste token: \");\n }\n\n if (!token) {\n throw new CanvasCliError(\"EMPTY_TOKEN\", \"No token entered.\");\n }\n\n const client = new CanvasClient({ baseUrl: school.url, token });\n const user = await validateToken(client);\n const now = new Date().toISOString();\n const config: CanvasConfig = {\n version: 1,\n activeProfile: \"default\",\n profiles: {\n default: {\n schoolName: school.name,\n baseUrl: school.url,\n token,\n createdAt: now,\n validatedAt: now,\n user\n }\n }\n };\n\n await new ConfigStore().write(config);\n const bootstrap = await runPostLoginBootstrap();\n\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: true,\n school: {\n name: school.name,\n baseUrl: school.url\n },\n user,\n contextBootstrap: bootstrap,\n next: \"canvas courses list --active --page-all\"\n },\n meta: {\n command: \"auth login\"\n }\n },\n options\n );\n return 0;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n } finally {\n io.close();\n }\n}\n\nasync function authSchools(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const [subcommand] = argv;\n const query =\n subcommand === \"search\"\n ? positionalArgs(argv.slice(1)).join(\" \")\n : flagValue(argv, \"--query\") ?? positionalArgs(argv).join(\" \");\n\n await writeOutput(\n {\n ok: true,\n data: searchSchools(query).map((school) => ({\n name: school.name,\n baseUrl: school.url\n })),\n meta: {\n command: \"auth schools\",\n query\n }\n },\n options\n );\n return 0;\n}\n\nasync function authStatus(options: { format: OutputFormat }): Promise<number> {\n const store = new ConfigStore();\n const config = await store.readRedacted();\n\n if (!config) {\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: false,\n message: \"No Canvas auth config found. Run canvas auth login.\"\n },\n meta: {\n command: \"auth status\"\n }\n },\n options\n );\n return 0;\n }\n\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: true,\n activeProfile: config.activeProfile,\n profile: config.profiles[config.activeProfile]\n },\n meta: {\n command: \"auth status\"\n }\n },\n options\n );\n return 0;\n}\n\nasync function authLogout(options: { format: OutputFormat }): Promise<number> {\n await new ConfigStore().remove();\n await writeOutput(\n {\n ok: true,\n data: {\n authenticated: false,\n message: \"Canvas auth config removed.\"\n },\n meta: {\n command: \"auth logout\"\n }\n },\n options\n );\n return 0;\n}\n\nexport async function chooseSchool(\n io: PromptIO,\n write: (message: string) => void = (message) => process.stdout.write(message)\n): Promise<School> {\n write(\"Search for your school, or press Enter to browse the first matches.\\n\");\n const query = await io.question(\"School: \");\n const matches = searchSchools(query);\n\n if (matches.length === 1) {\n const school = matches[0];\n const answer = (\n await io.question(`Is this your school: ${school.name} (${school.url})? Choose: y/n `)\n )\n .trim()\n .toLowerCase();\n\n if (answer === \"y\" || answer === \"yes\") {\n return {\n name: school.name,\n url: normalizeBaseUrl(school.url)\n };\n }\n\n if (answer === \"n\" || answer === \"no\") {\n return promptCustomSchool(io);\n }\n\n throw new CanvasCliError(\"INVALID_SELECTION\", \"Please answer y or n.\");\n }\n\n for (const [index, school] of matches.entries()) {\n write(`${index + 1}. ${school.name}\\n ${school.url}\\n`);\n }\n write(`${matches.length + 1}. Not found? Add your own\\n`);\n\n const selected = Number.parseInt(await io.question(\"Choose: \"), 10);\n if (!Number.isFinite(selected) || selected < 1 || selected > matches.length + 1) {\n throw new CanvasCliError(\"INVALID_SELECTION\", \"Invalid school selection.\");\n }\n\n if (selected === matches.length + 1) {\n return promptCustomSchool(io);\n }\n\n const school = matches[selected - 1];\n return {\n name: school.name,\n url: normalizeBaseUrl(school.url)\n };\n}\n\nexport function resolveSchoolFromArgs(argv: string[]): School {\n const schoolUrl = flagValue(argv, \"--school-url\") ?? flagValue(argv, \"--url\");\n if (schoolUrl) {\n return makeCustomSchool(flagValue(argv, \"--school-name\") ?? flagValue(argv, \"--name\") ?? \"Custom Canvas School\", schoolUrl);\n }\n\n const schoolQuery = flagValue(argv, \"--school\") ?? flagValue(argv, \"--school-query\");\n if (!schoolQuery) {\n throw new CanvasCliError(\n \"MISSING_SCHOOL\",\n \"Non-interactive auth requires --school <query> or --school-url <url>.\"\n );\n }\n\n const matches = searchSchools(schoolQuery, 20);\n if (matches.length === 0) {\n throw new CanvasCliError(\n \"SCHOOL_NOT_FOUND\",\n `No Canvas school matched \"${schoolQuery}\". Use --school-url <url> for a custom Canvas URL.`\n );\n }\n\n const exact = matches.find((school) => {\n return school.name.toLowerCase() === schoolQuery.toLowerCase() || school.url.toLowerCase() === schoolQuery.toLowerCase();\n });\n\n if (exact) {\n return {\n name: exact.name,\n url: normalizeBaseUrl(exact.url)\n };\n }\n\n if (matches.length === 1) {\n const school = matches[0];\n return {\n name: school.name,\n url: normalizeBaseUrl(school.url)\n };\n }\n\n throw new CanvasCliError(\n \"AMBIGUOUS_SCHOOL\",\n `Multiple schools matched \"${schoolQuery}\": ${matches\n .map((school) => `${school.name} (${school.url})`)\n .join(\"; \")}. Use a more specific --school value or --school-url.`\n );\n}\n\nexport async function tokenFromArgs(argv: string[]): Promise<string | undefined> {\n const directToken = flagValue(argv, \"--token\");\n if (directToken) {\n return directToken.trim();\n }\n\n const envName = flagValue(argv, \"--token-env\");\n if (envName) {\n return process.env[envName]?.trim();\n }\n\n if (argv.includes(\"--token-stdin\")) {\n return readStdin().then((value) => value.trim());\n }\n\n return undefined;\n}\n\nexport function tokenSetupForSchool(school: School) {\n const settingsUrl = `${school.url}/profile/settings`;\n const schoolArg = JSON.stringify(school.name);\n return {\n requiresToken: true,\n message: `Open ${school.name}'s Canvas settings, create a new access token with purpose \"${TOKEN_PURPOSE}\", then send the token back so I can finish connecting Canvas.`,\n school: {\n name: school.name,\n baseUrl: school.url,\n settingsUrl\n },\n tokenPurpose: TOKEN_PURPOSE,\n steps: [\n `Open ${settingsUrl}`,\n 'Click \"+ New Access Token\"',\n `Use \"${TOKEN_PURPOSE}\" as the purpose`,\n \"Generate the token and copy it\",\n \"Send the token back, or put it in CANVAS_TOKEN\"\n ],\n nextCommands: {\n directToken: `canvas auth login --school ${schoolArg} --token \"paste-token-here\"`,\n envToken: `CANVAS_TOKEN=\"paste-token-here\" canvas auth login --school ${schoolArg} --token-env CANVAS_TOKEN`,\n stdinToken: `printf '%s' \"paste-token-here\" | canvas auth login --school ${schoolArg} --token-stdin`\n }\n };\n}\n\nasync function promptCustomSchool(io: PromptIO): Promise<School> {\n const name = await io.question(\"School display name: \");\n const url = await io.question(\"Canvas base URL: \");\n return makeCustomSchool(name, url);\n}\n\nfunction hasNonInteractiveLoginArgs(argv: string[]): boolean {\n return Boolean(\n flagValue(argv, \"--school\") ||\n flagValue(argv, \"--school-query\") ||\n flagValue(argv, \"--school-url\") ||\n flagValue(argv, \"--url\")\n );\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nfunction tokenInstructions(school: School, settingsUrl: string): string {\n return `\nLet's connect ${school.name} to Canvas CLI.\n\n1. Open ${settingsUrl}\n2. Click \"+ New Access Token\"\n3. Enter \"${TOKEN_PURPOSE}\" as the purpose\n4. Optionally set an expiration date\n5. Click \"Generate Token\"\n6. Copy the token and paste it back here\n\n`;\n}\n\nasync function validateToken(client: CanvasClient): Promise<{ id?: string; name?: string }> {\n try {\n const response = await client.get<{ id?: string; name?: string; short_name?: string }>(\n \"/api/v1/users/self/profile\"\n );\n return {\n id: response.data.id,\n name: response.data.name ?? response.data.short_name\n };\n } catch (error) {\n if (error instanceof CanvasCliError && error.status === 404) {\n await client.get(\"/api/v1/courses\");\n return {};\n }\n throw error;\n }\n}\n","import { CanvasCliError, toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue, pageOptions, positionalArgs } from \"./shared.js\";\n\ntype QueryValue = string | number | boolean | Array<string | number | boolean> | undefined;\n\nexport async function handleApiCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"get\") {\n return await apiGet(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown api command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function apiGet(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const path = positionalArgs(argv)[0];\n if (!path) {\n throw new Error(\"Usage: canvas api get /api/v1/<path> [--params '<json>'] [--page-all]\");\n }\n if (!path.startsWith(\"/api/v1/\")) {\n throw new CanvasCliError(\"INVALID_API_PATH\", \"Raw API paths must start with /api/v1/.\");\n }\n\n const params = parseParams(flagValue(argv, \"--params\"));\n const { client, profile } = await activeCanvas();\n const response = await client.get(path, {\n query: params,\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data,\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function parseParams(raw: string | undefined): Record<string, QueryValue> {\n if (!raw) {\n return {};\n }\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new CanvasCliError(\"INVALID_PARAMS\", \"--params must be a JSON object.\");\n }\n\n const params: Record<string, QueryValue> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (value === null) {\n continue;\n }\n if (isQueryValue(value)) {\n params[key] = value;\n continue;\n }\n throw new CanvasCliError(\n \"INVALID_PARAMS\",\n `Unsupported query value for ${key}. Use string, number, boolean, or arrays of those.`\n );\n }\n return params;\n}\n\nfunction isQueryValue(value: unknown): value is QueryValue {\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return true;\n }\n if (Array.isArray(value)) {\n return value.every(\n (item) => typeof item === \"string\" || typeof item === \"number\" || typeof item === \"boolean\"\n );\n }\n return value === undefined;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport {\n activeCanvas,\n csvFlag,\n flagValue,\n pageOptions,\n positionalArgs,\n requiredFlag\n} from \"./shared.js\";\n\nexport type CanvasAssignment = {\n id: string | number;\n name?: string;\n description?: string | null;\n due_at?: string | null;\n unlock_at?: string | null;\n lock_at?: string | null;\n points_possible?: number | null;\n grading_type?: string;\n submission_types?: string[];\n allowed_extensions?: string[];\n html_url?: string;\n assignment_group_id?: string | number;\n position?: number;\n published?: boolean;\n muted?: boolean;\n has_submitted_submissions?: boolean;\n locked_for_user?: boolean;\n lock_explanation?: string;\n needs_grading_count?: number;\n all_dates?: unknown[];\n external_tool_tag_attributes?: unknown;\n rubric?: unknown[];\n attachments?: CanvasAttachment[];\n};\n\nexport type CanvasAttachment = {\n id: string | number;\n display_name?: string;\n filename?: string;\n content_type?: string;\n url?: string;\n size?: number;\n};\n\nexport async function handleAssignmentsCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listAssignments(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showAssignment(argv.slice(1), options);\n }\n if (subcommand === \"export\") {\n return await exportAssignment(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown assignments command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listAssignments(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas assignments list --course-id <course-id>\"\n );\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasAssignment[]>(\n `/api/v1/courses/${courseId}/assignments`,\n {\n query: assignmentListQuery(argv),\n ...pageOptions(argv)\n }\n );\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeAssignment),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showAssignment(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas assignments show --course-id <course-id> --assignment-id <assignment-id>\"\n );\n const assignmentId =\n flagValue(argv, \"--assignment-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas assignments show --course-id <course-id> --assignment-id <assignment-id>\");\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasAssignment>(\n `/api/v1/courses/${courseId}/assignments/${assignmentId}`,\n { query: assignmentShowQuery(argv) }\n );\n\n await writeOutput(\n {\n ok: true,\n data: normalizeAssignment(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function exportAssignment(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas assignments export --course-id <course-id> --assignment-id <assignment-id> --out <dir>\"\n );\n const assignmentId =\n flagValue(argv, \"--assignment-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas assignments export --course-id <course-id> --assignment-id <assignment-id> --out <dir>\");\n const outDir = requiredFlag(\n argv,\n \"--out\",\n \"Usage: canvas assignments export --course-id <course-id> --assignment-id <assignment-id> --out <dir>\"\n );\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasAssignment>(\n `/api/v1/courses/${courseId}/assignments/${assignmentId}`,\n { query: { \"include[]\": [\"all_dates\", \"description\", \"submission\"] } }\n );\n const assignment = normalizeAssignment(response.data);\n\n await mkdir(outDir, { recursive: true });\n const jsonPath = join(outDir, `assignment-${assignment.id}.json`);\n const markdownPath = join(outDir, `assignment-${assignment.id}.md`);\n await writeFile(jsonPath, `${JSON.stringify(assignment, null, 2)}\\n`, \"utf8\");\n await writeFile(markdownPath, assignmentMarkdown(assignment), \"utf8\");\n\n await writeOutput(\n {\n ok: true,\n data: {\n assignment,\n written: [\n { path: jsonPath, kind: \"assignment-json\" },\n { path: markdownPath, kind: \"assignment-markdown\" }\n ]\n },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function assignmentListQuery(argv: string[]) {\n return {\n bucket: flagValue(argv, \"--bucket\"),\n search_term: flagValue(argv, \"--search\"),\n order_by: flagValue(argv, \"--order-by\"),\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function assignmentShowQuery(argv: string[]) {\n return {\n \"include[]\": csvFlag(argv, \"--include\") ?? [\"all_dates\", \"description\"]\n };\n}\n\nexport function normalizeAssignment(assignment: CanvasAssignment) {\n return {\n id: String(assignment.id),\n name: assignment.name,\n description: assignment.description,\n dueAt: assignment.due_at,\n unlockAt: assignment.unlock_at,\n lockAt: assignment.lock_at,\n pointsPossible: assignment.points_possible,\n gradingType: assignment.grading_type,\n submissionTypes: assignment.submission_types,\n allowedExtensions: assignment.allowed_extensions,\n htmlUrl: assignment.html_url,\n assignmentGroupId:\n assignment.assignment_group_id === undefined ? undefined : String(assignment.assignment_group_id),\n position: assignment.position,\n published: assignment.published,\n muted: assignment.muted,\n hasSubmittedSubmissions: assignment.has_submitted_submissions,\n lockedForUser: assignment.locked_for_user,\n lockExplanation: assignment.lock_explanation,\n needsGradingCount: assignment.needs_grading_count,\n allDates: assignment.all_dates,\n externalToolTagAttributes: assignment.external_tool_tag_attributes,\n rubric: assignment.rubric,\n attachments: assignment.attachments?.map(normalizeAttachment)\n };\n}\n\nexport function normalizeAttachment(attachment: CanvasAttachment) {\n return {\n id: String(attachment.id),\n displayName: attachment.display_name,\n filename: attachment.filename,\n contentType: attachment.content_type,\n url: attachment.url,\n size: attachment.size\n };\n}\n\nfunction assignmentMarkdown(assignment: ReturnType<typeof normalizeAssignment>): string {\n const lines = [\n `# ${assignment.name ?? `Assignment ${assignment.id}`}`,\n \"\",\n `- id: ${assignment.id}`,\n `- due: ${assignment.dueAt ?? \"none\"}`,\n `- points: ${assignment.pointsPossible ?? \"none\"}`,\n `- html: ${assignment.htmlUrl ?? \"none\"}`,\n \"\",\n \"## Description\",\n \"\",\n assignment.description ?? \"\"\n ];\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { ConfigStore } from \"../core/config-store.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\n\nexport async function handleConfigCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n if (subcommand !== \"show\") {\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown config command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n }\n\n const config = await new ConfigStore().readRedacted();\n await writeOutput(\n {\n ok: true,\n data: config ?? {\n configured: false,\n message: \"No Canvas config found. Run canvas auth login.\"\n },\n meta: {\n command: \"config show\"\n }\n },\n options\n );\n return 0;\n}\n","import { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue, hasFlag, pageOptions, positionalArgs } from \"./shared.js\";\n\nexport type CanvasCourse = {\n id: string;\n name?: string;\n course_code?: string;\n workflow_state?: string;\n enrollment_term_id?: string;\n term?: {\n id?: string;\n name?: string;\n start_at?: string;\n end_at?: string;\n };\n enrollments?: Array<{\n type?: string;\n role?: string;\n enrollment_state?: string;\n }>;\n};\n\nexport async function handleCoursesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listCourses(argv.slice(1), options);\n }\n if (subcommand === \"search\") {\n return await searchCourses(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showCourse(argv.slice(1), options);\n }\n if (subcommand === \"overview\") {\n return await overviewCourse(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown courses command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listCourses(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasCourse[]>(\"/api/v1/courses\", {\n query: courseListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeCourse),\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n}\n\nasync function searchCourses(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const query = positionalArgs(argv).join(\" \").trim();\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasCourse[]>(\"/api/v1/courses\", {\n query: courseListQuery([\"--active\"]),\n pageAll: true\n });\n\n const matches = response.data\n .map(normalizeCourse)\n .filter((course) => {\n const haystack = `${course.name ?? \"\"} ${course.courseCode ?? \"\"}`.toLowerCase();\n return haystack.includes(query.toLowerCase());\n });\n\n await writeOutput(\n {\n ok: true,\n data: matches,\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl,\n query\n }\n },\n options\n );\n return 0;\n}\n\nasync function showCourse(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = positionalArgs(argv)[0];\n if (!courseId) {\n throw new Error(\"Usage: canvas courses show <course-id>\");\n }\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasCourse>(`/api/v1/courses/${courseId}`, {\n query: {\n \"include[]\": [\"term\", \"course_image\", \"total_scores\", \"teachers\"]\n }\n });\n\n await writeOutput(\n {\n ok: true,\n data: normalizeCourse(response.data),\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n}\n\nasync function overviewCourse(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = positionalArgs(argv)[0];\n if (!courseId) {\n throw new Error(\"Usage: canvas courses overview <course-id>\");\n }\n\n const { client, profile } = await activeCanvas();\n const [course, tabs, modules, assignments] = await Promise.all([\n client.get<CanvasCourse>(`/api/v1/courses/${courseId}`, {\n query: { \"include[]\": [\"term\", \"course_image\"] }\n }),\n client.get<Array<{ id: string; label?: string; visibility?: string }>>(\n `/api/v1/courses/${courseId}/tabs`\n ),\n client.get<Array<{ id: string; name?: string; position?: number }>>(\n `/api/v1/courses/${courseId}/modules`,\n { query: { per_page: 100 } }\n ),\n client.get<Array<{ id: string; name?: string; due_at?: string }>>(\n `/api/v1/courses/${courseId}/assignments`,\n { query: { bucket: \"upcoming\", per_page: 20 } }\n )\n ]);\n\n await writeOutput(\n {\n ok: true,\n data: {\n course: normalizeCourse(course.data),\n tabs: tabs.data,\n setup: {\n hasModules: modules.data.length > 0,\n hasAssignments: assignments.data.length > 0,\n hasFilesTab: tabs.data.some((tab) => tab.id === \"files\"),\n isModuleHeavy: modules.data.length > 0\n },\n counts: {\n tabs: tabs.data.length,\n modules: modules.data.length,\n upcomingAssignments: assignments.data.length\n },\n modules: modules.data.map((module) => ({\n id: module.id,\n name: module.name,\n position: module.position\n })),\n upcomingAssignments: assignments.data.map((assignment) => ({\n id: assignment.id,\n name: assignment.name,\n dueAt: assignment.due_at\n }))\n },\n meta: {\n baseUrl: profile.baseUrl,\n request: {\n method: \"GET\",\n path: `/api/v1/courses/${courseId}/overview`\n }\n }\n },\n options\n );\n return 0;\n}\n\nexport function courseListQuery(argv: string[]) {\n return {\n enrollment_state: hasFlag(argv, \"--active\") ? \"active\" : flagValue(argv, \"--enrollment-state\"),\n state: flagValue(argv, \"--state\"),\n per_page: flagValue(argv, \"--page-size\"),\n \"include[]\": [\"term\", \"total_scores\"]\n };\n}\n\nexport function normalizeCourse(course: CanvasCourse) {\n return {\n id: String(course.id),\n name: course.name,\n courseCode: course.course_code,\n workflowState: course.workflow_state,\n enrollmentTermId: course.enrollment_term_id,\n term: course.term\n ? {\n id: course.term.id,\n name: course.term.name,\n startAt: course.term.start_at,\n endAt: course.term.end_at\n }\n : undefined,\n enrollments: course.enrollments?.map((enrollment) => ({\n type: enrollment.type,\n role: enrollment.role,\n state: enrollment.enrollment_state\n }))\n };\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { basename, join, resolve } from \"node:path\";\nimport { CanvasCliError, toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport {\n activeCanvas,\n csvFlag,\n flagValue,\n pageOptions,\n positionalArgs,\n requiredFlag\n} from \"./shared.js\";\n\nexport type CanvasFile = {\n id: string | number;\n uuid?: string;\n folder_id?: string | number;\n display_name?: string;\n filename?: string;\n content_type?: string;\n url?: string;\n size?: number;\n created_at?: string;\n updated_at?: string;\n modified_at?: string;\n unlock_at?: string | null;\n locked?: boolean;\n hidden?: boolean;\n locked_for_user?: boolean;\n lock_explanation?: string;\n thumbnail_url?: string;\n preview_url?: string;\n mime_class?: string;\n};\n\nexport type CanvasFolder = {\n id: string | number;\n name?: string;\n full_name?: string;\n context_id?: string | number;\n context_type?: string;\n parent_folder_id?: string | number | null;\n files_count?: number;\n folders_count?: number;\n position?: number;\n locked?: boolean;\n hidden?: boolean;\n locked_for_user?: boolean;\n for_submissions?: boolean;\n};\n\nexport async function handleFilesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listFiles(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showFile(argv.slice(1), options);\n }\n if (subcommand === \"download\") {\n return await downloadFile(argv.slice(1), options);\n }\n if (subcommand === \"download-linked\") {\n return await downloadLinkedFiles(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown files command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nexport async function handleFoldersCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listFolders(argv.slice(1), options);\n }\n if (subcommand === \"path\") {\n return await folderPath(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown folders command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listFiles(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const path = filesListPath(argv);\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasFile[]>(path, {\n query: filesListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeFile),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showFile(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const fileId =\n flagValue(argv, \"--file-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas files show <file-id>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasFile>(`/api/v1/files/${fileId}`, {\n query: { \"include[]\": csvFlag(argv, \"--include\") }\n });\n\n await writeOutput(\n {\n ok: true,\n data: normalizeFile(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function downloadFile(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const fileId =\n flagValue(argv, \"--file-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas files download <file-id> --out <dir>\");\n const outDir = requiredFlag(argv, \"--out\", \"Usage: canvas files download <file-id> --out <dir>\");\n const { client, profile } = await activeCanvas();\n const fileResponse = await client.get<CanvasFile>(`/api/v1/files/${fileId}`);\n const file = normalizeFile(fileResponse.data);\n if (!file.url) {\n throw new CanvasCliError(\"FILE_URL_UNAVAILABLE\", \"Canvas did not return a download URL for this file.\");\n }\n\n const download = await client.download(file.url);\n const filename = safeFilename(download.filename ?? file.displayName ?? file.filename ?? `file-${file.id}`);\n const filePath = safeJoin(outDir, filename);\n await mkdir(outDir, { recursive: true });\n await writeFile(filePath, download.data);\n\n await writeOutput(\n {\n ok: true,\n data: {\n file,\n written: {\n path: filePath,\n bytes: download.data.byteLength,\n contentType: download.contentType\n }\n },\n meta: { baseUrl: profile.baseUrl, download: download.meta }\n },\n options\n );\n return 0;\n}\n\nasync function downloadLinkedFiles(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas files download-linked --course-id <course-id> --out <dir>\"\n );\n const outDir = requiredFlag(\n argv,\n \"--out\",\n \"Usage: canvas files download-linked --course-id <course-id> --out <dir>\"\n );\n const { client, profile } = await activeCanvas();\n const [moduleItems, assignments] = await Promise.all([\n client.get<Array<{ type?: string; content_id?: string | number; title?: string }>>(\n `/api/v1/courses/${courseId}/modules/items`,\n { query: { per_page: 100 }, pageAll: true }\n ).catch(() => ({ data: [] })),\n client.get<Array<{ attachments?: CanvasFile[] }>>(`/api/v1/courses/${courseId}/assignments`, {\n query: { \"include[]\": [\"description\"], per_page: 100 },\n pageAll: true\n }).catch(() => ({ data: [] }))\n ]);\n\n const ids = new Set<string>();\n for (const item of moduleItems.data) {\n if (item.type === \"File\" && item.content_id !== undefined) {\n ids.add(String(item.content_id));\n }\n }\n for (const assignment of assignments.data) {\n for (const attachment of assignment.attachments ?? []) {\n ids.add(String(attachment.id));\n }\n }\n\n const written: Array<{ id: string; path?: string; error?: string }> = [];\n for (const id of ids) {\n try {\n const fileResponse = await client.get<CanvasFile>(`/api/v1/files/${id}`);\n const file = normalizeFile(fileResponse.data);\n if (!file.url) {\n written.push({ id, error: \"FILE_URL_UNAVAILABLE\" });\n continue;\n }\n const download = await client.download(file.url);\n const filename = safeFilename(download.filename ?? file.displayName ?? file.filename ?? `file-${id}`);\n const filePath = safeJoin(outDir, filename);\n await mkdir(outDir, { recursive: true });\n await writeFile(filePath, download.data);\n written.push({ id, path: filePath });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n written.push({ id, error: message });\n }\n }\n\n await writeOutput(\n {\n ok: true,\n data: { count: ids.size, written },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function listFolders(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas folders list --course-id <course-id>\"\n );\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasFolder[]>(`/api/v1/courses/${courseId}/folders`, {\n query: { per_page: flagValue(argv, \"--page-size\") },\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeFolder),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function folderPath(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas folders path --course-id <course-id> --path <path>\"\n );\n const folderPathValue = requiredFlag(\n argv,\n \"--path\",\n \"Usage: canvas folders path --course-id <course-id> --path <path>\"\n );\n const { client, profile } = await activeCanvas();\n const encodedPath = folderPathValue\n .split(\"/\")\n .filter(Boolean)\n .map(encodeURIComponent)\n .join(\"/\");\n const response = await client.get<CanvasFolder[]>(\n `/api/v1/courses/${courseId}/folders/by_path/${encodedPath}`\n );\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeFolder),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function filesListPath(argv: string[]): string {\n const groupId = flagValue(argv, \"--group-id\");\n if (groupId) {\n return `/api/v1/groups/${groupId}/files`;\n }\n const folderId = flagValue(argv, \"--folder-id\");\n if (folderId) {\n return `/api/v1/folders/${folderId}/files`;\n }\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas files list --course-id <course-id>\");\n return `/api/v1/courses/${courseId}/files`;\n}\n\nexport function filesListQuery(argv: string[]) {\n return {\n search_term: flagValue(argv, \"--search\"),\n sort: flagValue(argv, \"--sort\"),\n \"content_types[]\": csvFlag(argv, \"--content-type\"),\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function normalizeFile(file: CanvasFile) {\n return {\n id: String(file.id),\n uuid: file.uuid,\n folderId: file.folder_id === undefined ? undefined : String(file.folder_id),\n displayName: file.display_name,\n filename: file.filename,\n contentType: file.content_type,\n url: file.url,\n size: file.size,\n createdAt: file.created_at,\n updatedAt: file.updated_at,\n modifiedAt: file.modified_at,\n unlockAt: file.unlock_at,\n locked: file.locked,\n hidden: file.hidden,\n lockedForUser: file.locked_for_user,\n lockExplanation: file.lock_explanation,\n thumbnailUrl: file.thumbnail_url,\n previewUrl: file.preview_url,\n mimeClass: file.mime_class\n };\n}\n\nexport function normalizeFolder(folder: CanvasFolder) {\n return {\n id: String(folder.id),\n name: folder.name,\n fullName: folder.full_name,\n contextId: folder.context_id === undefined ? undefined : String(folder.context_id),\n contextType: folder.context_type,\n parentFolderId: folder.parent_folder_id === undefined ? undefined : String(folder.parent_folder_id),\n filesCount: folder.files_count,\n foldersCount: folder.folders_count,\n position: folder.position,\n locked: folder.locked,\n hidden: folder.hidden,\n lockedForUser: folder.locked_for_user,\n forSubmissions: folder.for_submissions\n };\n}\n\nfunction safeFilename(input: string): string {\n const name = basename(input).replace(/[/:\\\\]/g, \"_\").trim();\n return name || \"canvas-file\";\n}\n\nfunction safeJoin(outDir: string, filename: string): string {\n const base = resolve(outDir);\n const target = resolve(base, filename);\n if (!target.startsWith(`${base}/`) && target !== base) {\n throw new CanvasCliError(\"INVALID_OUTPUT_PATH\", \"Refusing to write outside the output directory.\");\n }\n return target;\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { CanvasClient } from \"../core/canvas-client.js\";\nimport { ConfigStore } from \"../core/config-store.js\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\n\nexport async function handleMeCommand(options: { format: OutputFormat }): Promise<number> {\n try {\n const profile = await new ConfigStore().activeProfile();\n const client = new CanvasClient({\n baseUrl: profile.baseUrl,\n token: profile.token\n });\n const response = await client.get(\"/api/v1/users/self/profile\");\n\n await writeOutput(\n {\n ok: true,\n data: response.data,\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport {\n activeCanvas,\n csvFlag,\n flagValue,\n pageOptions,\n positionalArgs,\n requiredFlag\n} from \"./shared.js\";\n\nexport type CanvasModule = {\n id: string | number;\n name?: string;\n position?: number;\n unlock_at?: string | null;\n require_sequential_progress?: boolean;\n publish_final_grade?: boolean;\n prerequisite_module_ids?: Array<string | number>;\n state?: string;\n completed_at?: string | null;\n items_count?: number;\n items_url?: string;\n items?: CanvasModuleItem[];\n};\n\nexport type CanvasModuleItem = {\n id: string | number;\n module_id?: string | number;\n title?: string;\n type?: string;\n content_id?: string | number;\n position?: number;\n indent?: number;\n page_url?: string;\n external_url?: string;\n html_url?: string;\n url?: string;\n new_tab?: boolean;\n completion_requirement?: unknown;\n content_details?: unknown;\n};\n\nexport async function handleModulesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listModules(argv.slice(1), options);\n }\n if (subcommand === \"items\") {\n return await listModuleItems(argv.slice(1), options);\n }\n if (subcommand === \"item\") {\n return await showModuleItem(argv.slice(1), options);\n }\n if (subcommand === \"export\") {\n return await exportModule(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown modules command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listModules(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas modules list --course-id <course-id>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasModule[]>(`/api/v1/courses/${courseId}/modules`, {\n query: moduleListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeModule),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function listModuleItems(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas modules items --course-id <course-id> --module-id <module-id>\"\n );\n const moduleId = requiredFlag(\n argv,\n \"--module-id\",\n \"Usage: canvas modules items --course-id <course-id> --module-id <module-id>\"\n );\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasModuleItem[]>(\n `/api/v1/courses/${courseId}/modules/${moduleId}/items`,\n {\n query: moduleItemsQuery(argv),\n ...pageOptions(argv)\n }\n );\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeModuleItem),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showModuleItem(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas modules item --course-id <course-id> --module-id <module-id> --item-id <item-id>\"\n );\n const moduleId = requiredFlag(\n argv,\n \"--module-id\",\n \"Usage: canvas modules item --course-id <course-id> --module-id <module-id> --item-id <item-id>\"\n );\n const itemId =\n flagValue(argv, \"--item-id\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas modules item --course-id <course-id> --module-id <module-id> --item-id <item-id>\");\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasModuleItem>(\n `/api/v1/courses/${courseId}/modules/${moduleId}/items/${itemId}`,\n { query: moduleItemsQuery(argv) }\n );\n\n await writeOutput(\n {\n ok: true,\n data: normalizeModuleItem(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function exportModule(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas modules export --course-id <course-id> --module-id <module-id> --out <dir>\"\n );\n const moduleId = requiredFlag(\n argv,\n \"--module-id\",\n \"Usage: canvas modules export --course-id <course-id> --module-id <module-id> --out <dir>\"\n );\n const outDir = requiredFlag(\n argv,\n \"--out\",\n \"Usage: canvas modules export --course-id <course-id> --module-id <module-id> --out <dir>\"\n );\n\n const { client, profile } = await activeCanvas();\n const [moduleResponse, itemsResponse] = await Promise.all([\n client.get<CanvasModule>(`/api/v1/courses/${courseId}/modules/${moduleId}`),\n client.get<CanvasModuleItem[]>(`/api/v1/courses/${courseId}/modules/${moduleId}/items`, {\n query: { \"include[]\": [\"content_details\"], per_page: 100 },\n pageAll: true\n })\n ]);\n const moduleData = normalizeModule({ ...moduleResponse.data, items: itemsResponse.data });\n\n await mkdir(outDir, { recursive: true });\n const filePath = join(outDir, `module-${moduleData.id}.json`);\n await writeFile(filePath, `${JSON.stringify(moduleData, null, 2)}\\n`, \"utf8\");\n\n await writeOutput(\n {\n ok: true,\n data: { module: moduleData, written: [{ path: filePath, kind: \"module-json\" }] },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function moduleListQuery(argv: string[]) {\n return {\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function moduleItemsQuery(argv: string[]) {\n return {\n \"include[]\": csvFlag(argv, \"--include\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function normalizeModule(module: CanvasModule) {\n return {\n id: String(module.id),\n name: module.name,\n position: module.position,\n state: module.state,\n unlockAt: module.unlock_at,\n completedAt: module.completed_at,\n requireSequentialProgress: module.require_sequential_progress,\n publishFinalGrade: module.publish_final_grade,\n prerequisiteModuleIds: module.prerequisite_module_ids?.map(String),\n itemsCount: module.items_count,\n itemsUrl: module.items_url,\n items: module.items?.map(normalizeModuleItem)\n };\n}\n\nexport function normalizeModuleItem(item: CanvasModuleItem) {\n return {\n id: String(item.id),\n moduleId: item.module_id === undefined ? undefined : String(item.module_id),\n title: item.title,\n type: item.type,\n contentId: item.content_id === undefined ? undefined : String(item.content_id),\n position: item.position,\n indent: item.indent,\n pageUrl: item.page_url,\n externalUrl: item.external_url,\n htmlUrl: item.html_url,\n apiUrl: item.url,\n newTab: item.new_tab,\n completionRequirement: item.completion_requirement,\n contentDetails: item.content_details\n };\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue, pageOptions, positionalArgs, requiredFlag } from \"./shared.js\";\n\nexport type CanvasPage = {\n page_id?: string | number;\n url: string;\n title?: string;\n created_at?: string;\n updated_at?: string;\n editing_roles?: string;\n last_edited_by?: unknown;\n body?: string;\n published?: boolean;\n hide_from_students?: boolean;\n front_page?: boolean;\n html_url?: string;\n locked_for_user?: boolean;\n lock_info?: unknown;\n lock_explanation?: string;\n};\n\nexport async function handlePagesCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"list\") {\n return await listPages(argv.slice(1), options);\n }\n if (subcommand === \"show\") {\n return await showPage(argv.slice(1), options);\n }\n if (subcommand === \"export\") {\n return await exportPage(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown pages command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function listPages(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas pages list --course-id <course-id>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasPage[]>(`/api/v1/courses/${courseId}/pages`, {\n query: pagesListQuery(argv),\n ...pageOptions(argv)\n });\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizePage),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function showPage(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(argv, \"--course-id\", \"Usage: canvas pages show --course-id <course-id> --page <url>\");\n const pageUrl =\n flagValue(argv, \"--page\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas pages show --course-id <course-id> --page <url>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasPage>(\n `/api/v1/courses/${courseId}/pages/${encodeURIComponent(pageUrl)}`\n );\n\n await writeOutput(\n {\n ok: true,\n data: normalizePage(response.data),\n meta: { ...response.meta, baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nasync function exportPage(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas pages export --course-id <course-id> --page <url> --out <dir>\"\n );\n const pageUrl =\n flagValue(argv, \"--page\") ??\n positionalArgs(argv)[0] ??\n missing(\"Usage: canvas pages export --course-id <course-id> --page <url> --out <dir>\");\n const outDir = requiredFlag(argv, \"--out\", \"Usage: canvas pages export --course-id <course-id> --page <url> --out <dir>\");\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasPage>(\n `/api/v1/courses/${courseId}/pages/${encodeURIComponent(pageUrl)}`\n );\n const page = normalizePage(response.data);\n await mkdir(outDir, { recursive: true });\n const jsonPath = join(outDir, `${page.url}.json`);\n const htmlPath = join(outDir, `${page.url}.html`);\n await writeFile(jsonPath, `${JSON.stringify(page, null, 2)}\\n`, \"utf8\");\n await writeFile(htmlPath, page.body ?? \"\", \"utf8\");\n\n await writeOutput(\n {\n ok: true,\n data: {\n page,\n written: [\n { path: jsonPath, kind: \"page-json\" },\n { path: htmlPath, kind: \"page-html\" }\n ]\n },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n\nexport function pagesListQuery(argv: string[]) {\n return {\n sort: flagValue(argv, \"--sort\"),\n search_term: flagValue(argv, \"--search\"),\n per_page: flagValue(argv, \"--page-size\")\n };\n}\n\nexport function normalizePage(page: CanvasPage) {\n return {\n id: page.page_id === undefined ? undefined : String(page.page_id),\n url: page.url,\n title: page.title,\n createdAt: page.created_at,\n updatedAt: page.updated_at,\n editingRoles: page.editing_roles,\n lastEditedBy: page.last_edited_by,\n body: page.body,\n published: page.published,\n hideFromStudents: page.hide_from_students,\n frontPage: page.front_page,\n htmlUrl: page.html_url,\n lockedForUser: page.locked_for_user,\n lockInfo: page.lock_info,\n lockExplanation: page.lock_explanation\n };\n}\n\nfunction missing(message: string): never {\n throw new Error(message);\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { normalizeAssignment, type CanvasAssignment } from \"./assignments.js\";\nimport { normalizeCourse, type CanvasCourse } from \"./courses.js\";\nimport { normalizeFile, type CanvasFile } from \"./files.js\";\nimport { normalizeModule, type CanvasModule } from \"./modules.js\";\nimport { normalizePage, type CanvasPage } from \"./pages.js\";\nimport { activeCanvas, hasFlag, requiredFlag } from \"./shared.js\";\nimport { normalizeTab, type CanvasTab } from \"./tabs.js\";\n\nexport async function handleReviewCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (subcommand === \"pack\") {\n return await reviewPack(argv.slice(1), options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown review command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function reviewPack(argv: string[], options: { format: OutputFormat }): Promise<number> {\n const courseId = requiredFlag(\n argv,\n \"--course-id\",\n \"Usage: canvas review pack --course-id <course-id> --out <dir>\"\n );\n const outDir = requiredFlag(argv, \"--out\", \"Usage: canvas review pack --course-id <course-id> --out <dir>\");\n const includeAllFiles = hasFlag(argv, \"--include-all-files\");\n\n const { client, profile } = await activeCanvas();\n const [course, tabs, modules, assignments, pages, files] = await Promise.all([\n client.get<CanvasCourse>(`/api/v1/courses/${courseId}`, {\n query: { \"include[]\": [\"term\", \"course_image\"] }\n }),\n client.get<CanvasTab[]>(`/api/v1/courses/${courseId}/tabs`).catch(() => ({ data: [] })),\n client\n .get<CanvasModule[]>(`/api/v1/courses/${courseId}/modules`, {\n query: { \"include[]\": [\"items\", \"content_details\"], per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] })),\n client\n .get<CanvasAssignment[]>(`/api/v1/courses/${courseId}/assignments`, {\n query: { per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] })),\n client\n .get<CanvasPage[]>(`/api/v1/courses/${courseId}/pages`, {\n query: { per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] })),\n includeAllFiles\n ? client\n .get<CanvasFile[]>(`/api/v1/courses/${courseId}/files`, {\n query: { per_page: 100 },\n pageAll: true\n })\n .catch(() => ({ data: [] }))\n : Promise.resolve({ data: [] })\n ]);\n\n const pack = {\n generatedAt: new Date().toISOString(),\n baseUrl: profile.baseUrl,\n course: normalizeCourse(course.data),\n tabs: tabs.data.map(normalizeTab),\n modules: modules.data.map(normalizeModule),\n assignments: assignments.data.map(normalizeAssignment),\n pages: pages.data.map(normalizePage),\n files: files.data.map(normalizeFile),\n notes: [\n \"This review pack preserves Canvas IDs and visible course structure.\",\n includeAllFiles\n ? \"All visible course files metadata was included; file bytes are not downloaded by this command yet.\"\n : \"All-files metadata is omitted by default. Re-run with --include-all-files to include visible file metadata.\"\n ]\n };\n\n await mkdir(outDir, { recursive: true });\n const manifestPath = join(outDir, \"manifest.json\");\n const coursePath = join(outDir, \"course.json\");\n const modulesPath = join(outDir, \"modules.json\");\n const assignmentsPath = join(outDir, \"assignments.json\");\n const pagesPath = join(outDir, \"pages.json\");\n await Promise.all([\n writeFile(manifestPath, `${JSON.stringify(pack, null, 2)}\\n`, \"utf8\"),\n writeFile(coursePath, `${JSON.stringify(pack.course, null, 2)}\\n`, \"utf8\"),\n writeFile(modulesPath, `${JSON.stringify(pack.modules, null, 2)}\\n`, \"utf8\"),\n writeFile(assignmentsPath, `${JSON.stringify(pack.assignments, null, 2)}\\n`, \"utf8\"),\n writeFile(pagesPath, `${JSON.stringify(pack.pages, null, 2)}\\n`, \"utf8\")\n ]);\n\n await writeOutput(\n {\n ok: true,\n data: {\n course: pack.course,\n counts: {\n tabs: pack.tabs.length,\n modules: pack.modules.length,\n assignments: pack.assignments.length,\n pages: pack.pages.length,\n files: pack.files.length\n },\n written: [\n { path: manifestPath, kind: \"manifest\" },\n { path: coursePath, kind: \"course-json\" },\n { path: modulesPath, kind: \"modules-json\" },\n { path: assignmentsPath, kind: \"assignments-json\" },\n { path: pagesPath, kind: \"pages-json\" }\n ]\n },\n meta: { baseUrl: profile.baseUrl }\n },\n options\n );\n return 0;\n}\n","import { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { activeCanvas, flagValue } from \"./shared.js\";\n\nexport type CanvasTab = {\n id: string;\n html_url?: string;\n full_url?: string;\n position?: number;\n label?: string;\n type?: string;\n hidden?: boolean;\n visibility?: string;\n};\n\nexport async function handleTabsCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n if (subcommand !== \"list\") {\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown tabs command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n }\n\n try {\n const courseId = flagValue(argv, \"--course-id\");\n if (!courseId) {\n throw new Error(\"Usage: canvas tabs list --course-id <course-id>\");\n }\n\n const { client, profile } = await activeCanvas();\n const response = await client.get<CanvasTab[]>(`/api/v1/courses/${courseId}/tabs`);\n\n await writeOutput(\n {\n ok: true,\n data: response.data.map(normalizeTab),\n meta: {\n ...response.meta,\n baseUrl: profile.baseUrl\n }\n },\n options\n );\n return 0;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nexport function normalizeTab(tab: CanvasTab) {\n return {\n id: tab.id,\n label: tab.label,\n type: tab.type,\n position: tab.position,\n hidden: tab.hidden,\n visibility: tab.visibility,\n htmlUrl: tab.html_url,\n fullUrl: tab.full_url\n };\n}\n","import { spawn } from \"node:child_process\";\nimport { toErrorEnvelope } from \"../core/errors.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { writeOutput } from \"../core/output.js\";\nimport { hasFlag } from \"./shared.js\";\n\nexport const SKILLS_INSTALL_COMMAND = [\n \"npx\",\n \"skills\",\n \"add\",\n \"lukeguo12210/canvas-cli\",\n \"-g\",\n \"--skill\",\n \"*\",\n \"-y\"\n] as const;\n\nexport const SKILLS_INSTALL_DISPLAY_COMMAND = 'npx skills add lukeguo12210/canvas-cli -g --skill \"*\" -y';\n\nexport async function handleSkillsCommand(\n argv: string[],\n options: { format: OutputFormat }\n): Promise<number> {\n const [subcommand] = argv;\n\n try {\n if (!subcommand || subcommand === \"--help\" || subcommand === \"-h\" || subcommand === \"help\") {\n process.stdout.write(skillsHelpText());\n return 0;\n }\n if (subcommand === \"install\") {\n return await installSkills(argv.slice(1), options);\n }\n if (subcommand === \"command\") {\n return await printSkillsCommand(options);\n }\n if (subcommand === \"status\") {\n return await skillsStatus(options);\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown skills command: ${argv.join(\" \")}`,\n retryable: false\n }\n },\n options\n );\n return 1;\n } catch (error) {\n await writeOutput(toErrorEnvelope(error), options);\n return 1;\n }\n}\n\nasync function installSkills(argv: string[], options: { format: OutputFormat }): Promise<number> {\n if (hasFlag(argv, \"--dry-run\") || hasFlag(argv, \"--print\")) {\n return printSkillsCommand(options);\n }\n\n const code = await run(SKILLS_INSTALL_COMMAND[0], SKILLS_INSTALL_COMMAND.slice(1));\n if (code !== 0) {\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"SKILLS_INSTALL_FAILED\",\n message: `Skills installer exited with code ${code}. Try: ${SKILLS_INSTALL_DISPLAY_COMMAND}`,\n retryable: true\n }\n },\n options\n );\n return code;\n }\n\n await writeOutput(\n {\n ok: true,\n data: {\n installed: true,\n command: SKILLS_INSTALL_DISPLAY_COMMAND,\n next: \"Restart or reload your agent so it can discover the updated Canvas skills.\"\n },\n meta: {\n command: \"skills install\"\n }\n },\n options\n );\n return 0;\n}\n\nasync function printSkillsCommand(options: { format: OutputFormat }): Promise<number> {\n await writeOutput(\n {\n ok: true,\n data: {\n command: SKILLS_INSTALL_DISPLAY_COMMAND,\n note: \"Run this to install or update all Canvas agent skills from GitHub.\"\n },\n meta: {\n command: \"skills command\"\n }\n },\n options\n );\n return 0;\n}\n\nasync function skillsStatus(options: { format: OutputFormat }): Promise<number> {\n await writeOutput(\n {\n ok: true,\n data: {\n installCommand: SKILLS_INSTALL_DISPLAY_COMMAND,\n skills: [\n \"canvas-shared\",\n \"canvas-courses\",\n \"canvas-modules\",\n \"canvas-pages\",\n \"canvas-files\",\n \"canvas-assignments\",\n \"canvas-review\"\n ],\n note: \"Use canvas skills install to install/update these skills.\"\n },\n meta: {\n command: \"skills status\"\n }\n },\n options\n );\n return 0;\n}\n\nfunction run(command: string, args: readonly string[]): Promise<number> {\n return new Promise((resolve) => {\n const child = spawn(command, [...args], {\n stdio: \"inherit\",\n shell: process.platform === \"win32\"\n });\n child.on(\"close\", (code) => resolve(code ?? 1));\n child.on(\"error\", () => resolve(1));\n });\n}\n\nexport function skillsHelpText(): string {\n return `canvas skills — install and inspect Canvas agent skills.\n\nUSAGE:\n canvas skills <command> [options]\n\nCOMMANDS:\n install Install or update all Canvas agent skills\n install --dry-run Print the install command without running it\n command Print the direct npx skills install command\n status Show bundled skill names and install command\n\nALIASES:\n canvas install-skills\n\nDIRECT INSTALLER:\n ${SKILLS_INSTALL_DISPLAY_COMMAND}\n`;\n}\n","import { writeOutput } from \"../core/output.js\";\nimport type { OutputFormat } from \"../core/output.js\";\nimport { handleAuthCommand } from \"../commands/auth.js\";\nimport { handleApiCommand } from \"../commands/api.js\";\nimport { handleAssignmentsCommand } from \"../commands/assignments.js\";\nimport { handleConfigCommand } from \"../commands/config.js\";\nimport { handleCoursesCommand } from \"../commands/courses.js\";\nimport { handleFilesCommand, handleFoldersCommand } from \"../commands/files.js\";\nimport { handleMeCommand } from \"../commands/me.js\";\nimport { handleModulesCommand } from \"../commands/modules.js\";\nimport { handlePagesCommand } from \"../commands/pages.js\";\nimport { handleReviewCommand } from \"../commands/review.js\";\nimport { handleSkillsCommand } from \"../commands/skills.js\";\nimport { handleTabsCommand } from \"../commands/tabs.js\";\n\nconst VERSION = \"0.0.8\";\n\nfunction helpText(): string {\n return `canvas — Canvas LMS CLI for students and agents.\n\nUSAGE:\n canvas <command> [options]\n\nCOMMANDS:\n auth login Interactive Canvas PAT setup\n auth status Show redacted auth status\n auth schools Search supported Canvas school URLs\n auth logout Remove local Canvas auth config\n config show Show redacted local config\n me Show current Canvas user profile\n courses list List active Canvas courses\n courses overview Summarize course setup\n tabs list List course tabs\n modules list List course modules\n modules items List module items\n assignments list List course assignments\n pages list List course pages\n files list List course files\n folders list List course folders\n review pack Create a local course review pack\n api get Raw read-only Canvas API GET\n skills install Install/update bundled agent skills\n install-skills Alias for skills install\n version Print CLI version\n\nFLAGS:\n -h, --help Show help\n --format <fmt> Output format: json | pretty | table | ndjson\n\nMVP STATUS:\n Read-only student commands are available for auth, courses, tabs, modules,\n assignments, pages, files, folders, review packs, and raw GET.\n`;\n}\n\nasync function main(argv: string[]): Promise<number> {\n const parsed = parseGlobalOptions(argv);\n const [command] = parsed.argv;\n\n if (!command || command === \"--help\" || command === \"-h\" || command === \"help\") {\n process.stdout.write(helpText());\n return 0;\n }\n\n if (command === \"version\" || command === \"--version\" || command === \"-v\") {\n await writeOutput(\n {\n ok: true,\n data: { version: VERSION },\n meta: { command: \"version\" }\n },\n { format: parsed.format === \"json\" ? \"json\" : \"pretty\" }\n );\n return 0;\n }\n\n if (command === \"auth\") {\n return handleAuthCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"config\") {\n return handleConfigCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"me\") {\n return handleMeCommand({ format: parsed.format });\n }\n\n if (command === \"courses\") {\n return handleCoursesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"tabs\") {\n return handleTabsCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"modules\") {\n return handleModulesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"assignments\") {\n return handleAssignmentsCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"pages\") {\n return handlePagesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"files\") {\n return handleFilesCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"folders\") {\n return handleFoldersCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"review\") {\n return handleReviewCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"api\") {\n return handleApiCommand(parsed.argv.slice(1), { format: parsed.format });\n }\n\n if (command === \"skills\" || command === \"install-skills\") {\n const skillsArgv = command === \"install-skills\" ? [\"install\", ...parsed.argv.slice(1)] : parsed.argv.slice(1);\n return handleSkillsCommand(skillsArgv, { format: parsed.format });\n }\n\n await writeOutput(\n {\n ok: false,\n error: {\n code: \"UNKNOWN_COMMAND\",\n message: `Unknown command: ${parsed.argv.join(\" \")}`,\n retryable: false\n }\n },\n { format: parsed.format }\n );\n return 1;\n}\n\nfunction parseGlobalOptions(argv: string[]): { argv: string[]; format: OutputFormat } {\n const nextArgv: string[] = [];\n let format: OutputFormat = \"json\";\n\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === \"--format\") {\n const value = argv[index + 1];\n if (isOutputFormat(value)) {\n format = value;\n index += 1;\n continue;\n }\n }\n nextArgv.push(arg);\n }\n\n return { argv: nextArgv, format };\n}\n\nfunction isOutputFormat(value: string | undefined): value is OutputFormat {\n return value === \"json\" || value === \"pretty\" || value === \"table\" || value === \"ndjson\";\n}\n\nmain(process.argv.slice(2))\n .then((code) => {\n process.exitCode = code;\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`canvas: ${message}\\n`);\n process.exitCode = 1;\n });\n"],"mappings":"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","names":["output","output","path","input","resolve","school","path","mkdir","writeFile","mkdir","writeFile","mkdir","writeFile","path","missing","mkdir","writeFile","input","mkdir","writeFile","join","missing","mkdir","join","writeFile","mkdir","writeFile","join","missing","mkdir","join","writeFile","mkdir","writeFile","join","mkdir","join","writeFile","spawn","resolve","spawn"]}
|
package/package.json
CHANGED
|
@@ -20,6 +20,7 @@ Before using this skill, read `../canvas-shared/SKILL.md`.
|
|
|
20
20
|
- `canvas context show` is planned but not implemented yet. Until it exists, use `canvas courses list --active --page-all`.
|
|
21
21
|
- Use tabs to understand whether the course is module-heavy, assignment-heavy, file-heavy, or page-heavy.
|
|
22
22
|
- For "pull this class" or "help me study", switch to `canvas-review` and use `canvas review pack`.
|
|
23
|
+
- For "what am I learning", inspect `courses overview`, then independently probe visible/likely surfaces such as modules, assignments, pages, and files. Continue if one optional surface returns `CANVAS_NOT_FOUND`.
|
|
23
24
|
|
|
24
25
|
## Commands
|
|
25
26
|
|
|
@@ -100,6 +101,16 @@ Tabs help agents infer course structure:
|
|
|
100
101
|
- `pages` or `wiki`: course may use pages outside modules.
|
|
101
102
|
- external tool tabs should be linked but not scraped.
|
|
102
103
|
|
|
104
|
+
Do not run optional probes as one `&&` chain. Prefer separate calls:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
canvas pages list --course-id <course-id> --format json
|
|
108
|
+
canvas files list --course-id <course-id> --format json
|
|
109
|
+
canvas assignments list --course-id <course-id> --page-all --format json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If one returns `CANVAS_NOT_FOUND`, say that surface is unavailable and continue with the others.
|
|
113
|
+
|
|
103
114
|
## Output Notes
|
|
104
115
|
|
|
105
116
|
Course names can be school-specific, abbreviated, or nicknamed. Preserve Canvas IDs in summaries.
|
|
@@ -39,3 +39,4 @@ canvas folders path --course-id <course-id> --path <path> --format json
|
|
|
39
39
|
- `files download` writes one file to the requested output directory.
|
|
40
40
|
- `files download-linked` currently downloads file IDs discoverable from module file items and assignment attachments when Canvas exposes them.
|
|
41
41
|
- Folder commands are separate top-level commands: use `canvas folders ...`, not `canvas files folders ...`.
|
|
42
|
+
- Do not skip file checks just because pages or modules are unavailable. Run `canvas files list` as its own command.
|
|
@@ -26,3 +26,4 @@ canvas pages export --course-id <course-id> --page <page-url> --out <dir> --form
|
|
|
26
26
|
- Canvas page identifiers are usually URL slugs such as `syllabus`, not numeric IDs.
|
|
27
27
|
- Page bodies are Canvas HTML. Preserve the original HTML in exports.
|
|
28
28
|
- Locked pages should be reported as locked, not treated as fatal when traversing a whole course.
|
|
29
|
+
- `CANVAS_NOT_FOUND` from `pages list` often means the course does not expose Canvas Pages. Treat it as "pages unavailable" and continue checking modules, assignments, files, or tabs.
|
|
@@ -84,12 +84,16 @@ Planned but not implemented yet:
|
|
|
84
84
|
## Core Rules
|
|
85
85
|
|
|
86
86
|
- Use `canvas auth status` first if auth state is uncertain.
|
|
87
|
-
- If no auth config exists, use `canvas auth schools search <query
|
|
88
|
-
-
|
|
87
|
+
- If no auth config exists, use `canvas auth schools search <query>`.
|
|
88
|
+
- If the user has not provided a PAT yet, run `canvas auth login --school <query>` to get a friendly token setup response. Show the user the Canvas base URL, settings URL, and token purpose `canvas-cli`.
|
|
89
|
+
- Once the user provides a PAT, run `canvas auth login --school <query> --token <token>` or `canvas auth login --school <query> --token-env <env>`.
|
|
90
|
+
- If the user provides a PAT in chat, use it directly with `canvas auth login --school <query> --token <token>`.
|
|
89
91
|
- Default output is JSON and should be preferred for agents.
|
|
90
92
|
- Use `--format pretty` only when presenting a compact human-facing result.
|
|
91
93
|
- Use `--page-all` when completeness matters.
|
|
92
94
|
- Canvas pagination follows `Link` headers; do not synthesize next-page URLs.
|
|
95
|
+
- Treat optional course surfaces independently. Pages, Files, Modules, Assignments, and external tools may be hidden or disabled per course.
|
|
96
|
+
- Do not chain optional probes with `&&`; a `CANVAS_NOT_FOUND` from one surface should not stop the next probe.
|
|
93
97
|
- MVP cannot write to Canvas.
|
|
94
98
|
- Do not pretend planned commands exist. If a command is marked planned, say it is not implemented yet.
|
|
95
99
|
|
|
@@ -4,6 +4,7 @@ Implemented auth commands:
|
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
canvas auth login
|
|
7
|
+
canvas auth login --school "Berkeley"
|
|
7
8
|
canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
|
|
8
9
|
canvas auth login --school-url https://courseworks2.columbia.edu --school-name "Columbia University (CourseWorks)" --token "paste-token-here"
|
|
9
10
|
canvas auth schools search "Columbia" --format json
|
|
@@ -33,33 +34,48 @@ Do not attempt `sudo npm install -g` from inside an agent session. Prefer the fa
|
|
|
33
34
|
|
|
34
35
|
## Agent Login Flow
|
|
35
36
|
|
|
36
|
-
Agents can complete login non-interactively
|
|
37
|
+
Agents can guide and complete login non-interactively.
|
|
37
38
|
|
|
38
39
|
1. Search schools:
|
|
39
40
|
|
|
40
41
|
```bash
|
|
41
|
-
canvas auth schools search "
|
|
42
|
+
canvas auth schools search "Berkeley" --format json
|
|
42
43
|
```
|
|
43
44
|
|
|
44
|
-
2.
|
|
45
|
+
2. If the user has not provided a PAT yet, get a friendly token setup response:
|
|
45
46
|
|
|
46
47
|
```bash
|
|
47
|
-
canvas auth login --school "
|
|
48
|
+
canvas auth login --school "Berkeley" --format json
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
Show the user:
|
|
52
|
+
|
|
53
|
+
- Canvas URL: `school.baseUrl`
|
|
54
|
+
- Token page: `school.settingsUrl`
|
|
55
|
+
- Token purpose: `canvas-cli`
|
|
56
|
+
- The steps returned by the command
|
|
57
|
+
|
|
58
|
+
Tell the user to open the settings URL, create a new access token with purpose `canvas-cli`, then send the token back.
|
|
59
|
+
|
|
60
|
+
3. Finish login once the user provides a token:
|
|
51
61
|
|
|
52
62
|
```bash
|
|
53
|
-
canvas auth login --school "
|
|
63
|
+
canvas auth login --school "Berkeley" --token "paste-token-here"
|
|
54
64
|
```
|
|
55
65
|
|
|
56
|
-
|
|
66
|
+
or:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
canvas auth login --school "Berkeley" --token-env CANVAS_TOKEN
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
4. For a custom Canvas URL:
|
|
57
73
|
|
|
58
74
|
```bash
|
|
59
75
|
canvas auth login --school-url https://courseworks2.columbia.edu --school-name "Columbia University (CourseWorks)" --token-env CANVAS_TOKEN
|
|
60
76
|
```
|
|
61
77
|
|
|
62
|
-
|
|
78
|
+
5. Verify:
|
|
63
79
|
|
|
64
80
|
```bash
|
|
65
81
|
canvas auth status --format json
|
|
@@ -97,14 +113,13 @@ The CLI supports agent-provided PATs for initial setup:
|
|
|
97
113
|
- `--token-env <ENV_NAME>`: read token from an environment variable.
|
|
98
114
|
- `--token-stdin`: read token from stdin.
|
|
99
115
|
|
|
100
|
-
|
|
116
|
+
If the user pastes a PAT into chat, use it directly to complete login:
|
|
101
117
|
|
|
102
|
-
|
|
118
|
+
```bash
|
|
119
|
+
canvas auth login --school "Berkeley" --token "paste-token-here"
|
|
120
|
+
```
|
|
103
121
|
|
|
104
|
-
|
|
105
|
-
- `Authorization` headers
|
|
106
|
-
- bearer tokens
|
|
107
|
-
- query params named `token`, `access_token`, `api_key`, `verifier`, or `code`
|
|
122
|
+
After login, continue with `canvas auth status --format json` and course discovery.
|
|
108
123
|
|
|
109
124
|
## Auth Status
|
|
110
125
|
|
|
@@ -43,4 +43,4 @@ Use JSON for reasoning and tool chaining. Use pretty only when the user wants a
|
|
|
43
43
|
|
|
44
44
|
## Redaction
|
|
45
45
|
|
|
46
|
-
The CLI redacts token-like values from output.
|
|
46
|
+
The CLI redacts token-like values from output. If the user provides a Canvas PAT during auth setup, use it with `canvas auth login --token`.
|