cselab 0.2.0__tar.gz

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.
Files changed (53) hide show
  1. cselab-0.2.0/.gitignore +8 -0
  2. cselab-0.2.0/CLAUDE.md +54 -0
  3. cselab-0.2.0/LICENSE +21 -0
  4. cselab-0.2.0/PKG-INFO +467 -0
  5. cselab-0.2.0/README.md +446 -0
  6. cselab-0.2.0/README_CN.md +199 -0
  7. cselab-0.2.0/assets/demo-hero.gif +0 -0
  8. cselab-0.2.0/assets/demo-hero.mp4 +0 -0
  9. cselab-0.2.0/assets/demo-hero.tape +139 -0
  10. cselab-0.2.0/assets/demo-repl.gif +0 -0
  11. cselab-0.2.0/assets/demo-repl.mp4 +0 -0
  12. cselab-0.2.0/assets/demo-repl.tape +31 -0
  13. cselab-0.2.0/assets/demo-typing.gif +0 -0
  14. cselab-0.2.0/assets/demo-typing.mp4 +0 -0
  15. cselab-0.2.0/assets/demo-typing.tape +37 -0
  16. cselab-0.2.0/assets/fake-autotest.sh +27 -0
  17. cselab-0.2.0/assets/fake-repl-autotest.sh +38 -0
  18. cselab-0.2.0/assets/fake-repl-bye.sh +6 -0
  19. cselab-0.2.0/assets/fake-repl-cmd.sh +32 -0
  20. cselab-0.2.0/assets/fake-repl-demo.sh +148 -0
  21. cselab-0.2.0/assets/fake-repl-hello.sh +18 -0
  22. cselab-0.2.0/assets/fake-repl-startup.sh +33 -0
  23. cselab-0.2.0/assets/fake-repl.sh +43 -0
  24. cselab-0.2.0/assets/render-banner.py +23 -0
  25. cselab-0.2.0/docs/brand-guide.md +145 -0
  26. cselab-0.2.0/docs/deployment.md +140 -0
  27. cselab-0.2.0/docs/index.html +664 -0
  28. cselab-0.2.0/docs/plans/2026-03-10-repl-mode-design.md +570 -0
  29. cselab-0.2.0/examples/autotest.sh +19 -0
  30. cselab-0.2.0/examples/submit.sh +20 -0
  31. cselab-0.2.0/examples/watch-test.sh +14 -0
  32. cselab-0.2.0/install.sh +77 -0
  33. cselab-0.2.0/pyproject.toml +36 -0
  34. cselab-0.2.0/skills/AGENTS.md +57 -0
  35. cselab-0.2.0/skills/GEMINI.md +27 -0
  36. cselab-0.2.0/skills/cselab.md +191 -0
  37. cselab-0.2.0/src/cselab/__init__.py +1 -0
  38. cselab-0.2.0/src/cselab/__main__.py +10 -0
  39. cselab-0.2.0/src/cselab/assets/zap-default.png +0 -0
  40. cselab-0.2.0/src/cselab/banner.py +44 -0
  41. cselab-0.2.0/src/cselab/cli.py +385 -0
  42. cselab-0.2.0/src/cselab/config.py +112 -0
  43. cselab-0.2.0/src/cselab/connection.py +229 -0
  44. cselab-0.2.0/src/cselab/mascot.py +100 -0
  45. cselab-0.2.0/src/cselab/repl.py +321 -0
  46. cselab-0.2.0/src/cselab/theme.py +44 -0
  47. cselab-0.2.0/task.json +173 -0
  48. cselab-0.2.0/tests/__init__.py +0 -0
  49. cselab-0.2.0/tests/test_cli.py +286 -0
  50. cselab-0.2.0/tests/test_config.py +209 -0
  51. cselab-0.2.0/tests/test_connection.py +328 -0
  52. cselab-0.2.0/tests/test_mascot.py +151 -0
  53. cselab-0.2.0/tests/test_repl.py +207 -0
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ dist/
4
+ build/
5
+ *.pyc
6
+ .eggs/
7
+ .claude-flow/
8
+ .swarm/
cselab-0.2.0/CLAUDE.md ADDED
@@ -0,0 +1,54 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## What This Is
6
+
7
+ cselab is a Python CLI that lets UNSW CSE students run server commands (`autotest`, `give`, etc.) from their local machine. It syncs files via rsync and executes remotely via SSH ControlMaster — no manual SSH or file copying needed.
8
+
9
+ ## Build & Run
10
+
11
+ ```bash
12
+ pip install -e . # editable install
13
+ cselab --version # verify
14
+ cselab init --user z5555555 # setup config
15
+ cselab run "echo hello" # test
16
+ ```
17
+
18
+ Build system is hatchling. No test suite yet. No linter configured.
19
+
20
+ ## Architecture
21
+
22
+ Modules in `src/cselab/`, one dependency (`prompt-toolkit>=3.0` for rich REPL UI, optional `tomli` for Python <3.11):
23
+
24
+ **`connection.py`** — SSH/rsync transport layer
25
+ - `connect()` starts an SSH ControlMaster (`ssh -fNM`) with ControlPersist=1800s
26
+ - Password auth uses a temp SSH_ASKPASS script (written to `/tmp/cselab_askpass_*`, cleaned up in finally block)
27
+ - `rsync_up/rsync_down` pass `-e "ssh <control-args>"` so rsync reuses the ControlMaster socket
28
+ - rsync respects `.gitignore` via `--filter=:- .gitignore`
29
+ - Socket path: `/tmp/cselab-{user}@{host}-{port}`
30
+
31
+ **`config.py`** — TOML config at `~/.config/cselab/config.toml`
32
+ - `Config` dataclass holds all settings
33
+ - `remote_workspace()` generates a deterministic remote path from MD5 of the local cwd: `~/.cselab/workspaces/{dirname}-{hash12}`
34
+ - Supports password auth (SSH_ASKPASS) and key auth (`-i`)
35
+
36
+ **`cli.py`** — 9 subcommands, all follow the same pattern: `load_config() → connect() → do_work()`
37
+ - `run` is the main command: connect → rsync_up → ssh_exec (3-step with timing output)
38
+ - `watch` uses fswatch on macOS (preferred) with polling fallback
39
+ - Lazy imports (`from cselab.connection import ...` inside functions) keep `--help` fast
40
+
41
+ ## Key Design Decisions
42
+
43
+ - **SSH ControlMaster over libssh2**: persistent socket means 0ms reconnect on subsequent commands
44
+ - **rsync over SFTP**: delta compression, .gitignore support, `--delete` keeps remote clean
45
+ - **SSH_ASKPASS trick**: password auth without interactive TTY — creates temp script, sets `SSH_ASKPASS_REQUIRE=force`, connects with `stdin=DEVNULL`
46
+ - **No dependencies**: runs on stock Python 3.10+ with system ssh/rsync (pre-installed on macOS/Linux)
47
+
48
+ ## Remote File Layout
49
+
50
+ On the CSE server, cselab creates:
51
+ ```
52
+ ~/.cselab/workspaces/{dirname}-{md5_12char}/
53
+ ```
54
+ Each local directory maps to a unique remote workspace. `cselab clean` removes all of them.
cselab-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Steven Cai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
cselab-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,467 @@
1
+ Metadata-Version: 2.4
2
+ Name: cselab
3
+ Version: 0.2.0
4
+ Summary: Run UNSW CSE commands locally with fast sync and interactive support
5
+ Project-URL: Repository, https://github.com/Genius-Cai/cselab
6
+ Project-URL: Homepage, https://github.com/Genius-Cai/cselab
7
+ Project-URL: Bug Tracker, https://github.com/Genius-Cai/cselab/issues
8
+ Author: Steven Cai
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: autotest,cse,ssh,unsw
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Education
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: prompt-toolkit>=3.0
20
+ Description-Content-Type: text/markdown
21
+
22
+ <div align="center">
23
+
24
+ # cselab
25
+
26
+ **Run UNSW CSE commands from your local machine — fast, reliable, interactive.**
27
+
28
+ <p>
29
+ <img src="https://img.shields.io/pypi/v/cselab?color=blue&label=PyPI" alt="PyPI version" />
30
+ <img src="https://img.shields.io/badge/Python-3.10+-blue?logo=python&logoColor=white" alt="Python 3.10+" />
31
+ <img src="https://img.shields.io/badge/License-MIT-yellow" alt="MIT License" />
32
+ <img src="https://img.shields.io/badge/SSH-ControlMaster-orange" alt="SSH ControlMaster" />
33
+ <img src="https://img.shields.io/badge/Sync-rsync-green" alt="rsync" />
34
+ </p>
35
+
36
+ English | [简体中文](README_CN.md)
37
+
38
+ [Features](#why-cselab) · [Comparison](#comparison-with-other-approaches) · [Quick Start](#quick-start) · [For CSE Staff](#for-cse-staff--administrators) · [AI Integration](#ai-platform-integration)
39
+
40
+ <!-- TODO: Replace with actual GIF recording (use `vhs` or OBS) -->
41
+ <!-- <p><img src="assets/demo.gif" alt="cselab demo — autotest in one command" width="700" /></p> -->
42
+ <pre>
43
+ $ cselab run "1521 autotest"
44
+ [1/3] Connecting to cse.unsw.edu.au... OK (0.0s)
45
+ [2/3] Syncing files... OK (0.2s)
46
+ [3/3] Running: 1521 autotest
47
+ ========================================
48
+ Test 1 - ... passed
49
+ Test 2 - ... passed
50
+ All tests passed!
51
+ ========================================
52
+ Exit: OK
53
+ </pre>
54
+
55
+ </div>
56
+
57
+ ---
58
+
59
+ ## Why cselab?
60
+
61
+ UNSW CSE students must run `autotest`, `give`, and other course commands on the CSE server (`cse.unsw.edu.au`). The typical workflow is:
62
+
63
+ 1. SSH into CSE server
64
+ 2. Edit code there (or manually copy files back and forth)
65
+ 3. Run the command
66
+ 4. Repeat
67
+
68
+ This is painful. You lose your local editor, extensions, and tools. Or you waste time copying files manually.
69
+
70
+ **cselab lets you write code locally and run CSE commands as if you were on the server.** One command syncs your files and executes remotely — your local VS Code / Vim stays untouched.
71
+
72
+ ## How It Works
73
+
74
+ ```
75
+ Local Machine (your laptop) CSE Server
76
+ ┌─────────────────────────┐ ┌──────────────────────┐
77
+ │ │ 1. SSH │ │
78
+ │ ~/COMP1521/lab01/ │──────────────│ ControlMaster │
79
+ │ hello.c │ (once) │ (persistent conn) │
80
+ │ Makefile │ │ │
81
+ │ │ 2. rsync │ ~/.cselab/ │
82
+ │ │──────────────│ workspaces/ │
83
+ │ │ (delta) │ lab01-a3f2/ │
84
+ │ │ │ hello.c │
85
+ │ │ 3. ssh │ Makefile │
86
+ │ │──────────────│ │
87
+ │ │ (exec) │ $ 1521 autotest │
88
+ │ │ │ │
89
+ │ Terminal: │ 4. output │ │
90
+ │ ✅ All tests passed │◄─────────────│ │
91
+ │ │ (stream) │ │
92
+ └─────────────────────────┘ └──────────────────────┘
93
+ ```
94
+
95
+ ### Step-by-step flow
96
+
97
+ When you run `cselab run "1521 autotest"`:
98
+
99
+ 1. **Connect** — Establishes an SSH ControlMaster connection (reused across all subsequent commands, password entered only once)
100
+ 2. **Sync** — `rsync` uploads your local directory to the server, using delta compression (only changed bytes are transferred)
101
+ 3. **Execute** — Runs your command on the server in the synced directory, with full interactive terminal support
102
+ 4. **Stream** — Output streams back to your terminal in real-time, exit code is preserved
103
+
104
+ Subsequent runs reuse the SSH connection (0ms reconnect) and rsync only transfers changes (sub-second for typical edits).
105
+
106
+ ## Installation
107
+
108
+ **Requirements:** Python 3.10+, `rsync`, `ssh` (pre-installed on macOS and most Linux)
109
+
110
+ **One-line install (recommended):**
111
+
112
+ ```sh
113
+ curl -sSL https://raw.githubusercontent.com/Genius-Cai/cselab/master/install.sh | bash
114
+ ```
115
+
116
+ **Or via pip:**
117
+
118
+ ```sh
119
+ pip install git+https://github.com/Genius-Cai/cselab.git
120
+ ```
121
+
122
+ **Or clone and install locally:**
123
+
124
+ ```sh
125
+ git clone https://github.com/Genius-Cai/cselab.git
126
+ cd cselab
127
+ pip install .
128
+ ```
129
+
130
+ ## Quick Start
131
+
132
+ ```sh
133
+ # 1. One-time setup
134
+ cselab init
135
+ # Enter your zID and password when prompted
136
+
137
+ # 2. Go to your assignment directory
138
+ cd ~/COMP1521/lab01
139
+
140
+ # 3. Run any CSE command
141
+ cselab run "1521 autotest"
142
+ ```
143
+
144
+ That's it. Your local files are synced and the command runs on CSE.
145
+
146
+ ## Interactive Mode
147
+
148
+ Just type `cselab` with no arguments to enter the REPL:
149
+
150
+ ```
151
+ $ cd ~/COMP1521/lab01
152
+ $ cselab
153
+
154
+ cselab v0.2.0
155
+ z5502277@cse.unsw.edu.au
156
+
157
+ Type any CSE command. Ctrl+C to exit.
158
+
159
+ Connecting... OK
160
+
161
+ ⚡ 1521 autotest collatz
162
+ [sync] OK (0.1s)
163
+ 5 tests passed 0 tests failed
164
+
165
+ ⚡ give cs1521 lab01 collatz.c
166
+ [sync] OK (0.1s)
167
+ Submission received.
168
+
169
+ ⚡ exit
170
+ ```
171
+
172
+ Same commands as the CSE server — zero learning curve.
173
+
174
+ The headless mode still works for scripts:
175
+ ```bash
176
+ cselab run "1521 autotest collatz"
177
+ ```
178
+
179
+ ## Usage
180
+
181
+ ### `cselab run <command>`
182
+
183
+ Sync files + run command on CSE server.
184
+
185
+ ```sh
186
+ cselab run "1521 autotest" # sync + autotest
187
+ cselab run "2521 autotest" # works with any course
188
+ cselab run "give cs1521 lab01 hello.c" # submit assignment
189
+ cselab run --no-sync "1521 classrun -sturec" # skip sync for non-file commands
190
+ ```
191
+
192
+ Example output:
193
+
194
+ ```
195
+ [1/3] Connecting to cse.unsw.edu.au... OK (0.0s)
196
+ [2/3] Syncing files... OK (0.2s)
197
+ [3/3] Running: 1521 autotest
198
+ ========================================
199
+ Test 1 - ... passed
200
+ Test 2 - ... passed
201
+ All tests passed!
202
+ ========================================
203
+ Exit: OK
204
+ ```
205
+
206
+ ### `cselab pull`
207
+
208
+ Download files from the server back to your local machine. Useful when the server generates output files.
209
+
210
+ ```sh
211
+ cselab run "make" # compile on server, generates binary
212
+ cselab pull # pull generated files back
213
+ ```
214
+
215
+ ### `cselab watch <command>`
216
+
217
+ Watch for local file changes and auto-run a command. Save a file, autotest runs automatically.
218
+
219
+ ```sh
220
+ cselab watch "1521 autotest"
221
+ # Now edit hello.c in your editor, save, and autotest runs automatically
222
+ ```
223
+
224
+ ### `cselab ssh`
225
+
226
+ Open an interactive SSH session directly in your synced workspace directory.
227
+
228
+ ```sh
229
+ cselab ssh
230
+ # You're now in a shell on CSE, in the same directory as your local files
231
+ ```
232
+
233
+ ### `cselab sync`
234
+
235
+ Sync files without running a command.
236
+
237
+ ```sh
238
+ cselab sync
239
+ ```
240
+
241
+ ### Other commands
242
+
243
+ ```sh
244
+ cselab config # show config file location and contents
245
+ cselab clean # remove all remote workspace directories
246
+ cselab disconnect # close SSH connection
247
+ cselab --help # full help
248
+ ```
249
+
250
+ ## Configuration
251
+
252
+ Config file: `~/.config/cselab/config.toml`
253
+
254
+ ```toml
255
+ [server]
256
+ host = "cse.unsw.edu.au"
257
+ port = 22
258
+ user = "z5555555" # your zID
259
+
260
+ [auth]
261
+ method = "password"
262
+ password = "your_password" # optional, will prompt if missing
263
+
264
+ # Alternative: SSH key auth (no password needed)
265
+ # [auth]
266
+ # method = "key"
267
+ # key_path = "~/.ssh/id_rsa"
268
+
269
+ [sync]
270
+ # Directories excluded from sync (in addition to .gitignore)
271
+ exclude = [".git", "__pycache__", "node_modules", ".venv", "target"]
272
+ ```
273
+
274
+ cselab respects `.gitignore` and `.ignore` files — directories like `node_modules/` and `__pycache__/` are automatically excluded from sync.
275
+
276
+ ## How cselab Helps Students
277
+
278
+ ### The problem
279
+
280
+ CSE students face a daily friction loop:
281
+
282
+ - **SSH + remote editing** — You lose VS Code, your extensions, copilot, your muscle memory. Editing in `vim` over SSH is a skill barrier unrelated to the course material.
283
+ - **Manual file copy** — `scp` files back and forth before every autotest. Easy to forget, easy to test stale code.
284
+ - **Slow iteration** — Each cycle (edit → copy → test) takes 30-60 seconds. Over a 10-week term, this adds up to hours of wasted time.
285
+ - **No local tooling** — Can't use local debuggers, linters, or formatters on code that must run on CSE.
286
+
287
+ ### What cselab enables
288
+
289
+ - **Stay in your editor.** Write code in VS Code, Cursor, or any local editor with full language support, extensions, and AI assistance.
290
+ - **One-command testing.** `cselab run "1521 autotest"` replaces the entire SSH-copy-run cycle.
291
+ - **Sub-second iteration.** After the first run, syncing a single file change takes ~0.1s. Edit, save, test — near-instant feedback.
292
+ - **Watch mode.** `cselab watch "1521 autotest"` makes it fully automatic — save file, see test results.
293
+ - **Focus on learning.** Remove the tooling friction so students can focus on the actual course content: C, data structures, algorithms — not SSH workflows.
294
+
295
+ ## Comparison with Other Approaches
296
+
297
+ Every UNSW CSE student needs to run `autotest` and `give` on the CSE server. Here's how the available options stack up:
298
+
299
+ | | VLAB | SSH FS | Remote-SSH | cserun | **cselab** |
300
+ |---|:---:|:---:|:---:|:---:|:---:|
301
+ | **Use local editor** (VS Code, Cursor, Vim) | No | Partial | Yes | Yes | **Yes** |
302
+ | **Run autotest/give** | Yes | Needs separate terminal | Yes | Yes | **Yes** |
303
+ | **Server load** | High | Low | **Very High** | Low | **Near Zero** |
304
+ | **Reliability** | Disconnects after 2h idle | Good | Process reapers kill it | 45% (libssh2 failures) | **100%** |
305
+ | **Watch mode** (auto-test on save) | No | No | No | No | **Yes** |
306
+ | **Install difficulty** | None (browser) | Medium (FUSE) | Medium (VS Code ext) | Hard (Rust toolchain) | **Easy** (`pip install`) |
307
+ | **AI editor support** (Cursor, Windsurf) | No | No | No | No | **Yes** |
308
+ | **Offline editing** | No | No | No | No | **Yes** |
309
+ | **Pull files from server** | N/A | Automatic | Automatic | No | **Yes** |
310
+ | **Interactive SSH** | Yes (full desktop) | No | Yes | No | **Yes** |
311
+
312
+ > **Key insight:** VS Code Remote-SSH gives the best editing experience, but CSE [explicitly discourages it](https://taggi.cse.unsw.edu.au/FAQ/VS_Code_Remote-SSH/) because it spawns Node.js processes that consume ~200-500MB RAM per student. CSE runs reaper scripts to kill these processes, and students risk account restrictions.
313
+ >
314
+ > cselab gives you the same local editing workflow with **zero server-side footprint**.
315
+
316
+ ---
317
+
318
+ ## Comparison with cserun
319
+
320
+ This project was inspired by [cserun](https://github.com/xxxbrian/cserun) by [@xxxbrian](https://github.com/xxxbrian), which pioneered the idea of running CSE commands from a local machine. cserun demonstrated the concept and solved a real pain point for UNSW students.
321
+
322
+ We chose to build a new project rather than contribute to cserun because the improvements we wanted required fundamental architectural changes — a different language, different SSH transport, and different sync mechanism. These aren't incremental fixes but a different technical foundation.
323
+
324
+ ### Architectural differences
325
+
326
+ | | cselab | cserun |
327
+ |---|---|---|
328
+ | **Language** | Python | Rust |
329
+ | **SSH library** | Native OpenSSH (via subprocess) | libssh2 (C binding via `ssh2` crate) |
330
+ | **Connection** | SSH ControlMaster (persistent, reused) | Fresh TCP+SSH per invocation |
331
+ | **File sync** | `rsync` (delta compression, incremental) | SFTP (full file upload, one-by-one) |
332
+ | **Interactive I/O** | Full PTY via `ssh -tt` | Non-blocking poll loop, no stdin |
333
+ | **Dependencies** | Python 3.10+ (pre-installed on macOS) | Rust toolchain + C compiler (for libssh2) |
334
+
335
+ ### Performance (real measurements, 50 files x 10KB)
336
+
337
+ | Metric | cselab | cserun | Improvement |
338
+ |--------|--------|--------|-------------|
339
+ | Command latency (warm) | **0.15s** | 0.73s | 4.9x faster |
340
+ | File sync (50 files) | **0.30s** | 2.13s | 7.1x faster |
341
+ | End-to-end (sync + compile + run) | **0.42s** | 2.14s | 5.0x faster |
342
+ | Cold connect | **0.48s** | 0.73s | 1.5x faster |
343
+
344
+ ### Reliability (20 rapid sequential invocations)
345
+
346
+ | | cselab | cserun |
347
+ |---|---|---|
348
+ | Success rate | **20/20 (100%)** | 9/20 (45%) |
349
+ | Failure mode | — | `libssh2: Failed getting banner` |
350
+
351
+ The reliability issue stems from libssh2's SSH handshake implementation, which intermittently fails under rapid reconnection. cselab avoids this entirely by maintaining a persistent connection via ControlMaster.
352
+
353
+ ### Feature comparison
354
+
355
+ | Feature | cselab | cserun |
356
+ |---------|--------|--------|
357
+ | Run commands | yes | yes |
358
+ | File sync | yes (rsync) | yes (SFTP) |
359
+ | .gitignore support | yes | yes |
360
+ | Skip sync (`--no-sync`) | yes | yes |
361
+ | Environment variables | planned | yes |
362
+ | **Pull files from server** | **yes** | no |
363
+ | **Interactive commands** | **yes** | no |
364
+ | **Watch mode** | **yes** | no |
365
+ | **Interactive SSH session** | **yes** | no |
366
+ | **Connection reuse** | **yes** | no |
367
+ | **Workspace cleanup** | **yes** | no |
368
+
369
+ ### Acknowledgment
370
+
371
+ Thank you to [@xxxbrian](https://github.com/xxxbrian) for creating cserun and proving that local-to-CSE command execution is both possible and valuable. cselab builds on that vision with a different technical approach.
372
+
373
+ ## AI Platform Integration
374
+
375
+ cselab ships with skill files for popular AI coding assistants — let AI help you run CSE commands:
376
+
377
+ | Platform | File | Install |
378
+ |----------|------|---------|
379
+ | **Claude Code** | `skills/cselab.md` | `cp skills/cselab.md ~/.claude/commands/` |
380
+ | **Codex CLI** | `skills/AGENTS.md` | `cp skills/AGENTS.md ./AGENTS.md` |
381
+ | **Gemini CLI** | `skills/GEMINI.md` | `cp skills/GEMINI.md ./GEMINI.md` |
382
+ | **Claude.ai** | `skills/cselab.md` | Upload to Project Knowledge |
383
+ | **Cursor** | `skills/cselab.md` | `cp skills/cselab.md .cursor/rules/` |
384
+ | **Windsurf** | `skills/cselab.md` | `cp skills/cselab.md .windsurfrules/` |
385
+
386
+ See [docs/deployment.md](docs/deployment.md) for detailed setup instructions.
387
+
388
+ ## For CSE Staff / Administrators
389
+
390
+ If you manage CSE infrastructure or coordinate a course, here's why cselab benefits the server environment.
391
+
392
+ ### The Problem: Remote-SSH is Straining Login Servers
393
+
394
+ Students increasingly use VS Code Remote-SSH for local editing convenience. But each Remote-SSH session spawns a persistent Node.js server on the login machines, causing:
395
+
396
+ - **200-500MB RAM per student** from VS Code Server + file watchers + language indexing
397
+ - Persistent connections that last entire coding sessions (hours)
398
+ - CSE has had to deploy **reaper scripts**, dedicate **vscode.cse/vscode2.cse** servers, and impose **SSH rate limits** (20/min firewall ban)
399
+
400
+ Students use Remote-SSH because the alternatives (VLAB, SSH FS) don't provide a satisfactory local editing experience. They need a better option.
401
+
402
+ ### How cselab Differs
403
+
404
+ ```
405
+ Server resource comparison (100 concurrent students):
406
+
407
+ VS Code Remote-SSH: Node.js resident process + file watchers + indexing
408
+ ~200-500MB RAM/student → 20-50GB total, persistent
409
+
410
+ SSH FS (SSHFS): SFTP connection held open
411
+ ~50MB/student → ~5GB total, persistent
412
+
413
+ cselab: rsync (0.3s) + SSH exec (<10s) + disconnect
414
+ ~0MB idle → near 0GB total, burst only
415
+ ```
416
+
417
+ cselab uses **rsync** for file sync (0.3s delta transfer) and **short-lived SSH** for command execution. There are no background processes, no persistent connections, and no Node.js. After each command completes, the server resources are fully released.
418
+
419
+ ### Benefits for CSE
420
+
421
+ 1. **Zero server load at idle** -- no Node.js, no persistent connections
422
+ 2. **Fewer SSH connections** -- SSH ControlMaster multiplexes over one socket, won't trigger rate limits
423
+ 3. **Open source (MIT)** -- fully auditable, no server-side components
424
+ 4. **Reduces support tickets** -- students stop asking about SSH disconnects and VLAB lag
425
+ 5. **Compatible with all courses** -- autotest, give, classrun all work unchanged
426
+
427
+ ### Recommendation
428
+
429
+ If you'd like to evaluate cselab, the source is at [github.com/Genius-Cai/cselab](https://github.com/Genius-Cai/cselab). It requires only standard `ssh` and `rsync` on the student's machine and makes no modifications to the server environment.
430
+
431
+ We'd welcome the opportunity to have cselab reviewed for inclusion in the [CSE Home Computing Guide](https://taggi.cse.unsw.edu.au/FAQ/Home_computing/).
432
+
433
+ ---
434
+
435
+ ## Project Structure
436
+
437
+ ```
438
+ cselab/
439
+ ├── src/cselab/
440
+ │ ├── cli.py # CLI entry point
441
+ │ ├── config.py # Config management
442
+ │ └── connection.py # SSH/rsync transport
443
+ ├── skills/
444
+ │ ├── cselab.md # Claude Code skill
445
+ │ ├── AGENTS.md # Codex CLI instructions
446
+ │ └── GEMINI.md # Gemini CLI context
447
+ ├── docs/
448
+ │ └── deployment.md # Multi-platform deployment guide
449
+ ├── examples/
450
+ │ ├── autotest.sh # Run autotest
451
+ │ ├── submit.sh # Submit via give
452
+ │ └── watch-test.sh # Watch mode demo
453
+ ├── install.sh # One-line installer
454
+ ├── README.md # English docs
455
+ ├── README_CN.md # 中文文档
456
+ └── LICENSE # MIT
457
+ ```
458
+
459
+ ## Author
460
+
461
+ **Steven Cai** ([@Genius-Cai](https://github.com/Genius-Cai))
462
+
463
+ UNSW Sydney — Bachelor of Commerce / Computer Science
464
+
465
+ ## License
466
+
467
+ [MIT](LICENSE)