/omnifs
/omnifs
DOCS GITHUB CONTACT
/intro

/OMNIFS

open a /path, read the world

omnifs lets you access the world through your filesystem. APIs and data sources become files and directories you can ls, cat, grep, pipe, and hand to an agent.

omnifs shell
# read GitHub as files
# issues are files: list, count, grep, cat
/ $ ls /github/0xff-ai/omnifs
actions issues pulls repo
/ $ ls /github/0xff-ai/omnifs/issues/open | wc -l
47
/ $ grep -rl "ROCm" /github/0xff-ai/omnifs/issues/open
/github/0xff-ai/omnifs/issues/open/1432/body /github/0xff-ai/omnifs/issues/open/1450/body
/ $ cat /github/0xff-ai/omnifs/issues/open/1432/title
Crash on long context with quantized model
quickstart
01 $npm install -g @0xff-ai/omnifs
02 $omnifs setup
03 $omnifs up && omnifs shell
04 $ls /github

every system already speaks omnifs
catlsgrep -rfindtail -fjqrsynctarvimdiffxargsheadwcmd5sum
/paths

Every API is a snowflake

APIs let us program against services, but each one is a world of its own. Schemas, auth, pagination, errors, rate limits. Agents pay the complexity tax in tokens.

In contrast, the filesystem is the most durable interface in computing. Every program, agent, language masters disk and file I/O. Semantics are strict and universally understood, and /filesystem/paths offer hierarchical addressing.

github.ts ts
const octokit = new Octokit({
  auth: process.env.GITHUB_TOKEN,
  request: { retries: 3 },
})
const issues = await octokit.paginate(
  octokit.rest.issues.listForRepo,
  { owner, repo, state: "open" },
)
return issues
  .filter((i) => !i.pull_request)
  .map((i) => i.title)
s3.py py
s3 = boto3.client("s3")
keys = []
paginator = s3.get_paginator("list_objects_v2")
try:
    for page in paginator.paginate(
            Bucket=bucket, Prefix=prefix):
        for o in page.get("Contents", []):
            keys.append(o["Key"])
except ClientError as e:
    raise RuntimeError(e.response["Error"]["Code"])
return keys
docker.go go
cli, err := client.NewClientWithOpts(
  client.FromEnv)
if err != nil {
  return false, err
}
defer cli.Close()
info, err := cli.ContainerInspect(
  context.Background(), id)
if err != nil {
  return false, fmt.Errorf("inspect: %w", err)
}
return info.State.Running, nil

omnifs unifies the world behind /paths

/omnifs mounts systems, services, and data sources (really, anything) onto the local filesystem. One stable interface replaces a client per service: files and directories you address by path.

$cat
/github
/ollama
/ollama
/issues
/open
/12959
/title
Support split GPU/CPU inference for 70B models
$cat
/linear
/teams
/ENG
/issues
/open
/ENG-204
/state
in_progress
$cat
/docker
/containers
/by-name
/api
/state
running
/setup

Tailored to your needs

One daemon, three axes: how the namespace is exposed, where it runs, and which providers it mounts. Pick across them and the setup command writes itself.

01

choose your frontend filesystem


Windows support is coming.

02

choose your environment

03

choose your providers

What gets mounted. Each is a sandboxed wasm component.

or pick a subset

huggingface kubernetes s3 slack discord
provider catalogue →
setup command
$omnifs setup --frontend fuse --mode host --providers github,dns
/providers

A growing pool of providers

Providers are the extension point. If a system has an API, socket, repository, database, object store, or control plane, it can have a path. Each translates its service into directories, files, fields, rendered views, and searchable trees.

GitHub

issues, PRs, CI, and repo trees

/github/ollama/ollama/issues/open/2853/title

reposissuesPRsCI runsrepo tree

DNS

records over DNS-over-HTTPS, dig without dig

/dns/example.com/MX

AAAAAMXNSTXT

arXiv

the arXiv corpus, by id or search

/arxiv/papers/1706.03762/paper.json

papersmetadataPDFsourceversions

Docker

Docker daemon metadata through a host socket

/docker/containers/by-name/postgres/state

containersstatesystem

Linear

teams, issues, state, and descriptions

/linear/teams/ENG/issues/open/ENG-1421/state

teamsissuesstateprioritydescription

db

a read-only SQLite database

/db/tables/Album/schema.sql

schemastablessample rows

Hugging Face

WIP

Models, datasets, and Spaces, mounted as files.

Kubernetes

WIP

Pods, services, and nodes, read like a tree.

S3

WIP

Buckets and objects, browsed as directories.

provider catalogue ->

/pipe

Pipe data and state across systems

Once services share a filesystem substrate, pipes can cross system boundaries. Read a CI run, inspect a container, grep the ticket queue, or sketch new providers for the systems you wish were files.

# provider sketch
$ cat /cloudflare/zones/0xff.ai/firewall/events/latest/client_ip \
    | xargs -I% cat /dns/reverse/%
census-12.shodan.io
cloudflarenextdns
/architecture

Providers ask. The host acts

Providers run sandboxed with no ambient authority, reaching the outside only through capability-gated callouts the host runs, so the gate, the cache, and the trace are one boundary. Read the architecture.

user / agentshell & tools
lscatgrepfindtarrsyncvim
read(path)
OMNIFS HOSTauthority boundary
path resolutioncachecredentialsnetwork calloutsinode identityprovider lifecycle
sandbox (wasmtime)
PROVIDER .wasmno ambient authority
lookup_childlist_childrenread_filesuspended calloutseffects
capability-gated callouts
upstream resource https, unix sockets, tcp, quic, p2p
apidatabasereporegistryqueue

a provider can

  • render bytes for a path
  • request a capability-gated callout (HTTPS, git, a unix socket)
  • declare which hosts, sockets, and auth schemes it needs

a provider cannot

  • grant itself new capabilities
  • see the credential behind a call
  • open its own socket or touch the network
  • browse arbitrary host files
  • read another provider's state
/sdk

Bring your own system

A provider teaches omnifs how one system appears as paths.

You own the routes, object identity, and rendering. The host owns FUSE, credentials, cache, and callouts.

github/provider.rs rust
use omnifs_sdk::{browse::FileContent, prelude::*};

#[omnifs_sdk::object(kind = "github.issue", key = IssueKey)]
#[derive(Clone, Serialize, Deserialize)]
struct Issue { title: String, state: String, body: String }

impl Issue {
    fn title(&self) -> Result<FileContent> { Ok(FileContent::new(self.title.as_bytes())) }
    fn state(&self) -> Result<FileContent> { Ok(FileContent::new(self.state.as_bytes())) }
    fn body(&self)  -> Result<FileContent> { Ok(FileContent::new(self.body.as_bytes())) }
}

#[path_captures]
struct IssueKey { owner: OwnerName, repo: RepoName, filter: Facet<StateFilter>, number: u64 }

impl Key for IssueKey {
    type Object = Issue;
    type State = State;

    async fn load(&self, cx: &Cx<State>, since: Option<Validator>) -> Result<Load<Issue>> {
        load_issue(cx, self, since).await
    }
}

#[omnifs_sdk::provider(
    metadata = "omnifs.provider.json",
    resources(endpoints = [api::GitHubApi], git = true),
)]
impl GithubProvider {
    type Config = Config;
    type State = State;

    fn start(_cfg: Config, r: &mut Router<State>) -> Result<State> {
        r.object::<Issue>("/{owner}/{repo}/issues/{filter}/{number}", |o| {
            o.representations("item", (Markdown,))?;
            o.file("title").project(Issue::title)?;
            o.file("state").project(Issue::state)?;
            o.file("body").lazy().project(Issue::body)?;
            Ok(())
        })?;
        Ok(State::default())
    }
}

/lineage

9p, realized with modern tech

Plan 9 made every resource a file reached through a tiny, uniform set of operations, served by a file server per resource. omnifs keeps the idea and swaps the 1990s mechanics for a sandboxed Wasm and FUSE stack, capability-gated callouts, and today's services.

Bell Labs Plan 9 everything is a file; 9P
2002 9P2000 the revision Linux v9fs speaks
2005 FUSE userspace filesystems in the kernel
2017 Wasm portable sandboxed bytecode
2020s WASI components sandboxed code, explicit capabilities
today omnifs external services, projected as files
/roadmap

Paths today, Git-shaped writes later

shipped
  • providers: github dns arxiv docker linear db
  • Linux FUSE mount
  • macOS through a Linux container shell
  • sandboxed wasm32-wasip2 providers
  • capability-gated HTTP, Git, and unix-socket callouts
  • host-held credentials
  • durable object cache, derived views, event invalidation
  • canonical object model: one fetch, many rendered files
  • Linux toolbox compatibility checks
  • live inspector TUI
upcoming
  • provider SDK ergonomics
  • cache behavior and invalidation polish
  • setup, auth, and status reporting
  • Git-shaped mutations
  • more providers
  • runtime frontends beyond Linux FUSE
  • background indexing and semantic search
  • community provider catalog and provider docs
  • persistent inode identity across remounts
  • signed provider capability manifests
/roadmap
dr-- shipped/read-only · done
r-- providers: githubdnsarxivdockerlineardb
r--Linux FUSE mount
r--macOS through a Linux container shell
r--sandboxed wasm32-wasip2 providers
r--capability-gated HTTP, Git, and unix-socket callouts
r--host-held credentials
r--durable object cache, derived views, event invalidation
r--canonical object model: one fetch, many rendered files
r--Linux toolbox compatibility checks
r--live inspector TUI
d--- upcoming/not yet mountable
---provider SDK ergonomics
---cache behavior and invalidation polish
---setup, auth, and status reporting
---Git-shaped mutations
---more providers
---runtime frontends beyond Linux FUSE
---background indexing and semantic search
---community provider catalog and provider docs
---persistent inode identity across remounts
---signed provider capability manifests
$ npm install -g @0xff-ai/omnifs

Open source under MIT OR Apache-2.0. If you would rather cat a path than learn another SDK, or you are shipping a provider against omnifs:provider@0.4.0, say hello.