Workspace Tooling and Environments

This page documents how the full CSL project is operated as a multi-repo workspace across three real environments:

  1. Android / Termux
  2. Omarchy Linux (Arch-based)
  3. 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 directory of sibling repos:

csl/
├── llc-course
├── llc-companion
├── llc-companion-pdf
├── llc-wiki
├── c-systems-lab-exercises
└── scripts

Key ownership boundaries:

  • llc-course owns the web app and the canonical content/ exercise tree
  • llc-companion owns the local execution helper
  • llc-companion-pdf owns the Typst product and solution-side tests
  • llc-wiki owns durable reference documentation
  • csl-tools owns cross-repo operator tooling

The top-level csl/ folder is a local workspace, not the authoritative home for the automation itself. The durable automation lives in source-csl-tools.

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

csl-tools exists to make those flows explicit and repeatable.

Command model

The current operator-facing commands are:

  • csl-update
  • csl-update --setup
  • csl-setup
  • csl-status
  • csl-log
  • csl-build
  • csl-push

High-level meaning:

  • csl-update: refresh repo contents
  • csl-setup: refresh the local runnable environment
  • csl-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/csl

is good for:

  • file visibility
  • editing from Android apps
  • keeping the workspace in one familiar place

But it is bad for:

  • node_modules/.bin symlink creation
  • execution of native binaries such as esbuild

That is why the project uses an internal mirror:

$HOME/code/csl

Standard 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 dev

What happens:

  1. shared-storage repos are pulled
  2. internal mirror is rebuilt from shared storage
  3. dependency install runs inside the internal mirror
  4. 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

Operate directly in the workspace repos:

csl-update
cd /path/to/csl/llc-course
npm install
npm run dev

Use 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 csl-tools/bin-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 -Dist

When 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-tools README: 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 --setup

Refresh repo contents only

csl-update

Rebuild only the internal Termux mirror and installs

csl-setup

Check cross-repo state

csl-status
csl-log

Design rule

Cross-repo automation should be versioned in csl-tools, not left as ad hoc scripts in the unversioned workspace root.

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.