GitHub - CommanderTurtle/preview: a previewer for fsharp orchestrator · GitHub
Skip to content
CommanderTurtlePublic

About

a previewer for fsharp orchestrator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

preview

A multiplatform site previewer, following the orchestrator CommanderTurtle/orc and reproducing the deploy topology locally. It reads .github/config/deploy-*.fs, creates one rendered working mirror per SourceFolder, launches each framework's own development server, and keeps the mirrors synchronized while source files are saved. It can also point one standalone source directory at any canonical ORC GenerateConfig.fsx runtime.

It is separate from both ORC and the small one-tree orc-reactor. The ORC checkout remains read-only.

Clone your repo, then natively preview 7 site frameworks, preserving realtime edits to the F# source code. Preview runs on reactor topology.

git clone https://github.com/CommanderTurtle/preview
cd preview
cargo build --release

Native dashboard

preview

Double-click target/release/orc-preview.exe (no arguments), or run orc-preview --gui. The GUI is compiled into the same Cargo binary using egui's native OpenGL renderer: no browser runtime, Electron, or GUI web server. Explicit CLI arguments continue to run the original console workflow. On Windows the EXE retains console-subsystem semantics so PowerShell waits and receives exit codes. GUI mode immediately detaches that console; Explorer may briefly show it during startup, but no console stays open beside the dashboard.

  • Select sites and ports, then Start selected. Nothing launches automatically.
  • Refresh re-renders one mirror, re-detects its framework, regenerates its launch configuration and restarts just that server. Use it after Zensical nav, Vite config or Jekyll YAML changes. Normal saves still use the existing watcher.
  • Each site has Stop / Start, framework/status, port and an Open link. A responding TCP port is shown as running; this is not an HTTP health guarantee.
  • Logs stay in the window, with per-site filtering, text search, follow, copy, save and clear. Memory is bounded to 4,000 lines; unusually verbose output may be dropped from the display. There are no per-server consoles in GUI mode.
  • Stop session and closing the window stop the owned process trees before deleting disposable output. A stalled shutdown gets 12 seconds, then the GUI terminates only its own worker tree. Windows job objects contain descendants even when a launcher exits early. Source repositories are never deleted.
  • Reuse framework downloads selects a shared cache; leaving it off gives a fresh disposable environment. Keep rendered mirrors also preserves native build/dependency folders. Switching either off does not delete an existing persistent folder. No generic recursive "clear cache" button is provided.

The dashboard reads the same .env / .env.example settings as the launcher. It looks in the current Preview checkout, then beside/above the executable; embedded defaults also let a copied EXE start without companion files. Paths resolve relative to the selected settings file. Load, Reload, Save, folder browsing and Discover sites make the configuration explicit. Settings are saved only when requested. ORC_OUTPUT is an optional GUI-only output path. An unchecked site is omitted from saved selections; Discover sites restores all available targets to the selection list. Topology changes still stop the coordinator safely; reload/discover and start a new session afterward.

orc-preview --gui --config C:\preview-settings\.env
orc-preview --gui --orc-dir C:\src\orc
# Existing direct / standalone CLI usage remains supported below.

Internally the GUI owns one hidden coordinator. A private stdin/stdout protocol carries control actions and tagged logs; no network control port is opened. The coordinator uses the same renderer, theme cache, launch scripts and watcher as the CLI. Framework runtimes still need to be installed as described below.

Tests: cargo test covers settings, bounded logs, native layout and Windows process cleanup. The opt-in real renderer/Bun test uses a disposable sample site, not the user's deployment targets:

$env:ORC_TEST_RUNTIME = 'C:\src\orc\GenerateConfig.fsx'
cargo test --test managed_smoke -- --ignored --nocapture

Direct CLI preview

Preview runs the canonical renderer from the ORC checkout; there is no copied or embedded GenerateConfig.fsx runtime in this repository. The common cases are intentionally positional:

# One selected ORC site.
.\target\release\orc-preview.exe --orc-dir=C:\src\orc app 2000

# Several selected ORC sites, paired left-to-right with their ports.
.\target\release\orc-preview.exe --orc-dir=C:\src\orc app,docs,lab 2000,2001,2002

