Getting newOS4

One public, read-only repository. Clone it on Linux, macOS, Windows or Android — no account, no key, no token.

git clone https://newos.webx11.duckdns.org/newos4.git

One URL for every platform. …/newos4 (without .git) also works — that is cgit's dumb-HTTP path and it is slower; use the .git form.

What you get
ContentsThe whole tree — a few MB — with full history, MIT licence
Latest tagv4.6.146 — see refs
Writesnone. git-receive-pack answers 403; there is no SSH endpoint
Private datastripped from every commit before publication — see Scope
Reading itrendered README · file tree · history

Linux

Install git, if it is missing

# Debian / Ubuntu / Mint
sudo apt update && sudo apt install -y git

# Fedora / RHEL
sudo dnf install -y git

# Arch / Manjaro
sudo pacman -S --noconfirm git

# Alpine
sudo apk add git

Clone and check

git --version                       # 2.30 or newer is fine
git clone https://newos.webx11.duckdns.org/newos4.git
cd newos4
git log --oneline -3
git describe --tags                 # v4.6.146

A distro without CA roots fails with SSL certificate problem: install ca-certificates. Behind a proxy, add git config --global http.proxy http://host:port.

macOS

xcode-select --install      # ships git (Apple's build is older but sufficient)
# or: brew install git

git clone https://newos.webx11.duckdns.org/newos4.git
cd newos4 && git describe --tags

If git opens a licence prompt, run sudo xcodebuild -license accept once. The clone lands in your working directory; nothing is installed system-wide.

Windows

winget install --id Git.Git -e --source winget

# new PowerShell window, then:
git clone https://newos.webx11.duckdns.org/newos4.git
cd newos4
git log --oneline -3
Set this before cloning on Windows: git config --global core.autocrlf false. The repository is served from a Linux host — a CRLF checkout silently rewrites every shell script and JS file, and they stop working when copied back. Linux and macOS default to false; Windows installers default to true.

Without winget: git-scm.com/download/win → “Git for Windows” → next-next-finish → “Git Bash” gives you the same commands as above. WSL2 works too and needs no special handling.

Android — Termux

Termux is a real Linux userland, so the Linux instructions apply almost unchanged. Three things differ:

1. Install git in Termux

pkg update && pkg upgrade -y
pkg install -y git ca-certificates
git --version

2. Clone into Termux's own home, not shared storage

cd ~
git clone https://newos.webx11.duckdns.org/newos4.git
cd newos4
git log --oneline -3
Do not clone into /sdcard or ~/storage/…: that filesystem is FUSE-mounted without POSIX permissions, and git dies with error: unable to write file … Permission denied halfway through. Clone to ~/newos4 and copy files out afterwards. If you need shared storage access at all, run termux-setup-storage once and grant the prompt.

3. Keep the session alive for a big clone

termux-wake-lock          # stops Android from freezing the download
git clone --depth 1 https://newos.webx11.duckdns.org/newos4.git
termux-wake-unlock

--depth 1 fetches the newest tree only — much faster on mobile data. You lose history; re-clone without it later if you want the full history.

Editing on the phone: pkg install nano or pkg install micro, then nano newos4/README.md. Termux's own git is a standard build, so git status, git diff and git log behave exactly as on a laptop.

iPhone / iPad

a-Shell (free) includes git: run the same git clone command. Working Copy is a GUI alternative that can also clone a public HTTPS repository without an account.

Automating with the pi agent

pi is a terminal coding agent (a Node CLI — pi --help). Everything below uses only documented flags, treats the mirror as read-only, and was run against pi 0.80.3 (what this host had installed — npm currently ships 1.5.0) before being written down.

Install

node -v                       # needs Node >= 22.19.0
npm install -g @earendil-works/pi-coding-agent
pi --version                  # e.g. 1.5.0

That package installs the pi binary (bin: pi → dist/bundle/cli.js). A system-wide install lands in /usr/lib/node_modules/@earendil-works/pi-coding-agent; a user install needs ~/.local/bin on PATH.

Point it at Ollama

Ollama speaks the OpenAI wire format on http://127.0.0.1:11434/v1 by default, which is exactly what pi expects. Two files under ~/.pi/agent/ do the whole job:

