CLI
The sysdef CLI is built using Commander.js and provides a simple interface for managing your system configuration. The main entry point is through the sysdef command located in your bin/ directory.
Root Directory
Section titled “Root Directory”Sysdef uses a root directory (defaults to $HOME/sysdef or can be set via SYSDEF_ROOT_DIR environment variable) that contains:
Directorybin/
- bun
- sysdef
Directorysysdef-src/
- *.ts (source files)
Directorymodules/
- *.ts (module definitions)
Directoryproviders/
- *.ts (provider definitions)
- config.yaml
- sysdef-lock.json (auto-generated)
- sysdef-track.json (auto-generated)
Available Commands
Section titled “Available Commands”sysdef
Section titled “sysdef”Running sysdef without arguments displays help information for all available commands.
sysdef sync
Section titled “sysdef sync”The primary command for synchronizing your system configuration. This command:
- Syncs files: Creates symlinks and generates files from your modules
- Manages packages: Installs/removes packages through configured providers
- Runs events: Executes any
onEverySyncfunctions in your modules - Updates lockfile: Records exact package versions for reproducibility
Options:
-d, --dry-run: Preview changes without executing them-s, --safe: Install packages but don’t remove any (safer for testing)-f, --files-only: Only sync files, skip package management-h, --help: Show help for this command
Examples:
# Normal syncsysdef sync
# Preview what would happensysdef sync --dry-run
# Only sync files, don't touch packagessysdef sync --files-only
# Sync but don't remove any packagessysdef sync --safesysdef update [provider] [packages...]
Section titled “sysdef update [provider] [packages...]”Updates managed packages to their newest available versions and refreshes the lockfile. With no arguments it updates every package for every configured provider; pass a provider (and optionally specific package names) to narrow it.
Examples:
# Update everythingsysdef update
# Update all packages for one providersysdef update npm
# Update specific packagessysdef update npm typescript left-padsysdef update-lockfile
Section titled “sysdef update-lockfile”Snapshots the versions currently installed on your system into sysdef-lock.json
without installing, removing, or changing anything. This is bookkeeping-only: it
re-pins each managed package to the version that’s actually present.
Use it when packages changed out-of-band (for example, you upgraded something with your
package manager directly) and you want the lockfile to reflect reality without running a
full sync.
sysdef update-lockfilesysdef track [subcommand]
Section titled “sysdef track [subcommand]”Manages which installed-but-unmanaged packages sysdef warns about. During sync, system
providers (arch-official, apt, dnf) report every package on the machine through
getInstalled(), so sysdef prints a warning listing packages that are installed but not
declared in any module (it never removes these — sysdef only removes packages it installed
itself and recorded in the lockfile). The trackfile (sysdef-track.json) lets you silence
that warning for packages you don’t intend to manage. It is stored separately from the
lockfile because it varies per machine (keep the lockfile committed, the trackfile
gitignored).
Running sysdef track with no subcommand prints help. Subcommands:
sysdef track ignore <provider> [packages...]— mark specific packages untracked sosyncstops warning about them.sysdef track ignore-all [provider]— mark every currently installed-but-unmanaged package untracked (for one provider, or all if omitted). Handy for the first sync on an existing system.sysdef track unignore <provider> [packages...]— remove packages from the untracked list, re-enabling the warning.sysdef track list [provider]— show which packages are currently marked untracked.
Note: adding a package to a module (so it becomes managed) automatically drops it from the untracked list on the next sync.
# Stop warning about base-system packages you'll never manage with sysdefsysdef track ignore-all arch-official
# Silence just a couple of packagessysdef track ignore apt vim curl
# See what's currently ignoredsysdef track listsysdef providers
Section titled “sysdef providers”Lists all configured providers and checks their installation status. Each provider can define a checkInstallation() function to verify it’s working correctly.
Example output:
arch-official is installed correctlyapt is installed correctlybun failed when checking its own installation: command not foundsysdef list-installed [provider]
Section titled “sysdef list-installed [provider]”Shows all packages currently installed through sysdef providers.
Arguments:
provider(optional): Filter by specific provider name
Examples:
# List packages from all providerssysdef list-installed
# List only packages from the arch-official providersysdef list-installed arch-officialExample output:
Currently installed packages for arch-official: firefox@latest git@2.42.0 neovim@0.9.4
Currently installed packages for bun: typescript@5.2.2 @types/node@20.8.0sysdef hello
Section titled “sysdef hello”A simple test command that prints “Hello, world!” - useful for verifying the CLI is working.
Error Handling
Section titled “Error Handling”The CLI uses the errorOut() function from sysdef.ts:9 for fatal errors, which prints an error message and exits with code 1. Common error scenarios:
- Missing configuration file
- Invalid module or provider files
- Provider installation check failures
- Package version conflicts between modules
Configuration Loading
Section titled “Configuration Loading”The CLI loads configuration from:
- config.yaml: Main configuration specifying which modules and providers to load
- Module files: TypeScript files in the
modules/directory - Provider files: TypeScript files in the
providers/directory - Variables file: Optional
variables.{ts,js,tsx,jsx}for global variables - Lockfile:
sysdef-lock.jsonfor tracking exact package versions - Trackfile:
sysdef-track.jsonfor packages you’ve marked untracked (seesysdef track)
All TypeScript/JavaScript files are dynamically imported and must export a default function that returns the appropriate object (Module, Provider, or variables record).