aboutsummaryrefslogtreecommitdiff
path: root/docs/usage.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/usage.html')
-rw-r--r--docs/usage.html161
1 files changed, 158 insertions, 3 deletions
diff --git a/docs/usage.html b/docs/usage.html
index 9564012..52314fa 100644
--- a/docs/usage.html
+++ b/docs/usage.html
@@ -66,7 +66,7 @@ no key, no token.</p>
<tr><td>Latest tag</td><td><code>v4.6.146</code> — <a href="/newos4/refs/">see refs</a></td></tr>
<tr><td>Writes</td><td>none. <code>git-receive-pack</code> answers 403; there is no SSH endpoint</td></tr>
<tr><td>Private data</td><td>stripped from every commit before publication — see <a href="/usage.html#scope">Scope</a></td></tr>
- <tr><td>Reading it</td><td><a href="/about/">rendered README</a> · <a href="/newos4/tree/">file tree</a> · <a href="/newos4/log/">history</a></td></tr>
+ <tr><td>Reading it</td><td><a href="/newos4/about/">rendered README</a> · <a href="/newos4/tree/">file tree</a> · <a href="/newos4/log/">history</a></td></tr>
</table>
<h2 id="linux">Linux</h2>
@@ -155,7 +155,7 @@ git clone --depth 1 https://newos.webx11.duckdns.org/newos4.git
termux-wake-unlock</code></pre>
<p style="color:var(--dim);font-size:.9rem;margin:6px 0 0">
<code>--depth 1</code> fetches the newest tree only — much faster on mobile data. You lose history;
- re-clone without it later if you want the full 181 commits.</p>
+ re-clone without it later if you want the full history.</p>
</div>
</div>
<p style="color:var(--dim);font-size:.9rem">Editing on the phone: <code>pkg install nano</code> or
@@ -167,6 +167,161 @@ termux-wake-unlock</code></pre>
<code>git clone</code> command. <a href="https://workingcopy.app/">Working Copy</a> is a GUI alternative that can
also clone a public HTTPS repository without an account.</p>
+<h2 id="pi">Automating with the pi agent</h2>
+<p><code>pi</code> is a terminal coding agent (a Node CLI — <code>pi --help</code>). Everything below uses
+only documented flags, treats the mirror as read-only, and was run against <code>pi 0.80.3</code> (what this
+host had installed — npm currently ships 1.5.0) before being
+written down.</p>
+
+<h3>Install</h3>
+<pre><code>node -v # needs Node &gt;= 22.19.0
+npm install -g @earendil-works/pi-coding-agent
+pi --version # e.g. 1.5.0</code></pre>
+<p style="color:var(--dim);font-size:.9rem">That package installs the <code>pi</code> binary
+(<code>bin: pi → dist/bundle/cli.js</code>). A system-wide install lands in
+<code>/usr/lib/node_modules/@earendil-works/pi-coding-agent</code>; a user install needs
+<code>~/.local/bin</code> on <code>PATH</code>.</p>
+
+<h3>Point it at Ollama</h3>
+<p>Ollama speaks the OpenAI wire format on <code>http://127.0.0.1:11434/v1</code> by default, which is exactly
+what <code>pi</code> expects. Two files under <code>~/.pi/agent/</code> do the whole job:</p>
+<pre><code>// ~/.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)" }
+ ]
+ }
+ }
+}</code></pre>
+<pre><code>// ~/.pi/agent/settings.json
+{ "defaultProvider": "ollama", "defaultModel": "llama3.2:latest" }</code></pre>
+<p style="color:var(--dim);font-size:.9rem"><code>baseUrl</code> points at your daemon — use
+<code>http://localhost:11434/v1</code> for a local Ollama, or your own host:port. <code>apiKey</code> must be a
+non-empty string because the client sends it as a bearer token; Ollama ignores the value. The two
+<code>compat</code> flags off are what this provider needs.</p>
+
+<div class="warn">
+ <strong>Pulling a model in Ollama is not enough.</strong> It must also be listed under
+ <code>models[]</code>. Undeclared, <code>pi --model llama3.2:latest</code> fails with
+ <code>Error: Model "llama3.2:latest" not found. Use --list-models</code> — that is the single most common
+ configuration mistake and it looks like a connection problem.
+</div>
+
+<h3>Verify the wiring</h3>
+<pre><code>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"</code></pre>
+<p style="color:var(--dim);font-size:.9rem">A reply of <code>LOCAL OK</code> means the whole chain works:
+config → local daemon → model. Ids ending in <code>-cloud</code> are relayed by Ollama to
+<code>ollama.com</code> and need an <code>ollama signin</code>; local tags have no suffix.</p>
+
+<h3>1. One-shot: analyse a file, print an answer, exit</h3>
+<pre><code>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?"</code></pre>
+<p style="color:var(--dim);font-size:.9rem">Output: <em>“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.”</em> — <code>-p</code> is the non-interactive mode, <code>@file</code> inlines the file,
+<code>--no-tools</code> forbids tool use entirely, <code>--no-session</code> leaves nothing behind.</p>
+
+<h3>2. Machine-readable output for scripts</h3>
+<pre><code>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'</code></pre>
+<p style="color:var(--dim);font-size:.9rem"><code>--mode json</code> emits one JSON object per line. The event
+types in order are <code>session</code>, <code>agent_start</code>, <code>turn_start</code>,
+<code>message_start</code>/<code>message_end</code> (the assistant's text is in
+<code>message.content[].text</code>), <code>turn_end</code>, <code>agent_end</code>. Parse on
+<code>message_end</code> and you never have to scrape the terminal UI.</p>
+
+<h3>3. Let it read the tree — with a read-only tool allowlist</h3>
+<pre><code>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?"</code></pre>
+<p style="color:var(--dim);font-size:.9rem">Tool names are <code>read</code>, <code>bash</code>,
+<code>edit</code>, <code>write</code>; <code>--tools</code> is an allowlist, so leaving <code>edit</code> and
+<code>write</code> out makes the run read-only by construction. <code>--tools read</code> alone cannot list a
+directory — <code>read</code> reads files — so add <code>bash</code> when it needs to <code>ls</code>.</p>
+
+<h3>Flags worth knowing for automation</h3>
+<table>
+ <tr><th>Flag</th><th>What it buys you</th></tr>
+ <tr><td><code>--list-models</code></td><td>What your install can actually reach, with context and output limits</td></tr>
+ <tr><td><code>--model</code></td><td>Pin the model in scripts. A saved default can be retired server-side and fail with HTTP 410 “was retired” — passing <code>--model</code> keeps a job reproducible</td></tr>
+ <tr><td><code>--offline</code></td><td>Skip startup network calls (<code>PI_OFFLINE=1</code> also works)</td></tr>
+ <tr><td><code>--session-id</code> / <code>--continue</code></td><td>Resume the same conversation across runs instead of re-sending context</td></tr>
+ <tr><td><code>--append-system-prompt &lt;file&gt;</code></td><td>Append text or a file's contents to the system prompt — the cheap way to give every run your house rules</td></tr>
+ <tr><td><code>--skill &lt;path&gt;</code></td><td>Load a skill file or directory; <code>--no-skills</code> / <code>--no-context-files</code> turn discovery off</td></tr>
+</table>
+
+<h3>Safety: this repository is untrusted input</h3>
+<div class="warn">
+ <code>pi</code> auto-loads project files (<code>AGENTS.md</code>, <code>CLAUDE.md</code>, skills, extensions)
+ from the working directory. For a clone of a public repository you did not write, run with
+ <code>--no-approve</code> (ignores project-local files) and a tool allowlist that cannot write —
+ <code>--tools read</code>, or <code>--tools read,bash</code> 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.
+</div>
+
+<h3>A cron-able digest</h3>
+<pre><code>#!/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' \
+ &gt; "$HOME/newos4-digest.md"</code></pre>
+<p style="color:var(--dim);font-size:.9rem">The mirror only fast-forwards, so <code>git pull --ff-only</code>
+can never wedge. Nothing here can push — the repository refuses <code>receive-pack</code> at three levels.</p>
+
+<h2 id="contributing">Contributing (contrib branches)</h2>
+<p>The mirror accepts contributions, but only as <strong>contrib branches</strong> — <code>main</code> 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 <code>origin</code> stays anonymous
+and read-only.</p>
+<pre><code># 1. one token per account: Dashboard -> "Git push token" -> Create (shown once, revocable)
+# (looks like: https://&lt;user&gt;: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/&lt;your-username&gt;/my-fix
+git commit -am "fix(shell): handle an empty command"
+git push push HEAD:refs/heads/contrib/&lt;your-username&gt;/my-fix</code></pre>
+<p style="color:var(--dim);font-size:.9rem">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
+(<code>git config --global credential.helper store</code> writes it to a plain file — choose
+<code>cache</code> or your OS keychain if that matters).</p>
+
+<h3>What the server enforces</h3>
+<table>
+ <tr><th>Rule</th><th>Reason</th></tr>
+ <tr><td>Only <code>refs/heads/contrib/&lt;you&gt;/*</code></td><td><code>main</code> 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</td></tr>
+ <tr><td>No credentials in the diff</td><td>The repository is public. Every added blob is scanned before it is accepted; a match rejects the whole push with the file name</td></tr>
+ <tr><td>No profile or key files</td><td><code>.user.json</code>, <code>.session</code>, <code>.env</code>, <code>*.pem</code>, <code>id_rsa</code> are refused by path</td></tr>
+ <tr><td>≤ 200 files, ≤ 2 MB of new content per push</td><td>Keeps one push from making the mirror unusable</td></tr>
+ <tr><td>Deleting your own contrib branch</td><td>Allowed — it is your branch</td></tr>
+</table>
+
+<h3>What happens after you push</h3>
+<p>A moderator triages every branch automatically: docs-only changes are marked <em>ready</em>, 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.</p>
+<pre><code>git fetch push 'refs/heads/contrib/*:refs/remotes/contrib/*'
+git log --oneline main..contrib/<your-username>/my-fix # what your branch adds
+git push push --delete contrib/<your-username>/my-fix # withdraw it</code></pre>
+
<h2 id="updating">Updating later</h2>
<pre><code>cd newos4
git pull --ff-only # the mirror only ever fast-forwards
@@ -206,7 +361,7 @@ repository that cannot accept them.</p>
<footer>
Served from the same repository it documents ·
Source: <a href="/newos4/tree/docs/usage.html">docs/usage.html</a> ·
- <a href="/about/">README</a> · MIT licence · updated 2026-11-05
+ <a href="/newos4/about/">README</a> · MIT licence · updated 2026-11-05
</footer>
</div>