@lukeguo12210/canvas-cli 0.0.3 → 0.0.4

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
@@ -8,6 +8,10 @@ Connect Canvas courses to AI agents.
8
8
 
9
9
  [Install](#installation--quick-start) · [Agent Skills](#agent-skills) · [Auth](#authentication) · [Commands](#command-system) · [Security](#security--privacy) · [License](#license) · [Roadmap](#roadmap)
10
10
 
11
+ ## Star History
12
+
13
+ [![Star History Chart](https://api.star-history.com/svg?repos=lukeguo12210/canvas-cli&type=Date)](https://www.star-history.com/#lukeguo12210/canvas-cli&Date)
14
+
11
15
  ## Why @lukeguo12210/canvas-cli?
12
16
 
13
17
  - **Built for technical students** — bring Canvas into your terminal, scripts, and AI workflow.
@@ -74,6 +78,10 @@ npm install -g @lukeguo12210/canvas-cli
74
78
  # 1. Authenticate with your Canvas school
75
79
  canvas auth login
76
80
 
81
+ # Agent/non-interactive auth
82
+ canvas auth schools search "Columbia"
83
+ canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
84
+
77
85
  # 2. List courses
78
86
  canvas courses list
79
87
 
@@ -137,6 +145,9 @@ canvas review pack --course-id <course-id> --out ./review/<course> --include-all
137
145
 
138
146
  ```bash
139
147
  canvas auth login
148
+ canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
149
+ canvas auth login --school-url https://courseworks2.columbia.edu --school-name "Columbia University (CourseWorks)" --token "paste-token-here"
150
+ canvas auth schools search "Columbia"
140
151
  canvas auth status
141
152
  canvas auth logout
142
153
  canvas config show
@@ -519,16 +519,112 @@ async function runPostLoginBootstrap() {
519
519
  };
520
520
  }
521
521
 
522
+ // src/commands/shared.ts
523
+ async function activeCanvas() {
524
+ const profile = await new ConfigStore().activeProfile();
525
+ return {
526
+ profile,
527
+ client: new CanvasClient({
528
+ baseUrl: profile.baseUrl,
529
+ token: profile.token
530
+ })
531
+ };
532
+ }
533
+ function flagValue(argv, flag) {
534
+ const index = argv.indexOf(flag);
535
+ if (index === -1) {
536
+ return void 0;
537
+ }
538
+ return argv[index + 1];
539
+ }
540
+ function requiredFlag(argv, flag, usage) {
541
+ const value = flagValue(argv, flag);
542
+ if (!value) {
543
+ throw new Error(usage);
544
+ }
545
+ return value;
546
+ }
547
+ function hasFlag(argv, flag) {
548
+ return argv.includes(flag);
549
+ }
550
+ function csvFlag(argv, flag) {
551
+ const raw = flagValue(argv, flag);
552
+ if (!raw) {
553
+ return void 0;
554
+ }
555
+ const values = raw.split(",").map((value) => value.trim()).filter(Boolean);
556
+ return values.length > 0 ? values : void 0;
557
+ }
558
+ function pageOptions(argv) {
559
+ const pageLimitRaw = flagValue(argv, "--page-limit");
560
+ return {
561
+ pageAll: hasFlag(argv, "--page-all"),
562
+ pageLimit: pageLimitRaw ? Number.parseInt(pageLimitRaw, 10) : void 0
563
+ };
564
+ }
565
+ function positionalArgs(argv) {
566
+ const valueFlags = /* @__PURE__ */ new Set([
567
+ "--course-id",
568
+ "--module-id",
569
+ "--item-id",
570
+ "--assignment-id",
571
+ "--quiz-id",
572
+ "--topic-id",
573
+ "--page",
574
+ "--path",
575
+ "--out",
576
+ "--format",
577
+ "--page-limit",
578
+ "--page-size",
579
+ "--page-delay",
580
+ "--enrollment-state",
581
+ "--state",
582
+ "--include",
583
+ "--params",
584
+ "--bucket",
585
+ "--search",
586
+ "--order-by",
587
+ "--sort",
588
+ "--file-id",
589
+ "--folder-id",
590
+ "--group-id",
591
+ "--content-type",
592
+ "--school",
593
+ "--school-query",
594
+ "--school-url",
595
+ "--url",
596
+ "--school-name",
597
+ "--name",
598
+ "--token",
599
+ "--token-env"
600
+ ]);
601
+ const values = [];
602
+ for (let index = 0; index < argv.length; index += 1) {
603
+ const arg = argv[index];
604
+ if (arg.startsWith("--")) {
605
+ if (valueFlags.has(arg)) {
606
+ index += 1;
607
+ }
608
+ continue;
609
+ }
610
+ values.push(arg);
611
+ }
612
+ return values;
613
+ }
614
+
522
615
  // src/commands/auth.ts
523
616
  var TOKEN_PURPOSE = "Hyperknow";
524
617
  async function handleAuthCommand(argv, options) {
525
618
  const [subcommand] = argv;
526
619
  if (subcommand === "login") {
527
- return authLogin(options);
620
+ return authLogin(argv.slice(1), options);
528
621
  }
529
622
  if (subcommand === "status") {
530
623
  return authStatus(options);
531
624
  }
625
+ if (subcommand === "schools") {
626
+ return authSchools(argv.slice(1), options);
627
+ }
532
628
  if (subcommand === "logout") {
533
629
  return authLogout(options);
534
630
  }
@@ -545,16 +641,21 @@ async function handleAuthCommand(argv, options) {
545
641
  );
546
642
  return 1;
547
643
  }
548
- async function authLogin(options) {
644
+ async function authLogin(argv, options) {
549
645
  const io = createPrompt();
550
646
  try {
551
- const school = await chooseSchool(io);
647
+ const nonInteractive = hasNonInteractiveLoginArgs(argv);
648
+ const school = nonInteractive ? resolveSchoolFromArgs(argv) : await chooseSchool(io);
552
649
  const settingsUrl = `${school.url}/profile/settings`;
553
- process.stdout.write(tokenInstructions(school, settingsUrl));
554
- await io.question("Press Enter to open Canvas settings in your browser...");
555
- await openBrowser(settingsUrl);
556
- process.stdout.write("\nWaiting for your Canvas personal access token.\n");
557
- const token = await promptHidden("Paste token: ");
650
+ const providedToken = await tokenFromArgs(argv);
651
+ let token = providedToken;
652
+ if (!token) {
653
+ process.stdout.write(tokenInstructions(school, settingsUrl));
654
+ await io.question("Press Enter to open Canvas settings in your browser...");
655
+ await openBrowser(settingsUrl);
656
+ process.stdout.write("\nWaiting for your Canvas personal access token.\n");
657
+ token = await promptHidden("Paste token: ");
658
+ }
558
659
  if (!token) {
559
660
  throw new CanvasCliError("EMPTY_TOKEN", "No token entered.");
560
661
  }
@@ -588,7 +689,7 @@ async function authLogin(options) {
588
689
  },
589
690
  user,
590
691
  contextBootstrap: bootstrap,
591
- next: "canvas context show"
692
+ next: "canvas courses list --active --page-all"
592
693
  },
593
694
  meta: {
594
695
  command: "auth login"
@@ -604,6 +705,25 @@ async function authLogin(options) {
604
705
  io.close();
605
706
  }
606
707
  }
708
+ async function authSchools(argv, options) {
709
+ const [subcommand] = argv;
710
+ const query = subcommand === "search" ? positionalArgs(argv.slice(1)).join(" ") : flagValue(argv, "--query") ?? positionalArgs(argv).join(" ");
711
+ await writeOutput(
712
+ {
713
+ ok: true,
714
+ data: searchSchools(query).map((school) => ({
715
+ name: school.name,
716
+ baseUrl: school.url
717
+ })),
718
+ meta: {
719
+ command: "auth schools",
720
+ query
721
+ }
722
+ },
723
+ options
724
+ );
725
+ return 0;
726
+ }
607
727
  async function authStatus(options) {
608
728
  const store = new ConfigStore();
609
729
  const config = await store.readRedacted();
@@ -694,11 +814,77 @@ async function chooseSchool(io, write = (message) => process.stdout.write(messag
694
814
  url: normalizeBaseUrl(school.url)
695
815
  };
696
816
  }
817
+ function resolveSchoolFromArgs(argv) {
818
+ const schoolUrl = flagValue(argv, "--school-url") ?? flagValue(argv, "--url");
819
+ if (schoolUrl) {
820
+ return makeCustomSchool(flagValue(argv, "--school-name") ?? flagValue(argv, "--name") ?? "Custom Canvas School", schoolUrl);
821
+ }
822
+ const schoolQuery = flagValue(argv, "--school") ?? flagValue(argv, "--school-query");
823
+ if (!schoolQuery) {
824
+ throw new CanvasCliError(
825
+ "MISSING_SCHOOL",
826
+ "Non-interactive auth requires --school <query> or --school-url <url>."
827
+ );
828
+ }
829
+ const matches = searchSchools(schoolQuery, 20);
830
+ if (matches.length === 0) {
831
+ throw new CanvasCliError(
832
+ "SCHOOL_NOT_FOUND",
833
+ `No Canvas school matched "${schoolQuery}". Use --school-url <url> for a custom Canvas URL.`
834
+ );
835
+ }
836
+ const exact = matches.find((school) => {
837
+ return school.name.toLowerCase() === schoolQuery.toLowerCase() || school.url.toLowerCase() === schoolQuery.toLowerCase();
838
+ });
839
+ if (exact) {
840
+ return {
841
+ name: exact.name,
842
+ url: normalizeBaseUrl(exact.url)
843
+ };
844
+ }
845
+ if (matches.length === 1) {
846
+ const school = matches[0];
847
+ return {
848
+ name: school.name,
849
+ url: normalizeBaseUrl(school.url)
850
+ };
851
+ }
852
+ throw new CanvasCliError(
853
+ "AMBIGUOUS_SCHOOL",
854
+ `Multiple schools matched "${schoolQuery}": ${matches.map((school) => `${school.name} (${school.url})`).join("; ")}. Use a more specific --school value or --school-url.`
855
+ );
856
+ }
857
+ async function tokenFromArgs(argv) {
858
+ const directToken = flagValue(argv, "--token");
859
+ if (directToken) {
860
+ return directToken.trim();
861
+ }
862
+ const envName = flagValue(argv, "--token-env");
863
+ if (envName) {
864
+ return process.env[envName]?.trim();
865
+ }
866
+ if (argv.includes("--token-stdin")) {
867
+ return readStdin().then((value) => value.trim());
868
+ }
869
+ return void 0;
870
+ }
697
871
  async function promptCustomSchool(io) {
698
872
  const name = await io.question("School display name: ");
699
873
  const url = await io.question("Canvas base URL: ");
700
874
  return makeCustomSchool(name, url);
701
875
  }
876
+ function hasNonInteractiveLoginArgs(argv) {
877
+ return Boolean(
878
+ flagValue(argv, "--school") || flagValue(argv, "--school-query") || flagValue(argv, "--school-url") || flagValue(argv, "--url")
879
+ );
880
+ }
881
+ async function readStdin() {
882
+ const chunks = [];
883
+ for await (const chunk of process.stdin) {
884
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
885
+ }
886
+ return Buffer.concat(chunks).toString("utf8");
887
+ }
702
888
  function tokenInstructions(school, settingsUrl) {
703
889
  return `
704
890
  Canvas token setup for ${school.name}
@@ -730,91 +916,6 @@ async function validateToken(client) {
730
916
  }
731
917
  }
732
918
 
733
- // src/commands/shared.ts
734
- async function activeCanvas() {
735
- const profile = await new ConfigStore().activeProfile();
736
- return {
737
- profile,
738
- client: new CanvasClient({
739
- baseUrl: profile.baseUrl,
740
- token: profile.token
741
- })
742
- };
743
- }
744
- function flagValue(argv, flag) {
745
- const index = argv.indexOf(flag);
746
- if (index === -1) {
747
- return void 0;
748
- }
749
- return argv[index + 1];
750
- }
751
- function requiredFlag(argv, flag, usage) {
752
- const value = flagValue(argv, flag);
753
- if (!value) {
754
- throw new Error(usage);
755
- }
756
- return value;
757
- }
758
- function hasFlag(argv, flag) {
759
- return argv.includes(flag);
760
- }
761
- function csvFlag(argv, flag) {
762
- const raw = flagValue(argv, flag);
763
- if (!raw) {
764
- return void 0;
765
- }
766
- const values = raw.split(",").map((value) => value.trim()).filter(Boolean);
767
- return values.length > 0 ? values : void 0;
768
- }
769
- function pageOptions(argv) {
770
- const pageLimitRaw = flagValue(argv, "--page-limit");
771
- return {
772
- pageAll: hasFlag(argv, "--page-all"),
773
- pageLimit: pageLimitRaw ? Number.parseInt(pageLimitRaw, 10) : void 0
774
- };
775
- }
776
- function positionalArgs(argv) {
777
- const valueFlags = /* @__PURE__ */ new Set([
778
- "--course-id",
779
- "--module-id",
780
- "--item-id",
781
- "--assignment-id",
782
- "--quiz-id",
783
- "--topic-id",
784
- "--page",
785
- "--path",
786
- "--out",
787
- "--format",
788
- "--page-limit",
789
- "--page-size",
790
- "--page-delay",
791
- "--enrollment-state",
792
- "--state",
793
- "--include",
794
- "--params",
795
- "--bucket",
796
- "--search",
797
- "--order-by",
798
- "--sort",
799
- "--file-id",
800
- "--folder-id",
801
- "--group-id",
802
- "--content-type"
803
- ]);
804
- const values = [];
805
- for (let index = 0; index < argv.length; index += 1) {
806
- const arg = argv[index];
807
- if (arg.startsWith("--")) {
808
- if (valueFlags.has(arg)) {
809
- index += 1;
810
- }
811
- continue;
812
- }
813
- values.push(arg);
814
- }
815
- return values;
816
- }
817
-
818
919
  // src/commands/api.ts
819
920
  async function handleApiCommand(argv, options) {
820
921
  const [subcommand] = argv;
@@ -2154,7 +2255,7 @@ async function reviewPack(argv, options) {
2154
2255
  }
2155
2256
 
2156
2257
  // src/bin/canvas.ts
2157
- var VERSION = "0.0.3";
2258
+ var VERSION = "0.0.4";
2158
2259
  function helpText() {
2159
2260
  return `canvas \u2014 Canvas LMS CLI for students and agents.
2160
2261
 
@@ -2164,6 +2265,7 @@ USAGE:
2164
2265
  COMMANDS:
2165
2266
  auth login Interactive Canvas PAT setup
2166
2267
  auth status Show redacted auth status
2268
+ auth schools Search supported Canvas school URLs
2167
2269
  auth logout Remove local Canvas auth config
2168
2270
  config show Show redacted local config
2169
2271
  me Show current Canvas user profile
@@ -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/auth.ts","../../src/commands/shared.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/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, 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\";\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(options);\n }\n\n if (subcommand === \"status\") {\n return authStatus(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(options: { format: OutputFormat }): Promise<number> {\n const io = createPrompt();\n\n try {\n const school = await chooseSchool(io);\n const settingsUrl = `${school.url}/profile/settings`;\n\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\n const token = await promptHidden(\"Paste token: \");\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 context show\"\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 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\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 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 { 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 ]);\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 { 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 { 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 { handleTabsCommand } from \"../commands/tabs.js\";\n\nconst VERSION = \"0.0.3\";\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 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 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 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"]}
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/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 { 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 { handleTabsCommand } from \"../commands/tabs.js\";\n\nconst VERSION = \"0.0.4\";\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 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 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukeguo12210/canvas-cli",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
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": {
@@ -48,6 +48,7 @@ Implemented now:
48
48
 
49
49
  - `canvas auth login`
50
50
  - `canvas auth status`
51
+ - `canvas auth schools search <query>`
51
52
  - `canvas auth logout`
52
53
  - `canvas config show`
53
54
  - `canvas me`
@@ -72,8 +73,8 @@ Planned but not implemented yet:
72
73
  ## Core Rules
73
74
 
74
75
  - Use `canvas auth status` first if auth state is uncertain.
75
- - If no auth config exists, ask the user to run `canvas auth login`.
76
- - Never print, paste, summarize, or expose a Canvas personal access token.
76
+ - 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.
77
+ - Never print, paste, summarize, or expose a Canvas personal access token after receiving it.
77
78
  - Default output is JSON and should be preferred for agents.
78
79
  - Use `--format pretty` only when presenting a compact human-facing result.
79
80
  - Use `--page-all` when completeness matters.
@@ -112,6 +113,7 @@ Do not include those in review packs unless the user explicitly asks.
112
113
 
113
114
  ```bash
114
115
  canvas auth status --format json
116
+ canvas auth schools search "Columbia" --format json
115
117
  canvas courses list --active --page-all --format json
116
118
  canvas courses search "course name" --format json
117
119
  canvas courses overview <course-id> --format json
@@ -4,6 +4,9 @@ Implemented auth commands:
4
4
 
5
5
  ```bash
6
6
  canvas auth login
7
+ canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
8
+ canvas auth login --school-url https://courseworks2.columbia.edu --school-name "Columbia University (CourseWorks)" --token "paste-token-here"
9
+ canvas auth schools search "Columbia" --format json
7
10
  canvas auth status --format json
8
11
  canvas auth logout
9
12
  canvas config show --format json
@@ -15,11 +18,49 @@ If `canvas` is not on `PATH`, use the npm exec fallback:
15
18
  ```bash
16
19
  npm exec --yes --package @lukeguo12210/canvas-cli -- canvas auth status --format json
17
20
  npm exec --yes --package @lukeguo12210/canvas-cli -- canvas auth login
21
+ npm exec --yes --package @lukeguo12210/canvas-cli -- canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
18
22
  ```
19
23
 
20
24
  Do not attempt `sudo npm install -g` from inside an agent session. Prefer the fallback above or ask the user to fix their npm global prefix.
21
25
 
22
- ## Login Flow
26
+ ## Agent Login Flow
27
+
28
+ Agents can complete login non-interactively when the user explicitly provides a Canvas PAT.
29
+
30
+ 1. Search schools:
31
+
32
+ ```bash
33
+ canvas auth schools search "Columbia" --format json
34
+ ```
35
+
36
+ 2. Login with a known school match:
37
+
38
+ ```bash
39
+ canvas auth login --school "Columbia" --token-env CANVAS_TOKEN
40
+ ```
41
+
42
+ or, if the user provides the token directly in chat:
43
+
44
+ ```bash
45
+ canvas auth login --school "Columbia" --token "paste-token-here"
46
+ ```
47
+
48
+ 3. For a custom Canvas URL:
49
+
50
+ ```bash
51
+ canvas auth login --school-url https://courseworks2.columbia.edu --school-name "Columbia University (CourseWorks)" --token-env CANVAS_TOKEN
52
+ ```
53
+
54
+ 4. Verify:
55
+
56
+ ```bash
57
+ canvas auth status --format json
58
+ canvas courses list --active --page-all --format json
59
+ ```
60
+
61
+ If `--school` matches multiple schools, run `canvas auth schools search <query>` and retry with a more specific value or use `--school-url`.
62
+
63
+ ## Interactive Login Flow
23
64
 
24
65
  `canvas auth login` is interactive.
25
66
 
@@ -40,9 +81,15 @@ Is this your school: Columbia University (CourseWorks) (https://courseworks2.col
40
81
  8. Validate token.
41
82
  9. Store local config.
42
83
 
43
- ## Token Safety
84
+ ## Token Handling
85
+
86
+ The CLI supports agent-provided PATs for initial setup:
87
+
88
+ - `--token <PAT>`: direct token argument.
89
+ - `--token-env <ENV_NAME>`: read token from an environment variable.
90
+ - `--token-stdin`: read token from stdin.
44
91
 
45
- Never ask the user to paste a token into chat. The token should be pasted into the local terminal prompt from `canvas auth login`.
92
+ 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.
46
93
 
47
94
  Never print:
48
95