@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 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
- Personal access tokens are for local/self use. Do not paste tokens into hosted apps or share them with other users.
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 and must never be printed.
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.
@@ -613,9 +613,13 @@ function positionalArgs(argv) {
613
613
  }
614
614
 
615
615
  // src/commands/auth.ts
616
- var TOKEN_PURPOSE = "Hyperknow";
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
- Canvas token setup for ${school.name}
960
+ Let's connect ${school.name} to Canvas CLI.
891
961
 
892
- 1. Go to ${settingsUrl}
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.6";
2480
+ var VERSION = "0.0.8";
2411
2481
  function helpText() {
2412
2482
  return `canvas \u2014 Canvas LMS CLI for students and agents.
2413
2483
 
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukeguo12210/canvas-cli",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Connect Canvas courses to AI agents: pull modules, files, assignments, pages, folders, and review packs without manual downloads.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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>` and then `canvas auth login --school <query> --token-env <env>` or `canvas auth login --school <query> --token <token>` when the user explicitly provides a PAT.
88
- - Never print, paste, summarize, or expose a Canvas personal access token after receiving it.
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 when the user explicitly provides a Canvas PAT.
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 "Columbia" --format json
42
+ canvas auth schools search "Berkeley" --format json
42
43
  ```
43
44
 
44
- 2. Login with a known school match:
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 "Columbia" --token-env CANVAS_TOKEN
48
+ canvas auth login --school "Berkeley" --format json
48
49
  ```
49
50
 
50
- or, if the user provides the token directly in chat:
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 "Columbia" --token "paste-token-here"
63
+ canvas auth login --school "Berkeley" --token "paste-token-here"
54
64
  ```
55
65
 
56
- 3. For a custom Canvas URL:
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
- 4. Verify:
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
- Prefer `--token-env` or `--token-stdin` when possible. If the user pastes a PAT into chat, use it only for `canvas auth login`, then do not repeat, print, summarize, or store it anywhere except the Canvas config written by the CLI.
116
+ If the user pastes a PAT into chat, use it directly to complete login:
101
117
 
102
- Never print:
118
+ ```bash
119
+ canvas auth login --school "Berkeley" --token "paste-token-here"
120
+ ```
103
121
 
104
- - PAT values
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. Agents must still avoid asking users to paste tokens into chat.
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`.