@learning-with-court/cli 0.1.0 → 0.1.1

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
@@ -4,17 +4,14 @@ CLI for the learning-with-court platform. Two modes:
4
4
 
5
5
  1. **Stdio MCP proxy** (default): forwards tool calls from a local agent to
6
6
  the hosted MCP server at `mcp.workshop.institute`. Auth resolves via env
7
- var (`LWC_TOKEN`) → cached `~/.lwc/token.json` → browser OAuth (PKCE).
7
+ var (`LWC_TOKEN`) → cached `~/.lwc/token.json` → browser sign-in.
8
8
  2. **Subcommands** for one-shot operations:
9
9
  - `setup <workshop-id> [--dir <path>]` — clone a workshop project
10
- repo (default: `~/learning-with-court/<workshop-id>/`) after Clerk
11
- sign-in. Pass `--dir` to install somewhere else; the CLI auto-creates
12
- parent directories.
10
+ repo (default: `~/learning-with-court/<workshop-id>/`). Pass `--dir`
11
+ to install somewhere else; the CLI auto-creates parent directories.
13
12
  - `refresh <workshop-id>` — refresh the clone token and `git pull`.
14
13
  - `auth login` / `auth logout` — manual control of the cached token.
15
14
 
16
- Modeled on `mixcraft-app/packages/mcp-proxy`.
17
-
18
15
  ## Usage
19
16
 
20
17
  ```sh
@@ -28,8 +25,34 @@ npx -y @learning-with-court/cli@latest setup mcp-workshop --dir ~/workshops/mcp-
28
25
  npx -y @learning-with-court/cli@latest
29
26
  ```
30
27
 
28
+ ## Auth flow
29
+
30
+ `lwc auth login` (and any subcommand that needs a token) runs an
31
+ authorization-code + PKCE flow against `workshop.institute`:
32
+
33
+ 1. The CLI starts a loopback server on an ephemeral localhost port and
34
+ opens `https://workshop.institute/cli-auth?...` with a PKCE challenge
35
+ and random state.
36
+ 2. You sign in (if needed) and click **Authorize**.
37
+ 3. The browser redirects to `http://localhost:<port>/callback?code=...`,
38
+ the CLI exchanges the code at `mcp.workshop.institute/cli/token`,
39
+ and caches the resulting JWT.
40
+
41
+ Tokens are RS256 JWTs signed by an AWS KMS key; the public key is
42
+ published at `https://mcp.workshop.institute/.well-known/jwks.json`.
43
+ Lifetime: 90 days. After expiry, re-run `lwc auth login`.
44
+
45
+ ### Environment overrides
46
+
47
+ - `LWC_TOKEN` — bypass the cache and use this token directly.
48
+ - `LWC_API_URL` — point at a different MCP API origin (default
49
+ `https://mcp.workshop.institute`).
50
+ - `LWC_LANDING_URL` — override the browser-side landing origin (default
51
+ is derived from `LWC_API_URL`: `mcp.` and `mcp-` prefixes are
52
+ stripped, so `mcp-dev.workshop.institute` → `dev.workshop.institute`).
53
+
31
54
  ## Token storage
32
55
 
33
- `~/.lwc/token.json`, mode `0600`. Contains the Clerk OAuth access token,
34
- refresh token, and expiry. Delete the file or run `lwc auth logout` to
56
+ `~/.lwc/token.json`, mode `0600`. Contains the JWT, expiry, and the
57
+ opaque user identifier. Delete the file or run `lwc auth logout` to
35
58
  revoke locally.
@@ -1,5 +1,6 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
+ import { spawnSync } from 'node:child_process';
3
4
  import { resolveBearerToken } from '../auth/resolve-token.js';
4
5
  import { callRemoteTool, parseStructured } from '../proxy/call-tool.js';
5
6
  import { ensureGitInstalled, git, cleanRemoteUrl } from '../git.js';
@@ -48,11 +49,52 @@ export async function runSetup(opts) {
48
49
  path: dest,
49
50
  installedAt: new Date().toISOString(),
50
51
  });
52
+ installDeps(dest);
51
53
  console.error('');
52
54
  console.error(`Done. Open the workshop:`);
53
55
  console.error(` cd ${dest}`);
54
56
  console.error(`Then start your coding agent (Claude Code, Cursor, Codex, etc.).`);
55
57
  }
58
+ /**
59
+ * Run the workshop's package install if a package.json is present, so the
60
+ * learner can run verify scripts immediately without a "node_modules is
61
+ * missing" prompt on first session start. Picks pnpm/npm/yarn from the
62
+ * lockfile present at the dest. If no lockfile, defaults to pnpm. If the
63
+ * required package manager isn't installed, surfaces a hint and continues
64
+ * — clone is still useful, the learner can install themselves.
65
+ */
66
+ function installDeps(dest) {
67
+ if (!fs.existsSync(path.join(dest, 'package.json'))) {
68
+ return;
69
+ }
70
+ const has = (f) => fs.existsSync(path.join(dest, f));
71
+ const tool = has('pnpm-lock.yaml')
72
+ ? 'pnpm'
73
+ : has('yarn.lock')
74
+ ? 'yarn'
75
+ : has('package-lock.json')
76
+ ? 'npm'
77
+ : 'pnpm';
78
+ step(`Installing dependencies (${tool} install)`);
79
+ const proc = spawnSync(tool, ['install'], {
80
+ cwd: dest,
81
+ stdio: 'inherit',
82
+ shell: process.platform === 'win32',
83
+ });
84
+ if (proc.error) {
85
+ if (proc.error.code === 'ENOENT') {
86
+ console.error(` Note: ${tool} is not installed; skipped dependency install. ` +
87
+ `Run '${tool} install' in ${dest} before starting the workshop.`);
88
+ return;
89
+ }
90
+ console.error(` Note: ${tool} install errored — ${proc.error.message}`);
91
+ return;
92
+ }
93
+ if (proc.status !== 0) {
94
+ console.error(` Note: ${tool} install exited ${proc.status}. ` +
95
+ `Re-run it manually in ${dest} if needed.`);
96
+ }
97
+ }
56
98
  /**
57
99
  * Per-phase progress line. Plain ASCII so it renders identically in TTY,
58
100
  * piped output, log files, and CI capture — no spinner, no Unicode, no
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learning-with-court/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI for learning-with-court — proxies MCP and bootstraps workshop projects.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",