Skip to content

AdrianParedez/milner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Milner

A Windows-first Rust shell experiment built around explicit process launch, typed parsing, and narrow execution policy.

CreateProcessW over cmd.exe fallback. Explicit handles over ambient inheritance. Small shell syntax over accidental compatibility.

CI Docs License: Apache-2.0 Rust 2024 Windows Experimental

Install · Docs · Quick Start · Capabilities · Syntax · Configuration · Verification

Created by Adrian Paredez, with Sole as his sovereign cognitive work partner.

M.I.L.N.E.R. stands for Managed Intent Layer for Native Execution Runtime. It is named in homage to Robin Milner, whose work on typed systems and communicating processes reflects the project's focus on structured intent, bounded execution, and process interaction.

Important

Milner is experimental. It is useful for studying a hardened Windows process runner and a deliberately small shell surface. Treat it as a research-grade command runtime, not as a production terminal environment.

Warning

Milner intentionally rejects .bat and .cmd targets. Batch files have command processor quoting and metacharacter semantics that Milner does not yet claim to make safe.

Install

Install the latest Windows release binary:

irm https://paredez.dev/install.ps1 | iex

Download and verify the latest Windows release binary manually:

$asset = "milner-x86_64-pc-windows-msvc.zip"
$base = "https://github.com/AdrianParedez/milner/releases/latest/download"

Invoke-WebRequest "$base/$asset" -OutFile $asset
Invoke-WebRequest "$base/$asset.sha256" -OutFile "$asset.sha256"

$expected = (Get-Content "$asset.sha256").Split(" ")[0]
$actual = (Get-FileHash $asset -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actual -ne $expected) { throw "checksum mismatch" }

Expand-Archive $asset -DestinationPath .\milner
.\milner\milner.exe --prompt

Install from source:

cargo install --git https://github.com/AdrianParedez/milner --locked
milner --prompt

Release binaries are published when a vX.Y.Z tag is pushed.

Documentation

The public documentation is organized under docs/:

Quick Start

cargo build
.\target\debug\milner.exe --no-config cargo --version
.\target\debug\milner.exe --no-config --line "cargo --version"
.\target\debug\milner.exe --no-config --prompt

Prompt mode:

milner> cargo --version
milner> pwd
milner> cd C:\Windows
milner> exit 0

Use exit [code] to leave prompt mode. In a Windows console, Ctrl + Z then Enter sends EOF.

Command Surface

milner.exe <program> <args...>
milner.exe [options] <program> <args...>
milner.exe [options] --line <command-line>
milner.exe [options] --prompt

options:
  --no-config
  --config <file>
  --cwd <dir>
  --set-env NAME=VALUE
  --unset-env NAME
  --timeout-ms <ms>

Examples:

milner.exe --no-config notepad.exe
milner.exe --no-config powershell -NoProfile -Command "Get-Date"
milner.exe --no-config --line "cargo --version > version.txt"
milner.exe --no-config --line "powershell -NoProfile -Command \"[Console]::Error.Write('err')\" 2> error.txt"
milner.exe --no-config --timeout-ms 1000 powershell -NoProfile -Command "Start-Sleep 30"

Policy shape at a glance:

+ milner.exe --line "cargo --version"
+ milner.exe --line "cargo --version > version.txt"
+ milner.exe --line "where powershell | findstr powershell"
- milner.exe --line "build.cmd"
- milner.exe --line "echo %PATH%"
- milner.exe --line "cargo test && cargo clippy"

Capabilities

Area Current behaviour
Native launch Resolves executables and launches with CreateProcessW.1
Command parsing Parses commands into typed structures before execution.
Prompt mode Provides cd, pwd, complete, and exit built-ins.
Redirection Supports stdin, stdout write/append, and stderr write/append redirection.
Pipelines Supports exactly one two-command external pipeline.
Execution policy Rejects unsupported operators, .bat, and .cmd targets.
Handles Gives children only intended stdin, stdout, and stderr.
Configuration Reads a small config subset for prompt, history, records, and aliases.
Cancellation Cancels foreground process trees with --timeout-ms <ms>, Ctrl+C, or Ctrl+Break.
More command examples
milner.exe --no-config --cwd C:\Windows notepad.exe
milner.exe --no-config --set-env MILNER_DEMO=1 powershell -NoProfile -Command "$env:MILNER_DEMO"
milner.exe --no-config --line "cargo --version >> output.txt"
milner.exe --no-config --line "powershell -NoProfile -Command \"[Console]::Error.Write('err')\" 2>> error.txt"
milner.exe --no-config --timeout-ms 1000 powershell -NoProfile -Command "Start-Sleep 30"

Supported Syntax

Form Status Notes
program arg Supported Bare words and quoted arguments.
"empty" "" Supported Empty quoted arguments are preserved.
stdout > file Supported Redirect stdout, replacing the target.
stdout >> file Supported Redirect stdout, appending to the target.
stderr 2> file Supported Redirect stderr, replacing the target.
stderr 2>> file Supported Redirect stderr, appending to the target.
stdin < file Supported Redirect stdin from a file.
left | right Supported Exactly one external two-command pipeline.
&&, ||, ; Rejected Explicit parse errors.
Variables, globs, substitution Not supported No silent expansion.
.bat, .cmd Rejected No cmd.exe fallback.

Configuration

Milner starts without configuration.

Default config path:

%APPDATA%\milner\config.toml

Use:

.\target\debug\milner.exe --config "$env:APPDATA\milner\config.toml" --prompt
.\target\debug\milner.exe --no-config --prompt

Current config subset:

[prompt]
text = "milner> "

[history]
enabled = false
path = C:\Users\you\AppData\Roaming\milner\history.txt

[records]
enabled = false
path = C:\Users\you\AppData\Roaming\milner\records.ndjson

[aliases]
gs = git status

Important

Unknown sections and keys are rejected with a file path and line number.

History is disabled by default. When enabled without an explicit path, Milner writes history to:

%APPDATA%\milner\history.txt

History avoids recording command lines that contain obvious secret words such as password, secret, or token.

Execution records are disabled by default. When enabled without an explicit path, Milner writes newline-delimited JSON records to:

%APPDATA%\milner\records.ndjson

Execution records are local only. They include parsed command structure, resolution result, cwd, timing, exit or error status, and policy decisions. They do not include environment values, stdout content, stderr content, or remote telemetry. Milner skips records for command lines that contain obvious secret words such as password, secret, or token.

Alias boundaries
  • Alias cycles are detected.
  • Alias values cannot include redirection.
  • Alias values cannot include pipelines.
  • Alias expansion cannot bypass executable resolution.
  • Alias expansion cannot bypass .bat or .cmd rejection.

Verification

cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test
.\target\debug\milner.exe --no-config powershell -NoProfile -Command "exit 0"

Optional combined runner:

cargo install cargo-make cargo-nextest
cargo make verify-tests

Generate local Rust HTML documentation:

cargo doc --no-deps --document-private-items

Open:

target\doc\milner\index.html

GitHub Actions also uploads generated Rust HTML docs as the milner-rustdoc-html artifact.

Known limitations
  • Windows-only.
  • No ConPTY or pseudoconsole terminal hosting.
  • No arbitrary-length pipelines.
  • No variables, globbing, aliases with redirection, or command substitution.
  • No background jobs.
  • No line editor crate, persistent completion engine, or theme system.

License

Licensed under the Apache License, Version 2.0. See LICENSE.

Footnotes

  1. CreateProcessW still receives a Windows command-line string, but Milner resolves the executable path first and passes it separately as lpApplicationName.

About

A Windows-first Rust shell experiment built around explicit process launch, typed parsing, and narrow execution policy.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages