Further MD Fixes
This commit is contained in:
@@ -10,22 +10,22 @@ requires: [read_file, read_proc_file, run_js_script]
|
||||
|
||||
## When to use
|
||||
|
||||
Use this skill when you (or the user) need to **author or debug** Bare OS **JavaScript** that runs **inside the guest** (kernel init, `/bin/*` utilities, `kernel.ext.d`, user `.mjs` run via **`run_js_script**`, or Pear/booter-hosted scripts). It complements repo docs: treat `**developer-guide/02-the-context-object.md**` and `**packages/bare-os-booter/lib/bare-os-ctx.d.ts`** as the canonical deep dives; this file is the **fast mental model**.
|
||||
Use this skill when you (or the user) need to **author or debug** Bare OS **JavaScript** that runs **inside the guest** (kernel init, `/bin/*` utilities, `kernel.ext.d`, user `.mjs` run via **`run_js_script`**, or Pear/booter-hosted scripts). It complements repo docs: treat **`developer-guide/02-the-context-object.md`** and **`packages/bare-os-booter/lib/bare-os-ctx.d.ts`** as the canonical deep dives; this file is the **fast mental model**.
|
||||
|
||||
## Core model
|
||||
|
||||
1. **Entrypoints** — Kernel: **`async function start(ctx)`** in `/boot/init.js` (or your image). Commands: **`async function run(ctx, argv)**` where `**argv[0]`** is the invoked name (e.g. `agent`). You **must** set **`ctx.exitCode`** (number) before returning on failure paths.
|
||||
2. **`ctx` is not Node** — There is no full **`process**`, no `**require('node:fs')**`. The booter assembles `**ctx**` as the narrow **syscall surface**: `**vfs**`, `**env**`, `**execLine**`, `**runBinCommand**`, optional `**httpFetch**`, `**bare`**, identity helpers, diagnostics, etc. See the mermaid overview in Chapter 2 of the developer guide.
|
||||
3. **`/bin/agent` is special** — The agent bundle uses **`run_js_script**` for guest JS and a frozen tool surface; do not assume `**node**` exists. For **general** in-guest scripting, prefer `**ctx.vfs**` + `**ctx.execLine**` / `**ctx.runBinCommand**` and optional `**ctx.bare.*`** modules when enabled.
|
||||
2. **`ctx` is not Node** — There is no full **`process`**, no `**require('node:fs')**`. The booter assembles **`ctx`** as the narrow **syscall surface**: **`vfs`**, **`env`**, **`execLine`**, **`runBinCommand`**, optional **`httpFetch`**, **`bare`**, identity helpers, diagnostics, etc. See the mermaid overview in Chapter 2 of the developer guide.
|
||||
3. **`/bin/agent` is special** — The agent bundle uses **`run_js_script`** for guest JS and a frozen tool surface; do not assume **`node`** exists. For **general** in-guest scripting, prefer **`ctx.vfs`** + **`ctx.execLine`** / **`ctx.runBinCommand`** and optional **`ctx.bare.*`** modules when enabled.
|
||||
|
||||
## Writing scripts (`run(ctx, argv)`)
|
||||
|
||||
- **Argv** — `argv` is a string array; **`argv[0]`** is how you were invoked (symlink name matters for multi-call binaries).
|
||||
- **Stdout** — Prefer **`ctx.console.log**` / `**ctx.console.error**` (session-aware). For binary or captured stdout, `**ctx.bareOsBinWrite`** may exist when the shell captures pipeline output.
|
||||
- **Shell a subprocess** — **`await ctx.execLine('some shell line', { signal, timeoutMs })**` returns a string (see booter `**raceWithAbortAndTimeout**`). Heavy work: `**await ctx.runBinCommand(['/bin/grep', …], opts)`** for same resolution as the interactive shell.
|
||||
- **Filesystem** — **`await ctx.vfs.readFile(path)**` → `**Uint8Array**`; `**await ctx.vfs.writeFile(path, buf, opts?)**`. Decode with `**ctx.b4a.toString(buf)**` or `**TextDecoder**`. Always use **absolute** paths under `**/home**`, `**/tmp**`, `**/mnt**`, `**/bin`**, etc., per policy.
|
||||
- **Environment** — **`ctx.env**` is mutable shell state (also `**ctx.vfs.env**`). After `**execLine**`, `**ctx.env.BARE_OS_EXIT_STATUS`** reflects last exit code when the booter sets it.
|
||||
- **Exit** — Set **`ctx.exitCode = 1**` (or other code) on error; `**0**` on success. `**ctx.requestBooterExit(code)**` ends the whole session from builtins like `**exit`**.
|
||||
- **Stdout** — Prefer **`ctx.console.log`** / **`ctx.console.error`** (session-aware). For binary or captured stdout, **`ctx.bareOsBinWrite`** may exist when the shell captures pipeline output.
|
||||
- **Shell a subprocess** — **`await ctx.execLine('some shell line', { signal, timeoutMs })**` returns a string (see booter **`raceWithAbortAndTimeout`**). Heavy work: `**await ctx.runBinCommand(['/bin/grep', …], opts)`** for same resolution as the interactive shell.
|
||||
- **Filesystem** — **`await ctx.vfs.readFile(path)**` → **`Uint8Array`**; `**await ctx.vfs.writeFile(path, buf, opts?)**`. Decode with `**ctx.b4a.toString(buf)**` or **`TextDecoder`**. Always use **absolute** paths under **`/home`**, **`/tmp`**, **`/mnt`**, **`/bin`**, etc., per policy.
|
||||
- **Environment** — **`ctx.env`** is mutable shell state (also **`ctx.vfs.env`**). After **`execLine`**, **`ctx.env.BARE_OS_EXIT_STATUS`** reflects last exit code when the booter sets it.
|
||||
- **Exit** — Set **`ctx.exitCode = 1**` (or other code) on error; **`0`** on success. `**ctx.requestBooterExit(code)**` ends the whole session from builtins like **`exit`**.
|
||||
|
||||
## Building “apps” (long-lived behaviour)
|
||||
|
||||
@@ -33,46 +33,46 @@ Think in layers the stock OS already uses:
|
||||
|
||||
| Layer | Mechanism | Notes |
|
||||
| --- | --- | --- |
|
||||
| **Init** | **`bareOsRegisterBootStepHook**`, initd units | Boot-order DAG (stock: `**bare-os-www**` before `**bare-holesail**` so `**bare-www-***` reaches loopback HTTP; `**bare-openssh**` + login stack ensure `**bare-ssh-***` in `**~/.holesail/state.json**`); pair `**registerKernelShutdownHook`** / initd disposers for teardown. |
|
||||
| **Virtual files** | **`bareOsRegisterVirtualFile(name, reader, opts?)**` | Serves `**/run/bare-os/virtual/<name>`**; gated by runtime caps. |
|
||||
| **IPC** | **`ctx.bareOsIpc**` when present | `**push`/`take**`, JSON helpers, fanout, duplex bridge — bounded; audit when `**BARE_OS_IPC_AUDIT=1`**. |
|
||||
| **Kernel extensions** | **`bareOsRegisterKernelExtensionRecord**`, `**bareOsRunImageScript**` under `**/lib/bare-os/extensions/`** | Trusted image paths only. |
|
||||
| **Sandboxed user JS** | **`bareOsSandboxRunScript(source, argv?, opts?)**` | Restricted `**ctx**`; disable with `**BARE_OS_SANDBOX_SCRIPT=0`**. |
|
||||
| **Pear / host** | **`bareOsPearIpcEmit**`, `**bareOsPearIpcRequest**`, mirror/export hints | Host must cooperate; return `**{ ok, hint }`** patterns. |
|
||||
| **Init** | **`bareOsRegisterBootStepHook`**, initd units | Boot-order DAG (stock: **`bare-os-www`** before **`bare-holesail`** so **`bare-www-*`** reaches loopback HTTP; **`bare-openssh`** + login stack ensure **`bare-ssh-*`** in **`~/.holesail/state.json`**); pair **`registerKernelShutdownHook`** / initd disposers for teardown. |
|
||||
| **Virtual files** | **`bareOsRegisterVirtualFile(name, reader, opts?)**` | Serves **`/run/bare-os/virtual/<name>`**; gated by runtime caps. |
|
||||
| **IPC** | **`ctx.bareOsIpc`** when present | `**push`/`take**`, JSON helpers, fanout, duplex bridge — bounded; audit when **`BARE_OS_IPC_AUDIT=1`**. |
|
||||
| **Kernel extensions** | **`bareOsRegisterKernelExtensionRecord`**, **`bareOsRunImageScript`** under **`/lib/bare-os/extensions/`** | Trusted image paths only. |
|
||||
| **Sandboxed user JS** | **`bareOsSandboxRunScript(source, argv?, opts?)**` | Restricted **`ctx`**; disable with **`BARE_OS_SANDBOX_SCRIPT=0`**. |
|
||||
| **Pear / host** | **`bareOsPearIpcEmit`**, **`bareOsPearIpcRequest`**, mirror/export hints | Host must cooperate; return `**{ ok, hint }`** patterns. |
|
||||
|
||||
Before touching sensitive **`ctx**` methods in hardened images, call `**ctx.bareOsIsCtxMethodAllowed?.(name)**` when boot policy `**BARE_OS_BOOT_POLICY_ALLOWED_CTX_METHODS`** is set.
|
||||
Before touching sensitive **`ctx`** methods in hardened images, call `**ctx.bareOsIsCtxMethodAllowed?.(name)**` when boot policy **`BARE_OS_BOOT_POLICY_ALLOWED_CTX_METHODS`** is set.
|
||||
|
||||
## `ctx` field map (cheat sheet)
|
||||
|
||||
**Always read live truth** for capability bits: **`read_proc_file**` on `**/proc/bare_os/features**` and `**/proc/bare_os/capabilities.json**` — do not infer from man pages alone (see `**bare-os-kernel-proc`** skill).
|
||||
**Always read live truth** for capability bits: **`read_proc_file`** on **`/proc/bare_os/features`** and **`/proc/bare_os/capabilities.json`** — do not infer from man pages alone (see **`bare-os-kernel-proc`** skill).
|
||||
|
||||
### Files, drives, process
|
||||
|
||||
- **`ctx.vfs**` — `**readFile**`, `**writeFile**`, `**mkdir**`, `**readdir**`, `**stat`/`lstat**`, `**chmod**`, … Path routing: system vs **personal** Hyperdrive; `**ctx.drive**` vs `**ctx.personalDrive`** for advanced use.
|
||||
- **`ctx.env**`, `**ctx.drive**`, `**ctx.personalDrive**`, `**ctx.disk`** — Session identity and mounts.
|
||||
- **`ctx.execLine**`, `**ctx.runBinCommand`** — Shell and `/bin` execution with shared policy (timeouts, abort).
|
||||
- **`ctx.vfs`** — **`readFile`**, **`writeFile`**, **`mkdir`**, **`readdir`**, `**stat`/`lstat**`, **`chmod`**, … Path routing: system vs **personal** Hyperdrive; **`ctx.drive`** vs **`ctx.personalDrive`** for advanced use.
|
||||
- **`ctx.env`**, **`ctx.drive`**, **`ctx.personalDrive`**, **`ctx.disk`** — Session identity and mounts.
|
||||
- **`ctx.execLine`**, **`ctx.runBinCommand`** — Shell and `/bin` execution with shared policy (timeouts, abort).
|
||||
|
||||
### Bytes, console, session
|
||||
|
||||
- **`ctx.b4a`** — Buffer/string helpers for Hyperdrive payloads.
|
||||
- **`ctx.console**`, `**ctx.readLine**`, `**ctx.writeScreen**` — REPL session ( `**readLine`** may be Fish-backed when enabled).
|
||||
- **`ctx.exitCode**`, `**ctx.requestBooterExit**`, `**ctx.registerKernelShutdownHook`**
|
||||
- **`ctx.console`**, **`ctx.readLine`**, **`ctx.writeScreen`** — REPL session ( **`readLine`** may be Fish-backed when enabled).
|
||||
- **`ctx.exitCode`**, **`ctx.requestBooterExit`**, **`ctx.registerKernelShutdownHook`**
|
||||
|
||||
### Bare OS introspection & policy
|
||||
|
||||
- **`ctx.bareOsCtxApiVersion**`, `**ctx.bareOsRuntimeCaps`** (frozen)
|
||||
- **`ctx.bareOsAdvertisedKernelCapabilityWords**`, `**ctx.bareOsSeedKernelCapabilityWords**` — `**>>> 0`** when testing bits.
|
||||
- **`ctx.bareOsGetResourceStatus**`, `**ctx.bareOsReadProcMetricsLive**`, `**ctx.bareOsReadBareTopSnapshot`**
|
||||
- **`ctx.bareOsRegisterVirtualFile**`, `**ctx.bareOsInvalidateVirtualFile**`, `**ctx.bareOsUpdateVirtualFileMeta`**
|
||||
- **`ctx.bareOsEmitIpcAudit**`, `**ctx.bareOsEvaluatePeerAdmission**`, `**ctx.bareOsEmitMirrorDriveHint`**
|
||||
- **`ctx.bareOsCtxApiVersion`**, **`ctx.bareOsRuntimeCaps`** (frozen)
|
||||
- **`ctx.bareOsAdvertisedKernelCapabilityWords`**, **`ctx.bareOsSeedKernelCapabilityWords`** — `**>>> 0`** when testing bits.
|
||||
- **`ctx.bareOsGetResourceStatus`**, **`ctx.bareOsReadProcMetricsLive`**, **`ctx.bareOsReadBareTopSnapshot`**
|
||||
- **`ctx.bareOsRegisterVirtualFile`**, **`ctx.bareOsInvalidateVirtualFile`**, **`ctx.bareOsUpdateVirtualFileMeta`**
|
||||
- **`ctx.bareOsEmitIpcAudit`**, **`ctx.bareOsEvaluatePeerAdmission`**, **`ctx.bareOsEmitMirrorDriveHint`**
|
||||
|
||||
### Optional / host-dependent
|
||||
|
||||
- **`ctx.httpFetch**` — Same allow/deny policy as `**curl**` / `**wget**`; every host for `**web_fetch`** must be allowlisted.
|
||||
- **`ctx.bare**` — Frozen map of vendored modules (`**b4a**`, `**protomux**`, …) when `**BARE_OS_BARE_MODULES`** allows.
|
||||
- **`ctx.bareOsHostStats**`, `**ctx.bareOsChat***`, `**ctx.bareOsPearIpc*`** — Present only when wired by the booter/host.
|
||||
- **`ctx.httpFetch`** — Same allow/deny policy as **`curl`** / **`wget`**; every host for **`web_fetch`** must be allowlisted.
|
||||
- **`ctx.bare`** — Frozen map of vendored modules (**`b4a`**, **`protomux`**, …) when **`BARE_OS_BARE_MODULES`** allows.
|
||||
- **`ctx.bareOsHostStats`**, **`ctx.bareOsChat*`**, **`ctx.bareOsPearIpc*`** — Present only when wired by the booter/host.
|
||||
|
||||
For the **full** list and semantics, open **`developer-guide/02-the-context-object.md**` in the repo (or `**read_file`** on a mounted checkout).
|
||||
For the **full** list and semantics, open **`developer-guide/02-the-context-object.md`** in the repo (or **`read_file`** on a mounted checkout).
|
||||
|
||||
## Minimal script template (guest)
|
||||
|
||||
@@ -103,22 +103,22 @@ export async function run(ctx, argv) {
|
||||
}
|
||||
```
|
||||
|
||||
Save under **`/home/.../my-tool.mjs**` and run by **absolute path** (or register under `**/bin**` on the image). **Do not** rely on `**node`** in the guest.
|
||||
Save under **`/home/.../my-tool.mjs`** and run by **absolute path** (or register under **`/bin`** on the image). **Do not** rely on **`node`** in the guest.
|
||||
|
||||
## Agent-specific note
|
||||
|
||||
When helping **inside `/bin/agent`**, the model uses **tools** (`read_file`, `run_js_script`, …) backed by the **same** personal/system VFS as the rest of the guest. **`run_js_script**` writes a temp `**.mjs**` under `**~/.agent/**` and executes it like a `**/bin**` script — the script body should use the same `**ctx**` patterns above when the harness passes `**ctx`**.
|
||||
When helping **inside `/bin/agent`**, the model uses **tools** (`read_file`, `run_js_script`, …) backed by the **same** personal/system VFS as the rest of the guest. **`run_js_script`** writes a temp **`.mjs`** under **`~/.agent/`** and executes it like a **`/bin`** script — the script body should use the same **`ctx`** patterns above when the harness passes **`ctx`**.
|
||||
|
||||
## Checklist before shipping
|
||||
|
||||
1. **`read_proc_file**` / `**get_system_info`** — confirm needed **features** and **caps** exist this session.
|
||||
1. **`read_proc_file`** / **`get_system_info`** — confirm needed **features** and **caps** exist this session.
|
||||
2. **Paths** — absolute, no **`..`** escape from allowed roots.
|
||||
3. **Timeouts** — pass **`AbortSignal**` / `**timeoutMs**` to `**execLine**` / `**readLine`** for network or slow FS.
|
||||
3. **Timeouts** — pass **`AbortSignal`** / **`timeoutMs`** to **`execLine`** / **`readLine`** for network or slow FS.
|
||||
4. **Teardown** — unregister hooks, clear intervals, dispose IPC fanout subscribers.
|
||||
5. **Secrets** — never log **`~/.agent/config.json**` or keys; redact in `**MEMORY.md`**.
|
||||
5. **Secrets** — never log **`~/.agent/config.json`** or keys; redact in **`MEMORY.md`**.
|
||||
|
||||
## Output format (when this skill was used)
|
||||
|
||||
- **What you read** — which **`ctx**` fields or `**/proc`** files grounded the answer.
|
||||
- **What you read** — which **`ctx`** fields or **`/proc`** files grounded the answer.
|
||||
- **Plan** — file paths, entrypoint (`run` vs `start`), and exit semantics.
|
||||
- **Risks** — policy gates, missing caps, host-only APIs.
|
||||
|
||||
Reference in New Issue
Block a user