# An unrelated source folder, rendered by an explicitly pointed ORC runtime.
.\target\release\orc-preview.exe `
    --single-dir=C:\src\other-site `
    --runtime-dir=C:\src\orc\GenerateConfig.fsx `
    --sharedstrings=true

--single-dir defaults to port 4000; use --ports 4173 to choose another. In topology mode, omitting the positional selection previews every discovered deployment on consecutive ports beginning at 4000.

By default, rendered mirrors, launch files, downloaded frameworks, virtual environments, and theme checkouts live in one unique temporary session and are removed on normal exit or Ctrl+C. Add bare --cache to preserve reusable framework downloads in .cache, or --cache C:\preview-cache to choose the location. Add --output C:\preview\orc only when the rendered mirrors themselves should survive.

Shared strings normally follow each deploy record's UseSharedStrings value. --sharedstrings=true|false overrides it. For an external or unusually placed catalog, select one site and pass --shared-file=C:\path\sharedstrings.fs.

Zero-configuration Windows launcher

Place the preview and orc checkouts beside one another using the default layout, then run:

.\orc-server.ps1

The launcher reads the Git-ignored .env when present and otherwise uses the complete .env.example baseline directly. The checked-in defaults resolve the adjacent ../orc/orc checkout and start the canonical seven targets. It builds Preview when needed, creates a unique rendered environment beneath the Windows temporary directory, and launches the existing multi-server coordinator. Reusable themes and framework downloads live inside that disposable environment by default. Ctrl+C stops every framework process tree, then removes the rendered sites, generated launch files, package downloads, virtual environments, theme checkouts, and the session directory itself. Nothing is created in the ORC checkout: it remains an unbuilt, pristine source clone without dist, node_modules, .venv, or framework output.

To preserve reusable framework downloads without preserving rendered sites, set an explicit cache in .env:

ORC_CACHE=.orc-preview-cache

That opt-in, Git-ignored directory retains the Zensical environment, Netdocs binary, Ruby bundles, Bun package cache, and theme checkouts. Session output is still deleted on shutdown. Leave ORC_CACHE= blank for the fully disposable fresh-install lifecycle.

Site selection is explicit and independent of deploy-file sort order:

ORC_SITE_APP=app:4000
ORC_SITE_BLOG=blog:4111
ORC_SITE_DOCS=docs:4222
ORC_SITE_LAB=lab:4333
ORC_SITE_NET=net:4666
ORC_SITE_PAGES=pages:4444
ORC_SITE_VITE=vite:4555

To activate an eighth site, add one line to .env. The value names the ORC SourceFolder and its port; the setting name is a human-readable label:

ORC_SITE_PRETTIART=vite2:4777

The matching source folder and .github/config/deploy-*.fs definition must exist in the configured ORC checkout. No Preview code or positional port list needs to change. Use .\orc-server.ps1 -RenderOnly to validate rendering and cleanup without starting framework servers.

Build

Required on PATH:

  • Rust/Cargo and .NET for the preview binary and ORC renderer;
  • PowerShell (pwsh, or Windows PowerShell via --powershell powershell.exe) for the visible server consoles;
  • uv for Zensical projects;
  • Ruby 3.4 and Bundler for Jekyll and GitHub Pages projects;
  • Bun for Vite projects.

Netdocs is installed into the shared preview state automatically. It does not alter the user's global .NET or PATH configuration.

Run every discovered site

Ports are assigned in sorted SourceFolder order. The current ORC tree sorts as app, blog, docs, lab, net, pages, vite. Ports do not need to be numerically sorted, so an existing six-site layout can retain its URLs:

.\target\release\orc-preview.exe `
    --orc-dir C:\src\orc `
    --output C:\preview\orc `
    --ports 4000,4111,4222,4333,4666,4444,4555

For explicit target selection, use named source-folder assignments. Unlike the legacy positional form, unselected deploy definitions are ignored:

.\target\release\orc-preview.exe `
    --orc-dir C:\src\orc `
    --output C:\preview\orc `
    --sites app=4000,blog=4111,docs=4222,lab=4333,net=4666,pages=4444,vite=4555

The output contains:

C:\preview\orc\
  app\
  blog\
  docs\
  lab\
  net\
  pages\
  vite\
  .orc-preview\        # launch scripts, manifests, and shared preview state

Each site folder is a deployment-like working mirror: rendered ORC files and literal assets remain beside native framework output such as site, _site, or dist. A startup reconciliation replaces only ORC-managed files, so native dependency/build directories can remain warm.

One visible PowerShell console is opened per site. The existing framework launchers bind to 0.0.0.0; Netdocs currently follows its upstream Kestrel behavior and binds to loopback. The parent prints every loopback URL. Press Ctrl+C in the parent console to close the complete process tree.

Use --render-only to create/reconcile mirrors and inspect the generated launch scripts without opening servers.

Framework behavior

Detection keeps the common deploy workflow's precedence:

  1. appsettings.json — Netdocs;
  2. zensical.toml — a Python 3.12.10 uv environment, Zensical, and tomli-w;
  3. Gemfile — the project's Bundler/Jekyll environment;
  4. package.json — Bun and the package's Vite development script;
  5. otherwise — implicit GitHub Pages/Jekyll.

A Netdocs target uses the upstream native self-contained executable and the documented netdocs serve --config ./appsettings.json --port <port> flow. At server startup, the shared preview cache checks the upstream latest-release API and downloads a new Windows x64 or Linux x64 executable only when needed. Multiple Netdocs targets share that installation and a startup lock, while each target retains its own appsettings.json, docs/, configured siteDir, watcher, and live-reload server.

The last case matters: ORC's app, lab, and pages targets are GitHub Pages sites even though only pages currently renders an explicit _config.yml. Only these otherwise-unclaimed targets use the shared, preview-only github-pages bundle. Native Gemfile, Zensical, and Vite projects never enter that compatibility path. The bundle supplies Pages behavior such as optional front matter, default layouts, README indexes, relative links, and GitHub Flavored Markdown. This is the local equivalent of the second Jekyll build GitHub performs after ORC pushes a rendered tree to its target repository.

For an implicit Pages target, remote_theme: owner/repository[@ref] is resolved to that Git repository. Supported default jekyll-theme-* selections resolve to their official pages-themes repositories; an omitted selection uses the GitHub Pages default pages-themes/primer. Identical selections share one shallow checkout, and layered files use hard links where the filesystem supports them. The preview refreshes each unique checkout once when it starts, then layers only the theme's _layouts, _includes, _sass, _data, and assets beneath the rendered site. Copying is non-destructive: an ORC-rendered path always wins. Theme configuration, Gemfiles, sample pages, and repository metadata are never imported, so a theme cannot replace project configuration or content. Declared/default gem theme settings remain active so their plugin dependencies load normally. For a remote_theme, the server reads a preview-only copy of the ORC config with only that fetch directive removed; the source _config.yml is not edited.

GitHub metadata uses the checkout's origin owner together with each deployment's TargetRepo. Local-path clones are followed back to their upstream checkout. If the owner cannot be inferred, set it explicitly before starting:

$env:GITHUB_REPOSITORY_OWNER = "CommanderTurtle"

The first implicit Pages launch installs the shared gem bundle. Later launches reuse it. A project with its own Gemfile remains independent and uses its native bundle. A theme Git checkout records the exact commit used and refreshes on the next preview start. The launcher also carries a process-local Ruby 3.4 compatibility fix for the edit-link tag in the version of jekyll-github-metadata pinned by GitHub Pages; no installed gem is modified.

Saving a file does not trigger a replacement build system. ORC overwrites only the corresponding mirror file (or dependent pages after a helper change), and Zensical, Jekyll, or Vite performs its normal rebuild/reload. A brief quiet window coalesces editor save patterns and folder replacements; configure it with --settle-ms.

Each deploy record's UseSharedStrings boolean is also honored locally. When true, the preview loads that site's strings/sharedstrings.fs helper through open SharedStrings before rendering its wrappers. Other sites are untouched, and the helper never appears in their working mirrors.

When the deploy configuration itself changes, the parent shuts down cleanly. Restart it with a port for each newly discovered target.

About

a previewer for fsharp orchestrator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages