A terminal application for iOS 26, on iPhone and iPad. The default shell runs real ARM commands inside the app, with no emulation in that path. Selectable Linux environments are in development. The source is public and the app is meant to be sold as a signed, maintained App Store build.
Fiosh opens a terminal on the device and runs a native shell in it. The shell runs the commands
of the bundled ios_system frameworks: the core plus files, shell, text, awk and tar.
The terminal is SwiftTerm. The app holds up to eight session tabs. Each session runs Fiosh's own
line editor, with cursor editing, command history, ctrl-c and ctrl-d. The home of the shell is
the app's Documents directory. Every session starts there, and the Files app shows it.
Network commands are not bundled. The command dictionary drops the entries for curl and ssh,
so those names stay unknown to the shell.
The native lane works, and it is what the app runs today. The Linux lanes are in development: the tree carries the vendored upstreams, the cross-builds that turn them into iOS binaries, and standalone spike apps that measure them on real hardware. No Linux engine package exists yet.
| Lane | Engine | Guest | State in the tree |
|---|---|---|---|
| Native, the default | ios_system | real ARM code inside the app | works; the app runs it today |
| Usermode | gadget interpreter, iSH-AOK lineage | aarch64 Linux userspace | fork vendored, iOS cross-build, boot spike app |
| Full-system | QEMU + TCTI | a real Linux kernel | fork vendored, iOS cross-build, measured boot and snapshot spikes |
Packages/FioshCore holds the engine protocol that every lane implements, and the conformance
suite that every engine has to pass. Packages/FioshInfra is still a skeleton with the
checkpoint store in it.
A build of the app needs two things:
- macOS with Xcode 26. Xcode 26 carries the iOS 26 SDK.
- mise. mise pins xcodegen and swiftlint.
Formatting and linting need nothing more. Both use the Xcode toolchain's own swift format.
A rebuild of the engine binaries also needs the submodules under Vendor/ and the Homebrew
packages scripts/README.md names per script.
mise install
make generate
open Fiosh.xcodeprojmake generate writes Fiosh.xcodeproj from project.yml. git does not track the generated
project file, so run make generate on a fresh clone before you open the project.
Run everything that CI runs:
make check| Target | What it does |
|---|---|
generate |
writes Fiosh.xcodeproj from project.yml |
fmt |
formats the Swift sources in place |
lint |
runs swift format in strict mode, then SwiftLint |
test |
runs the package tests on the host, plus the native engine's tests on an iPhone 17 simulator |
engines |
rebuilds the vendored engine binaries from source |
check |
runs generate, lint and test, then a simulator build of the app |
The git submodules under Vendor/ are optional, and a normal build never reads them. The native
engine's binary targets point at checksummed xcframeworks published as releases of the project's
own ios_system fork, and Packages/EngineNative/Package.swift pins both URLs and checksums.
make engines rebuilds those binaries from source. It builds the ios_system xcframeworks from
Vendor/ios_system and runs scripts/build-qemu-ios.sh for Vendor/qemu. It reports each absent
checkout and still exits successfully, so a clone with no submodule initialised is safe to run.
Neither Linux lane has a prebuilt release. scripts/build-qemu-ios.sh builds the full-system one
from source or it is not built at all. scripts/build-gadget-ios.sh builds the usermode one,
outside make engines. Vendor/README.md describes the vendoring arrangement, and
scripts/README.md the engine builds and the guest images.
| Path | Contents |
|---|---|
Packages/FioshCore |
the engine protocol, the models and the conformance suite |
Packages/EngineNative |
the ios_system lane and the line editor |
Packages/FioshInfra |
the checkpoint store, and the layer where image and catalog handling land |
FioshApp/ |
the iOS app: terminal UI, session tabs, and the one place engines and infrastructure are wired together |
Vendor/ |
the engine upstreams as pinned submodules of the project's forks: ios_system, QEMU and iSH-AOK |
Spikes/ |
standalone apps that each answer one measurement question on real hardware, plus the harness package they share |
| Symptom | Cause | Action |
|---|---|---|
open Fiosh.xcodeproj finds no project. |
The project file is generated. git does not track it. | Run make generate. |
| The build fails on a Metal shader. | SwiftTerm compiles a Metal shader. Xcode 26 ships the Metal toolchain as an optional download. | Run xcodebuild -downloadComponent MetalToolchain one time. |
make test fails on the destination. |
The test target needs an iPhone 17 simulator. |
Install that simulator in Xcode. |
make engines reports that nothing is vendored. |
The submodule is absent. A fresh clone does not fetch it. | Run git submodule update --init --recursive Vendor/ios_system. |
The shell reports that curl or ssh is unknown. |
The network command frameworks are not bundled. | None. The absence is deliberate. |
Fiosh's own code is GPLv3. This covers the app, the packages, the spike apps and the build
scripts. See LICENSE for the full text. The patch files under scripts/ change
third-party sources, and each patch follows the license of the project it applies to.
The vendored engines are not ours. Each one carries its own terms:
| Component | Terms |
|---|---|
| ios_system | BSD-3-Clause |
| the command frameworks built from ios_system | the permissive licenses of their third-party command sources: mostly BSD, with individual files under APSL 2.0, and awk under the Lucent license |
| QEMU | GPLv2. The slim iOS build links a set of files that are GPLv2-only. |
| the gadget interpreter fork | GPLv3, with its later contributions additionally offered under GPLv2 |
The license of the combined shipping app is therefore an open question rather than a settled one,
and the project keeps it open on purpose. Engines are designed as on-demand dlopen'd frameworks,
so the decision stays reversible. No license has been chosen for a shipped binary, and none can
be inferred from this repository.