Canonical home of the Endstate CLI — A declarative system provisioning and recovery tool that restores a machine to a known-good end state safely, repeatably, and without guesswork.
Author: Hugo Ander Kivi
Primary Language: PowerShell
Status: v1.0.0 — Stable
Rebuilding a machine after a clean install is tedious, error-prone, and mentally draining. Configuration drift accumulates silently. Manual steps get forgotten. The result is machines that cannot be reliably reconstructed.
Endstate exists to eliminate this clean install tax.
A machine should be:
- Rebuildable — from a single manifest
- Auditable — with clear records of what was applied
- Deterministic — same inputs produce same outcomes
- Safe to re-run — at any time, without side effects
Endstate is designed for developers, power users, and small teams who:
- Reinstall or migrate machines regularly
- Care about reproducibility and auditability
- Want automation without sacrificing safety or control
- Declarative desired state — describe what should be true, not how to do it
- Idempotence — re-running converges to the same result without duplicating work
- Non-destructive defaults — no silent deletions, explicit opt-in for destructive operations
- Verification-first — "it ran" is not success; success means the desired state is observable
- Separation of concerns — install ≠ configure ≠ verify
Spec → Planner → Drivers → Restorers → Verifiers → Reports/State
| Stage | Responsibility |
|---|---|
| Spec | Declarative manifest describing desired state (apps, configs, preferences) |
| Planner | Resolves spec into executable steps, detects drift, computes minimal diff |
| Drivers | Install software via platform-specific package managers (winget, apt, brew) |
| Restorers | Apply configuration files, registry keys, symlinks, preferences |
| Verifiers | Confirm desired state is achieved (file exists, app responds, config matches) |
| Reports/State | Persist run history, enable drift detection, provide human-readable logs |
endstate/
├── bin/ # CLI entrypoints
│ ├── endstate.ps1 # Main CLI entrypoint
│ ├── endstate.cmd # Windows CMD wrapper
│ └── cli.ps1 # Legacy provisioning subsystem CLI
├── engine/ # Core orchestration logic
├── drivers/ # Software installation adapters (winget, apt, brew)
├── restorers/ # Configuration restoration modules
├── verifiers/ # State verification modules
├── modules/ # Config module catalog (apps.git, apps.vscodium, etc.)
├── manifests/ # Desired state declarations
│ ├── examples/ # Shareable example manifests
│ ├── includes/ # Reusable manifest fragments
│ └── local/ # Machine-specific captures (gitignored)
├── tests/ # Pester unit tests
├── scripts/ # Test runners and utilities
└── tools/ # Vendored dependencies (Pester)
# Clone the repo
git clone https://github.com/Artexis10/endstate.git
cd endstate
# (Optional) Unblock downloaded scripts
Get-ChildItem -Recurse -Filter *.ps1 | Unblock-File
# Bootstrap: Install endstate to PATH for global access
.\bin\endstate.ps1 bootstrapAfter bootstrap completes, the endstate command is available globally from any directory.
# 1. Capture current machine state
endstate capture
# 2. Preview what would be applied (dry-run)
endstate apply -Manifest manifests/local/my-machine.jsonc -DryRun
# 3. Apply the manifest
endstate apply -Manifest manifests/local/my-machine.jsonc
# 4. Verify end state is achieved
endstate verify -Manifest manifests/local/my-machine.jsonc
# 5. Check environment health
endstate doctor| Command | Description |
|---|---|
bootstrap |
Install endstate command to user PATH for global access |
capture |
Capture current machine state into a manifest |
plan |
Generate execution plan from manifest without applying |
apply |
Execute the plan (with optional -DryRun) |
restore |
Restore configuration files from manifest (requires -EnableRestore) |
export-config |
Export config files from system to export folder (inverse of restore) |
validate-export |
Validate export integrity before restore |
revert |
Revert last restore operation by restoring backups |
verify |
Check current state against manifest without modifying |
doctor |
Diagnose environment issues (missing drivers, permissions, etc.) |
report |
Show history of previous runs and their outcomes |
state |
Manage endstate state (subcommands: reset, export, import) |
Humans author manifests in JSONC (JSON with comments). Plans, state, and reports are emitted as plain JSON.
Supported formats: .jsonc (preferred), .json, .yaml, .yml
Large manifests can be split into reusable modules:
// main.jsonc
{
"version": 1,
"name": "dev-workstation",
// Include other manifest files (resolved relative to this file)
"includes": [
"./includes/dev-tools.jsonc",
"./includes/media.jsonc",
"./includes/dotfiles.jsonc"
],
// Local apps are merged with included apps
"apps": [
{ "id": "custom-tool", "refs": { "windows": "Custom.Tool" } }
]
}Include rules:
- Paths are resolved relative to the including manifest
- Arrays (
apps,restore,verify) are concatenated - Scalar fields in the root manifest take precedence
- Circular includes are detected and rejected with a clear error
Endstate prioritizes safety over speed:
| Default | Behavior |
|---|---|
| Backup before overwrite | Existing files are backed up before restoration |
| Non-destructive | No deletions unless explicitly configured |
| Dry-run support | All commands support -DryRun to preview changes |
| Explicit destructive ops | Destructive operations require explicit flags |
| Atomic operations | Failed operations roll back where possible |
| Checksum verification | Restored files are verified against expected hashes |
Backup location: state/backups/<timestamp>/
| Requirement | Version | Purpose |
|---|---|---|
| PowerShell | 5.1+ | Script execution |
| winget | Latest | App installation (Windows) |
Endstate uses Pester 5.7.1 (vendored in tools/pester/) for deterministic, offline-capable testing.
# Run all tests
.\scripts\test_pester.ps1
# Run specific test suite
.\scripts\test_pester.ps1 -Path tests/unit
# Run tests with tag filter
.\scripts\test_pester.ps1 -Tag "Manifest"Endstate v1.0.0 is the first stable release. The CLI contract (JSON schema 1.0) is locked. Capture, apply, verify, restore, and drift detection are production-ready. Winget is the primary driver with planned expansion to macOS/Linux.
A desktop GUI is available as a separate commercial product built on top of Endstate's open-source core — substratesystems.io/endstate
Endstate is licensed under the Apache License, Version 2.0.
See the LICENSE file for details.
Copyright © 2025–2026 Substrate Systems OÜ
Created by Hugo Ander Kivi at Substrate Systems OÜ.