// ~/.pi/agent/models.json
{
  "providers": {
    "ollama": {
      "baseUrl": "http://localhost:11434/v1",
      "api": "openai-completions",
      "apiKey": "ollama",
      "compat": { "supportsDeveloperRole": false, "supportsReasoningEffort": false },
      "models": [
        { "id": "llama3.2:latest", "name": "Llama 3.2 (local)" },
        { "id": "qwen2.5-coder:7b", "name": "Qwen2.5 Coder 7B (local)" }
      ]
    }
  }
}
// ~/.pi/agent/settings.json
{ "defaultProvider": "ollama", "defaultModel": "llama3.2:latest" }

baseUrl points at your daemon — use http://localhost:11434/v1 for a local Ollama, or your own host:port. apiKey must be a non-empty string because the client sends it as a bearer token; Ollama ignores the value. The two compat flags off are what this provider needs.

Pulling a model in Ollama is not enough. It must also be listed under models[]. Undeclared, pi --model llama3.2:latest fails with Error: Model "llama3.2:latest" not found. Use --list-models — that is the single most common configuration mistake and it looks like a connection problem.

Verify the wiring

pi --list-models | grep ollama           # your declared ids, with context limits
ollama list                              # what the daemon actually serves
pi -p --no-session --no-tools --model llama3.2:latest "Reply with exactly: LOCAL OK"

A reply of LOCAL OK means the whole chain works: config → local daemon → model. Ids ending in -cloud are relayed by Ollama to ollama.com and need an ollama signin; local tags have no suffix.

1. One-shot: analyse a file, print an answer, exit

git clone --depth 1 https://newos.webx11.duckdns.org/newos4.git /tmp/newos4

pi -p --no-session --no-tools --model gemma4:31b-cloud \
   @/tmp/newos4/README.md "In one sentence, what is this repository?"

Output: “This repository contains newOS4, a browser-based terminal featuring a filesystem, command shell, editor, and AI agent backed by WebDAV storage and WebX11 user spaces.” — -p is the non-interactive mode, @file inlines the file, --no-tools forbids tool use entirely, --no-session leaves nothing behind.

2. Machine-readable output for scripts

pi -p --no-session --no-tools --mode json --model gemma4:31b-cloud \
   @/tmp/newos4/CHANGELOG.md "Summarise the newest release in one line" \
 | jq -r 'select(.type=="message_end" and .message.role=="assistant")
          | .message.content[0].text'

--mode json emits one JSON object per line. The event types in order are session, agent_start, turn_start, message_start/message_end (the assistant's text is in message.content[].text), turn_end, agent_end. Parse on message_end and you never have to scrape the terminal UI.

3. Let it read the tree — with a read-only tool allowlist

cd /tmp/newos4
pi -p --no-session --tools read,bash --no-approve --model gemma4:31b-cloud \
   "Which files does main.html load, and where is the module loader defined?"

Tool names are read, bash, edit, write; --tools is an allowlist, so leaving edit and write out makes the run read-only by construction. --tools read alone cannot list a directory — read reads files — so add bash when it needs to ls.

Flags worth knowing for automation

FlagWhat it buys you
--list-modelsWhat your install can actually reach, with context and output limits
--modelPin the model in scripts. A saved default can be retired server-side and fail with HTTP 410 “was retired” — passing --model keeps a job reproducible
--offlineSkip startup network calls (PI_OFFLINE=1 also works)
--session-id / --continueResume the same conversation across runs instead of re-sending context
--append-system-prompt <file>Append text or a file's contents to the system prompt — the cheap way to give every run your house rules
--skill <path>Load a skill file or directory; --no-skills / --no-context-files turn discovery off

Safety: this repository is untrusted input

pi auto-loads project files (AGENTS.md, CLAUDE.md, skills, extensions) from the working directory. For a clone of a public repository you did not write, run with --no-approve (ignores project-local files) and a tool allowlist that cannot write — --tools read, or --tools read,bash if it must list files. Never point a full-tool run at a repo you have not read: a prompt-injection in a README is executed the same way your own instructions would be.

A cron-able digest

#!/bin/sh
# nightly: refresh the mirror, ask one question, write markdown
set -eu
cd /tmp/newos4 2>/dev/null || git clone -q --depth 1 https://newos.webx11.duckdns.org/newos4.git /tmp/newos4
git pull -q --ff-only
pi -p --no-session --no-tools --mode json --model gemma4:31b-cloud \
   @CHANGELOG.md "Three bullets: what changed in the newest release?" \
 | jq -r 'select(.type=="message_end" and .message.role=="assistant") | .message.content[0].text' \
 > "$HOME/newos4-digest.md"

The mirror only fast-forwards, so git pull --ff-only can never wedge. Nothing here can push — the repository refuses receive-pack at three levels.

Contributing (contrib branches)

The mirror accepts contributions, but only as contrib branches — main is generated from the platform's monorepo and a push to it would be erased by the next publish. Pushes go to a separate host that asks for credentials; the read-only host in your origin stays anonymous and read-only.

# 1. one token per account: Dashboard -> "Git push token" -> Create (shown once, revocable)
#    (looks like: https://<user>:wx11gp_…@push.newos.webx11.duckdns.org/newos4.git)
git remote add push https://push.newos.webx11.duckdns.org/newos4.git

# 2. work on a branch, push it under contrib/
git switch -c contrib/<your-username>/my-fix
git commit -am "fix(shell): handle an empty command"
git push push HEAD:refs/heads/contrib/<your-username>/my-fix

Use a credential helper rather than pasting the token into the URL of a repository you might publish. Git will ask once and can remember it (git config --global credential.helper store writes it to a plain file — choose cache or your OS keychain if that matters).

What the server enforces

RuleReason
Only refs/heads/contrib/<you>/*main and tags are generated by the publisher; a push there would disappear at the next publish. The middle segment must be your own username — the hook compares it to the account that authenticated, so nobody can overwrite a neighbour's branch
No credentials in the diffThe repository is public. Every added blob is scanned before it is accepted; a match rejects the whole push with the file name
No profile or key files.user.json, .session, .env, *.pem, id_rsa are refused by path
≤ 200 files, ≤ 2 MB of new content per pushKeeps one push from making the mirror unusable
Deleting your own contrib branchAllowed — it is your branch

What happens after you push

A moderator triages every branch automatically: docs-only changes are marked ready, anything touching code is queued for a human with a diff summary, and a branch that breaks a hard rule is deleted. The queue is visible to the operator; you will hear back on your branch, not in a black hole.

git fetch push 'refs/heads/contrib/*:refs/remotes/contrib/*'
git log --oneline main..contrib//my-fix   # what your branch adds
git push push --delete contrib//my-fix    # withdraw it

Updating later

cd newos4
git pull --ff-only          # the mirror only ever fast-forwards
git describe --tags         # new tag appears when a release is published

The mirror is refreshed daily at 05:50 UTC and a new release tag is minted on each publish. Nothing you do locally can be pushed back — see below.

Verifying what you got

git -C newos4 rev-parse --short HEAD      # tip commit
git -C newos4 tag -l                      # v4.6.146
git -C newos4 ls-files | wc -l            # every published file
git -C newos4 rev-list --count HEAD       # every published commit
du -sh newos4/.git                      # a few MB

Scope, and why you cannot push

The mirror is generated from a private monorepo by admin/scripts/publish-newos4.py: it keeps only the spaces/newos4 subtree, removes private paths (data/, backups/, .hermes/, credentials, profile JSON) from every commit, and scans all blobs for secrets before anything is pushed. That is why the history starts where it does: earlier private commits were never published.

Pushing is disabled at three levels — no git-receive-pack route on the vhost, 403 on the advertisement, and http.receivepack=false in the repository. If you want to report a bug or ask for a change, email darkmotox11@gmail.com; do not send patches to a repository that cannot accept them.

Troubleshooting

SymptomCause and fix
Repository not foundWrong URL. Use https://newos.webx11.duckdns.org/newos4.git — the host is newos., not git.
SSL certificate problemMissing CA bundle → apt install ca-certificates / pkg install ca-certificates
Could not resolve hostOffline, or a corporate DNS that drops wildcard subdomains
403 on git pushExpected — the mirror is read-only by design
Clone stalls on mobilegit clone --depth 1, and termux-wake-lock on Android
Scripts arrive with CRLFgit config --global core.autocrlf false, then re-clone