Workspace Tooling and Environments
This page documents how the full CSL project is operated as a multi-repo workspace across three real environments:
- Android / Termux
- Omarchy Linux (Arch-based)
- Windows 11 via VS Code + PowerShell, with bash available when needed
The goal is not just command reference. The goal is to explain the operating model of the project.
Workspace shape
The project is not a monorepo. It is a workspace meta repo plus sibling repos:
csl/ ← VHCosta/csl (workspace meta repo, git)
├── CLAUDE.md
├── STATUS.md
├── plans/ ← active plans + archive
├── tools/bash/ ← Linux/Android operator scripts
├── tools/win/ ← Windows PowerShell operator scripts
├── llc-course/ ← VHCosta/llc-course (own git)
├── llc-companion/ ← VHCosta/llc-companion (own git)
├── llc-companion-pdf/ ← VHCosta/llc-companion-pdf (own git)
├── llc-wiki/ ← VHCosta/llc-wiki (own git)
└── c-systems-lab-exercises/ ← VHCosta/c-systems-lab-exercises (own git)Key ownership boundaries:
csl/(meta repo) owns workspace plans, tooling, and status surfacellc-courseowns the web app and the canonicalcontent/exercise treellc-companionowns the local execution helperllc-companion-pdfowns the Typst product and solution-side testsllc-wikiowns durable cross-repo reference documentation
The sub-repos are gitignored at the csl/ level — each tracks its own remote independently. See source-csl-tools for the tooling migration history.
Why workspace tooling exists
Without cross-repo tooling, routine work becomes repetitive and error-prone:
- pull five repos manually
- remember which repo owns which build or export step
- remember which environments can install Node deps directly
- keep a local internal mirror in sync by hand on Termux
The tools/ scripts exist to make those flows explicit and repeatable.
Command model
The current operator-facing commands are:
csl-updatecsl-update --setupcsl-setupcsl-statuscsl-logcsl-buildcsl-push
High-level meaning:
csl-update: refresh repo contentscsl-setup: refresh the local runnable environmentcsl-update --setup: do both in sequence
Environment 1 — Android / Termux
Why this environment is special
On Android, shared storage is convenient but technically hostile to Node-based tooling.
The shared-storage path:
/storage/emulated/0/code/cslis good for:
- file visibility
- editing from Android apps
- keeping the workspace in one familiar place
But it is bad for:
node_modules/.binsymlink creation- execution of native binaries such as
esbuild
That is why the project uses an internal mirror:
$HOME/code/cslStandard Termux workflow
Source of truth:
/storage/emulated/0/code/csl
Runnable/internal workspace:
$HOME/code/csl
Standard commands:
csl-update --setup
csl-int
cd llc-course
npm run devWhat happens:
- shared-storage repos are pulled
- internal mirror is rebuilt from shared storage
- dependency install runs inside the internal mirror
- active development commands run from the internal tree
Important consequence
The internal mirror is disposable. It is not the source of truth.
If something goes wrong in the internal tree, it can be recreated from the shared-storage workspace.
Environment 2 — Omarchy Linux (Arch-based)
Main difference from Termux
On Omarchy/Arch Linux, the filesystem constraints that force the Termux mirror pattern generally do not exist.
That means:
- Node installs can usually run directly in the workspace
- native binaries are not blocked by Android shared-storage rules
- the mirror is usually unnecessary
Recommended Linux workflow
Operate directly in the workspace repos:
csl-update
cd /path/to/csl/llc-course
npm install
npm run devUse csl-update --setup only if you intentionally want the same mirrored model
as Termux. The tooling supports it, but Linux does not require it by default.
Main value of tooling on Linux
The Linux value is less about filesystem workaround and more about:
- cross-repo updates
- cross-repo logs/status
- repeatable build/export flows
Environment 3 — Windows 11 via VS Code + PowerShell
Operating model
Windows is supported through PowerShell wrappers in tools/win/.
PowerShell is the user-facing shell, but bash is still allowed and expected when a project’s real build scripts are bash.
That is the correct compromise:
- PowerShell for Windows-native command ergonomics
- bash where the project already has stable bash automation
Practical implication
Do not force a full PowerShell rewrite of every repo-local script just to make the command surface look uniform. The wrapper layer can be PowerShell while the actual build step still calls bash where appropriate.
Typical Windows flow
csl-update
csl-status
csl-build -DistWhen the underlying step is bash-based, the wrapper delegates to bash.
Where to look for what
Use the right documentation layer:
- Wiki: durable cross-repo technical documentation
csl-toolsREADME: command usage and flags- individual repo READMEs: repo-local setup and architecture
This split is intentional. The wiki explains the system; command READMEs explain the interface.
Source-of-truth map
Cross-repo tooling:
Canonical exercises and web content:
PDF/source-side solution validation:
Exercise/export distribution model:
Current standard operator flows
Refresh everything on Termux
csl-update --setupRefresh repo contents only
csl-updateRebuild only the internal Termux mirror and installs
csl-setupCheck cross-repo state
csl-status
csl-logDesign rule
Cross-repo automation lives in tools/ inside the workspace meta repo
(VHCosta/csl), not as ad hoc scripts in unversioned locations.
That rule exists to avoid exactly the failure mode the project already hit:
useful local automation being lost, diverging, or blocking pulls because it
lived in the wrong place. The csl-tools standalone repo was the previous
solution; the meta repo is the current one.