diff --git a/developer-guide/21-discord-bots.md b/developer-guide/21-discord-bots.md index 5c13a393..fd328e06 100644 --- a/developer-guide/21-discord-bots.md +++ b/developer-guide/21-discord-bots.md @@ -99,6 +99,7 @@ If `ctx.bare.discordJS` is missing, check `ctx.env.BARE_OS_DISCORD_LOAD_ERROR` ( | Path | When to use | How it starts | | --- | --- | --- | +| **`init-discord`** | First-time setup: `.env` + hello plugin | Interactive prompts or `--yes --token …` | | **Stock `/bin/discord-bot`** | Full Bare OS slash surface (`/bare`, `/sys`, `/fs`, …) | Foreground in the guest shell | | **`bare-os-discord` unit** | Same catalog, background after identity unlock | `systemctl start` when `~/.discord/.env` exists | | **Guest script** (`~/my-bot.js`) | Your own commands; copy the ping-pong example | `./my-bot.js` or `my-bot.js` in `$PWD` | @@ -123,7 +124,15 @@ The stock binary and the initd unit share one guest-safe catalog: [`bare-os-disc ## Secrets, `.env`, and token load order -Preferred guest file: +Preferred setup: + +``` +init-discord +``` + +That asks for **token**, **guild id**, and **whitelist**, creates `~/.discord/` and `~/.discord/plugins/`, writes `~/.discord/.env`, and installs `/hello` from [`examples/discord-plugins/hello.json`](../examples/discord-plugins/hello.json). Flags (`--token`, `--guild`, `--whitelist`, `--yes`) work for scripts. The full token is never printed. + +Or write the file yourself: ```bash # ~/.discord/.env (VFS path on the personal drive) @@ -654,6 +663,7 @@ Do not assert on live tokens in CI. Redact `DISCORD_TOKEN` in any fixture `.env` | macOS `SIGKILL` after replacing booter | Code signature invalidated | Atomic replace + codesign a new inode | | Channel `ping` ignored | No Message Content | Expected on Guilds-only. Use `/ping` | | `reply failed: process.emitWarning is not a function` | Bare `process` lacks Node's `emitWarning`; older bots passed `ephemeral:` | Rebuild `/bin/discord-bot` / booter. Replies use `flags` (64) instead of `ephemeral`. Restart the bot. | +| `Supplying "fetchReply" … is deprecated` | Older catalog passed `fetchReply: true` on `reply` / `followUp` | Rebuild. Replies no longer send that option; the message is fetched afterwards for the idle timer. | `--debug` / `DISCORD_DEBUG=1` prints discord.js debug during login. Token JSON is redacted in the stock `ws send` hook (`"token":"***"`). @@ -674,6 +684,7 @@ Do not assert on live tokens in CI. Redact `DISCORD_TOKEN` in any fixture `.env` | Path | Role | | --- | --- | +| [`packages/bare-os-coreutils/src/init-discord.js`](../packages/bare-os-coreutils/src/init-discord.js) | Setup wizard (`~/.discord/.env` + hello plugin) | | [`packages/bare-os-coreutils/src/discord-bot.js`](../packages/bare-os-coreutils/src/discord-bot.js) | Foreground guest bot (`run`) | | [`packages/bare-os-coreutils/man/pages/discord-bot.json`](../packages/bare-os-coreutils/man/pages/discord-bot.json) | `man discord-bot` | | [`packages/bare-os-booter/lib/bare-os-discord-commands-guest.cjs`](../packages/bare-os-booter/lib/bare-os-discord-commands-guest.cjs) | Slash catalog (guest-safe CJS) | diff --git a/kernel/bin/discord-bot b/kernel/bin/discord-bot index 2d1bc7c6..a1f34a26 100644 --- a/kernel/bin/discord-bot +++ b/kernel/bin/discord-bot @@ -1022,6 +1022,8 @@ function discordCmdReplyPayload(result) { if (result && result.text) payload.content = discordCmdClip(result.text) if (!payload.content && !payload.embeds) payload.content = '(no output)' if (result && result.ephemeral) payload.flags = BARE_OS_DISCORD_FLAG_EPHEMERAL + delete payload.fetchReply + delete payload.ephemeral return payload } @@ -5496,9 +5498,9 @@ async function discordSendResult(ctx, interaction, result) { } else if (interaction.deferred && typeof interaction.editReply === 'function') { sent = await interaction.editReply(payload) } else if (interaction.replied && typeof interaction.followUp === 'function') { - sent = await interaction.followUp(Object.assign({ fetchReply: true }, payload)) + sent = await interaction.followUp(payload) } else { - sent = await interaction.reply(Object.assign({ fetchReply: true }, payload)) + sent = await interaction.reply(payload) } } catch (err) { if (ctx && ctx.console && typeof ctx.console.error === 'function') { diff --git a/kernel/bin/help b/kernel/bin/help index 2f92a1fc..44abb015 100644 --- a/kernel/bin/help +++ b/kernel/bin/help @@ -311,7 +311,7 @@ function bareOsHexEncode(u8) { return s } -var BARE_OS_HELP_BIN_SPACED = "agent appctl appstore arch awk baresay baretop base32 base64 basename basenc btop bundlebee cat chat chgrp chmod chown cksum clear cmp comm corestorectl cp crontab ctxbaredoctor curl cut date dd df dhtctl dhtscan dhttop diff dir dircolors dirname discord-bot du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help holepunch-view holesail hostid hostname hrpc hypershell-board iconv id install irc join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill link ln locale logger login logname logout ls man md5sum meshdrop mkdir mkfifo mktemp mount mv nano nice nl nohup nproc numfmt od oidc-publish openssl openssl p2ping p2ptrace paste patch pathcap-verify pathchk pear pear-runtime-matrix peerctl peerdiscover peernote pkg-swarm-index pr printenv printf procstat ps pwd readlink realpath rev rm rmdir routeview savevault say sed seq setfacl sh sha1sum sha224sum sha256sum sha384sum sha512sum shuf sidecar sleep sort split ssh ssh-keygen ssh-keygen sshd sshd stat sum summon swarmdoctor swarmmap swarmtop sync systemctl tac tail tar tar taskmesh tee telnet test theme time timeout touch tr true truncate trustctl tsort tty tui ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami whois xargs xattr yes" +var BARE_OS_HELP_BIN_SPACED = "agent appctl appstore arch awk baresay baretop base32 base64 basename basenc btop bundlebee cat chat chgrp chmod chown cksum clear cmp comm corestorectl cp crontab ctxbaredoctor curl cut date dd df dhtctl dhtscan dhttop diff dir dircolors dirname discord-bot du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help holepunch-view holesail hostid hostname hrpc hypershell-board iconv id init-discord install irc join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill link ln locale logger login logname logout ls man md5sum meshdrop mkdir mkfifo mktemp mount mv nano nice nl nohup nproc numfmt od oidc-publish openssl openssl p2ping p2ptrace paste patch pathcap-verify pathchk pear pear-runtime-matrix peerctl peerdiscover peernote pkg-swarm-index pr printenv printf procstat ps pwd readlink realpath rev rm rmdir routeview savevault say sed seq setfacl sh sha1sum sha224sum sha256sum sha384sum sha512sum shuf sidecar sleep sort split ssh ssh-keygen ssh-keygen sshd sshd stat sum summon swarmdoctor swarmmap swarmtop sync systemctl tac tail tar tar taskmesh tee telnet test theme time timeout touch tr true truncate trustctl tsort tty tui ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami whois xargs xattr yes" async function run(ctx, argv) { ctx.console.log( 'Bare OS — default user: guest | shell builtins: alias, barerc, cd, command, export, exit, login, logout, readonly, type, umask, unalias, unset, : | /bin: ' + diff --git a/kernel/bin/init-discord b/kernel/bin/init-discord new file mode 100644 index 00000000..a6e059c5 --- /dev/null +++ b/kernel/bin/init-discord @@ -0,0 +1,539 @@ +/* BARE_OS_BIN_API 1.0.0 — bump when staged /bin script semantics change (see developer guide). */ +/** Shared helpers for drive-resident /bin scripts (prepended before each command). */ +function bareStdin(ctx) { + return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : '' +} + +/** @param {number} mode @param {'file' | 'directory' | 'symlink'} type */ +function bareFormatModeString(mode, type) { + const typeChar = type === 'directory' ? 'd' : type === 'symlink' ? 'l' : '-' + const perm = mode & 0o777 + const r = (bit) => (perm & bit ? 'r' : '-') + const w = (bit) => (perm & bit ? 'w' : '-') + const x = (bit) => (perm & bit ? 'x' : '-') + return ( + typeChar + + r(0o400) + + w(0o200) + + x(0o100) + + r(0o040) + + w(0o020) + + x(0o010) + + r(0o004) + + w(0o002) + + x(0o001) + ) +} + +/** @param {number} mtimeMs @param {number} [nowMs] */ +function bareFormatLsMtime(mtimeMs, nowMs) { + const now = nowMs != null ? nowMs : Date.now() + const d = new Date(mtimeMs) + const months = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec' + ] + const mon = months[d.getMonth()] + const day = String(d.getDate()).padStart(2, ' ') + const sixMo = 180 * 24 * 3600 * 1000 + if (Math.abs(now - mtimeMs) > sixMo) { + const yr = String(d.getFullYear()).padStart(4, ' ') + return mon + ' ' + day + ' ' + yr + } + const hh = String(d.getHours()).padStart(2, '0') + const mm = String(d.getMinutes()).padStart(2, '0') + return mon + ' ' + day + ' ' + hh + ':' + mm +} + +/** @param {number} size */ +function barePosixBlocks(size) { + return Math.ceil(Number(size) / 512) || 0 +} + +/** + * Raw stdout for NUL/binary when **`process.stdout.write`** is missing. + * If **`ctx.bareOsBinWrite(Uint8Array|string)`** is set (tests / host), use it. + * @param {Record} ctx + * @param {string | Uint8Array} chunk + * @returns {boolean} + */ +function bareOsEmitRaw(ctx, chunk) { + if (typeof ctx.bareOsBinWrite === 'function') { + const b4 = ctx.b4a + const u8 = + typeof chunk === 'string' + ? b4 && typeof b4.from === 'function' + ? b4.from(chunk) + : new TextEncoder().encode(chunk) + : chunk + ctx.bareOsBinWrite(u8 instanceof Uint8Array ? u8 : new Uint8Array(u8)) + return true + } + const w = globalThis.process?.stdout?.write + if (typeof w === 'function') { + w.call(globalThis.process.stdout, chunk) + return true + } + return false +} + +/** Session env map (`vfs.env`, then `ctx.env`). Never throws. */ +function bareOsEnv(ctx) { + const v = ctx && ctx.vfs && ctx.vfs.env + if (v && typeof v === 'object') return v + const e = ctx && ctx.env + if (e && typeof e === 'object') return e + return {} +} + +/** + * Strict POSIX-ish decimal integer (no octal, no exponent, no empty). + * @param {unknown} s + * @returns {number} + */ +function bareOsParseDecInt(s) { + const t = String(s == null ? '' : s).trim() + if (!/^[+-]?(?:0|[1-9][0-9]*)$/.test(t)) return NaN + const n = Number.parseInt(t, 10) + return Number.isSafeInteger(n) ? n : NaN +} + +/** @param {unknown} s */ +function bareOsParseNonNegInt(s) { + const n = bareOsParseDecInt(s) + return n >= 0 ? n : NaN +} + +/** + * @param {Record} ctx + * @param {string} name + * @param {number} fallback + * @param {number} [min] + * @param {number} [max] + */ +function bareOsEnvInt(ctx, name, fallback, min, max) { + const raw = bareOsEnv(ctx)[name] + if (raw == null || raw === '') return fallback + const n = Number.parseInt(String(raw), 10) + if (!Number.isFinite(n)) return fallback + let v = n + if (min != null && v < min) v = min + if (max != null && v > max) v = max + return v +} + +/** + * @param {Record} ctx + * @param {string} msg + * @param {number} [code] + */ +function bareOsFail(ctx, msg, code) { + if (msg) ctx.console.error(msg) + ctx.exitCode = code == null ? 1 : code +} + +/** @param {unknown} e */ +function bareOsIsNotFoundErr(e) { + const code = e && typeof e === 'object' ? e.code : '' + if (code === 'ENOENT') return true + const msg = String((e && e.message) || e || '') + return /ENOENT|No such file|not found/i.test(msg) +} + +/** + * @param {Record} ctx + * @param {unknown} buf + * @returns {Uint8Array} + */ +function bareOsToU8(ctx, buf) { + if (!buf) return new Uint8Array(0) + if (buf instanceof Uint8Array) return buf + if (ctx && ctx.b4a && typeof ctx.b4a.from === 'function') return ctx.b4a.from(buf) + return new Uint8Array(buf) +} + +/** @param {string} dir @param {string} name */ +function bareOsJoinPath(dir, name) { + const d = String(dir || '').replace(/\/+$/, '') + const n = String(name || '').replace(/^\/+/, '') + if (!d || d === '/') return '/' + n + return d + '/' + n +} + +/** @param {string} p */ +function bareOsBaseName(p) { + const t = String(p || '').replace(/\/+$/, '') + if (!t || t === '/') return t === '/' ? '/' : '' + const i = t.lastIndexOf('/') + return i < 0 ? t : t.slice(i + 1) || t +} + +/** @param {string} p */ +function bareOsParentDir(p) { + const t = String(p || '').replace(/\/+$/, '') || '/' + if (t === '/') return '/' + const i = t.lastIndexOf('/') + return i <= 0 ? '/' : t.slice(0, i) || '/' +} + +/** @param {string} p */ +function bareOsNormPath(p) { + return String(p || '').replace(/\/+$/, '') || '/' +} + +/** + * @param {Record} ctx + * @param {string} p + */ +function bareOsResolvePath(ctx, p) { + if (ctx && ctx.vfs && typeof ctx.vfs.resolveLogical === 'function') { + try { + return String(ctx.vfs.resolveLogical(p) || p) + } catch { + /* fall through */ + } + } + return String(p || '') +} + +/** + * True when dest is src or lives under src (self-copy / self-move). + * @param {Record} ctx + * @param {string} src + * @param {string} dest + */ +function bareOsDestInsideSrc(ctx, src, dest) { + const s = bareOsNormPath(bareOsResolvePath(ctx, src)) + const d = bareOsNormPath(bareOsResolvePath(ctx, dest)) + if (s === d) return true + if (s === '/') return d !== '/' + return d === s || d.startsWith(s + '/') +} + +const BARE_OS_B64_ALPH = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + +/** @param {Uint8Array} u8 */ +function bareOsB64Encode(u8) { + let out = '' + let i = 0 + for (; i + 2 < u8.length; i += 3) { + const n = (u8[i] << 16) | (u8[i + 1] << 8) | u8[i + 2] + out += + BARE_OS_B64_ALPH[(n >> 18) & 63] + + BARE_OS_B64_ALPH[(n >> 12) & 63] + + BARE_OS_B64_ALPH[(n >> 6) & 63] + + BARE_OS_B64_ALPH[n & 63] + } + const rest = u8.length - i + if (rest === 1) { + const n = u8[i] << 16 + out += BARE_OS_B64_ALPH[(n >> 18) & 63] + BARE_OS_B64_ALPH[(n >> 12) & 63] + '==' + } else if (rest === 2) { + const n = (u8[i] << 16) | (u8[i + 1] << 8) + out += + BARE_OS_B64_ALPH[(n >> 18) & 63] + + BARE_OS_B64_ALPH[(n >> 12) & 63] + + BARE_OS_B64_ALPH[(n >> 6) & 63] + + '=' + } + return out +} + +/** + * RFC 4648 Base64 decode (also accepts URL-safe alphabet). Rejects junk. + * @param {string} s + * @returns {Uint8Array} + */ +function bareOsB64Decode(s) { + const t = String(s).replace(/\s+/g, '') + if (!t) return new Uint8Array(0) + if (t.length % 4 === 1) throw new Error('invalid base64 length') + let pad = 0 + if (t.endsWith('==')) pad = 2 + else if (t.endsWith('=')) pad = 1 + const body = pad ? t.slice(0, t.length - pad) : t + const bytes = [] + let buf = 0 + let bits = 0 + for (let i = 0; i < body.length; i++) { + const c = body[i] + let v = BARE_OS_B64_ALPH.indexOf(c) + if (v < 0) { + if (c === '-') v = 62 + else if (c === '_') v = 63 + else throw new Error('invalid base64 character') + } + buf = (buf << 6) | v + bits += 6 + if (bits >= 8) { + bits -= 8 + bytes.push((buf >> bits) & 255) + } + } + if (pad) { + const want = Math.floor((body.length * 6) / 8) + if (bytes.length > want) bytes.length = want + } + return new Uint8Array(bytes) +} + +/** + * @param {string} s + * @returns {Uint8Array} + */ +function bareOsHexDecode(s) { + const t = String(s).replace(/\s+/g, '') + if (t.length % 2 !== 0) throw new Error('odd hex length') + const out = new Uint8Array(t.length / 2) + for (let i = 0; i < out.length; i++) { + const pair = t.slice(i * 2, i * 2 + 2) + if (!/^[0-9a-fA-F]{2}$/.test(pair)) throw new Error('invalid hex') + out[i] = Number.parseInt(pair, 16) + } + return out +} + +/** @param {Uint8Array} u8 */ +function bareOsHexEncode(u8) { + let s = '' + for (let i = 0; i < u8.length; i++) s += u8[i].toString(16).padStart(2, '0') + return s +} + +/** + * Interactive Discord bot setup: ~/.discord/.env + hello-world plugin. + */ + +var INIT_DISCORD_HELLO_JSON = + '{\n' + + ' "name": "hello",\n' + + ' "description": "Greet someone from Bare OS",\n' + + ' "version": "1.0.0",\n' + + ' "options": [\n' + + ' {\n' + + ' "name": "who",\n' + + ' "description": "Name to greet",\n' + + ' "required": false\n' + + ' }\n' + + ' ],\n' + + ' "run": "echo Hello, ${who:-world} — from $USER on $HOSTNAME",\n' + + ' "title": "hello"\n' + + '}\n' + +function initDiscordHasFlag(argv, names) { + for (let i = 1; i < argv.length; i++) { + const a = String(argv[i] || '') + for (let n = 0; n < names.length; n++) { + if (a === names[n]) return true + } + } + return false +} + +function initDiscordArg(argv, names) { + for (let i = 1; i < argv.length; i++) { + const a = String(argv[i] || '') + for (let n = 0; n < names.length; n++) { + const name = names[n] + if (a === name) return argv[i + 1] != null ? String(argv[i + 1]) : '' + if (a.indexOf(name + '=') === 0) return a.slice(name.length + 1) + } + } + return '' +} + +function initDiscordParseEnv(text) { + const out = {} + const lines = String(text || '').split(/\r?\n/) + for (let i = 0; i < lines.length; i++) { + let s = lines[i].replace(/^\uFEFF/, '').trim() + if (!s || s.charAt(0) === '#') continue + if (s.indexOf('export ') === 0) s = s.slice(7).trim() + const eq = s.indexOf('=') + if (eq < 1) continue + let val = s.slice(eq + 1).trim() + if ( + (val.charAt(0) === '"' && val.charAt(val.length - 1) === '"') || + (val.charAt(0) === "'" && val.charAt(val.length - 1) === "'") + ) { + val = val.slice(1, -1) + } + out[s.slice(0, eq).trim()] = val + } + return out +} + +function initDiscordMaskToken(tok) { + const t = String(tok || '') + if (t.length < 8) return '(set)' + return t.slice(0, 4) + '…' + t.slice(-4) +} + +function initDiscordUpsertEnv(text, key, value) { + const line = key + '=' + value + const re = new RegExp('^\\s*(?:export\\s+)?' + key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\$&') + '=.*$', 'm') + if (re.test(text)) return text.replace(re, line) + const body = text && !/\n$/.test(text) ? text + '\n' : text || '' + return body + line + '\n' +} + +async function initDiscordReadText(ctx, path) { + try { + const buf = await ctx.vfs.readFile(path) + if (!buf) return '' + if (ctx.b4a && typeof ctx.b4a.toString === 'function') return ctx.b4a.toString(buf) + return String(buf) + } catch { + return '' + } +} + +async function initDiscordWriteText(ctx, path, text) { + const buf = ctx.b4a && typeof ctx.b4a.from === 'function' ? ctx.b4a.from(text) : text + await ctx.vfs.writeFile(path, buf) +} + +async function initDiscordMkdir(ctx, path) { + if (!ctx.vfs || typeof ctx.vfs.mkdir !== 'function') return + try { + await ctx.vfs.mkdir(path, { recursive: true }) + } catch { + /* exists */ + } +} + +async function initDiscordAsk(ctx, prompt, fallback) { + if (typeof ctx.readLine !== 'function') return fallback || '' + const hint = fallback ? ' [' + fallback + ']' : '' + const raw = await ctx.readLine(prompt + hint + ': ') + const s = String(raw == null ? '' : raw).trim() + return s || fallback || '' +} + +async function run(ctx, argv) { + const argv0 = argv[0] || 'init-discord' + if (initDiscordHasFlag(argv, ['-h', '--help'])) { + ctx.console.log( + 'usage: ' + + argv0 + + ' [--token TOKEN] [--guild ID] [--whitelist ID,ID] [--yes] [--force] [--plugin-only]\n\n' + + 'Create ~/.discord, write ~/.discord/.env, and install a hello-world plugin.\n' + + 'Interactive by default (asks for token, guild id, whitelist). Use flags for scripts.\n\n' + + ' --token TOKEN Bot token (Developer Portal → Bot). Never logged.\n' + + ' --guild ID Guild id for instant slash registration.\n' + + ' --whitelist ID,ID Discord user ids allowed to use the bot.\n' + + ' --yes Non-interactive: require --token (or an existing .env).\n' + + ' --force Overwrite an existing token / hello.json.\n' + + ' --plugin-only Only ensure the hello plugin; leave .env alone.\n\n' + + 'Then: discord-bot --check --env ~/.discord/.env\n' + + ' systemctl daemon-reload && systemctl start bare-os-discord' + ) + ctx.exitCode = 0 + return + } + if (!ctx.vfs || typeof ctx.vfs.writeFile !== 'function') { + ctx.console.error(argv0 + ': vfs.writeFile unavailable') + ctx.exitCode = 1 + return + } + + const yes = initDiscordHasFlag(argv, ['--yes', '-y']) + const force = initDiscordHasFlag(argv, ['--force']) + const pluginOnly = initDiscordHasFlag(argv, ['--plugin-only']) + let tokenFlag = initDiscordArg(argv, ['--token']) + let guildFlag = initDiscordArg(argv, ['--guild', '--guild-id']) + let whiteFlag = initDiscordArg(argv, ['--whitelist', '--id-whitelist']) + + await initDiscordMkdir(ctx, '~/.discord') + await initDiscordMkdir(ctx, '~/.discord/plugins') + + const envPath = '~/.discord/.env' + const prevText = await initDiscordReadText(ctx, envPath) + const prev = initDiscordParseEnv(prevText) + const prevToken = prev.DISCORD_TOKEN || prev.BOT_TOKEN || '' + const prevGuild = prev.DISCORD_GUILD_ID || '' + const prevWhite = prev.DISCORD_ID_WHITELIST || '' + + if (!pluginOnly) { + let token = tokenFlag + let guild = guildFlag + let white = whiteFlag + if (!yes) { + ctx.console.log('Bare OS Discord setup') + ctx.console.log('Token from Developer Portal → Bot → Reset Token (not the OAuth2 client secret).') + if (prevToken && !token) { + ctx.console.log('Existing token: ' + initDiscordMaskToken(prevToken) + ' (Enter keeps it)') + } + token = await initDiscordAsk(ctx, 'DISCORD_TOKEN', token || '') + if (!token && prevToken) token = prevToken + guild = await initDiscordAsk( + ctx, + 'DISCORD_GUILD_ID (optional, instant slash commands)', + guild || prevGuild + ) + white = await initDiscordAsk( + ctx, + 'DISCORD_ID_WHITELIST (your user id, comma-separated)', + white || prevWhite + ) + } else if (!token) { + token = prevToken + } + if (!token) { + ctx.console.error(argv0 + ': DISCORD_TOKEN is required (flag --token or interactive prompt)') + ctx.exitCode = 1 + return + } + if (prevToken && token !== prevToken && !force && yes) { + ctx.console.error(argv0 + ': ~/.discord/.env already has a token (pass --force to replace)') + ctx.exitCode = 1 + return + } + let next = prevText || '# Bare OS Discord bot\n' + next = initDiscordUpsertEnv(next, 'DISCORD_TOKEN', token) + if (guild) next = initDiscordUpsertEnv(next, 'DISCORD_GUILD_ID', guild) + if (white) next = initDiscordUpsertEnv(next, 'DISCORD_ID_WHITELIST', white) + await initDiscordWriteText(ctx, envPath, next) + if (ctx.env) { + ctx.env.DISCORD_TOKEN = token + if (guild) ctx.env.DISCORD_GUILD_ID = guild + if (white) ctx.env.DISCORD_ID_WHITELIST = white + } + if (ctx.vfs.env) { + ctx.vfs.env.DISCORD_TOKEN = token + if (guild) ctx.vfs.env.DISCORD_GUILD_ID = guild + if (white) ctx.vfs.env.DISCORD_ID_WHITELIST = white + } + ctx.console.log('Wrote ' + envPath + ' (token ' + initDiscordMaskToken(token) + ')') + if (guild) ctx.console.log('Guild id ' + guild) + if (white) ctx.console.log('Whitelist ' + white) + } + + const pluginPath = '~/.discord/plugins/hello.json' + const existingPlugin = await initDiscordReadText(ctx, pluginPath) + if (existingPlugin && !force) { + ctx.console.log('Kept existing ' + pluginPath) + } else { + await initDiscordWriteText(ctx, pluginPath, INIT_DISCORD_HELLO_JSON) + ctx.console.log('Installed example plugin ' + pluginPath + ' (/hello)') + } + + ctx.console.log('') + ctx.console.log('Next:') + ctx.console.log(' discord-bot --check --env ~/.discord/.env') + ctx.console.log(' discord-bot --env ~/.discord/.env') + ctx.console.log(' systemctl daemon-reload && systemctl start bare-os-discord') + ctx.console.log(' /plugins reload (after the bot is online)') + ctx.exitCode = 0 +} diff --git a/kernel/etc/bare-os/posix_utilities.json b/kernel/etc/bare-os/posix_utilities.json index f1b6acc4..8f040aec 100644 --- a/kernel/etc/bare-os/posix_utilities.json +++ b/kernel/etc/bare-os/posix_utilities.json @@ -1,7 +1,7 @@ { "schema": 2, "profileId": "bare-os-posix-like", - "generatedAt": "2026-08-13T18:35:08.437Z", + "generatedAt": "2026-08-13T18:38:53.092Z", "note": "Sparse POSIX Issue 7 coverage hints; commandIndex is generated each coreutils build.", "commandIndex": [ { @@ -264,6 +264,10 @@ "name": "id", "tier": "tier1_bin" }, + { + "name": "init-discord", + "tier": "tier1_bin" + }, { "name": "install", "tier": "tier1_bin" diff --git a/kernel/lib/bare/shell-completion.json b/kernel/lib/bare/shell-completion.json index 49e0eab2..f39a1155 100644 --- a/kernel/lib/bare/shell-completion.json +++ b/kernel/lib/bare/shell-completion.json @@ -1,6 +1,6 @@ { "schema": 1, - "atMs": 1786646108433, + "atMs": 1786646333088, "commands": [ "agent", "appctl", @@ -67,6 +67,7 @@ "hypershell-board", "iconv", "id", + "init-discord", "install", "irc", "join", diff --git a/kernel/share/man/man.json b/kernel/share/man/man.json index 14c46eaa..4b87728b 100644 --- a/kernel/share/man/man.json +++ b/kernel/share/man/man.json @@ -1 +1 @@ -{"schemaVersion":1,"generatedAt":"2026-08-13T18:35:08.089Z","pages":[{"name":"agent","section":1,"title":"agent","synopsis":["agent [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of agent. Full behavior is defined in packages/bare-os-coreutils/src/agent.js.","options":[],"keywords":["agent","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"appctl","section":1,"title":"appctl","synopsis":["appctl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of appctl. Full behavior is defined in packages/bare-os-coreutils/src/appctl.js.","options":[],"keywords":["appctl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"appstore","section":1,"title":"appstore","synopsis":["appstore list | info NAME | install NAME pear://LINK --yes","appstore launch NAME | update NAME | uninstall NAME","appstore setup | search [query] | services [NAME]"],"description":"P2P App Store client for Bare OS. Installs packages from pear:// links by copying the release Hyperdrive tree into ~/.appstore/packages/ (or /mnt/appstore when the appstore HDMS drive is mounted). install uses lib/appstore-pear.js: prefers a local HDMS mount with the same key, otherwise opens an ephemeral readonly HDMS mount and mirrors files over VFS. launch runs the materialized entry script (package.json main, usually sources/index.js) in the guest shell via ctx.console. Requires login for remote pear:// fetch. See docs/guides/guest-pear-and-appstore-workflow.md.","options":[],"keywords":["appstore","bare-os","coreutils","pear","p2p","hdms"],"listCategory":"coreutils"},{"name":"arch","section":1,"title":"arch","synopsis":["arch [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of arch. Full behavior is defined in packages/bare-os-coreutils/src/arch.js.","options":[],"keywords":["arch","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"awk","section":1,"title":"pattern scanning and processing language","synopsis":["awk [OPTION]... [OPERAND]..."],"description":"Pattern-directed scanning and processing. Engine in lib/awk-engine.js; not full POSIX awk.","options":[],"keywords":["awk","pattern","field","script"],"seeAlso":[{"name":"sed","section":1},{"name":"grep","section":1}],"bareOsNotes":"See handbook ch.9 for divergence from Issue 7.","examples":[{"caption":"print column 1","code":"awk '{print $1}' file.txt"},{"caption":"field separator","code":"awk -F: '{print $1}' /etc/passwd"},{"caption":"sum numbers in first column","code":"awk '{s+=$1} END{print s}' nums.txt"},{"caption":"lines matching /re/","code":"awk '/error/{print NR\": \"$0}' log.txt"}],"listCategory":"coreutils"},{"name":"baretop","section":1,"title":"baretop","synopsis":["baretop [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of baretop. Full behavior is defined in packages/bare-os-coreutils/src/baretop.js.","options":[],"keywords":["baretop","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"btop","section":1,"title":"btop","synopsis":["btop [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of btop. Full behavior is defined in packages/bare-os-coreutils/src/btop.js.","options":[],"keywords":["btop","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"base32","section":1,"title":"base32","synopsis":["base32 [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of base32. Full behavior is defined in packages/bare-os-coreutils/src/base32.js.","options":[],"keywords":["base32","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"base64","section":1,"title":"base64","synopsis":["base64 [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of base64. Full behavior is defined in packages/bare-os-coreutils/src/base64.js.","options":[],"keywords":["base64","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"basename","section":1,"title":"strip directory and suffix from pathnames","synopsis":["basename [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of strip directory and suffix from pathnames. Full behavior is defined in packages/bare-os-coreutils/src/basename.js.","options":[],"keywords":["basename","bare-os","coreutils"],"examples":[{"caption":"strip directory","code":"basename /home/user/docs/readme.md"},{"caption":"strip suffix","code":"basename -s .md /path/readme.md"}],"listCategory":"coreutils"},{"name":"baresay","section":1,"title":"baresay","synopsis":["baresay [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of baresay. Full behavior is defined in packages/bare-os-coreutils/src/baresay.js.","options":[],"keywords":["baresay","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"basenc","section":1,"title":"basenc","synopsis":["basenc [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of basenc. Full behavior is defined in packages/bare-os-coreutils/src/basenc.js.","options":[],"keywords":["basenc","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"cat","section":1,"title":"concatenate and print files","synopsis":["cat [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of concatenate and print files. Full behavior is defined in packages/bare-os-coreutils/src/cat.js.","options":[],"keywords":["cat","bare-os","coreutils"],"examples":[{"caption":"stdout several files","code":"cat a.txt b.txt"},{"caption":"number lines (use nl)","code":"cat -n file.txt # if supported; else nl file"},{"caption":"here-string via echo pipe","code":"echo hello | cat"}],"listCategory":"coreutils"},{"name":"chat","section":1,"title":"chat","synopsis":["chat [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of chat. Full behavior is defined in packages/bare-os-coreutils/src/chat.js.","options":[],"keywords":["chat","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"chgrp","section":1,"title":"change file group ownership","synopsis":["chgrp [OPTION]... [OPERAND]..."],"description":"Updates group metadata on the personal Hyperdrive for writable paths (session home, $HOME, /tmp, /var/log).","options":[],"keywords":["chgrp","bare-os","coreutils"],"bareOsNotes":"Uses vfs.chown with preserved uid; system image paths are read-only. See packages/bare-os-booter/lib/vfs.js.","examples":[{"caption":"set group by name","code":"chgrp guest shared.conf"}],"listCategory":"coreutils"},{"name":"chmod","section":1,"title":"change file mode bits","synopsis":["chmod MODE FILE...","MODE is octal (e.g. 644) or symbolic (e.g. u+rw)"],"description":"Sets file mode bits on the VFS. Supports POSIX-style symbolic modes (u/g/o/a, +/-/=, rwxX) and octal modes.","options":[],"keywords":["chmod","mode","permission","octal","symbolic"],"diagnostics":["chmod: No such file","chmod: invalid mode"],"bareOsNotes":"Applies to Hyperdrive metadata; not a host inode.","examples":[{"caption":"octal","code":"chmod 644 ~/.profile"},{"caption":"recursive-ish (run find + chmod per file)","code":"find . -type f -name \"*.sh\" -print"},{"caption":"symbolic user bits","code":"chmod u+x script.sh"},{"caption":"all read, owner write","code":"chmod a+r,u+w shared.txt"}],"listCategory":"coreutils"},{"name":"chown","section":1,"title":"change file owner and group","synopsis":["chown [OPTION]... [OPERAND]..."],"description":"Updates uid/gid metadata on the personal Hyperdrive where the booter allows writes; euid 0 may set any owner.","options":[],"keywords":["chown","bare-os","coreutils"],"bareOsNotes":"OWNER/GROUP may be numeric or root/guest/nobody/current user. See vfs chown and identity env UID/GID.","examples":[{"caption":"group only","code":"chown :guest file.txt"},{"caption":"numeric ids","code":"chown 1000:1000 notes.txt"}],"listCategory":"coreutils"},{"name":"cksum","section":1,"title":"write file checksums and sizes","synopsis":["cksum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of write file checksums and sizes. Full behavior is defined in packages/bare-os-coreutils/src/cksum.js.","options":[],"keywords":["cksum","bare-os","coreutils"],"examples":[{"caption":"checksum file","code":"cksum iso.img"},{"caption":"verify pipeline","code":"cat f | cksum"}],"listCategory":"coreutils"},{"name":"clear","section":1,"title":"clear the terminal screen","synopsis":["clear [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of clear the terminal screen. Full behavior is defined in packages/bare-os-coreutils/src/clear.js.","options":[],"keywords":["clear","bare-os","coreutils"],"examples":[{"caption":"wipe screen","code":"clear"}],"listCategory":"coreutils"},{"name":"comm","section":1,"title":"comm","synopsis":["comm [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of comm. Full behavior is defined in packages/bare-os-coreutils/src/comm.js.","options":[],"keywords":["comm","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"cmp","section":1,"title":"cmp","synopsis":["cmp [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of cmp. Full behavior is defined in packages/bare-os-coreutils/src/cmp.js.","options":[],"keywords":["cmp","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"cp","section":1,"title":"copy files","synopsis":["cp [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of copy files. Full behavior is defined in packages/bare-os-coreutils/src/cp.js.","options":[],"keywords":["cp","bare-os","coreutils"],"examples":[{"caption":"copy file","code":"cp src.txt dest.txt"},{"caption":"into directory","code":"cp a b c ~/backup/"},{"caption":"preserve implied (if implemented)","code":"cp -R proj proj.bak"}],"listCategory":"coreutils"},{"name":"corestorectl","section":1,"title":"corestorectl","synopsis":["corestorectl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of corestorectl. Full behavior is defined in packages/bare-os-coreutils/src/corestorectl.js.","options":[],"keywords":["corestorectl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"crontab","section":1,"title":"user crontab manipulation","synopsis":["crontab [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of user crontab manipulation. Full behavior is defined in packages/bare-os-coreutils/src/crontab.js.","options":[],"keywords":["crontab","bare-os","coreutils"],"examples":[{"caption":"list jobs","code":"crontab -l"},{"caption":"install from file","code":"crontab ~/.crontab"},{"caption":"remove all","code":"crontab -r"}],"listCategory":"coreutils"},{"name":"ctxbaredoctor","section":1,"title":"ctxbaredoctor","synopsis":["ctxbaredoctor [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of ctxbaredoctor. Full behavior is defined in packages/bare-os-coreutils/src/ctxbaredoctor.js.","options":[],"keywords":["ctxbaredoctor","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"curl","section":1,"title":"curl","synopsis":["curl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of curl. Full behavior is defined in packages/bare-os-coreutils/src/curl.js.","options":[],"keywords":["curl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"cut","section":1,"title":"cut out selected fields of each line","synopsis":["cut [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of cut out selected fields of each line. Full behavior is defined in packages/bare-os-coreutils/src/cut.js.","options":[],"keywords":["cut","bare-os","coreutils"],"examples":[{"caption":"fields by delimiter","code":"cut -d: -f1,3 /etc/passwd"},{"caption":"characters","code":"cut -c1-16 file.txt"}],"listCategory":"coreutils"},{"name":"date","section":1,"title":"display or set date and time","synopsis":["date [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of display or set date and time. Full behavior is defined in packages/bare-os-coreutils/src/date.js.","options":[],"keywords":["date","bare-os","coreutils"],"examples":[{"caption":"RFC-ish output","code":"date"},{"caption":"epoch seconds","code":"date +%s"}],"listCategory":"coreutils"},{"name":"dd","section":1,"title":"dd","synopsis":["dd [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of dd. Full behavior is defined in packages/bare-os-coreutils/src/dd.js.","options":[],"keywords":["dd","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"df","section":1,"title":"df","synopsis":["df [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of df. Full behavior is defined in packages/bare-os-coreutils/src/df.js.","options":[],"keywords":["df","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"diff","section":1,"title":"diff","synopsis":["diff [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of diff. Full behavior is defined in packages/bare-os-coreutils/src/diff.js.","options":[],"keywords":["diff","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"dir","section":1,"title":"dir","synopsis":["dir [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of dir. Full behavior is defined in packages/bare-os-coreutils/src/dir.js.","options":[],"keywords":["dir","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"dirname","section":1,"title":"return directory portion of a pathname","synopsis":["dirname [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return directory portion of a pathname. Full behavior is defined in packages/bare-os-coreutils/src/dirname.js.","options":[],"keywords":["dirname","bare-os","coreutils"],"examples":[{"caption":"parent path","code":"dirname /a/b/c.txt"},{"caption":"compose with basename","code":"p=/x/y/z; echo $(dirname $p)/$(basename $p)"}],"listCategory":"coreutils"},{"name":"dircolors","section":1,"title":"dircolors","synopsis":["dircolors [-b] [FILE]","dircolors -p"],"description":"Print LS_COLORS from a dircolors database (GNU subset: TERM blocks, key/value pairs). -p prints the default Bare OS database.","options":[{"flag":"-b, --sh","meaning":"Bourne-shell export LS_COLORS"},{"flag":"-p, --print-database","meaning":"Print default database"}],"keywords":["dircolors","LS_COLORS","color"],"bareOsNotes":"FILE read via VFS.","listCategory":"coreutils"},{"name":"dhtctl","section":1,"title":"dhtctl","synopsis":["dhtctl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of dhtctl. Full behavior is defined in packages/bare-os-coreutils/src/dhtctl.js.","options":[],"keywords":["dhtctl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"dhtscan","section":1,"title":"dhtscan","synopsis":["dhtscan [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of dhtscan. Full behavior is defined in packages/bare-os-coreutils/src/dhtscan.js.","options":[],"keywords":["dhtscan","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"dhttop","section":1,"title":"dhttop","synopsis":["dhttop [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of dhttop. Full behavior is defined in packages/bare-os-coreutils/src/dhttop.js.","options":[],"keywords":["dhttop","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"discord-bot","section":1,"title":"discord-bot","synopsis":["discord-bot [--env PATH] [--token TOKEN] [--guild ID] [--check] [--debug] [--message-content] [--login-timeout MS]"],"description":"Bare OS Discord bot via ctx.bare.discordJS. Commands run as the unlocked session user (not guest). /run is a non-interactive shell (cwd, history, autocomplete). /plugins loads JSON or JS from ~/.discord/plugins (see developer-guide ch.21). Also /settings, /files, /panel, /edit, /create, /bare, /sys, /svc, /fs, /net, /man, /say, /journal, /ping. Embeds paginate when large and expire after 2 minutes idle. Token from --token, DISCORD_TOKEN, or ~/.discord/.env. DISCORD_ID_WHITELIST restricts who may use the bot. The initd unit bare-os-discord is listed by systemctl only when ~/.discord/.env exists.","options":[{"flag":"--env PATH","meaning":"VFS path to a .env file containing DISCORD_TOKEN=... (also --env-file)."},{"flag":"--token TOKEN","meaning":"Bot token (Developer Portal → Bot → Token). Prefer a .env file."},{"flag":"--guild ID","meaning":"Guild id for instant /ping registration (else global, up to ~1 hour)."},{"flag":"--check","meaning":"Verify ctx.bare.discordJS and that a token can be resolved; do not login."},{"flag":"--debug","meaning":"Print discord.js debug lines (also DISCORD_DEBUG=1)."},{"flag":"--message-content","meaning":"Request the privileged Message Content Intent so channel 'ping' replies pong. Enable the same intent in the Developer Portal first."},{"flag":"--login-timeout MS","meaning":"Fail login if the gateway is not ready after MS milliseconds (default 45000)."}],"keywords":["discord","bot","ping","pong","ctx.bare"],"environment":["DISCORD_TOKEN — bot token in the guest session (also copied from the host when set).","DISCORD_ENV_FILE / BARE_OS_DISCORD_ENV_FILE — path to a .env file. On the host this may be a host filesystem path (booter reads it). In the guest it is a VFS path. Preferred guest path: ~/.discord/.env.","BARE_OS_DISCORD_INITD — set 0 / false to never register the bare-os-discord systemctl unit, even when ~/.discord/.env exists.","DISCORD_GUILD_ID — optional guild for slash-command registration.","DISCORD_ID_WHITELIST — comma-separated Discord user ids allowed to use the bot. Unset or empty allows everyone. A user not on a non-empty list is denied (ephemeral for slash commands).","DISCORD_MESSAGE_CONTENT / BARE_OS_DISCORD_MESSAGE_CONTENT — set 1 to request Message Content Intent (same as --message-content).","DISCORD_DEBUG / BARE_OS_DISCORD_DEBUG — set 1 to print discord.js debug lines.","DISCORD_LOGIN_TIMEOUT_MS — login deadline in milliseconds (default 45000).","BARE_OS_DISCORD — set 0 / false to skip loading ctx.bare.discordJS.","BARE_OS_BARE_MODULES — set 0 to omit ctx.bare entirely."],"seeAlso":[{"name":"bare-os-ctx-bare","section":7},{"name":"devguide-21-discord-bots","section":7}],"bareOsNotes":"Requires a Bare/Pear host so vendored bare-discord-js can remap Node builtins. Guest scripts have no import/require; use ctx.bare.discordJS.","examples":[{"caption":"check token resolution without connecting","code":"discord-bot --check --env ~/.discord/.env"},{"caption":"run the ping-pong bot","code":"discord-bot --env ~/.discord/.env --guild 123456789012345678"}],"listCategory":"coreutils"},{"name":"du","section":1,"title":"estimate file space usage","synopsis":["du [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of estimate file space usage. Full behavior is defined in packages/bare-os-coreutils/src/du.js.","options":[],"keywords":["du","bare-os","coreutils"],"examples":[{"caption":"sizes under cwd","code":"du ."},{"caption":"human (if supported)","code":"du -h ~"}],"listCategory":"coreutils"},{"name":"edit","section":1,"title":"edit","synopsis":["edit [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of edit. Full behavior is defined in packages/bare-os-coreutils/src/edit.js.","options":[],"keywords":["edit","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"echo","section":1,"title":"write arguments to standard output","synopsis":["echo [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of write arguments to standard output. Full behavior is defined in packages/bare-os-coreutils/src/echo.js.","options":[],"keywords":["echo","bare-os","coreutils"],"examples":[{"caption":"literal","code":"echo hello world"},{"caption":"no newline (if -n supported)","code":"echo -n OK"}],"listCategory":"coreutils"},{"name":"env","section":1,"title":"set the environment for command invocation","synopsis":["env [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of set the environment for command invocation. Full behavior is defined in packages/bare-os-coreutils/src/env.js.","options":[],"keywords":["env","bare-os","coreutils"],"examples":[{"caption":"print environment","code":"env"},{"caption":"run with override","code":"env PATH=/bin:/usr/bin man ls"}],"listCategory":"coreutils"},{"name":"exit","section":1,"title":"exit the shell or booter session","synopsis":["exit [status]"],"description":"When run as /bin/exit, requests the booter to end the session via ctx.requestBooterExit. Status defaults to 0.","options":[],"keywords":["exit","bare-os","coreutils"],"bareOsNotes":"Also available as a shell builtin with different wiring.","examples":[{"caption":"leave session with status","code":"exit 0"},{"caption":"from script","code":"/bin/exit 42"}],"listCategory":"coreutils"},{"name":"expand","section":1,"title":"expand","synopsis":["expand [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of expand. Full behavior is defined in packages/bare-os-coreutils/src/expand.js.","options":[],"keywords":["expand","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"expr","section":1,"title":"expr","synopsis":["expr [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of expr. Full behavior is defined in packages/bare-os-coreutils/src/expr.js.","options":[],"keywords":["expr","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"factor","section":1,"title":"factor","synopsis":["factor [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of factor. Full behavior is defined in packages/bare-os-coreutils/src/factor.js.","options":[],"keywords":["factor","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"false","section":1,"title":"return false value","synopsis":["false [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return false value. Full behavior is defined in packages/bare-os-coreutils/src/false.js.","options":[],"keywords":["false","bare-os","coreutils"],"examples":[{"caption":"force failure in pipeline tests","code":"false; echo $?"}],"listCategory":"coreutils"},{"name":"find","section":1,"title":"find files","synopsis":["find [PATH...] [EXPRESSION]"],"description":"Walks directories and applies expressions (-name, -type, -print, -maxdepth, logical -and/-or/-not).","options":[],"keywords":["find","directory","walk","search"],"bareOsNotes":"Expression syntax is a simplified subset.","examples":[{"caption":"files by name glob","code":"find . -name \"*.js\""},{"caption":"directories only","code":"find . -type d"},{"caption":"max depth","code":"find . -maxdepth 2 -type f"},{"caption":"OR names","code":"find . \\( -name \"*.c\" -o -name \"*.h\" \\)"}],"listCategory":"coreutils"},{"name":"fmt","section":1,"title":"fmt","synopsis":["fmt [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of fmt. Full behavior is defined in packages/bare-os-coreutils/src/fmt.js.","options":[],"keywords":["fmt","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"fold","section":1,"title":"fold","synopsis":["fold [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of fold. Full behavior is defined in packages/bare-os-coreutils/src/fold.js.","options":[],"keywords":["fold","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"getconf","section":1,"title":"get configuration values","synopsis":["getconf [OPTION]... [OPERAND]..."],"description":"Prints a fixed subset of configuration limits for Bare OS (JavaScript runtime and VFS). There is no host sysconf(3); values are documented constants, not live kernel queries.","options":[{"flag":"-a","meaning":"Write all known variables (name then value per pair)"}],"keywords":["getconf","bare-os","coreutils"],"bareOsNotes":"Unknown variable names exit with status 1. Not a full Issue 7 getconf implementation.","examples":[{"caption":"path length limit","code":"getconf PATH_MAX"},{"caption":"list known names and values","code":"getconf -a"}],"listCategory":"coreutils"},{"name":"getfacl","section":1,"title":"getfacl","synopsis":["getfacl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of getfacl. Full behavior is defined in packages/bare-os-coreutils/src/getfacl.js.","options":[],"keywords":["getfacl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"git-pear","section":1,"title":"git-pear","synopsis":["git-pear [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of git-pear. Full behavior is defined in packages/bare-os-coreutils/src/git-pear.js.","options":[],"keywords":["git-pear","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"grep","section":1,"title":"pattern matching utility","synopsis":["grep [-E|-F] [-i] [-v] [-n] [-c] [-l] [-q] [-s] [-H|-h] [-e pat] ... [-f file] ... [pattern] [file...]"],"description":"Searches input or files for lines matching a pattern. Uses JavaScript RegExp unless -F (fixed string). Not bit-identical to GNU grep.","options":[{"flag":"-E","meaning":"Extended regex (accepted; patterns use JS RegExp)"},{"flag":"-F","meaning":"Fixed string match"},{"flag":"-i","meaning":"Ignore case"},{"flag":"-v","meaning":"Invert match"},{"flag":"-n","meaning":"Prefix lines with line number"},{"flag":"-c","meaning":"Count matching lines only"},{"flag":"-l","meaning":"List files with matches"},{"flag":"-q","meaning":"Quiet (exit status only)"},{"flag":"-s","meaning":"Suppress error messages"},{"flag":"-H / -h","meaning":"Force / suppress filename prefix"},{"flag":"-e pat","meaning":"Specify pattern"},{"flag":"-f file","meaning":"Read patterns from file"}],"keywords":["grep","search","regex","pattern","filter"],"seeAlso":[{"name":"sed","section":1},{"name":"awk","section":1}],"bareOsNotes":"UTF-16 strings and JS regex differ from strict POSIX/GNU.","examples":[{"caption":"recursive feel (grep each file)","code":"grep -n error *.log"},{"caption":"case insensitive","code":"grep -i todo NOTES.md"},{"caption":"invert (lines without)","code":"grep -v '^#' config"},{"caption":"fixed string (no regex)","code":"grep -F \"v1.0\" CHANGES"},{"caption":"count matches","code":"grep -c FAIL build.log"},{"caption":"only filenames","code":"grep -l main *.js"},{"caption":"multiple patterns","code":"grep -e foo -e bar file.txt"}],"listCategory":"coreutils"},{"name":"groups","section":1,"title":"groups","synopsis":["groups [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of groups. Full behavior is defined in packages/bare-os-coreutils/src/groups.js.","options":[],"keywords":["groups","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"head","section":1,"title":"copy the first part of files","synopsis":["head [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of copy the first part of files. Full behavior is defined in packages/bare-os-coreutils/src/head.js.","options":[],"keywords":["head","bare-os","coreutils"],"examples":[{"caption":"first 10 lines","code":"head /etc/os-release"},{"caption":"first N","code":"head -n 50 big.log"},{"caption":"stdin","code":"cat long.txt | head"}],"listCategory":"coreutils"},{"name":"hdms","section":1,"title":"Hyperswarm distributed map store","synopsis":["hdms [OPTION]... [OPERAND]..."],"description":"Invokes ctx.runHdms when the booter provides HDMS integration; otherwise prints unavailable.","options":[],"keywords":["hdms","hyperswarm","map"],"bareOsNotes":"Optional booter capability.","examples":[{"caption":"when booter wires HDMS","code":"hdms ls /mnt"},{"caption":"otherwise","code":"# prints unavailable without ctx.runHdms"}],"listCategory":"coreutils"},{"name":"help","section":1,"title":"Bare OS help summary","synopsis":["help"],"description":"Prints a one-screen summary of shell builtins and /bin command names. Use man for long-form documentation.","options":[],"keywords":["help","summary","builtins","commands"],"seeAlso":[{"name":"man","section":1},{"name":"bare-os-shell","section":1}],"examples":[{"caption":"quick index","code":"help"},{"caption":"then deep dive","code":"man grep"}],"listCategory":"coreutils"},{"name":"holesail","section":1,"title":"holesail","synopsis":["holesail [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of holesail. Full behavior is defined in packages/bare-os-coreutils/src/holesail.js.","options":[],"keywords":["holesail","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"holepunch-view","section":1,"title":"holepunch-view","synopsis":["holepunch-view [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of holepunch-view. Full behavior is defined in packages/bare-os-coreutils/src/holepunch-view.js.","options":[],"keywords":["holepunch-view","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"hostid","section":1,"title":"hostid","synopsis":["hostid [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of hostid. Full behavior is defined in packages/bare-os-coreutils/src/hostid.js.","options":[],"keywords":["hostid","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"hostname","section":1,"title":"set or print hostname","synopsis":["hostname [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of set or print hostname. Full behavior is defined in packages/bare-os-coreutils/src/hostname.js.","options":[],"keywords":["hostname","bare-os","coreutils"],"examples":[{"caption":"show host","code":"hostname"}],"listCategory":"coreutils"},{"name":"hypershell-board","section":1,"title":"hypershell-board","synopsis":["hypershell-board [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of hypershell-board. Full behavior is defined in packages/bare-os-coreutils/src/hypershell-board.js.","options":[],"keywords":["hypershell-board","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"iconv","section":1,"title":"iconv","synopsis":["iconv [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of iconv. Full behavior is defined in packages/bare-os-coreutils/src/iconv.js.","options":[],"keywords":["iconv","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"id","section":1,"title":"return user identity","synopsis":["id [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return user identity. Full behavior is defined in packages/bare-os-coreutils/src/id.js.","options":[],"keywords":["id","bare-os","coreutils"],"examples":[{"caption":"who am I numerically","code":"id"}],"listCategory":"coreutils"},{"name":"install","section":1,"title":"install","synopsis":["install [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of install. Full behavior is defined in packages/bare-os-coreutils/src/install.js.","options":[],"keywords":["install","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"irc","section":1,"title":"irc","synopsis":["irc [libera|HOST] [--tls|--plain] [--nick N]","irc send TARGET TEXT","irc join #channel","irc whois NICK","irc status"],"description":"Modern IRC client (IRCv3 CAP LS 302). Default network is Libera.Chat over TLS at irc.libera.chat:6697. On a TTY, opens a full-screen ctx.tui session with a room browser (/rooms) and a random nick when none is configured. Without a TTY, use send/join/whois/status. Config lives in ~/.irc/config.json; SASL secrets in ~/.irc/secrets.json.","options":[{"flag":"--tls","meaning":"Require TLS (default)."},{"flag":"--plain","meaning":"Plaintext TCP. Blocked for libera.chat unless --insecure-plain."},{"flag":"--insecure-plain","meaning":"Allow plaintext even for Libera hostnames."},{"flag":"--nick","meaning":"Nickname (else ~/.irc/config.json, BARE_IRC_NICK, or a random osXXXXX nick)."},{"flag":"--sasl-user","meaning":"SASL PLAIN account. Password from ~/.irc/secrets.json."}],"keywords":["irc","libera","tui","chat"],"bareOsNotes":"TLS via ctx.bareOsTlsConnect (ctx API 1.57.0) or ctx.bare.bareTls on older Bare standalone binaries. Disable with BARE_OS_IRC=0.","listCategory":"coreutils"},{"name":"join","section":1,"title":"join","synopsis":["join [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of join. Full behavior is defined in packages/bare-os-coreutils/src/join.js.","options":[],"keywords":["join","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kill","section":1,"title":"kill","synopsis":["kill [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kill. Full behavior is defined in packages/bare-os-coreutils/src/kill.js.","options":[],"keywords":["kill","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-boot-diff","section":1,"title":"kernel-boot-diff","synopsis":["kernel-boot-diff [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-boot-diff. Full behavior is defined in packages/bare-os-coreutils/src/kernel-boot-diff.js.","options":[],"keywords":["kernel-boot-diff","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-doctor","section":1,"title":"kernel-doctor","synopsis":["kernel-doctor [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-doctor. Full behavior is defined in packages/bare-os-coreutils/src/kernel-doctor.js.","options":[],"keywords":["kernel-doctor","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-explain","section":1,"title":"kernel-explain","synopsis":["kernel-explain [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-explain. Full behavior is defined in packages/bare-os-coreutils/src/kernel-explain.js.","options":[],"keywords":["kernel-explain","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-fsck","section":1,"title":"kernel-fsck","synopsis":["kernel-fsck [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-fsck. Full behavior is defined in packages/bare-os-coreutils/src/kernel-fsck.js.","options":[],"keywords":["kernel-fsck","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-home-snapshot","section":1,"title":"kernel-home-snapshot","synopsis":["kernel-home-snapshot [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-home-snapshot. Full behavior is defined in packages/bare-os-coreutils/src/kernel-home-snapshot.js.","options":[],"keywords":["kernel-home-snapshot","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-manifest-validate","section":1,"title":"kernel-manifest-validate","synopsis":["kernel-manifest-validate [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-manifest-validate. Full behavior is defined in packages/bare-os-coreutils/src/kernel-manifest-validate.js.","options":[],"keywords":["kernel-manifest-validate","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-preflight","section":1,"title":"kernel-preflight","synopsis":["kernel-preflight [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-preflight. Full behavior is defined in packages/bare-os-coreutils/src/kernel-preflight.js.","options":[],"keywords":["kernel-preflight","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"kernel-triage","section":1,"title":"kernel-triage","synopsis":["kernel-triage [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of kernel-triage. Full behavior is defined in packages/bare-os-coreutils/src/kernel-triage.js.","options":[],"keywords":["kernel-triage","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"jq","section":1,"title":"command-line JSON processor (jq language subset)","synopsis":["jq [-n] [-R] [-s] [-c] [-r] [-e] [-f file] filter [file...]","jq reads JSON (concatenated values or NDJSON-style streams) from files or stdin."],"description":"Runs a jq filter program against JSON values. The engine is vendored jqjs (pure JavaScript), not the C implementation at https://github.com/jqlang/jq — language coverage and edge cases differ.","options":[{"flag":"-n, --null-input","meaning":"Use null as the sole input (ignore file/stdin for input)"},{"flag":"-R, --raw-input","meaning":"Treat each line as a string instead of JSON"},{"flag":"-s, --slurp","meaning":"Read all inputs into one array; run the filter once"},{"flag":"-c, --compact-output","meaning":"Compact JSON on output"},{"flag":"-r, --raw-output","meaning":"Print strings without JSON quotes"},{"flag":"-e, --exit-status","meaning":"Set exit status from outputs (no output → 4; last false/null → 1)"},{"flag":"-f, --from-file","meaning":"Read filter program from file"}],"keywords":["jq","json","query","filter","jqjs"],"seeAlso":[{"name":"grep","section":1},{"name":"awk","section":1}],"bareOsNotes":"Engine: lib/jq-engine.js from @sscots/jqjs (mwh/jqjs). Missing vs C jq: try/catch, user-defined functions, recurse, many builtins, modules, full Unicode. See upstream jqjs README for the feature matrix.","examples":[{"caption":"pretty-print","code":"jq . data.json"},{"caption":"field","code":"jq .version package.json"},{"caption":"slurp array","code":"jq -s 'map(.x) | add' parts.jsonl"},{"caption":"compact","code":"jq -c '.[] | select(.ok)' items.json"}],"listCategory":"coreutils"},{"name":"ln","section":1,"title":"link files","synopsis":["ln [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of link files. Full behavior is defined in packages/bare-os-coreutils/src/ln.js.","options":[],"keywords":["ln","bare-os","coreutils"],"examples":[{"caption":"symlink","code":"ln -s target name"},{"caption":"hard link (if supported)","code":"ln file linkname"}],"listCategory":"coreutils"},{"name":"link","section":1,"title":"link","synopsis":["link [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of link. Full behavior is defined in packages/bare-os-coreutils/src/link.js.","options":[],"keywords":["link","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"logger","section":1,"title":"logger","synopsis":["logger [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of logger. Full behavior is defined in packages/bare-os-coreutils/src/logger.js.","options":[],"keywords":["logger","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"login","section":1,"title":"begin a session on the system","synopsis":["login [OPTION]... [OPERAND]..."],"description":"When invoked from /bin, behavior aligns with session identity hooks (see booter). Prefer the shell builtin for passphrase entry.","options":[],"keywords":["login","identity","passphrase"],"seeAlso":[{"name":"logout","section":1}],"examples":[{"caption":"unlock: run login, then type passphrase at prompt (multi-word ok)","code":"login"},{"caption":"register new identity","code":"login --new"}],"listCategory":"coreutils"},{"name":"logout","section":1,"title":"end session (save vault)","synopsis":["logout [OPTION]... [OPERAND]..."],"description":"Ends session; may persist vault depending on booter and flags.","options":[],"keywords":["logout","session"],"seeAlso":[{"name":"login","section":1}],"examples":[{"caption":"end session","code":"logout"},{"caption":"save vault hint","code":"logout --save"}],"listCategory":"coreutils"},{"name":"logname","section":1,"title":"return the user's login name","synopsis":["logname [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return the user's login name. Full behavior is defined in packages/bare-os-coreutils/src/logname.js.","options":[],"keywords":["logname","bare-os","coreutils"],"examples":[{"caption":"login name","code":"logname"}],"listCategory":"coreutils"},{"name":"locale","section":1,"title":"locale","synopsis":["locale [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of locale. Full behavior is defined in packages/bare-os-coreutils/src/locale.js.","options":[],"keywords":["locale","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"ls","section":1,"title":"list directory contents","synopsis":["ls [-1al] [--color[=never|auto|always]] [FILE...]"],"description":"Lists directory contents. Long format shows mode, links, owner, group, size, mtime, and symlink targets. With color (default auto on a TTY), directories, symlinks, executables, and permission bits are highlighted.","options":[{"flag":"-a","meaning":"Include names starting with ."},{"flag":"-l","meaning":"Long listing"},{"flag":"-1","meaning":"One name per line (short format)"},{"flag":"--color[=never|auto|always]","meaning":"ANSI colors: never, auto (TTY only), or always; plain --color is auto"}],"keywords":["ls","list","directory","dir"],"environment":["NO_COLOR — disable color even when a TTY or --color=always"],"bareOsNotes":"Hides .bareos_empty marker like other tools.","examples":[{"caption":"long + hidden","code":"ls -la ~"},{"caption":"one per line","code":"ls -1 /bin | head"},{"caption":"multiple paths","code":"ls /bin /etc"}],"listCategory":"coreutils"},{"name":"man","section":1,"title":"display on-line manual pages","synopsis":["man [-k keyword] [-f name] [-l] [[section] name]","man reads /share/man/man.json on the system drive."],"description":"Displays manual pages from the merged JSON database. Section 1: /bin and git/shell pages. Section 7: handbook (man handbook), user manual (man users-manual), developer guide (man devguide), and docs/ (man docs), merged at build from handbook/*.md, users-manual/*.md, developer-guide/*.md, and docs/**/*.md.","options":[{"flag":"-k, --apropos","meaning":"Search keywords and titles (substring)"},{"flag":"-f, --whatis","meaning":"One-line description for exact name"},{"flag":"-l, --list","meaning":"List pages grouped by category (/bin, git/shell, handbook, user manual, developer guide, docs/), then alphabetically"}],"keywords":["man","manual","help","documentation","apropos","whatis","cheat","examples"],"environment":["MANWIDTH — if set, wrap width (clamped 40–200); overrides auto width","COLUMNS — when stdout is not a TTY (or output is captured), used if MANWIDTH unset","NO_COLOR — disable bold headings on TTY"],"seeAlso":[{"name":"help","section":1},{"name":"bare-os-handbook","section":7},{"name":"bare-os-developer-guide","section":7},{"name":"bare-os-docs","section":7},{"name":"bare-os-users-manual","section":7}],"bareOsNotes":"No troff; no embedded DB fallback in v1.","examples":[{"caption":"open page","code":"man sed"},{"caption":"handbook TOC (section 7)","code":"man handbook"},{"caption":"handbook chapter by section","code":"man 7 handbook-01-introduction"},{"caption":"apropos","code":"man -k copy"},{"caption":"whatis","code":"man -f grep"},{"caption":"all pages","code":"man -l"},{"caption":"fixed width (overrides TTY)","code":"MANWIDTH=64 man awk"}],"listCategory":"coreutils"},{"name":"md5sum","section":1,"title":"md5sum","synopsis":["md5sum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of md5sum. Full behavior is defined in packages/bare-os-coreutils/src/md5sum.js.","options":[],"keywords":["md5sum","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"meshdrop","section":1,"title":"meshdrop","synopsis":["meshdrop [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of meshdrop. Full behavior is defined in packages/bare-os-coreutils/src/meshdrop.js.","options":[],"keywords":["meshdrop","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"mkdir","section":1,"title":"make directories","synopsis":["mkdir [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of make directories. Full behavior is defined in packages/bare-os-coreutils/src/mkdir.js.","options":[],"keywords":["mkdir","bare-os","coreutils"],"examples":[{"caption":"one dir","code":"mkdir proj"},{"caption":"parents","code":"mkdir -p a/b/c"}],"listCategory":"coreutils"},{"name":"mkfifo","section":1,"title":"make FIFO special files","synopsis":["mkfifo [OPTION]... [OPERAND]..."],"description":"Creates in-memory FIFO endpoints under /run/bare-os/ipc/ (not Hyperdrive specials).","options":[],"keywords":["mkfifo","bare-os","coreutils"],"bareOsNotes":"Uses ctx.bareOsIpc.create; optional BARE_OS_IPC_NAMESPACE prefixes keys. BARE_OS_IPC_MAX_CHANNELS caps distinct channels; see metrics_live.ipcTelemetry.","examples":[{"caption":"stub","code":"# FIFOs not on Hyperdrive — use shell pipelines"}],"listCategory":"coreutils"},{"name":"mktemp","section":1,"title":"mktemp","synopsis":["mktemp [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of mktemp. Full behavior is defined in packages/bare-os-coreutils/src/mktemp.js.","options":[],"keywords":["mktemp","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"mount","section":1,"title":"mount","synopsis":["mount [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of mount. Full behavior is defined in packages/bare-os-coreutils/src/mount.js.","options":[],"keywords":["mount","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"mv","section":1,"title":"move or rename files","synopsis":["mv [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of move or rename files. Full behavior is defined in packages/bare-os-coreutils/src/mv.js.","options":[],"keywords":["mv","bare-os","coreutils"],"examples":[{"caption":"rename","code":"mv old.txt new.txt"},{"caption":"into dir","code":"mv *.txt ~/inbox/"}],"listCategory":"coreutils"},{"name":"nano","section":1,"title":"nano","synopsis":["nano [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of nano. Full behavior is defined in packages/bare-os-coreutils/src/nano.js.","options":[],"keywords":["nano","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"nice","section":1,"title":"nice","synopsis":["nice [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of nice. Full behavior is defined in packages/bare-os-coreutils/src/nice.js.","options":[],"keywords":["nice","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"nl","section":1,"title":"line numbering utility","synopsis":["nl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of line numbering utility. Full behavior is defined in packages/bare-os-coreutils/src/nl.js.","options":[],"keywords":["nl","bare-os","coreutils"],"examples":[{"caption":"number all lines","code":"nl README.md"}],"listCategory":"coreutils"},{"name":"nohup","section":1,"title":"run command (hangup is a no-op in Bare OS)","synopsis":["nohup [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of run command (hangup is a no-op in Bare OS). Full behavior is defined in packages/bare-os-coreutils/src/nohup.js.","options":[],"keywords":["nohup","bare-os","coreutils"],"examples":[{"caption":"run utility (no real SIGHUP in guest)","code":"nohup long-job.sh"}],"listCategory":"coreutils"},{"name":"nproc","section":1,"title":"nproc","synopsis":["nproc [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of nproc. Full behavior is defined in packages/bare-os-coreutils/src/nproc.js.","options":[],"keywords":["nproc","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"numfmt","section":1,"title":"numfmt","synopsis":["numfmt [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of numfmt. Full behavior is defined in packages/bare-os-coreutils/src/numfmt.js.","options":[],"keywords":["numfmt","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"od","section":1,"title":"octal dump","synopsis":["od [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of octal dump. Full behavior is defined in packages/bare-os-coreutils/src/od.js.","options":[],"keywords":["od","bare-os","coreutils"],"examples":[{"caption":"hex dump vibe","code":"od -c file.bin | head"}],"listCategory":"coreutils"},{"name":"openssl","section":1,"title":"openssl","synopsis":["openssl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of openssl. Full behavior is defined in packages/bare-os-coreutils/src/openssl.js.","options":[],"keywords":["openssl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"oidc-publish","section":1,"title":"oidc-publish","synopsis":["oidc-publish [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of oidc-publish. Full behavior is defined in packages/bare-os-coreutils/src/oidc-publish.js.","options":[],"keywords":["oidc-publish","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"paste","section":1,"title":"paste","synopsis":["paste [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of paste. Full behavior is defined in packages/bare-os-coreutils/src/paste.js.","options":[],"keywords":["paste","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"patch","section":1,"title":"patch","synopsis":["patch [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of patch. Full behavior is defined in packages/bare-os-coreutils/src/patch.js.","options":[],"keywords":["patch","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"pear","section":1,"title":"pear","synopsis":["pear help | info | list | init [dir]","pear stage [dir] | build [dir] | bundle [dir]","pear release [dir] [--label HDMS-LABEL]","pear seed [dir] [--wait-ms N]"],"description":"Pear development tools inside Bare OS (ctx.pear surface). init scaffolds a project; stage writes .pear/stage/ (sources, bundles, stage.json) using ctx.pear/ctx.bare pack tools when enabled; release publishes the stage tree to a writable HDMS mount and prints pear:// links (no host Pear CLI required); seed flushes Hyperswarm for the release drive. Requires identity unlock (login) for release/seed. Implementation: packages/bare-os-coreutils/src/pear.js, lib/pear-stage.js, lib/pear-release.js. See docs/guides/guest-pear-and-appstore-workflow.md.","options":[],"keywords":["pear","bare-os","coreutils","p2p","build","release","hdms"],"listCategory":"coreutils"},{"name":"pathchk","section":1,"title":"check pathname portability","synopsis":["pathchk [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of check pathname portability. Full behavior is defined in packages/bare-os-coreutils/src/pathchk.js.","options":[],"keywords":["pathchk","bare-os","coreutils"],"examples":[{"caption":"portable path check","code":"pathchk -p \"$HOME/file name\""}],"listCategory":"coreutils"},{"name":"pathcap-verify","section":1,"title":"pathcap-verify","synopsis":["pathcap-verify [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of pathcap-verify. Full behavior is defined in packages/bare-os-coreutils/src/pathcap-verify.js.","options":[],"keywords":["pathcap-verify","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"p2ping","section":1,"title":"p2ping","synopsis":["p2ping [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of p2ping. Full behavior is defined in packages/bare-os-coreutils/src/p2ping.js.","options":[],"keywords":["p2ping","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"p2ptrace","section":1,"title":"p2ptrace","synopsis":["p2ptrace [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of p2ptrace. Full behavior is defined in packages/bare-os-coreutils/src/p2ptrace.js.","options":[],"keywords":["p2ptrace","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"peerctl","section":1,"title":"peerctl","synopsis":["peerctl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of peerctl. Full behavior is defined in packages/bare-os-coreutils/src/peerctl.js.","options":[],"keywords":["peerctl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"peerdiscover","section":1,"title":"peerdiscover","synopsis":["peerdiscover [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of peerdiscover. Full behavior is defined in packages/bare-os-coreutils/src/peerdiscover.js.","options":[],"keywords":["peerdiscover","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"peernote","section":1,"title":"peernote","synopsis":["peernote [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of peernote. Full behavior is defined in packages/bare-os-coreutils/src/peernote.js.","options":[],"keywords":["peernote","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"pr","section":1,"title":"pr","synopsis":["pr [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of pr. Full behavior is defined in packages/bare-os-coreutils/src/pr.js.","options":[],"keywords":["pr","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"printenv","section":1,"title":"print environment variables","synopsis":["printenv [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of print environment variables. Full behavior is defined in packages/bare-os-coreutils/src/printenv.js.","options":[],"keywords":["printenv","bare-os","coreutils"],"examples":[{"caption":"one variable","code":"printenv HOME"},{"caption":"all","code":"printenv"}],"listCategory":"coreutils"},{"name":"pkg-swarm-index","section":1,"title":"pkg-swarm-index","synopsis":["pkg-swarm-index [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of pkg-swarm-index. Full behavior is defined in packages/bare-os-coreutils/src/pkg-swarm-index.js.","options":[],"keywords":["pkg-swarm-index","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"printf","section":1,"title":"format and print","synopsis":["printf [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of format and print. Full behavior is defined in packages/bare-os-coreutils/src/printf.js.","options":[],"keywords":["printf","bare-os","coreutils"],"examples":[{"caption":"format","code":"printf \"hex=%x dec=%d\\n\" 255 255"},{"caption":"no newline","code":"printf \"%s\" OK"}],"listCategory":"coreutils"},{"name":"procstat","section":1,"title":"procstat","synopsis":["procstat [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of procstat. Full behavior is defined in packages/bare-os-coreutils/src/procstat.js.","options":[],"keywords":["procstat","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"ps","section":1,"title":"ps","synopsis":["ps [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of ps. Full behavior is defined in packages/bare-os-coreutils/src/ps.js.","options":[],"keywords":["ps","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"pwd","section":1,"title":"return working directory name","synopsis":["pwd [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return working directory name. Full behavior is defined in packages/bare-os-coreutils/src/pwd.js.","options":[],"keywords":["pwd","bare-os","coreutils"],"examples":[{"caption":"where am I","code":"pwd"}],"listCategory":"coreutils"},{"name":"readlink","section":1,"title":"print symbolic link targets","synopsis":["readlink [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of print symbolic link targets. Full behavior is defined in packages/bare-os-coreutils/src/readlink.js.","options":[],"keywords":["readlink","bare-os","coreutils"],"examples":[{"caption":"symlink target","code":"readlink ~/.config"}],"listCategory":"coreutils"},{"name":"realpath","section":1,"title":"realpath","synopsis":["realpath [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of realpath. Full behavior is defined in packages/bare-os-coreutils/src/realpath.js.","options":[],"keywords":["realpath","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"rev","section":1,"title":"rev","synopsis":["rev [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of rev. Full behavior is defined in packages/bare-os-coreutils/src/rev.js.","options":[],"keywords":["rev","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"rm","section":1,"title":"remove files","synopsis":["rm [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of remove files. Full behavior is defined in packages/bare-os-coreutils/src/rm.js.","options":[],"keywords":["rm","bare-os","coreutils"],"examples":[{"caption":"file","code":"rm tmp.txt"},{"caption":"tree","code":"rm -rf build/"}],"listCategory":"coreutils"},{"name":"rmdir","section":1,"title":"remove empty directories","synopsis":["rmdir [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of remove empty directories. Full behavior is defined in packages/bare-os-coreutils/src/rmdir.js.","options":[],"keywords":["rmdir","bare-os","coreutils"],"examples":[{"caption":"empty dir","code":"rmdir olddir"}],"listCategory":"coreutils"},{"name":"routeview","section":1,"title":"routeview","synopsis":["routeview [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of routeview. Full behavior is defined in packages/bare-os-coreutils/src/routeview.js.","options":[],"keywords":["routeview","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"savevault","section":1,"title":"encrypt snapshot of personal drive","synopsis":["savevault [OPTION]... [OPERAND]..."],"description":"Encrypts a copy of the personal drive under /.bare/vault/ when identity services are available.","options":[],"keywords":["savevault","vault","encrypt","backup"],"seeAlso":[{"name":"login","section":1}],"examples":[{"caption":"snapshot encrypted vault","code":"savevault"}],"listCategory":"coreutils"},{"name":"say","section":1,"title":"say","synopsis":["say [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of say. Full behavior is defined in packages/bare-os-coreutils/src/say.js.","options":[],"keywords":["say","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sed","section":1,"title":"stream editor","synopsis":["sed [OPTION]... [OPERAND]..."],"description":"Stream editor with a subset of POSIX sed. Large engine is vendored in lib/sed-engine.js.","options":[],"keywords":["sed","stream","edit","substitute"],"seeAlso":[{"name":"awk","section":1},{"name":"grep","section":1}],"bareOsNotes":"JavaScript implementation; edge cases differ from GNU sed.","examples":[{"caption":"substitute first per line","code":"sed 's/foo/bar/' file.txt"},{"caption":"global per line","code":"sed 's/ //g' spaced.txt"},{"caption":"in-place (if supported)","code":"sed -i.bak 's/^/# /' f.cfg"},{"caption":"print line 5 only","code":"sed -n '5p' file"},{"caption":"delete blank lines","code":"sed '/^$/d' file"}],"listCategory":"coreutils"},{"name":"seq","section":1,"title":"print sequences of numbers","synopsis":["seq [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of print sequences of numbers. Full behavior is defined in packages/bare-os-coreutils/src/seq.js.","options":[],"keywords":["seq","bare-os","coreutils"],"examples":[{"caption":"1..10","code":"seq 1 10"},{"caption":"step","code":"seq 0 2 20"}],"listCategory":"coreutils"},{"name":"setfacl","section":1,"title":"setfacl","synopsis":["setfacl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of setfacl. Full behavior is defined in packages/bare-os-coreutils/src/setfacl.js.","options":[],"keywords":["setfacl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sha1sum","section":1,"title":"sha1sum","synopsis":["sha1sum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sha1sum. Full behavior is defined in packages/bare-os-coreutils/src/sha1sum.js.","options":[],"keywords":["sha1sum","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sha224sum","section":1,"title":"sha224sum","synopsis":["sha224sum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sha224sum. Full behavior is defined in packages/bare-os-coreutils/src/sha224sum.js.","options":[],"keywords":["sha224sum","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sha256sum","section":1,"title":"sha256sum","synopsis":["sha256sum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sha256sum. Full behavior is defined in packages/bare-os-coreutils/src/sha256sum.js.","options":[],"keywords":["sha256sum","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sha384sum","section":1,"title":"sha384sum","synopsis":["sha384sum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sha384sum. Full behavior is defined in packages/bare-os-coreutils/src/sha384sum.js.","options":[],"keywords":["sha384sum","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sha512sum","section":1,"title":"sha512sum","synopsis":["sha512sum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sha512sum. Full behavior is defined in packages/bare-os-coreutils/src/sha512sum.js.","options":[],"keywords":["sha512sum","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sh","section":1,"title":"sh","synopsis":["sh [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sh. Full behavior is defined in packages/bare-os-coreutils/src/sh.js.","options":[],"keywords":["sh","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"shuf","section":1,"title":"shuf","synopsis":["shuf [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of shuf. Full behavior is defined in packages/bare-os-coreutils/src/shuf.js.","options":[],"keywords":["shuf","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sleep","section":1,"title":"suspend execution for an interval","synopsis":["sleep [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of suspend execution for an interval. Full behavior is defined in packages/bare-os-coreutils/src/sleep.js.","options":[],"keywords":["sleep","bare-os","coreutils"],"examples":[{"caption":"pause seconds","code":"sleep 2"}],"listCategory":"coreutils"},{"name":"sort","section":1,"title":"sort lines","synopsis":["sort [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sort lines. Full behavior is defined in packages/bare-os-coreutils/src/sort.js.","options":[],"keywords":["sort","bare-os","coreutils"],"examples":[{"caption":"lexicographic","code":"sort names.txt"},{"caption":"numeric","code":"sort -n scores.txt"},{"caption":"unique","code":"sort -u tags.txt"}],"listCategory":"coreutils"},{"name":"split","section":1,"title":"split","synopsis":["split [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of split. Full behavior is defined in packages/bare-os-coreutils/src/split.js.","options":[],"keywords":["split","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"ssh","section":1,"title":"ssh","synopsis":["ssh [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of ssh. Full behavior is defined in packages/bare-os-coreutils/src/ssh.js.","options":[],"keywords":["ssh","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"ssh-keygen","section":1,"title":"ssh-keygen","synopsis":["ssh-keygen [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of ssh-keygen. Full behavior is defined in packages/bare-os-coreutils/src/ssh-keygen.js.","options":[],"keywords":["ssh-keygen","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sshd","section":1,"title":"sshd","synopsis":["sshd [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sshd. Full behavior is defined in packages/bare-os-coreutils/src/sshd.js.","options":[],"keywords":["sshd","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"stat","section":1,"title":"display file status","synopsis":["stat [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of display file status. Full behavior is defined in packages/bare-os-coreutils/src/stat.js.","options":[],"keywords":["stat","bare-os","coreutils"],"examples":[{"caption":"metadata","code":"stat ~/README.md"}],"listCategory":"coreutils"},{"name":"swarmtop","section":1,"title":"swarmtop","synopsis":["swarmtop [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of swarmtop. Full behavior is defined in packages/bare-os-coreutils/src/swarmtop.js.","options":[],"keywords":["swarmtop","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"swarmdoctor","section":1,"title":"swarmdoctor","synopsis":["swarmdoctor [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of swarmdoctor. Full behavior is defined in packages/bare-os-coreutils/src/swarmdoctor.js.","options":[],"keywords":["swarmdoctor","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"swarmmap","section":1,"title":"swarmmap","synopsis":["swarmmap [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of swarmmap. Full behavior is defined in packages/bare-os-coreutils/src/swarmmap.js.","options":[],"keywords":["swarmmap","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"sum","section":1,"title":"sum","synopsis":["sum [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sum. Full behavior is defined in packages/bare-os-coreutils/src/sum.js.","options":[],"keywords":["sum","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"summon","section":1,"title":"summon","synopsis":["summon [URL]","summon dump URL","summon links URL","summon get URL","summon bookmarks [add URL [TITLE]]","summon about [summon|bookmarks|history|cookies|net|blank]"],"description":"Text web browser for Bare OS. On a TTY, opens a full-screen ctx.tui session (cell buffer). Page JS runs in Bare VM (ctx.bare.bareVm) when available. Without a TTY, dump/links/get print laid-out text, numbered links, or raw source. HTTP(S) uses ctx.httpFetch and the same allow/deny lists as curl/wget. Config, cookies, and bookmarks live in ~/.summon/.","options":[{"flag":"--json","meaning":"Machine-readable dump/links/bookmarks."},{"flag":"--reader","meaning":"Dump article-like text (p/h/li) instead of the full layout."},{"flag":"--cols N","meaning":"Wrap width for dump/layout (default 80)."},{"flag":"--js","meaning":"Run page JavaScript (default)."},{"flag":"--no-js","meaning":"Do not execute page scripts."}],"environment":["BARE_OS_HTTP_ALLOWLIST — host globs permitted for ctx.httpFetch","BARE_OS_HTTP_DENYLIST — host globs always blocked"],"files":["~/.summon/config.json","~/.summon/cookies.json","~/.summon/bookmarks.json"],"keywords":["summon","browser","html","tui","http"],"bareOsNotes":"First-party HTML/CSS engine (not Chromium). Page JS uses ctx.bare.bareVm (bare-vm / bare-realm) or a strict Function sandbox. Disable with --no-js or J.","listCategory":"coreutils"},{"name":"sync","section":1,"title":"sync","synopsis":["sync [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of sync. Full behavior is defined in packages/bare-os-coreutils/src/sync.js.","options":[],"keywords":["sync","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"tar","section":1,"title":"tar","synopsis":["tar [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of tar. Full behavior is defined in packages/bare-os-coreutils/src/tar.js.","options":[],"keywords":["tar","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"tac","section":1,"title":"tac","synopsis":["tac [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of tac. Full behavior is defined in packages/bare-os-coreutils/src/tac.js.","options":[],"keywords":["tac","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"tail","section":1,"title":"copy the last part of a file","synopsis":["tail [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of copy the last part of a file. Full behavior is defined in packages/bare-os-coreutils/src/tail.js.","options":[],"keywords":["tail","bare-os","coreutils"],"examples":[{"caption":"last lines","code":"tail -n 20 app.log"},{"caption":"follow vibe (Bare: poll manually)","code":"tail error.log"}],"listCategory":"coreutils"},{"name":"tee","section":1,"title":"duplicate standard input","synopsis":["tee [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of duplicate standard input. Full behavior is defined in packages/bare-os-coreutils/src/tee.js.","options":[],"keywords":["tee","bare-os","coreutils"],"examples":[{"caption":"copy stdout to file","code":"cat x | tee copy.txt | wc -l"}],"listCategory":"coreutils"},{"name":"telnet","section":1,"title":"telnet","synopsis":["telnet [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of telnet. Full behavior is defined in packages/bare-os-coreutils/src/telnet.js.","options":[],"keywords":["telnet","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"test","section":1,"title":"evaluate a condition","synopsis":["test [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of evaluate a condition. Full behavior is defined in packages/bare-os-coreutils/src/test.js.","options":[],"keywords":["test","bare-os","coreutils"],"examples":[{"caption":"file exists","code":"test -f ~/.barerc && echo yes"},{"caption":"directory","code":"test -d /home/user"},{"caption":"string equal","code":"test \"$USER\" = guest"}],"listCategory":"coreutils"},{"name":"theme","section":1,"title":"theme","synopsis":["theme [list|current|set |apply]"],"description":"Switch Bare OS UI preset: updates ~/.barerc theme line, sets BARE_OS_THEME, calls bareOsApplyTheme when available.","options":[],"keywords":["theme","colors","prompt"],"bareOsNotes":"list/current work without booter hooks; set/apply need ctx.bareOsApplyTheme.","listCategory":"coreutils"},{"name":"time","section":1,"title":"time a simple command","synopsis":["time [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of time a simple command. Full behavior is defined in packages/bare-os-coreutils/src/time.js.","options":[],"keywords":["time","bare-os","coreutils"],"examples":[{"caption":"wall time a command","code":"time sort big.txt"}],"listCategory":"coreutils"},{"name":"timeout","section":1,"title":"run command with bounded wall time","synopsis":["timeout [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of run command with bounded wall time. Full behavior is defined in packages/bare-os-coreutils/src/timeout.js.","options":[],"keywords":["timeout","bare-os","coreutils"],"examples":[{"caption":"kill long job after 5s","code":"timeout 5 slow-cmd"}],"listCategory":"coreutils"},{"name":"touch","section":1,"title":"change file timestamps or create files","synopsis":["touch [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of change file timestamps or create files. Full behavior is defined in packages/bare-os-coreutils/src/touch.js.","options":[],"keywords":["touch","bare-os","coreutils"],"examples":[{"caption":"create empty","code":"touch newfile"},{"caption":"refresh mtime","code":"touch -c existing"}],"listCategory":"coreutils"},{"name":"tr","section":1,"title":"translate or delete characters","synopsis":["tr [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of translate or delete characters. Full behavior is defined in packages/bare-os-coreutils/src/tr.js.","options":[],"keywords":["tr","bare-os","coreutils"],"examples":[{"caption":"uppercase","code":"echo hi | tr 'a-z' 'A-Z'"},{"caption":"delete chars","code":"tr -d '\\r' < win.txt"}],"listCategory":"coreutils"},{"name":"truncate","section":1,"title":"truncate","synopsis":["truncate [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of truncate. Full behavior is defined in packages/bare-os-coreutils/src/truncate.js.","options":[],"keywords":["truncate","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"true","section":1,"title":"return true value","synopsis":["true [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return true value. Full behavior is defined in packages/bare-os-coreutils/src/true.js.","options":[],"keywords":["true","bare-os","coreutils"],"examples":[{"caption":"always success","code":"true && echo ok"}],"listCategory":"coreutils"},{"name":"trustctl","section":1,"title":"trustctl","synopsis":["trustctl [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of trustctl. Full behavior is defined in packages/bare-os-coreutils/src/trustctl.js.","options":[],"keywords":["trustctl","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"tsort","section":1,"title":"tsort","synopsis":["tsort [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of tsort. Full behavior is defined in packages/bare-os-coreutils/src/tsort.js.","options":[],"keywords":["tsort","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"tty","section":1,"title":"return user's terminal name","synopsis":["tty [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return user's terminal name. Full behavior is defined in packages/bare-os-coreutils/src/tty.js.","options":[],"keywords":["tty","bare-os","coreutils"],"examples":[{"caption":"am I a tty","code":"tty"}],"listCategory":"coreutils"},{"name":"tui","section":1,"title":"tui","synopsis":["tui [--json]","tui demo"],"description":"Inspect the guest TUI SDK on ctx.tui (version, TTY, size, theme). tui demo runs a sample full-screen app. Disable the SDK with BARE_OS_TUI=0.","options":[{"flag":"--json","meaning":"Print inspector fields as one JSON object."}],"keywords":["tui","ctx","terminal"],"bareOsNotes":"Requires ctx.tui from bare-os-booter after the REPL session exists.","listCategory":"coreutils"},{"name":"taskmesh","section":1,"title":"taskmesh","synopsis":["taskmesh [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of taskmesh. Full behavior is defined in packages/bare-os-coreutils/src/taskmesh.js.","options":[],"keywords":["taskmesh","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"ulimit","section":1,"title":"ulimit","synopsis":["ulimit [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of ulimit. Full behavior is defined in packages/bare-os-coreutils/src/ulimit.js.","options":[],"keywords":["ulimit","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"uname","section":1,"title":"return operating system name","synopsis":["uname [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of return operating system name. Full behavior is defined in packages/bare-os-coreutils/src/uname.js.","options":[],"keywords":["uname","bare-os","coreutils"],"examples":[{"caption":"kernel-ish info","code":"uname -a"}],"listCategory":"coreutils"},{"name":"uniq","section":1,"title":"uniq","synopsis":["uniq [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of uniq. Full behavior is defined in packages/bare-os-coreutils/src/uniq.js.","options":[],"keywords":["uniq","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"unlink","section":1,"title":"unlink","synopsis":["unlink [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of unlink. Full behavior is defined in packages/bare-os-coreutils/src/unlink.js.","options":[],"keywords":["unlink","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"umount","section":1,"title":"umount","synopsis":["umount [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of umount. Full behavior is defined in packages/bare-os-coreutils/src/umount.js.","options":[],"keywords":["umount","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"unexpand","section":1,"title":"unexpand","synopsis":["unexpand [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of unexpand. Full behavior is defined in packages/bare-os-coreutils/src/unexpand.js.","options":[],"keywords":["unexpand","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"uptime","section":1,"title":"uptime","synopsis":["uptime [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of uptime. Full behavior is defined in packages/bare-os-coreutils/src/uptime.js.","options":[],"keywords":["uptime","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"users","section":1,"title":"users","synopsis":["users [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of users. Full behavior is defined in packages/bare-os-coreutils/src/users.js.","options":[],"keywords":["users","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"vdir","section":1,"title":"vdir","synopsis":["vdir [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of vdir. Full behavior is defined in packages/bare-os-coreutils/src/vdir.js.","options":[],"keywords":["vdir","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"wc","section":1,"title":"word, line, and byte or character count","synopsis":["wc [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of word, line, and byte or character count. Full behavior is defined in packages/bare-os-coreutils/src/wc.js.","options":[],"keywords":["wc","bare-os","coreutils"],"examples":[{"caption":"lines words bytes","code":"wc README.md"},{"caption":"stdin only","code":"cat f | wc -l"}],"listCategory":"coreutils"},{"name":"wget","section":1,"title":"wget","synopsis":["wget [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of wget. Full behavior is defined in packages/bare-os-coreutils/src/wget.js.","options":[],"keywords":["wget","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"which","section":1,"title":"locate a command","synopsis":["which [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of locate a command. Full behavior is defined in packages/bare-os-coreutils/src/which.js.","options":[],"keywords":["which","bare-os","coreutils"],"examples":[{"caption":"resolve on PATH","code":"which ls"}],"listCategory":"coreutils"},{"name":"who","section":1,"title":"who","synopsis":["who [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of who. Full behavior is defined in packages/bare-os-coreutils/src/who.js.","options":[],"keywords":["who","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"whoami","section":1,"title":"display effective user ID","synopsis":["whoami [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of display effective user ID. Full behavior is defined in packages/bare-os-coreutils/src/whoami.js.","options":[],"keywords":["whoami","bare-os","coreutils"],"examples":[{"caption":"effective user","code":"whoami"}],"listCategory":"coreutils"},{"name":"whois","section":1,"title":"whois","synopsis":["whois [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of whois. Full behavior is defined in packages/bare-os-coreutils/src/whois.js.","options":[],"keywords":["whois","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"xattr","section":1,"title":"xattr","synopsis":["xattr [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of xattr. Full behavior is defined in packages/bare-os-coreutils/src/xattr.js.","options":[],"keywords":["xattr","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"xargs","section":1,"title":"construct argument lists and invoke utility","synopsis":["xargs [OPTION]... [OPERAND]..."],"description":"Reads stdin into argument batches and runs **`ctx.runBinCommand`** (same as the shell). Enforces stdin size, token count, batch size, and invocation limits for safety.","options":[{"flag":"-0, --null","meaning":"Input items are null-terminated, not whitespace-separated"},{"flag":"-n, --max-args","meaning":"Up to N arguments per utility invocation (capped at 128)"}],"keywords":["xargs","bare-os","coreutils"],"bareOsNotes":"No host process spawn; not full POSIX xargs (no -I, -P, etc.). See src/xargs.js for limits.","examples":[{"caption":"pass lines as arguments","code":"printf 'a\\nb\\n' | xargs echo"},{"caption":"one argument per run","code":"printf 'a\\nb\\n' | xargs -n1 echo"},{"caption":"workaround for complex scripts","code":"# for f in *.txt; do grep -l foo $f; done"}],"listCategory":"coreutils"},{"name":"yes","section":1,"title":"yes","synopsis":["yes [OPTION]... [OPERAND]..."],"description":"Bare OS implementation of yes. Full behavior is defined in packages/bare-os-coreutils/src/yes.js.","options":[],"keywords":["yes","bare-os","coreutils"],"listCategory":"coreutils"},{"name":"bare-cron","section":1,"title":"Bare OS minute scheduler (bare-initd unit)","synopsis":["Managed via systemctl(1): systemctl status bare-cron","Crontab files: /etc/bare-os/crontab, ~/.crontab, ~/.config/bare-os/timers/*.timer"],"description":"The **bare-cron** bare-initd unit runs a bounded in-process scheduler: classic five-field lines, **@reboot**, optional **JitterSec=**, and systemd-inspired timer drop-ins (**OnCalendar=**, **EveryMs=**, **OnInactiveSec=**, **Persistent=**). Jobs execute through **ctx.execLine**; errors may be logged under **/var/log/bare-os/cron.log** when configured. This is not full **cron**(8) or **systemd.timer**(5) parity.","options":[],"keywords":["cron","scheduler","bare-initd","timer","crontab"],"seeAlso":[{"name":"systemctl","section":1},{"name":"crontab","section":1}],"bareOsNotes":"Implementation: packages/bare-os-booter/lib/bare-cron.js. Dependency: **kernel-logger** before **bare-cron** in the default initd graph.","examples":[{"caption":"list scheduler unit","code":"systemctl status bare-cron"},{"caption":"user crontab line (five-field)","code":"0 * * * * echo hourly"}],"listCategory":"extra"},{"name":"bare-os-ctx-bare","section":7,"title":"ctx.bare library and drive bundles","synopsis":["# reference — not a shell command"],"description":"Documents BARE_OS_BARE_MODULES and BARE_OS_BARE_DRIVE_BUNDLES for the booter ctx.bare registry. In-image scripts (AsyncFunction) use ctx.bare. instead of import(). Keys come from host dynamic import of packages listed in packages/bare-os-booter/lib/bare-module-manifest.json, then optional merge from trusted IIFE bundles under /lib/bare/bundles/ on the system image (see manifest.json there). The booter also attaches ctx.bare.discordJS from vendored bare-discord-js (official discord.js on Bare) unless BARE_OS_DISCORD=0. Set BARE_OS_BARE_MODULES=0 to omit ctx.bare entirely. Set BARE_OS_BARE_DRIVE_BUNDLES=0 to skip executing drive bundles (host imports only). Rebuild bundles with npm run build -w bare-os-bare-libs.","options":[],"keywords":["BARE_OS_BARE_MODULES","BARE_OS_BARE_DRIVE_BUNDLES","ctx.bare","bare-module-manifest","bare-os-bare-libs"],"environment":["BARE_OS_BARE_MODULES — set to 0 or false to disable ctx.bare (hardened sessions).","BARE_OS_BARE_DRIVE_BUNDLES — set to 0 or false to skip loading /lib/bare/bundles/*.js into ctx.bare."],"seeAlso":[{"name":"bare-os-developer-guide","section":7}],"bareOsNotes":"See developer-guide/05-modules-and-imports.md and 12-bare-modules-and-pear-ecosystem.md.","examples":[],"listCategory":"extra"},{"name":"bare-os-shell","section":1,"title":"Bare OS interactive shell (Issue 7–inspired subset)","synopsis":["# Interactive session: builtins + /bin via ctx.execLine (see handbook §9)","# /bin/sh is a separate script runner — see man sh"],"description":"The interactive shell runs in the booter: tokenization, pipelines (simulated capture), redirection, AND-OR lists (; && ||), bounded compound commands (if/fi, while/for/case), background jobs (&), optional command substitution ($(…)) when BARE_OS_SHELL_CMDSUBST=1, globbing, and subsets of errexit (-e), nounset (-u), and pipefail. There are no forked subshells and no full POSIX sh grammar. Canonical narrative: handbook ch.9; completion/REPL: docs/reference/shell-completion-and-repl-editor.md.","options":[],"aliases":["sh-builtins"],"keywords":["shell","builtin","pipeline","jobs","execLine","bare-os-shell","sh-builtins"],"builtins":[{"name":"alias","synopsis":["alias","alias name=value ...","unalias name ..."],"description":"Define or list command aliases; unalias removes definitions."},{"name":"cd","synopsis":["cd [DIR]"],"description":"Change working directory via vfs.chdir; default is HOME."},{"name":"export","synopsis":["export NAME=value ..."],"description":"Set environment variables visible to child /bin invocations."},{"name":"unset","synopsis":["unset NAME ..."],"description":"Remove variables; readonly names cannot be unset."},{"name":"readonly","synopsis":["readonly NAME[=value] ..."],"description":"Mark variables read-only."},{"name":"umask","synopsis":["umask [octal]"],"description":"Show or set shell file creation mask (stored in env UMASK)."},{"name":"set","synopsis":["set -o","set +o","set -e | +e | -u | +u | -f | +f","set -o errexit|nounset|pipefail","set +o errexit|nounset|pipefail"],"description":"Toggle errexit (BARE_OS_SHELL_ERREXIT), nounset (BARE_OS_SHELL_NOUNSET), pipefail (BARE_OS_SHELL_PIPEFAIL), noglob (BARE_OS_SHELL_NOGLOB). Use set -o / set +o alone to print current shell options (subset)."},{"name":"command","synopsis":["command -v|-V NAME","command ARGV..."],"description":"Resolve or run a command; -v/-V skip aliases."},{"name":"type","synopsis":["type NAME"],"description":"Report whether NAME is a builtin or a path under PATH."},{"name":"jobs","synopsis":["jobs [-l] [-p]"],"description":"List logical background jobs. -p prints pgid only; -l includes pgid/sid in the listing."},{"name":"fg / bg / wait","synopsis":["fg [%job]","bg [%job]","wait [n | %n]","wait -n (with BARE_OS_SHELL_POSIX_MODE=1)"],"description":"Cooperative job control: fg awaits a job; bg resumes stopped jobs; wait waits for jobs by id or all."},{"name":"suspend-job","synopsis":["suspend-job [%job]"],"description":"Mark a running background job stopped (logical); resume with fg or bg."},{"name":"disown","synopsis":["disown [%job]"],"description":"Remove a job from the jobs table without cancelling its async work (still runs to completion)."},{"name":"trap","synopsis":["trap -l","trap -p","trap CMD SIGNAL"],"description":"List signals, print handlers, or register synthetic trap handlers (ctx.shellTrapHandlers)."},{"name":"login / logout","synopsis":["login [--new]","logout [--save]"],"description":"login is a /bin utility: run it with no passphrase on the command line, then type the passphrase at the TTY prompt (hidden). logout remains a shell builtin for session teardown; both require booter hooks."},{"name":":","synopsis":[":"],"description":"No-op builtin."},{"name":"exit","synopsis":["exit [n]"],"description":"Request booter exit with status n (builtin path)."},{"name":"read","synopsis":["read [-r] [NAME ...]"],"description":"Optional when BARE_OS_SHELL_READ_BUILTIN=1; bounded line from shell stdin or readLine."}],"seeAlso":[{"name":"sh","section":1},{"name":"help","section":1},{"name":"man","section":1}],"bareOsNotes":"Pipelines use simulated capture (not OS pipes). kill and wait accept %n job specs when shellBackgroundJobs is populated. Full UX (history file, tab menu, Ctrl+R) uses BARE_OS_FISH≠0 on a TTY; see shell-completion-and-repl-editor.md.","examples":[{"caption":"pipeline (simulated)","code":"ls -1 /bin | grep man"},{"caption":"errexit + compound","code":"set -e\nif true; then echo ok; fi"},{"caption":"background job","code":"sleep 1 &\njobs"},{"caption":"redirect out","code":"echo hi > ~/hello.txt"},{"caption":"alias + use","code":"alias ll='ls -la'\nll ~"}],"listCategory":"extra"},{"name":"sshd_config","section":5,"title":"OpenSSH sshd configuration file (Bare OS subset)","synopsis":["/etc/ssh/sshd_config"],"description":"Bare OS reads a subset of OpenSSH sshd_config directives from the system image. Supported keys include Port, ListenAddress, HostKey (repeatable; tilde expands to $HOME on the personal drive), PasswordAuthentication, PubkeyAuthentication, PermitRootLogin, AllowTcpForwarding, MaxAuthTries, ClientAliveInterval, AuthorizedKeysFile (relative paths resolve under $HOME), and Subsystem sftp. Unsupported lines are ignored. Strong ciphers default to bare-ssh2 stock algorithm lists.","options":[],"keywords":["ssh","sshd","config","security"],"bareOsNotes":"HostKey paths must be writable; the stock config places keys under ~/.config/bare-os/ssh/host/.","seeAlso":[{"name":"sshd","section":8},{"name":"man","section":1}],"listCategory":"extra"},{"name":"systemctl","section":1,"title":"bare-initd service control (systemd-like subset)","synopsis":["systemctl list|list-units","systemctl status [UNIT] [--lines N]","systemctl logs UNIT [--lines N]","systemctl start|stop|restart UNIT","systemctl enable|disable UNIT","systemctl is-enabled UNIT","systemctl is-active UNIT","journalctl -u UNIT [--lines N]"],"description":"Lists and manages session-scoped bare-initd units (kernel-logger, bare-cron, …). Implemented by the booter (kernel-runner); /bin stubs exist for PATH and man(1). enable/disable toggle the personal-drive preset file ~/.config/bare-os/initd/disabled.txt for future boots in the same image. is-enabled reports enabled or disabled; is-active reports active vs inactive from runtime phase (exit 0 vs 3). Logs live under /var/log/bare-os/ when the unit defines a logPath. The legacy name bare-initctl is still accepted by the booter as an alias.","options":[{"flag":"--lines N","meaning":"Tail N lines from the unit log (status, logs, journalctl)"}],"aliases":["bare-initctl"],"keywords":["bare-initd","initctl","service","supervisor","cron","systemd"],"bareOsNotes":"journalctl supports -u UNIT and --lines / -n. Other systemd verbs are unavailable on Bare OS (exit 2).","seeAlso":[{"name":"crontab","section":1},{"name":"bare-os-shell","section":1}],"examples":[{"caption":"list units","code":"systemctl list-units"},{"caption":"restart scheduler","code":"systemctl restart bare-cron"},{"caption":"tail cron errors","code":"journalctl -u bare-cron --lines 20"}],"listCategory":"extra"},{"name":"git","section":1,"title":"Bare OS git front-end (isomorphic-git)","synopsis":["git [-C dir] [ARGUMENTS...]"],"description":"Runs isomorphic-git against the VFS-backed adapter. Remote HTTP(S) uses BARE_OS_GIT_HTTP when set; otherwise Pear bare module fetch.","options":[{"flag":"-C dir","meaning":"Run as if git was started in dir"}],"environment":["BARE_OS_GIT_HTTP — optional fetch implementation for remotes","GIT_* — standard hints where supported"],"keywords":["git","version control","repository","clone","commit","isomorphic-git"],"bareOsNotes":"Not a separate /bin script; booter delegates argv[0]=git to git-cli.js.","seeAlso":[{"name":"bare-os-shell","section":1}],"examples":[{"caption":"new repo","code":"git init -C ~/myrepo"},{"caption":"status","code":"git -C ~/myrepo status"},{"caption":"clone over HTTP (needs remote + fetch)","code":"git clone https://example.com/repo.git ~/work/repo"},{"caption":"config local","code":"git -C ~/myrepo config user.email \"you@example.com\""},{"caption":"log one line","code":"git -C ~/myrepo log --oneline -5"}],"listCategory":"extra"},{"name":"bare-os-handbook","section":7,"title":"Bare OS handbook — table of contents and reading order","synopsis":["man 7 bare-os-handbook","Handbook chapter (plain text from handbook/README.md)"],"description":"BARE OPERATING SYSTEM — HANDBOOK\n\nBare OS is an experimental, P2P-first system image: a Merkle-addressed Hyperdrive you replicate from peers over Hyperswarm, plus a second drive for everything that should stay yours (home, identity, logs). This handbook is the narrative spine—written like a long-form technical article so you can read it cover to cover or jump to a chapter. It explains why the pieces exist, how they connect, and where to look when something breaks.\n\nThis project is experimental research software, not a production OS. It is open source under Apache-2.0 and is owned, operated, and engineered by HoneyPeer, LLC, a DeKalb, Georgia limited liability company (LICENSE <../LICENSE>).\n\nON THIS PAGE\n\n- How this handbook fits the repo <#how-this-handbook-fits-the-repo>\n- Who should read what <#who-should-read-what-three-paths>\n- Chapters <#chapters>\n- Packages in one sentence each <#packages-in-one-sentence-each>\n- Root README <#root-readme>\n\nHOW THIS HANDBOOK FITS THE REPO\n\nDocumentation home <../docs/README.md> — Single map of every tree: user manual, this handbook, developer guide, reference, concepts (evergreen) <../docs/concepts/README.md>, glossary <../docs/glossary.md>, FAQ <../docs/faq.md>, troubleshooting router <../docs/troubleshooting.md>, contributing to docs <../docs/CONTRIBUTING-DOCS.md>.\n\nPreface — why Bare OS <00-preface.md> — Thesis, comparison to classic images, security limits, outlook, contributor paths.\n\n*This handbook (handbook/.md)** — Story, architecture, protocol, runtime, identity, POSIX surface, operations, and research directions.\n\nUser manual <../users-manual/README.md> — Short operator-oriented path: clone, run seeder and booter, use the shell and identity features, find man and troubleshooting without reading cover to cover.\n\ndocs/reference/README.md <../docs/reference/README.md> — File-by-file inventory, environment variables, data-flow diagram.\n\ndocs/architecture/KERNEL_CONTRACT.md <../docs/architecture/KERNEL_CONTRACT.md> — Single-page contract: subsystems, boot steps, ctx semver, typed errors.\n\nBoot trust model <../docs/security/boot-trust-model.md> — Concise operator checklist for block-0 provenance and swarm trust boundaries.\n\ndeveloper-guide/README.md <../developer-guide/README.md> — How to write run(ctx, argv) / start(ctx), extend /bin, and test under Pear.\n\nKernel extensions <../docs/reference/kernel-extensions.md> — Kernel feature bitmask, seed-channel RPC, and capability bits.\n\nThe ctx object is versioned for kernels and scripts that depend on booter behavior. Treat packages/bare-os-booter/CHANGELOG.md <../packages/bare-os-booter/CHANGELOG.md> as the contract history (bareOsCtxApiVersion / BARE_OS_CTX_API_VERSION). TypeScript authors can use packages/bare-os-booter/lib/bare-os-ctx.d.ts <../packages/bare-os-booter/lib/bare-os-ctx.d.ts>.\n\nWHO SHOULD READ WHAT (THREE PATHS)\n\nI want to run it. Start at the user manual <../users-manual/README.md> or the root README.md <../README.md>, then Chapter 7 — Operations <07-operations-and-development.md> (install, npm test, seeder/booter, Pear). Skim Chapter 1 <01-introduction.md> for vocabulary.\n\nI want to change the image or /bin. Read Preface <00-preface.md> → Chapter 6 <06-kernel-and-binaries.md> → the developer guide <../developer-guide/README.md>, especially extending coreutils <../developer-guide/06-extending-bin-coreutils.md> and the ctx object <../developer-guide/02-the-context-object.md>.\n\nI want the architecture and trust model. Read Preface <00-preface.md> → Chapter 2 — Blueprints <02-blueprints.md> → Chapter 3 — Protocol <03-protocol-and-disk.md> → Chapter 4 — Booter runtime <04-the-booter-runtime.md> → Chapter 5 — Identity <05-identity-vault-and-hdms.md>.\n\nCHAPTERS\n\n- Preface <00-preface.md> — Whitepaper-style thesis, documentation map, security limits, research directions, contributing.\n- 01 — Introduction <01-introduction.md> — Goals, vocabulary, Holepunch stack, clone-to-prompt story.\n- 02 — Blueprints <02-blueprints.md> — Layered architecture, trust, boot-flow diagram.\n- 03 — Protocol and disk <03-protocol-and-disk.md> — MBR, swarm, Protomux, SwarmDisk, peer-assisted block 0 mirroring, failure matrix.\n- 04 — The booter runtime <04-the-booter-runtime.md> — ctx, VFS, shell, kernel, initd, cron, REPL, host bridges.\n- 05 — Identity, vault, HDMS <05-identity-vault-and-hdms.md> — Guest vs user, account blob, vault, extra drives.\n- 06 — Kernel and binaries <06-kernel-and-binaries.md> — /boot/init.js, coreutils pipeline, /bin summary.\n- 07 — Operations and development <07-operations-and-development.md> — CI, pretest, Pear channels, env vars, troubleshooting.\n- 08 — Git on Bare OS <08-git-on-bare-os.md> — isomorphic-git, VFS adapter, HTTP modes.\n- 09 — POSIX utilities, shell, VFS <09-posix-utilities-shell-and-vfs.md> — XCU-style /bin, shell, divergence from Issue 7.\n- 10 — Manual pages and online help <10-manpages-and-online-help.md> — man(1), JSON DB, handbook ingest, help vs man.\n- 11 — Kernel program and research <11-kernel-program-and-research.md> — Pear/Bare/holepunch context, capability words, non-goals.\n- 12 — P2P stack vs POSIX boundaries <12-p2p-stack-and-posix-boundaries.md> — Hypercore replication, swarm, Protomux, and how they relate to the declared POSIX profile and non-goals.\n\nPear workflows, ctx.bare, drive bundles: developer-guide ch.11 <../developer-guide/11-kernel-pear-cookbook.md> and ch.12 <../developer-guide/12-bare-modules-and-pear-ecosystem.md>.\n\nPACKAGES IN ONE SENTENCE EACH\n\n- bare-os-protocol <../packages/bare-os-protocol/README.md> — Shared topic string, MBR layout, Protomux message IDs, and kernel feature bits used by seeder and booter.\n- bare-os-seeder <../packages/bare-os-seeder/README.md> — Stages kernel/ into a system Hyperdrive, publishes the canonical MBR block and joins the swarm so booters can replicate the image.\n- bare-os-booter <../packages/bare-os-booter/README.md> — Joins the swarm, opens system + personal drives, builds ctx, runs /boot/init.js, shell, initd, cron, and delegated tools (git, curl, wget); eligible booted peers may mirror block 0 and seed RPC snapshots.\n- bare-os-coreutils <../packages/bare-os-coreutils/README.md> — Sources and build for /bin utilities plus the merged man.json database.\n- bare-os-bare-libs <../packages/bare-os-bare-libs/README.md> — Builds optional /lib/bare bundles merged into ctx.bare when enabled.\n\nThe staged tree also includes kernel/README.md <../kernel/README.md> (what lands on the system drive) and scripts/README.md <../scripts/README.md> (repo automation). Pear release links and host env notes: PEAR-RUN.md <../docs/PEAR-RUN.md>.\n\nROOT README\n\nThe top-level README.md <../README.md> is the short runbook (clone, npm ci, seeder/booter commands). Use it when you only need copy-paste steps.\n\n_Open source under Apache-2.0. Owned, operated, and engineered by HoneyPeer, LLC, a DeKalb, Georgia limited liability company — see LICENSE <../LICENSE>._","descriptionMode":"preserve","options":[],"keywords":["handbook","bare-os","documentation","narrative","chapter","bare","os","table","contents","and","reading","order"],"seeAlso":[{"name":"handbook-00-preface","section":7},{"name":"man","section":1}],"bareOsNotes":"Generated at build time from handbook/README.md. Diagrams in ```mermaid blocks are omitted; open the Markdown in the repo for figures.","aliases":["handbook","bare-os-handbook-index"],"listCategory":"handbook"},{"name":"handbook-00-preface","section":7,"title":"Preface — why Bare OS exists","synopsis":["man 7 handbook-00-preface","Handbook chapter (plain text from handbook/00-preface.md)"],"description":"PREFACE — WHY BARE OS EXISTS\n\nTime to read: about 12 minutes. Prerequisites: curiosity about peer-to-peer software; no Holepunch background required.\n\nMost operating system images are fetched from a single place: an HTTP mirror, a registry, or a block device someone prepared for you. Bare operating system asks a different question: what if the “golden image” were a content-addressed tree that many peers could help you replicate, so discovery and distribution look more like joining a swarm than downloading a monolithic blob?\n\nThis preface states the thesis in plain language, places the project next to familiar ideas, names what the design does not promise, and points you to the chapters that unpack each layer. The code in this repository is experimental research software—useful for learning and prototyping, not audited for production threat models.\n\nTHE THESIS IN ONE PARAGRAPH\n\nBare OS is a Unix-flavored environment whose system root lives on a Hyperdrive keyed from a tiny 512-byte MBR you read from peers. A seeder application publishes that drive; a booter application finds peers on a fixed Hyperswarm topic, replicates the drive, mounts a separate personal Hyperdrive for mutable state, and runs a JavaScript kernel (/boot/init.js) and a Tier-1 /bin built from small AsyncFunction scripts. After successful boot, eligible peers can mirror the same block 0 and captured seed RPC snapshots for cold joiners. Execution is one host process (Pear or Node) simulating POSIX paths, a line shell, and synthetic /proc-style views—not a hardware kernel.\n\nA DELIBERATELY LEAKY ANALOGY\n\nPicture the system drive as a read-only live image many peers can help you replicate, and the personal drive as your private stick for home, identity, and vault data—except both are Hyperdrives and the “CPU” is still one Pear/Node process interpreting scripts. That image helps you orient; it is not a security promise. You still choose which peers to trust, and anything in /bin can reach whatever the host runtime allows. Short evergreen pages: docs/concepts — Two-drive model <../docs/concepts/two-drive-model.md>.\n\nNon-goal: “P2P” does not mean you can skip thinking about trust, backups, and passphrase quality.\n\nON THIS PAGE\n\n- The thesis in one paragraph <#the-thesis-in-one-paragraph>\n- A deliberately leaky analogy <#a-deliberately-leaky-analogy>\n- How this handbook relates to other docs <#how-this-handbook-relates-to-other-docs>\n- Comparison frame <#comparison-frame-not-marketing>\n- Security and limits <#security-and-limits>\n- Research directions <#research-directions>\n- Contributing <#contributing--first-steps>\n- Where to read next <#where-to-read-next>\n\nHOW THIS HANDBOOK RELATES TO OTHER DOCS\n\n- Documentation home <../docs/README.md> — Navigation hub for all trees plus shared glossary <../docs/glossary.md>, FAQ <../docs/faq.md>, and troubleshooting <../docs/troubleshooting.md>.\n- Handbook (handbook/.md) — Story and mental model*: why two drives, how the wire protocol boots the image, what the shell and identity layers do.\n- User manual <../users-manual/README.md> — Run and use: install, seeder and booter, shell basics, identity, troubleshooting, without reading the full architecture first.\n- docs/reference/ <../docs/reference/README.md> — Where everything lives: package paths, complete environment variable tables, byte-level MBR layout.\n- developer-guide/ <../developer-guide/README.md> — How to implement: ctx fields, coreutils build, testing with Brittle, Pear staging.\n- Contributing to documentation <../docs/CONTRIBUTING-DOCS.md> — Style and CI: admonitions, Mermaid, link checks, terminology governance.\n\nIf you edit handbook Markdown, those files are also ingested into man(7) inside the image (see Chapter 10 <10-manpages-and-online-help.md>); diagrams in mermaid fences are omitted in the terminal viewer—read the repo for figures.\n\nCOMPARISON FRAME (NOT MARKETING)\n\nVersus a static ISO or container layer: the system image is still “files in a tree,” but replication is sparse and keyed: peers contribute blocks; you verify structure against Hyperdrive semantics rather than trusting a single CDN tarball.\n\nVersus a traditional multi-user kernel: there is no fork, no hardware isolation between “processes,” and no guarantee that malicious /bin scripts cannot read host memory. Commands are JavaScript in the booter’s realm. See Security and limits <#security-and-limits> below.\n\nVersus “put / on IPFS”: the stack here is Holepunch-shaped (Corestore, Hyperdrive, Hyperswarm, Protomux) with a deliberate boot protocol (MBR block 0, seed channel, optional capability RPC). The goal is a coherent dev story (seeder + booter Pear apps), not maximal compatibility with every content network.\n\nSECURITY AND LIMITS\n\nBare OS separates system (replicated image) from personal (your writable drive), but does not sandbox the shell: anything execLine can do inherits the Pear/Node process capabilities. Identity uses PBKDF2 and AEAD for the on-disk account blob and vault snapshots—passphrase quality still matters, and ciphertext only stays private if replication and backups are under your control.\n\nFor a developer-oriented trust discussion (eval boundaries, import vs in-image scripts), read developer-guide — Security and trust <../developer-guide/09-security-and-trust.md>. Chapter 5 adds a trust boundary <05-identity-vault-and-hdms.md#trust-boundaries-what-the-design-does-not-promise> summary for identity and HDMS.\n\nRESEARCH DIRECTIONS\n\nThe codebase is a testbed for P2P distribution, POSIX ergonomics on Hyperdrive, optional ctx.bare module bundles, seed-channel capability negotiation, and Pear host bridges (reload, mirrors, snapshots). Open threads include stronger isolation (workers, Pear isolates), richer networking parity, and operational hardening. Treat roadmap bullets in Chapter 4 <04-the-booter-runtime.md#roadmap-and-out-of-scope> as current intent, not commitments.\n\nCONTRIBUTING — FIRST STEPS\n\n- Documentation: Follow the voice of this handbook (short hooks, clear “related” links). Run npm run build -w bare-os-coreutils after changing man pages; handbook ingest runs in that build.\n- Code: Read developer-guide README <../developer-guide/README.md>, then the package README for the area you touch (bare-os-booter, bare-os-coreutils, etc.). Run npm test from the repo root before opening a PR.\n\nWHERE TO READ NEXT\n\n- Vocabulary and a clone-to-prompt story — Chapter 1 — Introduction <01-introduction.md>.\n- Boxes, arrows, trust — Chapter 2 — Blueprints <02-blueprints.md>.\n- Wire format and failure modes — Chapter 3 — Protocol and disk <03-protocol-and-disk.md>.\n\nRelated: Handbook home · Root README <../README.md> · docs/reference <../docs/reference/README.md> · CHANGELOG — ctx API <../packages/bare-os-booter/CHANGELOG.md>\n\n_This project is experimental research software, not a production OS. Open source under Apache-2.0. Owned, operated, and engineered by HoneyPeer, LLC, a DeKalb, Georgia limited liability company — LICENSE <../LICENSE>._","descriptionMode":"preserve","options":[],"keywords":["handbook","bare-os","documentation","narrative","chapter","00","preface","why","bare","exists"],"seeAlso":[{"name":"handbook-01-introduction","section":7},{"name":"bare-os-handbook","section":7},{"name":"man","section":1}],"bareOsNotes":"Generated at build time from handbook/00-preface.md. Diagrams in ```mermaid blocks are omitted; open the Markdown in the repo for figures.","listCategory":"handbook"},{"name":"handbook-01-introduction","section":7,"title":"Chapter 1 — Introduction: what “Bare OS” is","synopsis":["man 7 handbook-01-introduction","Handbook chapter (plain text from handbook/01-introduction.md)"],"description":"CHAPTER 1 — INTRODUCTION: WHAT “BARE OS” IS\n\nTime to read: about 8 minutes. Prerequisites: none; Preface <00-preface.md> first if you want the thesis in essay form.\n\nCanonical refs: Compatibility matrix <../docs/reference/compatibility-matrix.md> · Environment appendix <../docs/reference/environment-and-posix-appendix.md> · Protocol package reference <../docs/reference/package-bare-os-protocol.md>.\n\nIf you have only a minute: Bare operating system is a tiny Unix-flavored environment whose root filesystem is a Hyperdrive replicated from peers. A seeder publishes that drive and a 512-byte MBR over Hyperswarm; a booter joins the swarm, downloads the image, mounts a second Hyperdrive for per-user mutable state, and runs JavaScript “kernel” and /bin scripts inside a Bare or Node runtime. Eligible already-booted peers can later mirror the same block 0 and seed RPC snapshots for cold joiners.\n\nThe rest of this chapter sets vocabulary straight—without it, the architecture diagrams in Chapter 2 <02-blueprints.md> will not stick.\n\nON THIS PAGE\n\n- From git clone to a first prompt <#from-git-clone-to-a-first-prompt-story-not-a-runbook>\n- The problem this project explores <#the-problem-this-project-explores>\n- Key vocabulary <#key-vocabulary>\n- Why Hyperdrive and Hyperswarm <#why-hyperdrive-and-hyperswarm>\n- Relationship to Pear and Bare <#relationship-to-pear-and-bare>\n- Where to go next <#where-to-go-next>\n\nFROM GIT CLONE TO A FIRST PROMPT (STORY, NOT A RUNBOOK)\n\nImagine two terminals on the same machine. In one you run the seeder: it loads the kernel/ tree into a system Hyperdrive, writes a 512-byte MBR (magic BIOS, embedded public keys), and joins Hyperswarm on the project topic plus the drive’s discovery key. In the other you run the booter: it joins the topic, finds a peer, opens a Protomux channel, reads block 0, parses the MBR, opens the system drive by key, creates your personal drive, and hands off to /boot/init.js. Once up, that booter can also help cold joiners by mirroring the same block 0 and captured seed RPC hints when eligibility passes. You see a line prompt; everything “POSIX” after that is the booter’s VFS and shell simulating a machine.\n\nExact commands, env vars, and Pear workflows live in Chapter 7 — Operations <07-operations-and-development.md> and the root README.md <../README.md>. This paragraph is only the narrative spine.\n\nTHE PROBLEM THIS PROJECT EXPLORES\n\nTraditional OS images live on block devices or tarball layers. Here, the image is a Merkle tree you can address by key and replicate live. Peers do not hand you a .iso; they help you fill in the same Hyperdrive from the same discovery key.\n\nThat raises three design questions this repo answers in code:\n\n1. Discovery — How does a fresh node find _someone_ who has block 0 (the MBR) and the drive root?\n2. Separation of concerns — What is immutable-ish OS vs mutable per-device home?\n3. Execution model — What runs in the host process vs what is “inside” the simulated POSIX surface?\n\nBare OS picks: one swarm topic for the project, Protomux channels for control + replication, two Hyperdrives (system + personal), and AsyncFunction-loaded JS for kernel and utilities.\n\nKEY VOCABULARY\n\n- System drive — Hyperdrive containing /boot/init.js, /bin, /etc; replicated from the seeder image.\n- Personal drive — Separate Hyperdrive (Corestore namespace) for $HOME, /.bare, cron, and logs.\n- MBR — 512 bytes: magic BIOS plus embedded Hyperdrive public keys (primary and optional failover slots).\n- Kernel — /boot/init.js with async function start(ctx); a session loop, not a hardware microkernel.\n- /bin — Small JavaScript programs (async function run(ctx, argv)) built from bare-os-coreutils, including a TTY editor (edit, nano) and usual POSIX-style tools.\n- VFS — Booter-provided path layer: routes paths under $HOME to the personal drive, otherwise the system drive.\n- ctx — Context object passed to kernel and commands: vfs, console, execLine, identity hooks, and many optional bridges.\n- Guest — Default session before login: predictable HOME=/home/guest, no Ed25519 identity material exposed.\n- HDMS — Hyperdrive management: optional extra drives mounted under /mnt after unlock.\n\nHOLEPUNCH STACK (FIRST-USE DEFINITIONS)\n\nUse these names consistently across docs:\n\n- Hyperdrive — Append-only, sparse-friendly filesystem identified by a public key; good for a shared OS tree.\n- Hyperswarm — DHT-style peer discovery; Bare OS uses a topic (bare-os-v1) and drive discovery keys.\n- Protomux — Multiplexes logical channels on one encrypted stream; the bare-os-v1 channel carries MBR reads and replication.\n- Corestore — Storage backend that holds Hyperdrive cores; seeder and booter use separate store paths.\n- Bare — Minimal JavaScript runtime; Pear wraps Bare for distributable apps (the seeder and booter are Pear apps).\n\nWHY HYPERDRIVE AND HYPERSWARM\n\nHyperdrive gives you a single-writer (per key) log-backed filesystem with deterministic reads and sparse replication—good for an OS tree that many nodes can share.\n\nHyperswarm gives you topic-based and discovery-key-based peer finding. The seeder joins both the bare-os-v1 topic (so booters find _some_ peer) and the drive discovery key (so Hyperdrive replication completes).\n\nYou do not need to agree with every product choice to read the code: the handbook describes what the repo does, not whether it is the only way to build a P2P OS.\n\nRELATIONSHIP TO PEAR AND BARE\n\n- Bare is a minimal JavaScript runtime used by Pear apps.\n- Both seeder and booter are Pear applications (pear field in package.json) and can run under node index.js for development.\n- brittle-bare vs brittle-node split in tests reflects native addons (e.g. identity crypto) that only load on Bare.\n\nWHERE TO GO NEXT\n\n- Essay-length thesis: Preface <00-preface.md>\n- Big picture: Chapter 2 — Blueprints <02-blueprints.md>\n- Wire protocol: Chapter 3 <03-protocol-and-disk.md>\n- Day-to-day hacking: Chapter 7 <07-operations-and-development.md>\n\nNext: Chapter 2 — Blueprints <02-blueprints.md>\n\nRelated: Documentation home <../docs/README.md> · Glossary <../docs/glossary.md> · Handbook home · Kernel extensions <../docs/reference/kernel-extensions.md> · CHANGELOG — ctx API <../packages/bare-os-booter/CHANGELOG.md>\n\n_Experimental research software, not a production OS. Open source under Apache-2.0. Owned, operated, and engineered by HoneyPeer, LLC, a DeKalb, Georgia limited liability company — LICENSE <../LICENSE>._","descriptionMode":"preserve","options":[],"keywords":["handbook","bare-os","documentation","narrative","chapter","01","introduction","what","bare"],"seeAlso":[{"name":"handbook-02-blueprints","section":7},{"name":"handbook-00-preface","section":7},{"name":"man","section":1}],"bareOsNotes":"Generated at build time from handbook/01-introduction.md. Diagrams in ```mermaid blocks are omitted; open the Markdown in the repo for figures.","listCategory":"handbook"},{"name":"handbook-02-blueprints","section":7,"title":"Chapter 2 — Blueprints: architecture and trust","synopsis":["man 7 handbook-02-blueprints","Handbook chapter (plain text from handbook/02-blueprints.md)"],"description":"CHAPTER 2 — BLUEPRINTS: ARCHITECTURE AND TRUST\n\nTime to read: about 10 minutes. Prerequisites: Chapter 1 <01-introduction.md> vocabulary.\n\nCanonical refs: Compatibility matrix <../docs/reference/compatibility-matrix.md> · KERNEL_CONTRACT <../docs/architecture/KERNEL_CONTRACT.md> · Protocol reference <../docs/reference/package-bare-os-protocol.md>.\n\nThis chapter is the aerial view: boxes, arrows, and what is allowed to trust what. Implementation details live in later chapters.\n\nFor a comparison to classic images and security limits, see Preface — Comparison frame and Security <00-preface.md#comparison-frame-not-marketing>.\n\nON THIS PAGE\n\n- Boot path from seeder to shell <#0-boot-path-from-seeder-to-shell>\n- Two applications, one protocol <#1-two-applications-one-protocol>\n- Two drives on the booter <#2-two-drives-on-the-booter>\n- Protocol, MBR, and discovery <#3-protocol-mbr-and-discovery>\n- Execution stack inside the booter <#4-execution-stack-inside-the-booter>\n- Services after the console exists <#5-services-after-the-console-exists>\n- Identity states <#6-identity-states>\n- What is not here (boundary) <#7-what-is-not-here-boundary>\n\n0. BOOT PATH FROM SEEDER TO SHELL\n\nThe following is the conceptual ordering (not every substep on the wire). It complements the reference sequence diagram in Architecture: end-to-end data flow <../docs/reference/architecture-data-flow.md>.\n\n1. TWO APPLICATIONS, ONE PROTOCOL\n\n- The seeder is the canonical publisher of the OS image (plus MBR in a small RAM map).\n- The booter is a consumer that refuses to invent a local copy: it must see peers.\n- After successful boot and eligibility checks, a booter can become a helper for cold joiners by mirroring the same block 0 MBR and captured seed RPC snapshots.\n\n2. TWO DRIVES ON THE BOOTER\n\nThe VFS merges both drives into one POSIX-shaped tree. Typical personal prefixes include $HOME, /tmp, /var/log, and /.bare/; most of /bin, /boot, /etc, /lib, … resolve on the system image. Exact routing is policy-sensitive—see the booter reference for guest /.bare visibility rules.\n\nEvergreen diagram: docs/concepts — Two-drive model <../docs/concepts/two-drive-model.md>.\n\nTrust model (pragmatic):\n\n- System drive content is whatever replicated from the swarm matching the MBR keys. In dev you treat the seeder as trusted; in the wild this is “who you peer with.”\n- Personal drive is your namespace (Corestore bare-os-personal-v1). It holds secrets, cron, dotfiles, HDMS registry, vault snapshots.\n\n3. PROTOCOL, MBR, AND DISCOVERY\n\nThe shared package bare-os-protocol pins:\n\n- TOPIC_STRING === 'bare-os-v1'\n- topicKey() = crypto.hash(b4a.from(TOPIC_STRING))\n- MBR layout: 512 bytes, magic BIOS, primary key at offset 8, optional failover keys at 40 and 72\n\nMBR layout (512 bytes, see bare-os-protocol/constants.js):\n\n- Bytes 0–3: BIOS magic\n- Bytes 8–39: primary system Hyperdrive public key\n- Bytes 40–71, 72–103: optional additional keys\n\nProtomux channel bare-os-v1 carries:\n\n- Block read requests (MBR and any indexed RAM the seeder exposes)\n- Hyperdrive replication on the same socket\n- Gossip bitfield (message 2), manifest search (3/4), and *bare_os. RPC (5/6) on the seed channel — including bare_os.capabilities, bare_os.replication_status, bare_os.manifest_hints, bare_os.peer_health, bare_os.staging_slot** (see packages/bare-os-protocol/lib/channel.js; Kernel extensions <../docs/reference/kernel-extensions.md>)\n\n4. EXECUTION STACK INSIDE THE BOOTER\n\nKernel and /bin scripts are not separate processes. They are AsyncFunction closures in the same JS realm as the booter, with a synthetic ctx instead of syscalls.\n\n5. SERVICES AFTER THE CONSOLE EXISTS\n\nstopBareInitd() runs from REPL session cleanup so timers do not leak across session restarts.\n\nBare mobile lifecycle: when the host registers bareOsRegisterSuspendHook / bareOsRegisterResumeHook, the booter wires bare-initd so units with ExecStop= / ExecStart= (or equivalent stop/start paths) run in dependency order on suspend and resume—mirroring ordered service pause on mobile shells without real process freeze.\n\n6. IDENTITY STATES\n\nGuest and unlocked sessions share the same booter process; the state machine below is about environment and policy, not separate OS processes.\n\n- Guest: fixed HOME=/home/guest, read-oriented personal tree policy for some operations.\n- Unlocked: HOME under /home/, HDMS can attach writable drives, crontab install/remove allowed.\n\nFull story: Chapter 5 — Identity, vault, HDMS <05-identity-vault-and-hdms.md>.\n\n7. WHAT IS _NOT_ HERE (BOUNDARY)\n\n- No hardware kernel, no MMU, no ELF loader for native /bin.\n- No container cgroup isolation—commands are JS with full host capability of the Pear/Bare process.\n- Future: stronger isolation would compose Bare workers, Pear runtime isolates, or bare-kit-style embeds; the stock ctx.bareOsSandboxRunScript hook is a documented placeholder until then (see developer guide security chapter).\n- No global consensus: two booters can diverge if they replicate different forks of the same discovery key (Hyperdrive versioning is a separate concern).\n\nNext: Chapter 3 — Protocol and disk <03-protocol-and-disk.md>\n\nRelated: Preface <00-preface.md> · Handbook home · Kernel extensions <../docs/reference/kernel-extensions.md>\n\n_Experimental research software, not a production OS. Open source under Apache-2.0. Owned, operated, and engineered by HoneyPeer, LLC, a DeKalb, Georgia limited liability company — LICENSE <../LICENSE>._","descriptionMode":"preserve","options":[],"keywords":["handbook","bare-os","documentation","narrative","chapter","02","blueprints","architecture","and","trust"],"seeAlso":[{"name":"handbook-03-protocol-and-disk","section":7},{"name":"handbook-01-introduction","section":7},{"name":"man","section":1}],"bareOsNotes":"Generated at build time from handbook/02-blueprints.md. Diagrams in ```mermaid blocks are omitted; open the Markdown in the repo for figures.","listCategory":"handbook"},{"name":"handbook-03-protocol-and-disk","section":7,"title":"Chapter 3 — Protocol, MBR, and SwarmDisk","synopsis":["man 7 handbook-03-protocol-and-disk","Handbook chapter (plain text from handbook/03-protocol-and-disk.md)"],"description":"CHAPTER 3 — PROTOCOL, MBR, AND SWARMDISK\n\nTime to read: about 12 minutes. Prerequisites: Chapter 2 — Blueprints <02-blueprints.md>.\n\nCanonical refs: package-bare-os-protocol <../docs/reference/package-bare-os-protocol.md> (bytes, offsets) · Kernel extensions <../docs/reference/kernel-extensions.md> (feature bits, seed RPC) · Compatibility matrix <../docs/reference/compatibility-matrix.md> (aligned versions).\n\nHere we connect bare-os-protocol to what seeder and booter actually do on the wire and in RAM. For byte offsets and constants, keep package-bare-os-protocol <../docs/reference/package-bare-os-protocol.md> open. For kernel feature bits and seed-channel RPC behavior, see Kernel extensions <../docs/reference/kernel-extensions.md>.\n\nON THIS PAGE\n\n- The MBR in plain language <#the-mbr-in-plain-language>\n- Seeder lifecycle <#seeder-lifecycle>\n- Booter: from peers to Hyperdrive <#booter-from-peers-to-hyperdrive>\n- Message IDs <#message-ids--what-each-is-for>\n- Kernel feature bitmask (documentation) <#kernel-feature-bitmask-documentation>\n- Personal drive replication <#personal-drive-replication>\n\nTHE MBR IN PLAIN LANGUAGE\n\nThink of the MBR as a business card for the system image: 512 bytes that say “this Hyperdrive key (and optional alternates) is the OS you want.” The first bytes are the ASCII magic BIOS so booters do not mistake random data for a catalog. Starting at offset 8, the card embeds 32-byte public keys—the primary system drive first, then optional failover keys at 40 and 72 if you publish multiple compatible images.\n\nThe booter always tries to obtain block 0 through the swarm-backed SwarmDisk; it does not silently fall back to your git checkout’s kernel/. That design choice forces you to confront availability: if nobody is seeding, you do not boot.\n\nBLOCK-0 TRUST ASSUMPTIONS\n\nBlock 0 is small, but it is a trust root: whichever peer satisfies read(0) first can define which system Hyperdrive key the booter opens. Peer-assisted mirrors (BARE_OS_PEER_SYSTEM_SEED) widen availability by letting already-booted nodes answer the same block 0 and captured seed RPC snapshots, but they do not create a stronger authority domain than the swarm itself.\n\nSee also: Boot trust model <../docs/security/boot-trust-model.md> for the concise operator checklist.\n\nTreat block-0 acceptance as an explicit operator policy:\n\n- allow only peers/topics you trust to publish the intended image lineage,\n- enforce strict capability/version gates before proceeding when possible,\n- and verify release provenance out-of-band for production-like deployments.\n\nDetails: bare-os-protocol/constants.js <../packages/bare-os-protocol/constants.js> and the reference doc above.\n\nSEEDER LIFECYCLE\n\n1. Resolve kernel root (BARE_OS_KERNEL_ROOT or vendored kernel/).\n2. Optionally rebuild coreutils when running under Node (file: URL) — skipped under Pear.\n3. Open Corestore + Hyperdrive, stageKernelTree:\n- init.js → /boot/init.js\n- bin/ → /bin/\n- etc/ → /etc/\n- Other paths under the kernel tree map to the same path on the drive; README.md at the kernel root is skipped (repository layout doc only — not installed as /README.md).\n4. Build MBR with buildMbr(drive.key) and store block 0 in a Map (localRAM).\n5. Hyperswarm join(topicKey()) and join(drive.discoveryKey).\n6. On each connection: Protomux + setupSeedChannel, which:\n- Answers read index requests from localRAM (index 0 → MBR)\n- Attaches drive.replicate(stream)\n- Optionally pairs a second channel bare-os-app-v1 when BARE_OS_PROTOMUX_APP_CHANNEL is set on the host/seeder (namespaced application RPC alongside the OS control plane on bare-os-v1; see bare-os-protocol PROTOCOL_APP_CHANNEL_NAME).\n\nStack view (discovery → channel → replication):\n\n> Note\n> Offsets, magic bytes, and message IDs are specified in package-bare-os-protocol <../docs/reference/package-bare-os-protocol.md>; this sequence is the behavioral summary.\n\nOPTIONAL READ-ONLY SYSTEM ALIAS MOUNT\n\nWhen the host sets BARE_OS_VFS_SYSTEM_RO_ALIAS to an absolute path (for example /snapshot/system), the VFS routes that prefix to the same read-only system Hyperdrive as / (writes denied via mntReadOnly). The path appears in /proc/mounts as bare-os-system-ro-alias. Use it for scripts and docs that expect a distinct “versioned root” without opening a second drive.\n\nBOOTER: FROM PEERS TO HYPERDRIVE\n\nSwarmDisk (booter) mirrors the seeder’s channel handlers:\n\n- read(index) — if not local RAM, broadcast msg 0 to peers, await msg 1 (timeout).\n- addPeer — open channel, replicate system (and later personal) drives on the mux stream.\n\nPeer-assisted seeding (default on): Unless the host sets BARE_OS_PEER_SYSTEM_SEED to 0, false, no, or off, eligibility checks run after initd; when they pass, the booter copies its boot MBR (512 bytes) into localRAM so read(0) can be answered like the publisher, and disk.os implements bare_os.capabilities plus the same best-effort *bare_os. mirror RPCs using snapshots taken from the publisher at this node’s boot. Helpers still replicate the system Hyperdrive over the mux as today. After a successful swarm boot, BARE_OS_PEER_SEED_SYNTHETIC_CAPABILITIES (default on) may fill seedCapabilityInfo with stock kernelCapabilityWords when the pre-MBR bare_os.capabilities RPC was skipped or incomplete, so more nodes can mirror block 0 without a perfect publisher snapshot. Operators should set BARE_OS_SEED_IMAGE_TIP_ID on the seeder (and the same value on booters, or BARE_OS_PEER_SEED_ADVERTISE_IMAGE_TIP_ID) so helpers advertise one image tip; optional BARE_OS_PEER_SEED_IMAGE_TIP_ID** on a helper still gates whether that node may mirror; see the environment appendix.\n\nBoot path:\n\n1. Wait until disk.peers.size > 0 or boot timeout.\n2. parseMbr(await disk.read(0)) → list of 32-byte keys.\n3. For each key, try Hyperdrive(store, key) + replicate until /boot/init.js exists.\n4. Initialize personal drive namespace and join its discovery key.\n5. Hand off to executeKernel.\n\nThere is intentionally no “use my checkout’s kernel/ if the network fails” path—the project forces you to think about availability of the swarm.\n\nEND-TO-END BOOT SEQUENCE (MBR TO START(CTX))\n\nThis view complements the seeder ↔ wire sketch above by naming both drives and /boot/init.js. Same story as docs/concepts — Boot timeline <../docs/concepts/boot-and-init-timeline.md>.\n\nMESSAGE IDS — WHAT EACH IS FOR\n\nAligned with packages/bare-os-protocol/lib/channel.js and swarm-disk.js. The boot-critical path is 0/1 plus Hyperdrive replication on the same socket; the rest supports discovery, ops, and capability negotiation (see Kernel extensions <../docs/reference/kernel-extensions.md>).\n\n- 0 (client → peers) — Fetch a RAM block by index (block 0 is the MBR) when the booter has no local copy.\n- 1 (peer → client) — Return the bytes for that index (or otherwise satisfy the read contract).\n- 2 (gossip stub) — Bitfield buffer for optional capability and gossip experiments (see kernel feature bits).\n- 3 / 4 (search request / response) — Manifest search so operators can ask whether the image contains a path without walking the whole tree client-side.\n- 5 / 6 (RPC request / response) — *bare_os. RPC: version, health, kernel info, capabilities, replication_status**, gossip; strict boot can require answers before trusting the image.\n\nThe important path for boot is 0/1 plus Hyperdrive replication on the same socket.\n\nBOOTER DISK.OS BRIDGE (AFTER INITD)\n\nOnce initd has started, the stock booter assigns disk.os on SwarmDisk. Peers use the same Protomux channel (messages 3–6) to query the running booter—not the static seeder RAM map:\n\n- searchLocal(query) — case-insensitive substring match over system Hyperdrive paths (recursive list, capped), returned on message 4.\n- execRpc(module, method, args) — whitelisted *bare_os. calls only, UTF-8 result string on message 6**:\n- bare_os.ping → pong\n- bare_os.ctx_api_version → BARE_OS_CTX_API_VERSION\n- bare_os.uptime_ms → ms since booter VFS construction started\n- bare_os.system_revision → JSON of ctx.bareOsSystemRevision\n- bare_os.ipc_list → JSON array of FIFO channel names\n- bare_os.service_names → JSON array of initd unit names\n- bare_os.echo → JSON {\"args\":[…]} (debug)\n- bare_os.disk_os_hints → JSON schema 3: schema 2 fields plus pathSearchLocal (last searchLocal metrics: manifest path, match counts, scan counts). searchLocal consults optional /etc/bare-os/path-manifest.json on the system drive first (BARE_OS_DISK_OS_PATH_MANIFEST, BARE_OS_DISK_OS_SEARCH_MANIFEST_ONLY, BARE_OS_DISK_OS_MANIFEST_CACHE_MS).\n- bare_os.replication_operator_sketch → JSON schema 7 (superset of 6): adds corestoreSnapshotUxHint (schema 3) comparing BARE_OS_CORESTORE_SNAPSHOT_JSON vs BARE_OS_CORESTORE_STATS_JSON handle/namespace counts; retains pkgIndexSurface + bare_os.pkg_index_get, corestoreOperatorSketch, peerPrioritySketch, blindTopologySketchV3, hyperblobsDedupSketch, Hyperswarm budget fields — non-secret operator JSON only.\n- bare_os.pkg_index_get → JSON schema 1: reads BARE_OS_PKG_INDEX_PATH (default /etc/bare-os/pkg-index.json) for package key listing or one name@version entry.\n- bare_os.replication_operator_intent — cap-gated (BARE_OS_DISK_OS_OPERATOR_INTENT_RPC=1): accepts a JSON object string, appends one disk_os.replication_operator_intent row via ctx.bareOsAuditLogAppendBatch when the booter wires auditBatch; EPERM when disabled.\n- Unknown pairs throw BareOsKernelError with code BARE_OS_EXEC_RPC_UNKNOWN (surfaced as RPC error text).\n\nsearchLocal: matches optional /etc/bare-os/path-manifest.json (or BARE_OS_DISK_OS_PATH_MANIFEST) on the system drive first, then (unless BARE_OS_DISK_OS_SEARCH_MANIFEST_ONLY) recursively lists the system Hyperdrive, then each SwarmDisk.auxiliaryDrives entry, dedupes paths, caps at 256 hits. Optional BARE_OS_DISK_OS_SEARCH_THROTTLE_MS (0–500) inserts a short setTimeout between auxiliary drive scans.\n\nImplementation: packages/bare-os-booter/lib/bare-os-disk-os-bridge.js <../packages/bare-os-booter/lib/bare-os-disk-os-bridge.js>. Architecture overview: docs/architecture/KERNEL_CONTRACT.md <../docs/architecture/KERNEL_CONTRACT.md>.\n\nEXPERIMENTAL — P2P-NATIVE PACKAGE INDEX\n\nStock pkg-swarm-index lists or resolves rows from the drive manifest (/etc/bare-os/pkg-index.json) or ctx.bareOsHrpcRequest('bare_os','pkg_index_get', …) when the booter exposes HRPC. For get, when an entry includes pathCapabilityEnvelope and ctx.bareOsVerifyPathCapabilityEnvelope exists, the utility adds pathCapabilityEnvelopeVerify to the printed JSON (same behavior as the /bin copy under kernel/bin/). Operators can still compose Hyperbee + hyperswarm to publish name@version → { driveKey, manifestHash } records signed with Ed25519, verified against boot policy instead of a central registry. See kernel/etc/bare-os/pkg-index.example.json <../kernel/etc/bare-os/pkg-index.example.json>, kernel/etc/bare-os/hyperbee-index-hint.example.json <../kernel/etc/bare-os/hyperbee-index-hint.example.json>, BARE_OS_PKG_SWARM_TOPIC_HEX, and kernel/etc/bare-os/bundlebee-extension-sidecar.example.json for extension sidecars.\n\nEXPERIMENTAL — MULTISIG-GATED KERNEL UPDATE STREAM\n\nSee kernel/etc/bare-os/kernel-stream.manifest.example.json <../kernel/etc/bare-os/kernel-stream.manifest.example.json> for a non-normative sketch tying /boot/init.js hash pins, quorum signers, and an optional swarm topic class — operators wire replication and verification outside the guest.\n\nEXPERIMENTAL — MULTISIG-GATED RC.D PROPOSALS\n\nCollaborative fleets install JSON under */etc/bare-os/rc.proposals/enabled/.json (see kernel/etc/bare-os/rc.proposal.multisig.example.json <../kernel/etc/bare-os/rc.proposal.multisig.example.json>). With BARE_OS_RC_PROPOSAL_MULTISIG_STRICT=1, the guest kernel requires /etc/bare-os/pear.multisig.json, validates each proposal’s signaturesFrom keys against that policy’s signers, and requires at least quorum distinct matches before rc.d runs. ctx.bareOsAuditLogAppend receives rc.proposal.multisig_ok / rc.proposal.multisig_fail rows when wired. Cryptographic attestation of proposal bytes remains a host / seeder** responsibility.\n\nKERNEL FEATURE BITMASK (DOCUMENTATION)\n\nThe package bare-os-protocol exports lib/kernel-feature-bits.js (re-exported from index.js) with versioned capability words describing optional booter / image capabilities across the current surface: shorthand words bits through bits11 and canonical kernelCapabilityWords (always >>> 0 when masking). Peers see a 250-byte bitfield on message 2 (gossip stub; bit 0 set today). The seeder answers bare_os.capabilities over RPC with doc / featureBitsDoc, bits…bits11, kernelCapabilityWords, protocolPackageVersion, role, and protocol so the booter can compare before MBR read (BARE_OS_SEED_CAP_STRICT covers all non-zero words the stock booter advertises). bare_os.replication_status adds seeder-local replication hints; bare_os.replication_queue (with bounded queue / snapshot notes), bare_os.capability_attestation, bare_os.mbr_layout, bare_os.snapshot_hints, and bare_os.peer_firewall_stats are optional RPCs (hints only; guests do not verify crypto). mbr_layout / replication JSON may surface parsed failover key slots (MBR offsets 40 / 72) as hex hints for operators, plus optional staging slot, manifest, peer health, and firewall sketches when the seeder implements them. Guests read dumps under /proc/bare_os_features, /proc/bare_os/, and related /proc nodes. Unknown bits should be ignored.\n\nAuthoritative tables: Kernel extensions <../docs/reference/kernel-extensions.md>.\n\nPERSONAL DRIVE REPLICATION\n\nSwarmDisk.initPersonalDrive creates a separate Hyperdrive under a stable Corestore namespace and swarm.join(personalDrive.discoveryKey). Your $HOME tree can therefore sync across your devices if peers share that discovery key—orthogonal to the system image key from the MBR.\n\nPeer admission audit (optional): when BARE_OS_PEER_ADMISSION_AUDIT_NDJSON is on, ctx.bareOsEvaluatePeerAdmission may emit peer_admission event-bus rows with verdict, optional reason, and a 16-hex-character peerKeyHexPrefix only (never the full key). BARE_OS_PEER_ADMISSION_AUDIT_RATE_MS throttles repeats per prefix bucket; /proc/bare_os/security_posture.json documents the env keys under peerAdmission. Allowlist/denylist fail-closed semantics are unchanged — audit is observability only.\n\nHost logging: mount and writability warnings use emitSwarmDiskHostLog in swarm-disk.js <../packages/bare-os-booter/lib/swarm-disk.js>. When BARE_OS_BOOT_TRACE is json or ndjson, one structured type\":\"booterHost\" line ( component\":\"swarm_disk\" ) is written to stderr per event; otherwise messages go to stderr (info) or console.warn (warnings), not guest ctx.console.\n\nWhat you should expect: personal data persists under the same store path between runs; if you delete the booter Corestore or switch BARE_OS_BOOT_STORE, you effectively get a new personal namespace unless you restore keys. Multi-device sync only happens if another device joins the same personal discovery key—there is no automatic “cloud account”; it is still P2P replication semantics.\n\nFAILURE MODES YOU WILL SEE IN THE WILD\n\nBooter exits after boot timeout — Likely no peer on the bare-os-v1 topic, or Hyperswarm is blocked. Start a seeder on the same network, review BARE_OS_BOOT_TIMEOUT_MS, and confirm HYPERSWARM_BOOTSTRAP if you use custom bootstrap nodes.\n\nInvalid MBR or parse error — Block 0 may not be from this project, the RAM map may be corrupt, or the seeder may be mismatched. Align bare-os-protocol versions between seeder and booter and rebuild the MBR from a known-good drive.\n\nDrive never finishes replicating — Often a discovery key mismatch, flaky peers, or a stalled mux. Watch peer counts, restart the seeder, inspect logs, and verify the booter joined the system discovery key from the MBR.\n\nCapabilities or strict seed errors — The booter may expect features the seeder image does not advertise. Align package versions; relax BARE_OS_SEED_CAP_STRICT only if you understand the tradeoff (Kernel extensions <../docs/reference/kernel-extensions.md>).\n\nPersonal files missing on a new machine — You may be using a new Corestore path or a new personal drive. Restore the same BARE_OS_BOOT_STORE (or key backup); the personal drive is not the system MBR key.\n\nNext: Chapter 4 — The booter runtime <04-the-booter-runtime.md>\n\nRelated: Chapter 2 — Blueprints <02-blueprints.md> · Handbook home · Kernel extensions <../docs/reference/kernel-extensions.md> · Environment appendix <../docs/reference/environment-and-posix-appendix.md>\n\n_Experimental research software, not a production OS. Open source under Apache-2.0. Owned, operated, and engineered by HoneyPeer, LLC, a DeKalb, Georgia limited liability company — LICENSE <../LICENSE>._","descriptionMode":"preserve","options":[],"keywords":["handbook","bare-os","documentation","narrative","chapter","03","protocol","and","disk","mbr","swarmdisk"],"seeAlso":[{"name":"handbook-04-the-booter-runtime","section":7},{"name":"handbook-02-blueprints","section":7},{"name":"man","section":1}],"bareOsNotes":"Generated at build time from handbook/03-protocol-and-disk.md. Diagrams in ```mermaid blocks are omitted; open the Markdown in the repo for figures.","listCategory":"handbook"},{"name":"handbook-04-the-booter-runtime","section":7,"title":"Chapter 4 — The booter runtime: ctx, VFS, shell, kernel, services","synopsis":["man 7 handbook-04-the-booter-runtime","Handbook chapter (plain text from handbook/04-the-booter-runtime.md)"],"description":"CHAPTER 4 — THE BOOTER RUNTIME: CTX, VFS, SHELL, KERNEL, SERVICES\n\nTime to read: about 20 minutes (skim headings first). Prerequisites: Chapters 2–3 <02-blueprints.md>.\n\nThe booter is the largest package because it is the machine: everything the user experiences as “the OS” (except the raw Hyperdrive bytes) is assembled in packages/bare-os-booter/index.js and *lib/.js**.\n\nCTX AT A GLANCE (SURFACE AREA)\n\nctx is the single handle passed into /boot/init.js and every /bin utility. You can think of it as the simulated machine:\n\n- ctx.vfs — path operations across system + personal drives (readFile, writeFile, stat, chdir, …).\n- ctx.console — log / error wired to the session console (and often mirrored to kernel logs).\n- ctx.execLine / ctx.readLine — the line shell and prompt input.\n- ctx.runBinCommand — run a /bin command as if typed (used by time, xargs, etc.).\n- Identity — hooks and state for guest vs unlocked sessions (login / logout).\n- Optional ctx.bare — merged Bare module map when the host allows imports + optional drive bundles (see below).\n- Policy and caps — ctx.bareOsRuntimeCaps, optional httpFetch (policy fetch for delegated curl/wget when a fetch backend exists at ctx build), IPC FIFOs, HDMS, Pear reload requests, audit flags, …\n\nThe authoritative field list and versioning story are in developer-guide — The context object <../developer-guide/02-the-context-object.md> and CHANGELOG <../packages/bare-os-booter/CHANGELOG.md>.\n\nBOOT SPLASH AND STDIO\n\nresolveStdio() picks session stdin/stdout appropriate for Pear/Bare vs Node. When stdout is a TTY and BARE_OS_NO_SPLASH is unset, createBootSplash draws a full-screen boot UI tied to BARE_OS_BOOT_TIMEOUT_MS: a centered block with title, tagline, framed log area and progress bar sized to the terminal, phase lines with spinner, and optional footer lines (booter and protocol versions from main()). Vertical padding is capped so very tall terminals do not push content too far down. prepareForKernel() clears the screen and restores the cursor before the line editor attaches.\n\nNon-TTY mode skips splash noise; automation uses BARE_OS_SKIP_REPL=1.\n\nHost vs guest logging: After the session ctx exists, user-visible kernel and shell output should flow through ctx.console (wired in createKernelReplSession / init). Pre-session and operator-only booter paths use packages/bare-os-booter/lib/bare-os-host-booter-log.js plus BARE_OS_HOST_BOOTER_LOG (stderr vs NDJSON file) so automation can separate host telemetry from guest REPL traffic. The seeder mirrors the same idea via packages/bare-os-seeder/lib/host-logger.mjs (seedLog).\n\nEXECUTEKERNEL IN ONE PARAGRAPH\n\nAfter the system and personal drives exist:\n\n1. Build shellEnv (guest defaults: HOME, PATH, USER, …, BARE_OS_CTX_API_VERSION), copying host keys when set — including *BARE_OS_PIPELINE_ (including BARE_OS_PIPELINE_ABS_MAX_), BARE_OS_SHELL_STREAMING, BARE_OS_SHELL_STREAMING_MULT (alias BARE_OS_STREAMING_MULTIPLIER), BARE_OS_SHELL_CMDSUBST, BARE_OS_SHELL_CMDSUBST_MAX_BYTES, boot and audit toggles (BARE_OS_BOOT_PROFILE, BARE_OS_ONBOOT, BARE_OS_BOOT_STRICT, BARE_OS_RC_D_SKIP, BARE_OS_BOOT_MINIMAL, BARE_OS_BOOT_SKIP, BARE_OS_BOOT_TRACE, BARE_OS_KERNEL_SELFTEST, BARE_OS_SELFTEST_FORMAT, BARE_OS_AUDIT, BARE_OS_AUDIT_JSON, BARE_OS_AUDIT_REDACT, BARE_OS_BOOT_ALLOWLIST, BARE_OS_EXEC_MAX_DEPTH, BARE_OS_EXEC_LINE_BUDGET_MS / BARE_OS_TIMER_BUDGET_MS, BARE_OS_IPC_, BARE_OS_IPC_CHANNEL_MAX_BYTES, BARE_OS_IPC_MAX_CHANNELS, BARE_OS_POSIX_MQ_MAX_MSGS, BARE_OS_POSIX_MQ_MSG_BYTES, BARE_OS_HTTP_ALLOWLIST, BARE_OS_HTTP_DENYLIST, BARE_OS_TLS_PIN_SHA256, BARE_OS_VFS_WATCH, BARE_OS_VFS_MAX_OPEN, BARE_OS_VFS_UNION_PREFIXES, BARE_OS_VFS_UNION_WRITE_DENY, BARE_OS_VFS_BIN_CACHE, BARE_OS_IMAGE_DIGEST, BARE_OS_PEAR_CHANNEL, BARE_OS_PEAR_RELEASE, BARE_OS_BARE_MODULES, BARE_OS_BARE_DRIVE_BUNDLES, BARE_OS_BOOT_MANIFEST, BARE_OS_BOOT_MANIFEST_SIGN, BARE_OS_BOOT_MANIFEST_PUBKEY_HEX, BARE_OS_BOOT_POLICY, BARE_OS_SANDBOX_SCRIPT, BARE_OS_SANDBOX_WORKER, BARE_OS_INITD_MAX_PARALLEL, BARE_OS_INITD_JOURNAL_MAX_LINES, BARE_OS_URANDOM_CRYPTO, BARE_OS_TELEMETRY_NDJSON, BARE_OS_TELEMETRY_OTEL_JSONL, BARE_OS_TELEMETRY_OTEL, BARE_OS_SEED_RPC_HANDSHAKE, BARE_OS_SEED_CAP_STRICT, BARE_OS_SEED_CAP_FAIL, BARE_OS_BLIND_BOOTSTRAP_URL, BARE_OS_BLIND_BOOTSTRAP_JSON, BARE_OS_MIRROR_READ_KEY, PEAR_CHANNEL, Capability word 9 keys (BARE_OS_SOCKS_PROXY_MAP_JSON, BARE_OS_BARE_CRYPTO_VERSION, BARE_OS_PEAR_IPC_PACKAGE_VERSION, BARE_OS_PEAR_UPDATER_CHANNEL, BARE_OS_HAPPY_EYEBALLS_V3_MODE, BARE_OS_BIN_WORKER_WASM_MS_MAX, BARE_OS_PROBE_ID_BARE_MODULE_CRYPTO_STAGING, optional BARE_OS__JSON for /proc/bare_os/ Capability word 9 files), and Capability word 10 keys (BARE_OS_PROBE_ID_PEAR_INSPECT_LOGGER_TLS, BARE_OS_BARE_RPC_PROBE_CLASS, BARE_OS_MTLS_PROXY_MAP_JSON, BARE_OS_THREAD_POOL_TELEMETRY_JSON, BARE_OS_HAPPY_EYEBALLS_V4_MODE, BARE_OS_BARE_BOOT_VERSION, BARE_OS_BARE_LOGGER_VERSION, BARE_OS_BARE_TLS_VERSION, BARE_OS_LIFECYCLE_SCHEMA_VERSION, optional BARE_OS__JSON for Capability word 10 /proc/bare_os/ files — see Chapter 7 <07-operations-and-development.md>, the environment appendix <../docs/reference/environment-and-posix-appendix.md#14-environment-variables-complete-list>, Kernel extensions <../docs/reference/kernel-extensions.md>, and the context object developer guide <../developer-guide/02-the-context-object.md>. Set BARE_OS_BOOT_PROFILE_RESOLVED from the host override or the first line of /etc/bare-os/profile on the system drive; assign BARE_OS_SESSION_ID for /run/bare-os/session. Seed /run/bare-os/boot.json fields imageDigest, pearChannel, pearRelease, and accumulate booterPhases (vfs, ctx, repl, initd, kernel_invoke) for observability alongside kernel phases.\n2. createBareOsIpc({ maxFifoBytes, maxChannels?, perChannelMaxBytes?, ipcRpcToken?, enableFanout?, maxJsonRpcLineBytes?, posixMqDefaultMaxmsg?, posixMqDefaultMaxBytes?, posixMqMaxmsgCeiling? }) — in-memory FIFOs under /run/bare-os/ipc/; optional distinct-channel cap BARE_OS_IPC_MAX_CHANNELS; optional per-name byte caps via BARE_OS_IPC_CHANNEL_MAX_BYTES (JSON map); pushJson/takeJson with optional shared-secret field bareOsIpcToken when BARE_OS_IPC_RPC_TOKEN is set; fan-out topics fanoutPublish/fanoutSubscribe (disable with BARE_OS_IPC_FANOUT=0); createDuplexBridge(baseName) pairs two push/take sides for bidirectional byte streams; duplexJsonRoundTrip(side, request) sends one JSON object and awaits one JSON reply (bounded); stats includes fan-out subscriber counts. POSIX-like message queues (mqOpen / mqSend / mqReceive, also ctx.bareOsSyscall('mq_open'|…)) live in the same module: bounded maxmsg and per-message maxBytes (optional session defaults from BARE_OS_POSIX_MQ_MAX_MSGS / BARE_OS_POSIX_MQ_MSG_BYTES when attrs omitted), priority order (higher numeric prio dequeued first, then FIFO by internal sequence), separate from FIFO semantics; stats().posixMessageQueues lists queue count and sample names.\n3. createVfs(drive, personalDrive, shellEnv, mntRef, vfsOptions?) — the two-drive router; optional vfsOptions supply procSnapshot (/proc/version, cmdline), dynamic text for /proc/net/dev, /proc/diskstats, /proc/bare_os_quotas, /proc/bare_os_resources, /proc/bare_os_features, /sys/class/net/lo, bootProfileText, sessionText, initdRunText, bootReadyJsonText, getVirtualReaders for /run/bare-os/virtual/, etc.\n4. After VFS: buildBareCtxObjectFromHost + maybeMergeBareFromDrive fill a bareLibrary map (host imports first; drive bundles only add missing keys). /lib/bare/manifest.json and */lib/bare/bundles/.js are trusted like /bin**. See developer guide ch.12 <../developer-guide/12-bare-modules-and-pear-ecosystem.md>.\n5. Construct ctx: disks, vfs, bareOsIpc, env, b4a, optional bare: Object.freeze(bareLibrary) when BARE_OS_BARE_MODULES is enabled, topic, bareOsRuntimeCaps (pipeline limits, quotas, pseudo path list, feature flags such as vfsWatch, ipcRpcJson, ipcFanout, initdSocketActivation, bareCtxModules, bareDriveBundles), optional httpFetch (policy-wrapped fetch when globalThis.fetch or ctx.bare.fetch is available at ctx build — see HTTP: curl and wget <../docs/reference/http-curl-and-wget.md>), optional bareOsHostStats from the bare-os module, bareOsGetResourceStatus, bareOsRegisterVirtualFile, Pear/sandbox stubs, identity hooks, bareOsSubscribeBootEvent / bareOsEmitBootEvent, bareOsSubscribeHdmsLifecycle, bareOsAwaitInitdUnits, runHdms, requestBooterExit, bareOsPublishBootReady, …\n6. applyGuestEnv + ensureGuestHome — identity stub and /.bare skeleton on the personal drive (after the ctx object exists).\n7. createKernelReplSession — Fish-style readLine + console bound to the same stdout as the prompt (tab completion, ghost suggestions, history on the personal drive; disable with BARE_OS_FISH=0 or non-TTY stdin). Full behavior: Shell completion and REPL editor <../docs/reference/shell-completion-and-repl-editor.md>.\n8. Set ctx.execLine, ctx.readLine, ctx.runBinCommand — optional AbortSignal/timeoutMs on execLine, readLine, runBinCommand, and VFS readFile/writeFile; exit, optional audit logging (BARE_OS_AUDIT, BARE_OS_AUDIT_JSON, redaction), execLine nesting cap (BARE_OS_EXEC_MAX_DEPTH), then execShellLine.\n9. await startBareInitd(ctx) — see below.\n10. runKernelFromSource(initSource, ctx) — runs /boot/init.js.\n\nCleanup path closes swarm/drives and calls session.cleanup(), which runs stopBareInitd().\n\nVFS: TWO DRIVES, ONE PATH SPACE\n\nlib/vfs.js implements resolveLogical with unix-path-resolve(cwd, userPath) (two arguments only—important when reading the code).\n\n- Paths under $HOME resolve to the personal Hyperdrive under /.bare-os/home//… (mutable writeFile / unlink where policy allows); writable /var/log uses /.bare-os/var/log//…; writable /tmp uses /.bare-os/tmp//… (session-isolated scratch). With BARE_OS_PERSONAL_ACCT_PREFIX=1, these three subtrees nest under /.bare-os/acct//… first (see multi-account design <../docs/design/multi-account-personal-subvolumes.md>).\n- Guest vs sealed /.bare: In guest mode, /.bare/account, /.bare/vault/, and vault-rotation-audit paths are not readable or writable (and readdir / .bare hides account / vault names) unless BARE_OS_GUEST_BARE_READ_ALL=1. login / logout** also clear warm read caches, reset simulated shell jobs, and reload fish history so another principal’s session does not bleed through.\n- Legacy flat-root migration — One-time lift from personal / into the active home prefix is governed by BARE_OS_PERSONAL_ROOT_MIGRATE and state /.bare-os/migration/legacy-root-v1.json; guest skips the lift when an account blob exists (so another user’s legacy files never land in /home/guest). Optional BARE_OS_GUEST_SCRUB wipes guest /tmp and selected caches when entering guest.\n- Other absolute paths hit the system drive (OS image).\n- Hyperdrive rejects / as a filename; the VFS special-cases logical root for stat, chdir, exists.\n\nVirtual listings include /home (session-specific), /mnt when HDMS mounts exist, and injected root entries proc, sys, tmp when absent from the system image.\n\nCatalog detail: Chapter 9 <09-posix-utilities-shell-and-vfs.md>.\n\nPSEUDO /PROC, /SYS, /RUN, /DEV (MOSTLY READ-ONLY)\n\nThese paths are synthetic (not stored on either Hyperdrive). They exist for inspection and scripting ergonomics, not Linux ABI compatibility. In blog terms: /proc is “what is this session doing?”; /sys is “tiny sysfs-shaped stubs”; /run is “volatile session state the booter owns”; /dev is “just enough device names that scripts stop crashing”; session /tmp is “scratch space that never lands on the read-only system drive.”\n\n- /proc: version, bare_os_version, uptime, meminfo, cpuinfo, loadavg, mounts, diskstats (peer-scaled synthetic lines), bare_os_quotas (JSON: pipeline limits, exec-depth cap, IPC cap, session stats, FIFO stats), bare_os_resources, bare_os_features (includes advertised stock words bits2 … bits10 when non-zero, optional seedHandshake summary after bare_os.capabilities RPC when enabled), bare_os_swarm (bounded P2P / session snapshot when the host provides it), bare_os_replication (JSON hints: version, peers, last error; may embed manifestHints, peerHealth, stagingSlot, seedSnapshotHints, seedPeerFirewallStats, seedReplication, mbrKeysHex from seed RPCs), bare_os_manifest_hints, bare_os_peer_health, bare_os_staging_slot, bare_os_snapshot_hints, bare_os_provenance (digest / signing / Pear channel summary), bare_os_pear_ipc_registry (well-known Pear IPC channel names), bare_os_pear_trust (operator JSON from BARE_OS_PEAR_TRUST_JSON), bare_os_initd_dag / bare_os_initd_graph (initd dependency graph JSON; graph may include a dot string), boot_graph.json (declarative kernel boot stage graph + boot-ready snapshot), bare_os_rlimits (getrlimit-shaped mirror of runtime caps; RLIMIT_NOFILE may follow BARE_OS_VFS_MAX_OPEN when set on the host), bare_os_hdms_health (non-secret mount/registry summary), bare_os_metrics_live (coalesced quotas/resources snapshot; interval BARE_OS_PROC_POLL_MS; schema 2 adds delegate inflight / rate-bucket samples), bare_os_net_summary (operator rollup of swarm topic, peer count, seed RPC hints; optional transport from BARE_OS_NET_TRANSPORT_STATS_JSON; optional udxTuning / hyperswarmTuning from BARE_OS_UDX_TUNING_JSON / BARE_OS_HYPERSWARM_TUNING_JSON), bare_os_host_os.json (Holepunch bare-os or injected JSON), bare_os_sync_window.json (BARE_OS_REPLICATION_SYNC_WINDOWS UTC windows), bare_os_debug.json when BARE_OS_KERNEL_DEBUG=1 (non-secret masks), bare_os_extensions.json / bare_os_hdms_hints.json (kernel extension registry + HDMS/autopass hints), bare_os_capabilities (human-readable dump of ctx.bareOsRuntimeCaps; bare_os_capabilities.json or Accept: application/json for machine output), bare_os_bootstrap, bare_os_union (JSON: union read prefixes + BARE_OS_VFS_UNION_WRITE_DENY), bare_os_seed_handshake (raw handshake / error object), bare_os_virtual_registry (registered virtual file metadata), /proc/bare_os/ (stable names + index.json mirroring the flat *bare_os_ aliases), net/dev (P2P-oriented stub), net/tcp, net/udp (header-only stubs), self/ with environ, cmdline, cgroups, exe, fd/0–2 (stub targets), plus bare_os_session_stats. environ omits keys whose names look secret-bearing (e.g. PASSWORD, TOKEN, VAULT) and only includes a small public set plus BARE_OS_ (including BARE_OS_SESSION_ID*).\n- /sys: fs/bare_os/version, fs/bare_os/build_id (same payload sources as /proc/version / build id), class/net/lo — one pseudo file whose text is operstate and carrier lines from the booter’s sysClassNetLoText hook (stock: operstate reflects swarm peer count carrier 0/1; see createVfs in vfs.js <../packages/bare-os-booter/lib/vfs.js>), devices/virtual/ — navigable empty directory for script portability (no per-device files).\n- /sys/fs/bare_os/version: same text as /proc/version.\n- /run/bare-os/units: tab-separated snapshot of bare-initd registered units (phase, start time, description).\n- /run/bare-os/unit-journal/: append-only NDJSON per unit (.ndjson) for start/stop/health/restart events (size-capped); journalctl -u also tails this file when present.\n- /run/bare-os/boot_profile: one line (plus newline): resolved boot profile name (BARE_OS_BOOT_PROFILE from the host, else first line of /etc/bare-os/profile, else empty). Listed in ctx.bareOsRuntimeCaps.pseudoFsPaths.\n- /run/bare-os/session: session UUID (from BARE_OS_SESSION_ID) plus newline.\n- /run/bare-os/virtual/: optional kernel-registered synthetic files via ctx.bareOsRegisterVirtualFile.\n- /dev/null, /dev/zero: minimal device semantics — null discards writes and reads empty; zero reads a fixed 64 KiB zero buffer. Not infinite /dev/zero like Linux.\n- /dev/shm: directory of in-memory named segments (/dev/shm/); readdir lists segment names; unlink removes a segment. This is not host shm_open—it is a guest-local buffer registry for scripts and tests.\n\nNon-goals: no real PIDs, accurate meminfo, or guarantees of path parity with Linux.\n\nvfs.watch(logicalPath) (Hyperdrive-backed paths only — not pseudo roots): returns { watcher, destroy, logicalAbs, driveFolder }; use Hyperdrive’s async iterator on watcher. Disabled when host sets BARE_OS_VFS_WATCH=0. With BARE_OS_VFS_WATCH_PSEUDO=1 or BARE_OS_VFS_WATCH_SWARM=1, a bounded poll watcher is also available on allowlisted /proc paths (metrics, swarm, replication). See ctx.bareOsRuntimeCaps.features.vfsWatch.\n\nUnion read: when BARE_OS_VFS_UNION_PREFIXES lists comma-separated logical prefixes, readFile / readlink on those paths may merge the system image with overlays (see vfs.js and ctx.bareOsRuntimeCaps.features.vfsUnionRead). BARE_OS_VFS_BIN_CACHE=1 enables a small LRU read cache for /bin entries, invalidated when vfs.watch notifications fire on watched prefixes.\n\nImplementation note: pseudo-file content is UTF-8 encoded with b4a, not TextEncoder, because some Bare/Pear runtimes omit the Web Encoding globals (TextEncoder / TextDecoder). The same applies elsewhere in the booter and in-image utilities that must run on Bare.\n\n/DEV AND /RUN (MINIMAL SUBSET)\n\nSee Pseudo /proc, /sys, /run, /dev above. A full device tree and /run parity with Linux are still out of scope.\n\nCTX.BARE AND DRIVE BUNDLES\n\nAfter the VFS exists, buildBareCtxObjectFromHost plus maybeMergeBareFromDrive fill a bareLibrary map: host-configured imports first, then /lib/bare/manifest.json and */lib/bare/bundles/.js on the system drive may supply only missing keys. Those paths are trusted like /bin**—they ship in the replicated image.\n\nUse this when you want real ESM modules (Holepunch *bare- packages) inside an otherwise AsyncFunction-only tree. Trust stance: enabling BARE_OS_BARE_MODULES** and drive bundles expands attack surface; treat manifests as part of your image signing story.\n\nDeep dive: developer-guide ch.12 — Bare modules and Pear ecosystem <../developer-guide/12-bare-modules-and-pear-ecosystem.md> · kernel/lib/bare/ <../kernel/lib/bare/> · PEAR-RUN.md — BARE_OS_BARE_MODULES <../docs/PEAR-RUN.md>.\n\nPEAR HOST BRIDGES AND HTTP POLICY\n\nThe booter exposes policy-gated hooks so a Pear host can react without forking the guest kernel:\n\n- ctx.bareOsRequestPearReload(opts?) — ask the host to reload the Pear runtime (OTA-style); optional persistRequest writes ~/.bare-os/pear-reload.request. Env mirrors BARE_OS_PEAR_CHANNEL, BARE_OS_PEAR_RELEASE, PEAR_CHANNEL into /run/bare-os/boot.json.\n- ctx.bareOsRequestMirror({ key?, label? }), ctx.bareOsExportPersonalSnapshot({ label? }), ctx.bareOsPearIpcEmit(channel, payload) — return hints or booleans; on Node the booter emits process events for embedding apps to implement real mirrors or snapshots.\n\nHTTP CLIENTS (CURL / WGET)\n\nDelegated curl and wget run from the booter’s host delegate registry before any /bin script on the system drive. They use a Fetch-shaped stack: policy-wrapped ctx.httpFetch when set, else ctx.bare.fetch from host imports or /lib/bare/bundles, else globalThis.fetch. On minimal Pear/Bare hosts, ensureBareFetchGlobals may install globals from bare-fetch or bare-https when no native fetch exists. Outbound URLs are constrained by BARE_OS_HTTP_ALLOWLIST / BARE_OS_HTTP_DENYLIST, optional BARE_OS_TLS_PIN_SHA256 (and init.bareOsCurlTls for curl TLS details), and optional BARE_OS_DNS_ALLOWLIST. The drive still ships /bin/curl and /bin/wget as manifest stubs; normal sessions never execute them.\n\nCanonical reference: HTTP: curl and wget <../docs/reference/http-curl-and-wget.md> · Flag matrix: CLI_PARITY.md <../packages/bare-os-booter/CLI_PARITY.md> · Full env tables: environment appendix <../docs/reference/environment-and-posix-appendix.md> · Pear notes: PEAR-RUN.md <../docs/PEAR-RUN.md>.\n\nagent: in-guest /bin/agent uses the same ctx.httpFetch stack for OpenAI-compatible /chat/completions requests and for the web_fetch tool (live http(s) fetches for the model). Treat BARE_OS_HTTP_ALLOWLIST / BARE_OS_HTTP_DENYLIST as covering both the API host and any sites you expect web_fetch to reach. Provider settings live under ~/.agent/ on the personal drive (man agent). chat (/bin/chat) is separate: swarm / Protomux chat when the booter enables it (man chat).\n\nROADMAP AND OUT-OF-SCOPE\n\nRemaining gaps are tracked in packages/bare-os-booter/CLI_PARITY.md, POSIX appendix — gaps <../docs/reference/environment-and-posix-appendix.md#14a-posix-userland-appendix-implemented-vs-gaps>, and Kernel extensions <../docs/reference/kernel-extensions.md>: transports and flags curl/wget may never match GNU; pipelines remain bounded captures rather than kernel pipes; bareOsSandboxRunScript is not a hard hardware-style isolate yet (optional stronger paths are documented in bare-os-sandbox.js); socket-activation idle stop remains directional work, not a promise.\n\nMilestone shape (current intent): (1) VFS + shell + synthetic proc/run + boot trace + allowlists — largely in place; (2) man and incremental /bin flags; (3) delegated HTTP parity where feasible; (4) init/protocol hardening as needs arise.\n\nDirectories: vfs.mkdir(path, { recursive }) and vfs.rmdir(path) implement POSIX-like tree creation and removal using a .bareos_empty marker file for empty directories (aligned with git-fs-adapter). See Chapter 9 <09-posix-utilities-shell-and-vfs.md>.\n\nctx.runBinCommand(argv) — same resolution as external commands in the shell; exposed for utilities such as /bin/time.\n\nSHELL AND KERNEL RUNNER\n\nexecShellLine (lib/shell.js):\n\n- Tokenizes words, quotes, escapes, $VAR, pipelines |, redirections > / >> / <.\n- Builtins: alias, unalias, cd, export, unset, readonly, umask, :, command, type, login, logout, exit, jobs, fg, bg, suspend-job, wait, bounded if/while/for/case — plus external commands via runBinCommand. Optional BARE_OS_SHELL_CMDSUBST enables bounded $(…) in words; optional BARE_OS_SHELL_STREAMING scales pipeline capture caps. readonly blocks export and assignment writes to the same name; command -v / -V and type use resolveBinInPath for PATH lookup.\n- First-word aliases (defaults like ll → ls -la, nano → edit) expand after $VAR substitution; alias / unalias match the restricted ~/.barerc syntax (not full POSIX sh).\n- Pipes capture console.log into the next stage or a string sink.\n\nrunBinCommand (lib/kernel-runner.js):\n\n1. If argv[0] contains / — resolve via VFS, drive.get, runScriptFromSource.\n2. Else if the name ends with .js — resolve $PWD/name.js first (same as explicit ./ for many cases).\n3. Else walk PATH on the system drive only.\n\nrunScriptFromSource strips an optional #! line, runs the script body as top-level code in an async function, then awaits a top-level run(ctx, argv) if one is defined (optional for user scripts; /bin utilities always define run). It catches errors—logs to ctx.console.error without unwinding the kernel loop.\n\nrunKernelFromSource requires async function start(ctx) at the top level of /boot/init.js.\n\n~/.BARERC (RESTRICTED STARTUP FILE)\n\nOn guest and logged-in identity transitions, the booter loads ~/.barerc from the personal drive if it exists. On login (unlocked identity), if the file is missing, the booter creates a comment-only skeleton you can edit. Only these forms are applied (other lines are ignored; set BARE_OS_STRICT_BARC=1 to log warnings):\n\n- export NAME=value — same name rules as the shell builtin; value is expanded like export in execShellLine.\n- alias name=value and unalias — same behavior as the interactive builtins (unalias -a resets to the default alias table).\n\nThere is no arbitrary command execution, source, or control flow — it is intentionally not a full sh profile.\n\nBARE-INITD, CRON, AND THEMES\n\nbare-initd.js (below) starts DAG-ordered units after the console exists. bare-cron (also below) reads /etc/bare-os/crontab and ~/.crontab.\n\nThemes live in docs/themes/README.md <../docs/themes/README.md> — preset packs (for example Nord) that align LS_COLORS, prompt colors, and sample Alacritty / Warp YAML so your host terminal and the in-guest theme / dircolors utilities agree. At login, ~/.barerc may contain theme nord (plus export / alias lines) to set *BARE_OS_COLOR_** without hand-editing escape codes.\n\nBARE-INITD AND KERNEL LOGGER\n\nbare-initd.js:\n\n- registerBareService({ name, start, stop?, description?, logPath? }) — optional stop enables systemctl stop / restart for that unit; logPath is a logical VFS path for systemctl status / logs\n- startBareInitd(ctx) — ensures /var/log/bare-os (see below), then DAG-ordered start with optional parallelism (BARE_OS_INITD_MAX_PARALLEL, default 1). Skips units listed in ~/.config/bare-os/initd/disabled.txt. Drop-ins ~/.config/bare-os/units/.unit support [Unit] keys After=, Before=, Requires=, Wants=, TimeoutStartSec=, TimeoutStopSec=, Restart=, RestartSec=, OnFailure=, FailureAction=, ExecStartPost=, SocketActivationIpc= (defers start() until the first read on that FIFO), IdleSec= (with socket activation and a stop handler: stop after idle seconds between FIFO messages), ReadinessPath= (VFS path until exists, or exec: gated by ReadinessTimeoutSec=), ReadinessTimeoutSec=, ConditionPathExists= (skip start when missing), AssertPathExists= (fail unit when missing). Optional fragments *~/.config/bare-os/units.d//.conf (sorted .conf) merge after the main .unit and before ~/.config/bare-init/units/ overrides. Cycles in After/Before are detected and logged; affected units fail start. Built-in default edges include bare-cron after kernel-logger, bare-os-www after kernel-logger, and bare-holesail after kernel-logger and bare-os-www (so the static HTTP listener is up before managed Holesail tunnels target that port). Per-service try/catch, [bare-initd] name: err on failure; failures append to /var/log/bare-os/initd.log and the structured unit journal; runtime state active / failed / inactive. waitForBareInitdUnits(names, timeoutMs) polls until listed units are active (exposed as ctx.bareOsAwaitInitdUnits). Mobile Bare.suspend / Bare.wakeup walks stop handlers in reverse boot order and start hooks forward, matching the DAG snapshot in /proc/bare_os/initd_graph.json. Coalesced /proc/bare_os/metrics_live.json (and ctx.bareOsReadProcMetricsLive()) include initdReadiness (schema 2**) for unit readiness summaries.\n- listBareServices(), getBareServiceRuntime(name), findBareServiceDefinition(name), startBareService / stopBareService / restartBareService — introspection and lifecycle (used by the CLI below)\n- bareInitdShutdownActiveUnitsReverse(ctx) — REPL session.cleanup awaits this first: calls stop on every active unit with a stop handler, in reverse boot-DAG order (same direction as mobile suspend).\n- registerKernelShutdownHook(fn) + runKernelShutdownHooks() — async-friendly teardown after initd reverse stop, before disposers; then stopBareInitd() clears intervals and runs registerBareInitdDisposer callbacks.\n- registerBareInitdDisposer(fn) + stopBareInitd() — for intervals and synchronous teardown\n- Kernel logger — mirrors console.log/error to /var/log/bare-os/kernel-console.log. The VFS exposes /var as a virtual directory and maps /var/log/… onto the personal Hyperdrive at /.bare-os/var/log/… (the system image drive stays read-only). Each log file is trimmed when it grows past 512 KiB (last 256 KiB kept plus a notice line).\n\nBuilt-in kernel-logger wraps ctx.console.log / error to append UTF-8 lines to that path (with stop / restart support). startBareInitd also creates /var/log/bare-os and a short README there. Other services use the same tree (e.g. cron.log, www.log for bare-os-www). Failures to write logs are swallowed so logging never kills the session.\n\nService control: /bin/systemctl is implemented by the booter (kernel-runner delegates to systemctl-cli.js), not by eval’d image JS. Subcommands: list / list-units (shows PRESET enabled/disabled from disabled.txt), status, logs, start, stop, restart, enable, disable, is-enabled. journalctl -u UNIT (log tail only) shares the same backend. The legacy name bare-initctl is still accepted as an alias. enable / disable only affect the next startBareInitd (personal-drive config); runtime start / stop remain session commands. See man systemctl.\n\nBARE-CRON\n\nbare-cron.js registers service bare-cron:\n\n- Reads /etc/bare-os/crontab on the system image (if present), then ~/.crontab on the personal drive (silent if missing). Invalid lines are skipped and logged to /var/log/bare-os/cron.log.\n- Loads timer drop-ins from *~/.config/bare-os/timers/.timer (max 8 files): [Timer] with OnCalendar= (five cron fields) + ExecLine= — merged into the same minute tick as crontab jobs; optional JitterSec= (spread execLine within 0…N seconds); or EveryMs= (1000–86400000) + ExecLine= — fixed-interval setInterval jobs (optional JitterSec= delays the first tick); or OnInactiveSec= + ExecLine= — fire after the last timer run finishes plus an idle window (Persistent= keeps scheduling state where supported). Image examples: /etc/bare-os/timers/.timer.example on the system drive (copy into ~/.config/bare-os/timers/ and rename to .timer**).\n- Parses five-field cron lines + command remainder, @reboot + command (once per bare-cron start), and optional leading JitterSec=N on the command side for calendar lines.\n- Aligns to minute boundaries, setInterval(60s), runs await ctx.execLine(command) with per-line in-flight guard; job errors are appended to /var/log/bare-os/cron.log as well as console.error. Calendar lines use wall-clock minute ticks; EveryMs= timers use monotonic-ish setInterval spacing (not drift-corrected to NTP — see distributed time sync in /proc/bare_os when enabled). With BARE_OS_TIMER_EVERY_MS_MONOTONIC=1, EveryMs= units may prefer monotonic scheduling where the runtime supports it.\n- One disposer at module load clears timers on session shutdown; stopBareCron is also the unit stop for systemctl.\n\nInstall/list/remove user crontab with /bin/crontab (see Chapter 6 <06-kernel-and-binaries.md>). See Developer guide ch.11 <../developer-guide/11-kernel-pear-cookbook.md> for timer file layout.\n\nBARE-OPENSSH (SSHD)\n\nbare-openssh.js registers initd service bare-openssh (starts after kernel-logger and bare-cron per the default DAG). It listens with bare-ssh2 on the booter host’s net stack (not as a concatenated /bin script). /bin/sshd and /bin/bare-sshd are thin delegates that call ctx.bareOsRunSshdCli.\n\n- Config — Stock /etc/ssh/sshd_config on the system image; HostKey paths resolve on the personal drive so the read-only system tree is not required for key material.\n- Auth — OpenSSH-format authorized_keys on the personal drive (default relative path from sshd_config), optional password auth using the same account crypto as login; successful password auth calls unlockIdentity and therefore upgrades the shared session identity (same caveat as console login).\n- Sessions — Shell and exec requests run through execShellLine on a per-connection ctx clone; PTY sessions can use the fish-style REPL when the channel supports it.\n- SFTP — Subsystem sftp implements a bounded subset over ctx.vfs (unsupported operations return SSH_FX_OP_UNSUPPORTED).\n- Observability — /proc/bare_os/openssh.json (schema 1) reports listen address, port, active clients, and last error; /var/log/bare-os/openssh.log receives start/listen failures.\n- Holesail (managed) — After listen succeeds, bare-os-ssh-holesail.js idempotently merges bare-ssh- into the same managed state.json as bare-www-* (see § bare-holesail below). port / host match the actual bind (defaults 127.0.0.1:2222; BARE_OS_SSH_BIND_ALL=1 can widen the address). Set BARE_OS_SSH_HOLESAIL=0 / false to skip auto-merge. If sshd started before managed bare-holesail was up (e.g. guest boot), startBareUserSessionStack runs ensureBareOsSshHolesailTunnel again after bare-holesail starts so the tunnel can attach without restarting sshd.\n\nDisable the unit for the next boot with ~/.config/bare-os/initd/disabled.txt (same mechanism as other initd services). Host env BARE_OS_SSH_LISTEN_PORT (guest vfs.env) overrides Port / supports ephemeral 0; BARE_OS_SSH_BIND_ALL=1 maps a config ListenAddress 127.0.0.1 to 0.0.0.0 for operator overrides.\n\nImplementation touchpoint: packages/bare-os-booter/lib/bare-os-ssh-holesail.js <../packages/bare-os-booter/lib/bare-os-ssh-holesail.js> (called from bare-openssh.js <../packages/bare-os-booter/lib/bare-openssh.js> and bare-user-session-stack.js <../packages/bare-os-booter/lib/bare-user-session-stack.js>).\n\nBARE-OS-WWW (STATIC HTTP FOR ~/.WWW)\n\nbare-os-www-initd.js registers initd unit bare-os-www: a minimal HTTP/1.1 static file server for the session docroot ~/.www (resolved through the VFS). Stock defaults: listen on 127.0.0.1:8088, GET and HEAD only, safe path resolution (no ..), small extension→Content-Type map. HEAD uses vfs.stat so Content-Length matches the file size.\n\n- Enable — On by default. Disable with BARE_OS_WWW_INITD=0 / false or systemctl disable bare-os-www (~/.config/bare-os/initd/disabled.txt).\n- Env — BARE_OS_WWW_PORT (default 8088), BARE_OS_WWW_HOST (default 127.0.0.1; use 0.0.0.0 only when you intend LAN exposure without Holesail). BARE_OS_WWW_HOLESAIL=0 skips auto-merging bare-www- into managed Holesail state.json (see § bare-holesail for seed / key persistence).\n- Bootstrap — If ~/.www/index.html is missing or empty, the unit creates ~/.www/ and writes the stock landing page. The same ensureBareOsWwwHomeDefaults(ctx) helper runs after a successful login, login --new, or applyLoginKeys in identity-session.js, so operators often already have ~/.www before initd starts.\n- Holesail — When managed bare-holesail is active, after HTTP listen succeeds the booter idempotently persists bare-www- ( server: true, port, host from BARE_OS_WWW_HOST, enabled: true) into ~/.holesail/state.json by default — same seed / key rules as every other managed server row (§ bare-holesail). Opt out with BARE_OS_WWW_HOLESAIL=0.\n- Logs — /var/log/bare-os/www.log (same personal-backed tree as other bare-os logs).\n- VFS + HDMS — When an HDMS mount with label www exists at /mnt/www, logical $HOME/.www and /home//.www route to that Hyperdrive root instead of the personal home tree (see Chapter 5 <05-identity-vault-and-hdms.md>). Without that mount, ~/.www stays on the personal drive under the session home prefix.\n\nImplementation: packages/bare-os-booter/lib/bare-os-www-initd.js <../packages/bare-os-booter/lib/bare-os-www-initd.js>, bare-os-www-holesail.js <../packages/bare-os-booter/lib/bare-os-www-holesail.js> (Node uses node:http; Bare/Pear uses bare-node-http).\n\nBARE-HOLESAIL (HOLESAIL P2P PROXY)\n\nbare-holesail.js wires the upstream holesail package (AGPL-3.0) using only its public class API (no direct Hyperswarm / HyperDHT usage in this integration). Under pear run, the booter cannot bare-import('holesail') from pear: modules, so bare-holesail resolves the class from ctx.bare.holesail when the drive merge succeeded, else import.meta.resolve('holesail'), else a one-off eval of /lib/bare/bundles/holesail.js via ctx.vfs (same IIFE semantics as maybeMergeBareFromDrive).\n\n- Initd unit bare-holesail — On by default ( BARE_OS_HOLESAIL_INITD=1 and BARE_OS_HOLESAIL_MANAGED=1 in stock shellEnv unless the host sets them empty or to 0/false). Disable for a session with BARE_OS_HOLESAIL_INITD=0 or systemctl disable bare-holesail ( ~/.config/bare-os/initd/disabled.txt). Either managed multi-tunnel or single env tunnel:\n- Managed (persisted list) — Stock default (BARE_OS_HOLESAIL_MANAGED=1). Tunnel definitions live in BARE_OS_HOLESAIL_STATE. Stock default path is ~/.holesail/state.json (logical path resolved under the session $HOME / VFS); set BARE_OS_HOLESAIL_STATE to override (any logical path). If the primary file is missing or empty, legacy rows are merged once from /.bare/holesail/state.json, /.bare/holesail/guest/state.json, and /home/guest/.holesail/state.json. On unit start, every enabled connection id gets its own holesail instance. After the first full pass, the daemon yields one tick and runs a second pass that starts only connections not already running (onlyNew) so late writers (bare-os-www, bare-openssh) can add rows without destroying tunnels that started in pass one. Use guest /bin/holesail ( ctx.bareOsRunHolesailCli) to list, add, remove, start, stop, enable, disable, restart.\n- Server rows: seed and key — Stable identity uses a persisted seed: 64-character hex ctor secret (minted when missing), or a valid z32-style suffix migrated from a legacy hs://…-only row. bareHolesailManagedEnsureServerSeedPersisted normalizes rows before new Holesail(). After ready(), bareHolesailManagedSyncPersistedServerKey writes the shareable hs://… URL into key only ( seed stays the ctor secret — do not replace seed with the URL suffix alone). bareHolesailManagedNewHolesailOpts passes seed to the upstream ctor in preference to the full hs://… string when both are present. holesail list shows the live URL when the tunnel is running.\n- Stock auto-managed entries — bare-www- ( bare-os-www ) and bare-ssh- ( bare-openssh ); same state.json file and the same seed / key semantics as manual holesail add rows.\n- Single tunnel — Set BARE_OS_HOLESAIL_MANAGED=0, then exactly one of BARE_OS_HOLESAIL_SERVER=1 or BARE_OS_HOLESAIL_CLIENT=1, BARE_OS_HOLESAIL_KEY=… when in client mode, and optional BARE_OS_HOLESAIL_SECURE, BARE_OS_HOLESAIL_PORT, BARE_OS_HOLESAIL_HOST, BARE_OS_HOLESAIL_UDP, BARE_OS_HOLESAIL_LOG.\nStarts after kernel-logger and bare-os-www by default (so *bare-www- server tunnels can reach the loopback HTTP listener). Logs: /var/log/bare-os/holesail.log. Example drop-in: /etc/bare-os/units/bare-holesail.unit.example** on the system image.\n- Early booter (“kernel-path”) instance — Separate optional instance started after the repl boot phase and before startBareInitd. Enable with BARE_OS_HOLESAIL_KERNEL=1 and the *BARE_OS_HOLESAIL_KERNEL_ mirror of the options above (e.g. BARE_OS_HOLESAIL_KERNEL_SERVER=1). Uses registerKernelShutdownHook for teardown. hs.pause() / hs.resume()** run on mobile suspend/resume hooks alongside other subsystems.\n- Guest scripts — Use ctx.bare.holesail (bundled under /lib/bare/bundles/holesail.js), not require('holesail'), because /bin and /boot/init.js are not Node modules. /bin/holesail is the operator CLI for persisted tunnels (see managed mode above). See kernel/etc/bare-os/kernel.d/.README.\n\nSet BARE_OS_HOLESAIL_DEBUG=1 for extra console lines (URLs only; keys are not logged in full).\n\nSHELL SESSION, CONTROLLING TTY SKETCH, AND JOB-CONTROL GAPS\n\nThe interactive shell keeps ctx.shellSessionState: sid (session id), nextPgid (for & background jobs), foregroundPgid (set to a job’s pgid while fg awaits that job, otherwise reset toward sid after each foreground line), and controllingTty (/dev/console or ipc: when BARE_OS_SESSION_FIFO / BARE_OS_IPC_SESSION_FIFO is set). Background jobs record sid / pgid in ctx.shellBackgroundJobs for jobs output. Cooperative logical job control: suspend-job sets stopped and the background runner yields between statements until fg or bg clears it; there is still no tcsetpgrp and no host SIGTSTP/SIGCONT. Host SIGINT may arrive as bare-os:host-sigint (via optional bare-signals or process.on('SIGINT')) for cooperative cancellation; ctx.bareOsSendSignal also records PIPE / CHLD / USR1 / USR2 on synthetic PIDs without ending the session. ctx.bareOsTrySpawnHostSubprocess against bare-subprocess 6 accepts ipc: true (stdio ['pipe','pipe','pipe','ipc'], serialization: 'json') and returns ipc: Boolean(child.channel).\n\nREPL: FISH-STYLE LINE EDITOR\n\nWhen stdin/stdout are a capable TTY and BARE_OS_FISH≠0, fish-readline.js provides history, hints, and synchronized Console output so prompts and console.log do not fight. History files live on the personal drive keyed by user identity, so guests and logged-in users do not stomp each other’s command recall. Set BARE_OS_FISH=0 for minimal readline or pipes-first automation; BARE_OS_SKIP_REPL=1 skips the interactive kernel loop entirely.\n\nImplementation touchpoint: packages/bare-os-booter/lib/fish-readline.js <../packages/bare-os-booter/lib/fish-readline.js>.\n\nDEBUG\n\ndebug-repl.js and env-driven logging can trace readline and write paths—useful when stdin is a pipe vs TTY.\n\nNext: Chapter 5 — Identity, vault, HDMS <05-identity-vault-and-hdms.md>\n\nRelated: Preface — Security <00-preface.md> · Kernel extensions <../docs/reference/kernel-extensions.md> · CHANGELOG <../packages/bare-os-booter/CHANGELOG.md>\n\nExperimental research software, not a production OS. Open source under Apache-2.0. Owned, operated, and engineered by HoneyPeer, LLC, a DeKalb, Georgia limited liability company — LICENSE <../LICENSE>.","descriptionMode":"preserve","options":[],"keywords":["handbook","bare-os","documentation","narrative","chapter","04","the","booter","runtime","ctx","vfs","shell","kernel","services"],"seeAlso":[{"name":"handbook-05-identity-vault-and-hdms","section":7},{"name":"handbook-03-protocol-and-disk","section":7},{"name":"man","section":1}],"bareOsNotes":"Generated at build time from handbook/04-the-booter-runtime.md. Diagrams in ```mermaid blocks are omitted; open the Markdown in the repo for figures.","listCategory":"handbook"},{"name":"handbook-05-identity-vault-and-hdms","section":7,"title":"Chapter 5 — Identity, vault, and HDMS","synopsis":["man 7 handbook-05-identity-vault-and-hdms","Handbook chapter (plain text from handbook/05-identity-vault-and-hdms.md)"],"description":"CHAPTER 5 — IDENTITY, VAULT, AND HDMS\n\nTime to read: about 12 minutes. Prerequisites: Chapter 4 — Booter runtime <04-the-booter-runtime.md> (VFS and shell).\n\nThis chapter covers who the session is (guest vs unlocked), where keys live, encrypted vault snapshots, and extra Hyperdrives under /mnt. Cryptographic details are implemented in identity-account.js <../packages/bare-os-booter/lib/identity-account.js> and identity-session.js <../packages/bare-os-booter/lib/identity-session.js>; here we stay at prose level.\n\nEND-TO-END: FROM COLD BOOT TO AN HDMS MOUNT\n\n1. Boot — The booter applies guest defaults: USER=guest, HOME=/home/guest, no Ed25519 material in the environment. You can already read the system image and write guest-scoped paths on the personal drive.\n2. login — You provide a passphrase. If the account exists, the booter decrypts /.bare/account and derives session keys; if login --new, it mints a new Ed25519 keypair and writes a v2 blob (see below).\n3. Unlocked — HOME moves under /home/, BARE_OS_PUBLIC_KEY is set, and HDMS may attach extra Hyperdrives registered on the personal drive.\n4. hdms create / hdms add — Writable or read-only drives appear under /mnt/