Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
7c88641
feat(ssh): add bounded controller message framing
Tutitoos Sep 19, 2026
8c43f57
feat(ssh): negotiate bounded controller handshakes
Tutitoos Sep 19, 2026
d4daf5f
feat(ssh): authenticate native desktop controller IPC
Tutitoos Sep 19, 2026
5e0e134
fix(ssh): reject linked IPC locks and canonicalize Windows root
Tutitoos Sep 19, 2026
0c86d73
Merge remote-tracking branch 'origin/main' into feat/151-ssh-desktop-…
Tutitoos Sep 19, 2026
abee0d5
feat(ssh): add fixture desktop shell and controller
Tutitoos Sep 19, 2026
6745fd0
docs(ssh): record native desktop CI results
Tutitoos Sep 19, 2026
9c9cd3f
fix(ssh): restrict Wails native bridge in desktop build
Tutitoos Sep 19, 2026
d924d5c
fix(ssh): decode Wails source as UTF-8 on Windows
Tutitoos Sep 19, 2026
01ef38b
test(ssh): probe native Wails bridge from macOS WebView
Tutitoos Sep 19, 2026
2de550f
docs(ssh): record user-level macOS install trial
Tutitoos Sep 19, 2026
203a108
docs(ssh): record Windows rendered preview evidence
Tutitoos Sep 19, 2026
9498934
docs(ssh): record Windows bridge probe result
Tutitoos Sep 19, 2026
86b5e94
fix(ssh): distinguish bridge timeouts from rejections
Tutitoos Sep 19, 2026
a6db23f
test(ssh): capture Linux virtual display window
Tutitoos Sep 19, 2026
de56555
docs(ssh): record Ubuntu virtual window evidence
Tutitoos Sep 19, 2026
f183222
test(ssh): capture Linux bridge diagnostics in CI
Tutitoos Sep 19, 2026
0dc33a7
docs(ssh): record Ubuntu bridge diagnostic evidence
Tutitoos Sep 19, 2026
d0ab8c4
fix(ssh): publish installation identity atomically
Tutitoos Sep 19, 2026
c248f02
test(ssh): verify controller ownership and crash restart
Tutitoos Sep 19, 2026
a36043f
docs(ssh): generalize workstation evidence
Tutitoos Sep 19, 2026
0e6868d
fix: restrict packaged SSH window navigation on macOS and Linux
Tutitoos Sep 19, 2026
b1609d4
fix: guard SSH desktop WebView2 navigation
Tutitoos Sep 19, 2026
3b111b9
fix: avoid incompatible WebView2 callback initializers
Tutitoos Sep 19, 2026
0013f86
test: capture SSH desktop navigation probes
Tutitoos Sep 19, 2026
3091594
fix: deny WebView2 browser permissions in SSH shell
Tutitoos Sep 19, 2026
4465243
fix(ssh): keep bridge payloads out of desktop logs
Tutitoos Sep 19, 2026
9a0ceca
test(ssh): verify controller isolation across processes
Tutitoos Sep 19, 2026
c33e94f
docs(ssh): record macOS concurrent window trial
Tutitoos Sep 19, 2026
c81e21a
docs(ssh): record Windows concurrent window trial
Tutitoos Sep 19, 2026
b31c28d
test: exercise SSH desktop under virtual Wayland
Tutitoos Sep 19, 2026
6123965
docs: record virtual Wayland lifecycle evidence
Tutitoos Sep 19, 2026
5e19990
chore: remove trailing blank line from macOS bridge patch
Tutitoos Sep 19, 2026
5a9235b
test: capture synthetic Wayland window in CI
Tutitoos Sep 19, 2026
e97ce06
docs: record inspected virtual Wayland rendering
Tutitoos Sep 19, 2026
2758583
test: probe SSH WebView navigation on virtual Wayland
Tutitoos Sep 19, 2026
abcae29
docs: record virtual Wayland navigation observation
Tutitoos Sep 19, 2026
8448576
fix(ssh): diagnose Linux desktop launch requirements
Tutitoos Sep 19, 2026
1d6e569
fix(ssh): resolve linked Linux desktop launcher
Tutitoos Sep 20, 2026
0f9cc34
test(ssh): render copied Linux desktop package via link
Tutitoos Sep 20, 2026
9cfc896
fix(ssh): bound native bridge call messages at ingress
Tutitoos Sep 20, 2026
0073317
fix(ssh): keep fixture navigation accessible
Tutitoos Sep 20, 2026
865f70b
test(ssh): probe native window title boundary
Tutitoos Sep 20, 2026
90063fa
fix(ssh): report overlong Unix controller endpoint
Tutitoos Sep 20, 2026
415ce0d
fix(ssh): expose fixture navigation selection
Tutitoos Sep 20, 2026
b0d3c52
fix(ssh): hide sidebar text at compact widths
Tutitoos Sep 20, 2026
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
122 changes: 122 additions & 0 deletions .github/workflows/ssh-desktop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: SSH desktop foundation

on:
pull_request:
paths:
- '.github/workflows/ssh-desktop.yml'
- 'cmd/atenea-ssh-controller/**'
- 'internal/sshcontrol/**'
- 'desktop/ssh/**'
- 'go.mod'
- 'go.sum'

jobs:
native-build:
strategy:
fail-fast: false
matrix:
os: [macos-15, windows-2025, ubuntu-24.04]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.26.7'
- uses: oven-sh/setup-bun@v2
with:
bun-version: '1.4.2'
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Linux WebView build dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev xvfb xauth xdotool imagemagick dbus-x11 weston
- name: Frontend check and build
working-directory: desktop/ssh/frontend
shell: bash
run: |
bun install --frozen-lockfile
bun run check
bun run build
- name: Native controller tests
shell: bash
run: go test -race -count=1 ./internal/sshcontrol/...
- name: Build Wails shell
working-directory: desktop/ssh
shell: bash
run: |
python scripts/restricted_wails.py test
python scripts/restricted_wails.py build
- name: Check Linux launcher diagnostics
if: runner.os == 'Linux'
working-directory: desktop/ssh
shell: bash
run: bash scripts/linux_launcher_test.sh
- name: Bundle controller beside window
shell: bash
run: |
case "${{ runner.os }}" in
macOS) target=desktop/ssh/build/bin/atenea-ssh.app/Contents/MacOS/atenea-ssh-controller ;;
Windows) target=desktop/ssh/build/bin/atenea-ssh-controller.exe ;;
Linux) target=desktop/ssh/build/bin/atenea-ssh-controller ;;
esac
go build -o "$target" ./cmd/atenea-ssh-controller
- name: Render Linux window in a virtual X11 session
if: runner.os == 'Linux'
working-directory: desktop/ssh
shell: bash
run: dbus-run-session -- xvfb-run -a -s '-screen 0 1280x800x24' bash scripts/linux_render_smoke.sh
- name: Render copied Linux package through a Terminal link
if: runner.os == 'Linux'
working-directory: desktop/ssh
shell: bash
run: |
install_root=$(mktemp -d)
trap 'rm -rf "$install_root"' EXIT
mkdir -p "$install_root/bin" "$install_root/command" "$install_root/config"
install -m 755 build/bin/atenea-ssh build/bin/atenea-ssh-bin build/bin/atenea-ssh-controller "$install_root/bin/"
ln -s ../bin/atenea-ssh "$install_root/command/atenea-ssh"
ATENEA_SSH_SHELL="$install_root/command/atenea-ssh" \
ATENEA_SSH_CONTROLLER="$install_root/bin/atenea-ssh-controller" \
ATENEA_SSH_CAPTURE=build/ci-artifacts/linux-installed-link.png \
XDG_CONFIG_HOME="$install_root/config" \
dbus-run-session -- xvfb-run -a -s '-screen 0 1280x800x24' bash scripts/linux_render_smoke.sh
- name: Exercise Linux lifecycle in a virtual Wayland session
if: runner.os == 'Linux'
working-directory: desktop/ssh
shell: bash
run: dbus-run-session -- bash scripts/linux_wayland_lifecycle.sh
- name: Probe Linux WebView bridge in virtual X11
if: runner.os == 'Linux'
working-directory: desktop/ssh
shell: bash
run: |
python scripts/restricted_wails.py probe-build
(cd ../.. && go build -o desktop/ssh/build/bin/atenea-ssh-controller ./cmd/atenea-ssh-controller)
ATENEA_SSH_CAPTURE=build/ci-artifacts/linux-bridge-probe.png dbus-run-session -- xvfb-run -a -s '-screen 0 1280x800x24' bash scripts/linux_render_smoke.sh
- name: Capture Linux WebView navigation probe in virtual X11
if: runner.os == 'Linux'
working-directory: desktop/ssh
shell: bash
run: |
python scripts/restricted_wails.py navigation-probe-build
(cd ../.. && go build -o desktop/ssh/build/bin/atenea-ssh-controller ./cmd/atenea-ssh-controller)
ATENEA_SSH_CAPTURE=build/ci-artifacts/linux-navigation-probe.png dbus-run-session -- xvfb-run -a -s '-screen 0 1280x800x24' bash scripts/linux_render_smoke.sh
- name: Capture Linux WebView navigation probe in virtual Wayland
if: runner.os == 'Linux'
working-directory: desktop/ssh
shell: bash
run: ATENEA_SSH_CAPTURE=build/ci-artifacts/linux-wayland-navigation-probe.png ATENEA_SSH_CAPTURE_DELAY=7 dbus-run-session -- bash scripts/linux_wayland_lifecycle.sh
- name: Save Linux window capture
if: runner.os == 'Linux' && always()
uses: actions/upload-artifact@v4
with:
name: atenea-ssh-linux-window
path: |
desktop/ssh/build/ci-artifacts/linux-render-smoke.png
desktop/ssh/build/ci-artifacts/linux-installed-link.png
desktop/ssh/build/ci-artifacts/linux-bridge-probe.png
desktop/ssh/build/ci-artifacts/linux-navigation-probe.png
desktop/ssh/build/ci-artifacts/linux-wayland.png
desktop/ssh/build/ci-artifacts/linux-wayland-navigation-probe.png
if-no-files-found: ignore
53 changes: 53 additions & 0 deletions cmd/atenea-ssh-controller/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"context"
"errors"
"flag"
"fmt"
"os"
"os/signal"
"time"

"github.com/Tutitoos/atenea/internal/sshcontrol/controller"
)

// The controller deliberately exposes no SSH commands in this foundation.
func main() {
rootFlag := flag.String("root", "", "absolute per-user state directory")
stopFlag := flag.Bool("stop", false, "stop the current user's controller")
flag.Parse()
if flag.NArg() != 0 {
fmt.Fprintln(os.Stderr, "unexpected arguments")
os.Exit(2)
}
root := *rootFlag
if root == "" {
var err error
root, err = controller.Root()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
id, err := controller.InstallationID(root)
if err == nil && *stopFlag {
ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
defer cancel()
_, err = controller.Call(ctx, root, id, "stop")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
return
}
if err == nil {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
err = controller.Serve(ctx, root, id)
}
if err != nil && !errors.Is(err, context.Canceled) {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
8 changes: 8 additions & 0 deletions desktop/ssh/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/build/bin/
/build/ci-artifacts/
/frontend/node_modules/
/frontend/dist/*
!/frontend/dist/gitkeep
/frontend/wailsjs/
/frontend/package.json.md5
/ssh
Loading
Loading