Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ jobs:
- run: sh -n install.sh && bash -n install.sh
- run: bun build --compile src/main.ts --outfile dist/hqterm && ./dist/hqterm --version

# The Windows installer for real: download, verify, install, PATH, twice
# (a re-run over an existing hqsh.exe must work too).
windows-install:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: install.ps1 (Windows PowerShell)
shell: powershell
run: ./install.ps1
- name: install.ps1 again (pwsh), then hqsh runs from the user PATH
shell: pwsh
run: |
./install.ps1
$env:Path = [Environment]::GetEnvironmentVariable('Path', 'User') + ';' + $env:Path
hqsh version
if ($LASTEXITCODE -ne 0) { exit 1 }

desktop:
runs-on: ubuntu-latest
defaults:
Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ curl -fsSL https://hqterm.sh/install | sh
Installs `hqterm` and `hqsh` for Linux or macOS (x86_64, arm64) into
`~/.local/bin` (or `$HQTERM_BIN`). On a server you connect to, only hqsh is
needed: `curl -fsSL https://hqterm.sh/install | sh -s -- --server` (the `i` key
in hqterm does it for you).
in hqterm does it for you). That also runs `hqsh server setup`: sessions run as
systemd user units on Linux (lingering on, so they survive logout) and as
launchd jobs on macOS. Windows PCs and servers:
`irm https://hqterm.sh/install.ps1 | iex` (hqsh.exe, put on your user PATH;
sessions run on ConPTY).

When Tailscale is running, your online tailnet machines appear as hosts and
hqsh connects over the tailnet (`--tailscale auto|on|off`).

**Full documentation: https://hqterm.sh/docs** (`site/docs.html`).

## Use

Expand Down Expand Up @@ -82,7 +91,8 @@ Releases: push a `v*` tag matching package.json; CI builds
`hqterm-{linux,darwin}-{amd64,arm64}`, `hqterm-desktop-linux-{x86_64,aarch64}.AppImage`
and `SHA256SUMS` (bump `desktop/package.json` too).

`site/index.html` is the hqterm.sh landing page; `install.sh` is served at
https://hqterm.sh/install.
`site/index.html` is the hqterm.sh landing page and `site/docs.html` is
https://hqterm.sh/docs; `install.sh` is served at https://hqterm.sh/install and
`install.ps1` at https://hqterm.sh/install.ps1.

MIT.
4 changes: 2 additions & 2 deletions desktop/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "hqterm-desktop",
"productName": "hqterm",
"version": "0.2.5",
"version": "0.3.0",
"description": "hqterm desktop: a terminal window that shows hqtui/qc images and HD emoji (xterm.js + node-pty).",
"license": "MIT",
"author": "Profullstack, Inc. <hello@profullstack.com>",
Expand Down
89 changes: 89 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# hqterm installer for Windows: https://hqterm.sh
#
# irm https://hqterm.sh/install.ps1 | iex
#
# Installs hqsh (the client and the host side of hqterm sessions) from the
# latest GitHub release of profullstack/hqsh into ~\.local\bin (or
# $env:HQTERM_BIN), checks it against SHA256SUMS, and puts that directory on
# your user PATH so ssh sessions find it. No admin rights. Safe to run again.
# Pin a version with $env:HQSH_VERSION = "v0.3.0".
$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'

function Say($msg) { Write-Host "hqterm install: $msg" }

$bin = if ($env:HQTERM_BIN) { $env:HQTERM_BIN } else { Join-Path $HOME '.local\bin' }
$arch = switch ($env:PROCESSOR_ARCHITECTURE) {
'AMD64' { 'amd64' }
'ARM64' { 'arm64' }
default { throw "hqterm install: unsupported CPU $($env:PROCESSOR_ARCHITECTURE) (x64 and arm64 only)" }
}
$base = if ($env:HQSH_VERSION) {
"https://github.com/profullstack/hqsh/releases/download/$($env:HQSH_VERSION)"
} else {
'https://github.com/profullstack/hqsh/releases/latest/download'
}

