Skip to content

Latest commit

 

History

124 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BicTerm

⚠️ WORK IN PROGRESS — NOT FULLY FUNCTIONAL

This project is under active development and is not ready for use. It was built using AI-assisted "vibe coding" — code was generated by AI agents working from a detailed plan, not hand-crafted by a human who understood every line. Treat it accordingly: there are bugs, untested edge cases, and rough edges. Review everything before relying on any of it.

An iOS 18+ SSH terminal client for iPhone and iPad, built on SwiftNIO SSH and SwiftTerm.

What Works

  • SSH connections with password auth (RFC 4252 password, secrets in Keychain) and public-key auth (ed25519 from Keychain, P-256 from Secure Enclave)
  • ProxyJump / jump chains up to 5 hops with per-hop host-key verification
  • TOFU host-key trust — fingerprint prompt on first connect, hard reject on changed keys
  • In-app SSH agent with per-request authorization, session cache, auto-deny when backgrounded
  • Terminal UI — SwiftTerm-based, hardware keyboard, IME/CJK composition, multi-window on iPad
  • Multiple concurrent sessions — session switcher with detach/reattach that preserves terminal state, on iPhone and iPad
  • Graceful reconnect — background suspends, foreground re-handshakes; no auto-reconnect after kill
  • Coder REST integration — multi-server config, workspace discovery, agent picker, start policy, connect to running workspaces
  • Coder tailnet tunnel (default flavor) — native coder ssh-style connectivity over the userspace tailnet core (CoderNet.xcframework, AGPL), compiled in behind the CODER_TUNNEL flag. The AppStore flavor excludes it entirely and uses direct SSH instead.
  • Herdr client — workspace handshake, native surface rendering, semantic keyboard/focus/resize input, clipboard text and bounded image paste, probe diagnostics, detach/reconnect
  • Transport abstraction — SSH is one conformer; ET/mosh can be added later without touching session layers

What Doesn't Work Yet

  • Live herdr-server validation on this dev host — building the herdr v0.9.0 server fixture needs zig 0.15.x, which fails to link libSystem on macOS 26 (toolchain-vs-host issue, not an app defect). Persistence and lifecycle tests currently run against committed-frame replay. See .omo/evidence/phase2-h16-server-fixture.md.
  • No mosh or Eternal Terminal — architecture supports adding them, but they are not implemented in v1.
  • Pointer/touch routing for herdr panes, graphics scenes, OSC 8 safe-open — triaged as future-phase work in Docs/HERDR-RELEASE-TRACEABILITY.md.

What's Not In Scope (v1)

  • Keyboard-interactive auth (NIOSSH has no keyboard-interactive client; password and public-key only)
  • RSA keys / key export
  • SFTP/SCP or port forwarding
  • Terminal transcript/scrollback persistence
  • Analytics
  • ssh_config/known_hosts import
  • Custom CA/self-signed Coder TLS

Architecture

BicTermCore (Swift package — no SwiftUI/UIKit)
├── SSH/          SSH transport, agent codec, ProxyJump
├── Transport/    TerminalTransport protocol + capability descriptors
├── Sessions/     Session registry, reconnect engine
├── Keys/         Keychain repo, OpenSSH parser, Secure Enclave
├── Trust/        Host-key TOFU verifier
├── Coder/        REST client, token store, workspace model
└── Models/       Connection, Hop, SessionSnapshot, etc.

BicTerm (iOS app)
├── App/          SwiftUI shell, scene manifest
├── Terminal/     SwiftTerm integration
├── Sessions/     Session UI, trust prompts
├── Connections/  Connection list + editor
├── Keys/         Key management UI
├── Coder/        Coder server config pane
├── Agent/        Agent authorization UI
└── Design/       Tokens, dark-first appearance

Dependencies

External tools the build, test, and fixture chain needs. SwiftTerm 1.20.0 and swift-nio-ssh 0.15.0 are vendored under Vendor/ and need no separate install; do not brew anything for them.

