← knowledge.oriz.in

Start dev server from source (OmniRoute, freellmapi, any fleet fork)

runbook runbookdev-serveromniroutefreellmapiforkwindowsstartup

Start dev server from source

Generalised procedure for migrating any fleet fork from global package install (npm install -g <pkg> / pipx install <pkg>) to running the dev server out of repos/frk/<name>. Already applied to OmniRoute and freellmapi; the pattern below works for any new fork.

When to use this

Pre-requisites

Procedure

1. Fork the upstream to chirag127

gh repo fork <upstream-org>/<upstream-name> --org chirag127 --clone=false --default-branch-only

If GitHub creates a <name>-1 because <name> was taken by an earlier fork, delete the old one first:

gh api orgs/chirag127/repos --paginate --jq '.[] | select(.name | startswith("<name>")) | "\(.name) | fork=\(.fork) | parent=\(.parent.full_name)"'
gh repo delete chirag127/<duplicate-name> --yes

Verify the canonical fork's parent matches the desired upstream.

2. Clone into the workspace

git clone https://github.com/chirag127/<name>.git C:\D\oriz\repos\frk\<name>
cd C:\D\oriz\repos\frk\<name>
git remote add upstream https://github.com/<upstream-org>/<upstream-name>.git

3. Identify the dev command + port

Get-Content package.json | Select-String -Pattern '"(dev|start|build)"'

Find the port:

4. Write the start script

Save as C:\D\oriz\scripts\start-<name>-dev.ps1. Template — fill in the bracketed placeholders:

#Requires -Version 5.1
$ErrorActionPreference = 'Continue'
$repo = 'C:\D\oriz\repos\frk\<NAME>'
$psPath = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
$serverPort = <PORT>   # e.g. 20128 for OmniRoute, 3001 for freellmapi

# Idempotency: skip if already running
$listening = Get-NetTCPConnection -LocalPort $serverPort -State Listen -ErrorAction SilentlyContinue
if ($listening) {
    Write-Host "<NAME> already on :$serverPort (PID $($listening[0].OwningProcess))" -ForegroundColor Yellow
    Start-Sleep 3
    exit 0
}

if (-not (Test-Path $repo)) { Write-Host "repo missing"; exit 1 }
Set-Location $repo

# Track lockfile state BEFORE pull (decide if install is needed)
$lockBefore = if (Test-Path '<LOCKFILE>') { (Get-FileHash '<LOCKFILE>' -Algorithm SHA256).Hash } else { '' }
$pkgBefore  = if (Test-Path 'package.json') { (Get-FileHash 'package.json' -Algorithm SHA256).Hash } else { '' }

# Pull upstream
git fetch upstream 2>&1 | Out-Null
git merge --ff-only upstream/main 2>&1 | Out-Null

# Re-hash; install only if changed
$lockAfter = if (Test-Path '<LOCKFILE>') { (Get-FileHash '<LOCKFILE>' -Algorithm SHA256).Hash } else { '' }
$pkgAfter  = if (Test-Path 'package.json') { (Get-FileHash 'package.json' -Algorithm SHA256).Hash } else { '' }
$needsInstall = (-not (Test-Path 'node_modules')) -or ($lockBefore -ne $lockAfter) -or ($pkgBefore -ne $pkgAfter)

# ABSOLUTE PATH — see rules/development/windows-shortcut-absolute-binary-paths
$pm = 'C:\Program Files\nodejs\<PM>.cmd'   # pnpm.cmd OR npm.cmd
$inner = if ($needsInstall) {
    "Write-Host 'Installing...'; & '$pm' install; & '$pm' <DEV-CMD>"
} else {
    "& '$pm' <DEV-CMD>"
}

Start-Process wt -ArgumentList "new-tab --title `"<NAME> Dev`" -d `"$repo`" `"$psPath`" -NoExit -Command `"$inner`""
Write-Host "<NAME> dev launching on http://localhost:$serverPort"
Start-Sleep 3

Replace <NAME>, <PORT>, <LOCKFILE> (pnpm-lock.yaml or package-lock.json), <PM> (pnpm or npm), <DEV-CMD> (dev or run dev).

5. Create the startup shortcut

$startupDir = [System.Environment]::GetFolderPath('Startup')
$shortcutPath = Join-Path $startupDir "<NAME> Dev.lnk"
$scriptPath = "C:\D\oriz\scripts\start-<name>-dev.ps1"

$wsh = New-Object -ComObject WScript.Shell
$lnk = $wsh.CreateShortcut($shortcutPath)
$lnk.TargetPath = "powershell.exe"
$lnk.Arguments = "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$scriptPath`""
$lnk.WorkingDirectory = "C:\D\oriz"
$lnk.IconLocation = "powershell.exe,0"
$lnk.Description = "Auto-pull and start <NAME> dev server"
$lnk.Save()

6. Optional: desktop shortcut for manual trigger

$desktop = [System.Environment]::GetFolderPath('Desktop')
Copy-Item $shortcutPath (Join-Path $desktop "<NAME> Dev.lnk") -Force

7. First-time install + sanity test

& "C:\D\oriz\scripts\start-<name>-dev.ps1"

A new Windows Terminal tab should appear, run pnpm install / npm install (5-8 min one-time), then start the dev server. Visit http://localhost:<PORT> to confirm.

8. Stop the old global install

# Free the port if the old npm-installed version is still running
Get-NetTCPConnection -LocalPort <PORT> -State Listen | ForEach-Object {
    Stop-Process -Id $_.OwningProcess -Force
}
# Optionally uninstall the global
npm uninstall -g <pkg-name>

Currently applied to

Reverting (back to global install)

# Remove the startup + desktop shortcuts
Remove-Item "$([Environment]::GetFolderPath('Startup'))\<NAME> Dev.lnk"
Remove-Item "$([Environment]::GetFolderPath('Desktop'))\<NAME> Dev.lnk"

# Stop the dev server
Get-NetTCPConnection -LocalPort <PORT> -State Listen | ForEach-Object {
    Stop-Process -Id $_.OwningProcess -Force
}

# Reinstall the global
npm install -g <pkg-name>

The fork at repos/frk/<name> can stay — it's just no longer auto-started.

Common gotchas

See also