New-Item -ItemType Directory -Force -Path $bin | Out-Null
$tmp = Join-Path ([IO.Path]::GetTempPath()) ("hqterm-" + [Guid]::NewGuid())
New-Item -ItemType Directory -Path $tmp | Out-Null
try {
$asset = "hqsh-windows-$arch.exe"
Say "downloading $asset from github.com/profullstack/hqsh"
try {
Invoke-WebRequest -UseBasicParsing "$base/$asset" -OutFile (Join-Path $tmp $asset)
} catch {
if ($arch -eq 'arm64') {
# Older releases have no arm64 build; Windows on ARM runs x64 binaries.
$asset = 'hqsh-windows-amd64.exe'
Say "no arm64 build in this release; using $asset (runs under emulation)"
Invoke-WebRequest -UseBasicParsing "$base/$asset" -OutFile (Join-Path $tmp $asset)
} else { throw }
}
$file = Join-Path $tmp $asset
try {
Invoke-WebRequest -UseBasicParsing "$base/SHA256SUMS" -OutFile (Join-Path $tmp 'SHA256SUMS')
$line = Get-Content (Join-Path $tmp 'SHA256SUMS') | Where-Object { $_ -match "\s\*?$([regex]::Escape($asset))$" } | Select-Object -First 1
if (-not $line) {
Say "warning: $asset is not listed in SHA256SUMS; not verified"
} else {
$want = ($line -split '\s+')[0].ToLower()
$got = (Get-FileHash -Algorithm SHA256 $file).Hash.ToLower()
if ($want -ne $got) { throw "hqterm install: checksum mismatch for $asset (expected $want, got $got)" }
Say "verified $asset (sha256 $got)"
}
} catch [System.Net.WebException] {
Say 'warning: no SHA256SUMS in the release; not verified'
}

$dest = Join-Path $bin 'hqsh.exe'
# A running hqsh.exe (a live session's daemon) cannot be overwritten, but it
# can be renamed: move it aside, then put the new one in place.
if (Test-Path $dest) {
$old = "$dest.old"
Remove-Item -Force $old -ErrorAction SilentlyContinue
try { Move-Item -Force $dest $old } catch { Say "warning: could not move the old hqsh.exe aside: $_" }
}
Move-Item -Force $file $dest
Say "installed $dest"
} finally {
Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
}

# On the user PATH, so `ssh this-pc hqsh server attach` finds it.
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (-not (($userPath -split ';') -contains $bin)) {
[Environment]::SetEnvironmentVariable('Path', ($(if ($userPath) { "$userPath;" } else { '' }) + $bin), 'User')
Say "added $bin to your user PATH (new terminals and ssh sessions pick it up)"
}
$env:Path = "$env:Path;$bin"

& (Join-Path $bin 'hqsh.exe') server setup 2>$null
if ($LASTEXITCODE -ne 0) { Say "note: this hqsh has no 'server setup' yet; sessions start as detached processes" }

if (-not (Get-Service -Name sshd -ErrorAction SilentlyContinue)) {
Say 'note: to connect TO this PC, enable the OpenSSH server (as Administrator):'
Say ' Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0'
Say " Start-Service sshd; Set-Service sshd -StartupType Automatic"
}
Say 'done. Connect from here with: hqsh <host> (or hqterm on Linux/macOS)'
5 changes: 5 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ case ":$PATH:" in
esac

if [ "$SERVER" = 1 ]; then
# Sessions run under the service manager: systemd (with lingering, so they
# survive logout; this turns it on) or launchd. Older hqsh lacks `setup`.
if ! "$BIN/hqsh" server setup 2>/dev/null; then
say "note: this hqsh has no 'server setup'; sessions start as detached processes"
fi
say "done: hqsh is ready on this host"
else
say "done. Try: hqterm doctor then: hqterm"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hqterm",
"version": "0.2.5",
"version": "0.3.0",
"description": "Terminal session manager: persistent hqsh sessions with images and HD emoji, built on hqtui.",
"license": "MIT",
"private": true,
Expand Down
Loading
Loading