This template keeps your repo clean and your workroot disposable. You get:
- A repo that is safe to commit (source only)
- A workroot for venvs, outputs, logs, and session wiring
- Zero global PowerShell policy changes (boot.cmd always uses ExecutionPolicy Bypass)
- Optional run manifests and per-session transcripts for traceability
- Copy and rename both folders so the base name matches:
Projects/
Project-A/
Project-A-workroot/
- Initialize the workroot (one time):
cd C:\Path\To\Projects\Project-A-workroot
.boot.cmd init.ps1- Start a session (every terminal):
.boot.cmd bootstrap.ps1Projects/
template-repo/
repo_marker.py
(your pipeline code here)
template-repo-workroot/
boot.cmd
bootstrap.ps1
init.ps1
workroot_tools.ps1
README.md <-- this file (optional location)
Three explicit layers:
-
Repo
- Source code only
- Safe to commit
- Never polluted by outputs or pycache
-
Workroot
- Where commands run
- Where outputs and logs land
- Where the venv lives
-
Boot/Init scripts
- Wire PowerShell and Python together
- Live with the project
- Make sessions repeatable
- Safe entry point for all sessions
- Launches PowerShell with ExecutionPolicy Bypass
- Does not modify system or user policy
Usage:
.boot.cmd init.ps1
.boot.cmd bootstrap.ps1Note: boot.cmd init.ps1 starts a new session, runs init, then drops you into bootstrap automatically.
What it does:
- Creates
.venvif missing - Installs
requirements.txtif present in the workroot - Activates the venv
- Derives repo path from the
*-workrootfolder name - Writes a
.pthfile so Python can import repo modules - Verifies import using
repo_marker.py
Think: "Bring this workroot online."
What it does:
- Activates the venv
- Sets
$env:REPOfor easy navigation and tab completion - Sets
$env:PYTHONDONTWRITEBYTECODE=1to avoid pycache in the repo - Starts a transcript (by default)
- Loads
workroot_tools.ps1sowris available
Think: "Prepare this shell to work."
Your repo must contain a unique importable module so init can verify imports:
# repo_marker.py
value = "ok"Do not name this file test.py (it collides with Python internals).
A transcript is started automatically in every init and bootstrap session.
- Default location:
<workroot>\_workroot_transcripts\ - File name:
session_yyyyMMdd_HHmmss_<shortid>.log - The path is printed once when the session starts
Disable or customize:
.boot.cmd bootstrap.ps1 -NoTranscript
.boot.cmd bootstrap.ps1 -TranscriptDir C:\Path\To\LogsNotes:
- Transcript files grow with output volume; avoid typing secrets.
- The transcript records host output (Write-Host), which is why
wr -CaptureOutputreplays captured output back to the host.
wr is an alias for Invoke-WorkrootCommand and is loaded by workroot_tools.ps1.
General usage:
wr [flags] -- <command> [args...]Flags:
-DryRunPrint derived paths and manifest location, do not execute-SnapshotInclude before/after file snapshots and change lists-IncludeUserInclude the username in the manifest-CaptureOutputCapture stdout/stderr into the manifest (opt-in)-NoCaptureForce output capture off-TranscriptCaptureForce transcript-friendly capture on (default)-NoTranscriptCaptureKeep native output unwrapped (better interactivity; transcript may miss it)-RawNativeStderrCapture raw native stderr (no PowerShell wrapper). Implies -CaptureOutput-MaxOutputBytes NLimit captured bytes per stream (default 65536)-OutputEncoding XDecode captured output using a specific encoding
Examples:
wr python $env:REPO\some_script.py --arg1 x
wr -Snapshot -- python $env:REPO\some_script.py --arg1 x
wr -IncludeUser -- python $env:REPO\some_script.py
wr -CaptureOutput -- python -c "print('hello')"
wr -CaptureOutput -RawNativeStderr -- python -c "import sys; print('err', file=sys.stderr)"Manifest output location:
<workroot>\_workroot_manifests\run_<run_id>.json
Output capture is OFF by default to preserve interactive behavior.
When you enable -CaptureOutput:
- Stdout/stderr are redirected to temp files
- Captured text is written into the manifest
- Output is replayed to the host so the transcript records it
Encoding defaults:
- Windows PowerShell (Desktop):
unicode - PowerShell 7+:
utf8
If you see odd characters in captured output, override explicitly:
wr -CaptureOutput -OutputEncoding unicode -- <command>
wr -CaptureOutput -OutputEncoding utf8 -- <command>Raw native stderr:
-RawNativeStderrusesStart-Process -RedirectStandardErrorto avoid PowerShell error-record wrappers- Best for non-interactive commands
- You lose PowerShell error context, but stderr is clean
When a transcript is active, wr will route native stdout/stderr through the PowerShell host so the transcript can record it.
Notes:
- This improves transcript completeness without storing output in the manifest.
- Some native tools detect piped output and may reduce interactivity (colors, progress, prompts).
- Opt out per command with
-NoTranscriptCapture.
If you see garbled characters in the host or transcript, your console codepage may not match the tool output encoding.
Tips:
- Try
chcp 65001before starting a session (UTF-8 codepage). - In PowerShell, you can set
$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new(). - For manifest capture, use
-OutputEncoding unicodeor-OutputEncoding utf8explicitly.
With -Snapshot, manifests include file change lists:
new_filesmodified_filesdeleted_files
Snapshots exclude:
.venv/.git/_workroot_manifests/manifests/
Default behavior in init.ps1:
py -m venv .venvTo pin a specific Python version:
py -0
py -3.11 -m venv .venvThe venv is tied to that version; deleting the workroot will recreate it correctly.
Workroots are disposable. Safe to delete:
.venv/_workroot_manifests/_workroot_transcripts/- outputs/logs
The repo stays clean and untouched.
- Ensure
repo_marker.pyexists in the repo root - Re-run:
\.boot.cmd init.ps1
You ran the command while your shell was in the repo.
(Get-Location).Path
cd C:\Path\To\Projects\Project-A-workrootYou forgot to bootstrap this session.
.boot.cmd bootstrap.ps1Always run through boot.cmd:
.boot.cmd bootstrap.ps1
.boot.cmd init.ps1- Copy repo + workroot
- Rename both to the same base name
- Run
init.ps1once - Run
bootstrap.ps1every session - Keep repos clean; delete workroots freely
This pattern scales cleanly across many projects without hidden state or global side effects.