Tool Minimum version Why it's needed Install (macOS)
Xcode 26, plus the iOS 26.3 simulator runtime Builds the app; provides xcodebuild, xcrun, clang, dsymutil, and the simulators every script targets Mac App Store or developer.apple.com, then xcode-select --install
XcodeGen 2.x Generates BicTerm.xcodeproj from project.yml; required before any Xcode or xcodebuild run brew install xcodegen
Go any recent release (the CoderNet/go.mod toolchain directive pins go1.26.5 and Go auto-downloads it) Builds CoderNet.xcframework via scripts/build-coder-net.sh (go build -buildmode=c-archive); also builds the derp-proxy in scripts/test-coder-derp.sh brew install go
Python 3 3.9+ (stdlib only) Runs the Coder API stub and UDS forwarder (Fixtures/coder/stub.py, Fixtures/bin/uds-forward.py) and the JSON/token helpers inside fixtures-up.sh and coder-dev-up.sh Ships with the Xcode Command Line Tools; Homebrew alternative: brew install python
Rust (rustup + cargo) stable, with targets aarch64-apple-ios and aarch64-apple-ios-sim Builds the herdr FFI core in scripts/build-herdr-core.sh and Vendor/herdr/check.sh. Both scripts override RUSTUP_HOME to the repo-local .build-artifacts/rustup, so add the targets with that env set: RUSTUP_HOME=.build-artifacts/rustup rustup target add aarch64-apple-ios aarch64-apple-ios-sim curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh (or brew install rustup-init + rustup-init)
cbindgen pinned by cargo install --locked Generates HerdrCore.h; build-herdr-core.sh installs it repo-locally into .build-artifacts/tools/ on first run No action needed
cargo-deny latest License and advisory policy checks in Vendor/herdr/check.sh cargo install cargo-deny
jq 1.6+ License inventory assembly in Vendor/herdr/check.sh brew install jq
OpenSSH (/usr/sbin/sshd, ssh, ssh-keygen), nc, curl, openssl, unzip system versions SSH fixtures on ports 12222/12223, Coder binary download and password generation Preinstalled on macOS; nothing to install
Ruby system Ruby (stdlib only) Coder acceptance helpers (scripts/*.rb) Preinstalled on macOS; nothing to install
xcbeautify any (optional) Prettier xcodebuild output in build-appstore.sh, test-core.sh, test-ui.sh; all three fall back to raw logs when absent brew install xcbeautify
cargo-audit, cargo-fuzz latest (optional, hardening only) Advisory audits and the herdr fuzz targets under Vendor/herdr/herdr-ios-ffi/fuzz/ (fuzz needs a nightly toolchain). Neither is installed on the current dev machine, and nothing in the normal build/test chain requires them cargo install cargo-audit cargo-fuzz

What each feature needs

Feature Required tools
Basic app build (xcodegen generate, open Xcode, build) Xcode, XcodeGen
Default flavor, scheme BicTerm (CoderNet tailnet tunnel) Above, plus Go, then scripts/build-coder-net.sh
AppStore flavor (scripts/build-appstore.sh) Xcode, XcodeGen (xcbeautify optional). No Go, no tunnel core
Test fixtures (scripts/fixtures-up.sh) Python 3 and the preinstalled OpenSSH/curl tools
Coder native dev fixture (scripts/coder-dev-up.sh) Python 3, curl, openssl, unzip, system Ruby. The script downloads and sha256-verifies the pinned coder v2.36.4 binary itself; PostgreSQL is embedded in coder server, so there is no database to install
herdr FFI build (scripts/build-herdr-core.sh) Rust with both iOS targets (cbindgen self-installs)
Hardening / SBOM (Vendor/herdr/check.sh, fuzz targets) cargo-deny, jq; cargo-audit and cargo-fuzz for the optional audit/fuzz passes

Not required: Docker (no container is used anywhere in the fixture flow), and zig. The live herdr server fixture would need zig 0.15.x, which fails to link on macOS 26 (see "What Doesn't Work Yet"), but no build or test script invokes zig.

Common-case install

brew install xcodegen go python jq
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
RUSTUP_HOME=.build-artifacts/rustup rustup target add aarch64-apple-ios aarch64-apple-ios-sim
cargo install cargo-deny   # only needed for Vendor/herdr/check.sh

Verify your setup

xcodebuild -version      # Xcode 26+
xcodegen --version       # 2.x
go version               # any recent Go; go.mod pins the exact toolchain
python3 --version        # 3.9+
cargo --version          # rustup-managed stable
RUSTUP_HOME=.build-artifacts/rustup rustup target list --installed | grep apple-ios   # both iOS targets
jq --version
/usr/sbin/sshd -? 2>&1 | head -1   # system sshd present

Building

Install the tools above first: see Dependencies.

# Prerequisites: Xcode 26+, iOS 26.3 simulator runtime
xcodegen generate
open BicTerm.xcodeproj
# Default (open-source) flavor: scheme BicTerm, destination iPhone 17 Pro
# or iPad Pro 13-inch (M5). Requires the tunnel core:
scripts/build-coder-net.sh   # builds .build-artifacts/coder-net/CoderNet.xcframework (AGPL)
# AppStore flavor (no AGPL code, no tunnel): script wrapper, scheme BicTerm-AppStore
scripts/build-appstore.sh    # AppStore-Release by default; pass AppStore-Debug to debug

Testing

The fixtures and suites below need the tools listed under Dependencies.

# Start local fixtures (sshd on 12222/12223, Coder stub on 18080)
scripts/fixtures-up.sh

# Core unit/integration tests
scripts/test-core.sh

# UI tests
scripts/test-ui.sh

# Tear down fixtures
scripts/fixtures-down.sh

Vendored Libraries

  • swift-nio-ssh 0.15.0 (Apache 2.0) — vendored fork with agent-forwarding patches
  • SwiftTerm 1.20.0 (MIT) — vendored fork

See DEPENDENCIES.md for the full license inventory.

License

TBD — not yet licensed. All rights reserved until decided.

Dual-build licensing note (phase 2, task 7): BicTerm ships in two build flavors.

  • The default flavor (scheme BicTerm, configurations Debug/Release) links the Coder tailnet-tunnel Go core (CoderNet.xcframework, built from CoderNet/ on top of coder/coder v2.36.4). Because that core is AGPL-3.0, default-flavor binaries are AGPL-3.0 binaries — fine for open-source distribution.
  • The AppStore flavor (scheme BicTerm-AppStore, configurations AppStore-Debug/AppStore-Release, built via scripts/build-appstore.sh) contains no AGPL code at all: the CoderTunnel framework target and the CODER_TUNNEL compilation flag are excluded, coder connections use the direct-SSH path, and a three-layer audit (build-system / bundle+otool / strings symbol sweep) proves the exclusion each release. See CoderNet/LICENSE-AGPL-NOTICE.md and Docs/SECURITY.md.

Disclaimer

This project was developed using AI-assisted code generation ("vibe coding"). The code was produced by autonomous AI agents executing a detailed plan. While it compiles, passes tests, and has been reviewed, it has not received the level of human scrutiny that hand-written production code would. Use at your own risk.

About

iOS SSH terminal client with agent forwarding, ProxyJump & Coder integration — WORK IN PROGRESS, vibe-coded

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages