feat(booter): disk.os bridge, systemctl ctx API, delegates, and docs
- Add createBareOsDiskOsBridge for Hyperdrive searchLocal + whitelisted bare_os.* execRpc; wire disk.os after initd - Expose ctx.bareOsRunSystemctlCli; route /bin/systemctl and journalctl through it (sync seeder kernel/bin) - Implement ssh-keygen passphrase envelope (bareOsKeySchema 2, PBKDF2 + ChaCha20-Poly1305); add warc and archive delegates - Extend basenc (--base32/--base64); improve hostid/users session UX - Introduce bare-os-boot-phases, bare-os-errors; CI boot-step alignment - Bump BARE_OS_CTX_API_VERSION to 1.28.0; update ctx d.ts and verifiers - Add KERNEL_CONTRACT, OTA_AND_BUNDLES, PLACEHOLDER_BASELINE; handbook disk.os + security hooks; reference docs and CHANGELOG
This commit is contained in:
@@ -33,6 +33,9 @@ The file-by-file inventory that used to live in a single monolith is now split u
|
||||
- **[Documentation hub](docs/README.md)** — `docs/` tree: reference index, catalog, themes.
|
||||
- **[Handbook](handbook/README.md)** — narrative architecture and operations.
|
||||
- **[Developer guide](developer-guide/README.md)** — extending the image, `ctx`, coreutils, testing.
|
||||
- **[Kernel architecture contract](docs/architecture/KERNEL_CONTRACT.md)** — booter vs image boundaries, boot steps, typed errors.
|
||||
- **[OTA and bundles](docs/deployment/OTA_AND_BUNDLES.md)** — Bare/Pear packaging hooks for operators.
|
||||
- **[Placeholder baseline (audit)](docs/audit/PLACEHOLDER_BASELINE.md)** — classified incomplete surfaces and closure notes.
|
||||
- **Legacy ↔ canonical names** — [`docs/reference/naming-alias-matrix.md`](docs/reference/naming-alias-matrix.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -14,6 +14,8 @@ This project is **experimental research software**. APIs described here follow t
|
||||
|
||||
**Contract checks:** changing **`bareOsCtxApiVersion`** or stock kernel feature bits should keep **`scripts/verify-ctx-api-feature-bits.mjs`** green (invoked from root **`pretest`**).
|
||||
|
||||
**Architecture contract (boundaries):** [`docs/architecture/KERNEL_CONTRACT.md`](../docs/architecture/KERNEL_CONTRACT.md) — booter vs guest image, **`disk.os`** RPC, boot step IDs.
|
||||
|
||||
---
|
||||
|
||||
## On this page
|
||||
|
||||
@@ -24,6 +24,9 @@ This directory is the **`docs/`** tree: reference material, JSON catalog inputs,
|
||||
## Reference
|
||||
|
||||
- **[Reference hub](reference/README.md)** — file-level inventory (packages, kernel tree, environment appendix, data-flow diagram). Split from the former root `DOCUMENTATION.md`.
|
||||
- **[Kernel architecture contract](architecture/KERNEL_CONTRACT.md)** — booter vs guest image boundaries, boot step IDs, typed errors.
|
||||
- **[Audit baseline](audit/PLACEHOLDER_BASELINE.md)** — classified incomplete surfaces (incl. vendored bundles).
|
||||
- **[OTA and bundles](deployment/OTA_AND_BUNDLES.md)** — Bare/Pear packaging notes for releases.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Kernel architecture contract (stock booter + guest image)
|
||||
|
||||
This document is the **single overview** of how the Bare OS “kernel” is split between the **host booter** (`packages/bare-os-booter`) and the **guest system image** (`kernel/` staged to Hyperdrive). Detailed behavior lives in the handbook and developer guide; this file defines **boundaries and naming** only.
|
||||
|
||||
## Subsystems
|
||||
|
||||
| Subsystem | Owner | Responsibility |
|
||||
|-----------|--------|------------------|
|
||||
| **Wire + disk I/O** | Booter | Hyperswarm, Protomux, `SwarmDisk`, Corestore, Hyperdrive open/replicate |
|
||||
| **VFS + policy** | Booter | `createVfs`, path classes, mounts, synthetic `/proc` |
|
||||
| **Identity / vault** | Booter + bins | Session env, account file, `login` / `savevault` flows |
|
||||
| **Init / services** | Booter | `bare-initd`, `systemctl` delegate, unit files |
|
||||
| **Guest shell + `/bin`** | Image + booter | Hyperdrive-resident scripts; host delegates for selected CLIs |
|
||||
| **Extensions** | Image | `kernel.ext.d`, manifests; resolver in booter |
|
||||
| **Peer search / OS RPC** | Booter | `disk.os` after initd (`bare-os-disk-os-bridge.js`) |
|
||||
|
||||
## Boot steps (booter)
|
||||
|
||||
Canonical identifiers: `BARE_OS_BOOTER_BOOT_STEPS` in [`packages/bare-os-booter/lib/bare-os-boot-phases.js`](../../packages/bare-os-booter/lib/bare-os-boot-phases.js). Emitted in order: **`vfs`** → **`ctx`** → **`repl`** → **`initd`** → **`kernel_invoke`**.
|
||||
|
||||
## Context API
|
||||
|
||||
- Version: **`BARE_OS_CTX_API_VERSION`** in [`packages/bare-os-booter/lib/bare-os-ctx-api.js`](../../packages/bare-os-booter/lib/bare-os-ctx-api.js).
|
||||
- Type hints: [`packages/bare-os-booter/lib/bare-os-ctx.d.ts`](../../packages/bare-os-booter/lib/bare-os-ctx.d.ts).
|
||||
|
||||
## Typed errors (for callers)
|
||||
|
||||
Shared error classes (stable `code` field): [`packages/bare-os-booter/lib/bare-os-errors.js`](../../packages/bare-os-booter/lib/bare-os-errors.js).
|
||||
|
||||
## Related docs
|
||||
|
||||
- [Handbook — protocol and disk](../../handbook/03-protocol-and-disk.md)
|
||||
- [Handbook — booter runtime](../../handbook/04-the-booter-runtime.md)
|
||||
- [Compatibility matrix](../reference/compatibility-matrix.md)
|
||||
- [Placeholder baseline (audit)](../audit/PLACEHOLDER_BASELINE.md)
|
||||
@@ -0,0 +1,51 @@
|
||||
# Placeholder and incomplete-code baseline (authoritative)
|
||||
|
||||
This document classifies incomplete surfaces as of the kernel hardening pass. It is the reference for risk triage and closure tracking.
|
||||
|
||||
## Severity legend
|
||||
|
||||
- **P0**: Affects trust, boot, security, or remote RPC surfaces.
|
||||
- **P1**: User-visible CLI or guest `/bin` behavior diverges from documented contracts.
|
||||
- **P2**: Operational or developer-experience gaps.
|
||||
- **P3**: Third-party generated artifacts; behavior owned by upstream Bare/Holepunch bundles.
|
||||
|
||||
## P0 — Host RPC and swarm disk (`disk.os`)
|
||||
|
||||
| Item | Location | Resolution |
|
||||
| ---------------------------- | ------------------------------------------------------------------------ | ---------- |
|
||||
| Empty `searchLocal` / `execRpc` | `packages/bare-os-booter/index.js` (wired via `bare-os-disk-os-bridge.js`) | Implemented: path substring search on system Hyperdrive; whitelisted `bare_os.*` RPC methods. |
|
||||
|
||||
## P1 — Guest `/bin` and host delegates
|
||||
|
||||
| Item | Location | Resolution |
|
||||
| ---------------------------- | --------------------------------------------- | ---------- |
|
||||
| `systemctl` / `journalctl` error-only scripts | `kernel/bin/systemctl`, `kernel/bin/journalctl` | Implemented: call `ctx.bareOsRunSystemctlCli` when present (parity with `curl`). |
|
||||
| `ssh-keygen` passphrase rejection | `packages/bare-os-booter/lib/ssh-keygen-cli.js` | Implemented: PBKDF2 + ChaCha20-Poly1305 sealed envelope (`bareOsKeySchema: 2`). |
|
||||
| `basenc` base16-only messaging | `packages/bare-os-coreutils/src/basenc.js` | Implemented: `--base64` / `--base32` (RFC-style) in addition to `--base16`. |
|
||||
| `hostid` / `users` “stub” UX | `packages/bare-os-coreutils/src/hostid.js`, `users.js` | Implemented: stable hostid from Ed25519 public key when identity unlocked; `users` documents active session. |
|
||||
| WARC / archive delegates labeled placeholder | `packages/bare-os-booter/lib/host-delegate-registry.js` | Implemented: `warc-cli.js`, `archive-cli.js` (archive maps to ustar `tar`). |
|
||||
| hrpc / bundlebee / sidecar / pear_runtime_matrix | `host-delegate-registry.js` | Remain **host-wired**: `shouldDelegate` false; messages describe required host bridge (no doc-only placeholder errors for warc/archive). |
|
||||
|
||||
## P2 — Scripts and documentation
|
||||
|
||||
| Item | Location | Notes |
|
||||
| ---------------------------- | --------------------------- | ----- |
|
||||
| `gen-ctx-client-stub.mjs` name | `scripts/` | Generates client helper; naming is historical. |
|
||||
| Man / reference “placeholder” prose | `docs/`, `kernel/share/man/` | Tracked for alignment with implemented behavior. |
|
||||
|
||||
## P3 — Vendored `kernel/lib/bare/bundles/*.js`
|
||||
|
||||
Upstream-generated IIFEs may contain `TODO` comments, `NOT_IMPLEMENTED` helpers, and abstract stream throws. These are **not** first-party kernel policy; they are rebuilt from `bare-os-bare-libs` and mirrored under `packages/bare-os-seeder/kernel/`. Closure strategy: upstream version bumps, selective excludes, or post-process policy documented in `kernel/lib/bare/README.md`.
|
||||
|
||||
## Subsystem matrix
|
||||
|
||||
| Subsystem | First-party status | Bundle / vendor |
|
||||
| ----------- | ------------------ | --------------- |
|
||||
| Booter / ctx | Hardened in this pass | — |
|
||||
| Protocol | No TODO scan in this file | Wire contracts in `bare-os-protocol` |
|
||||
| Guest kernel (`kernel/lib/boot`) | CI: `verify-runtime-no-incomplete-markers.mjs` | — |
|
||||
| Coreutils | basenc / hostid / users updated | — |
|
||||
|
||||
## Review cadence
|
||||
|
||||
Re-run a full-repo scan before each release and append a dated section here when new gaps are introduced or closed.
|
||||
@@ -0,0 +1,29 @@
|
||||
# OTA updates, bundles, and reproducible artifacts
|
||||
|
||||
Bare OS aligns with the **Holepunch** toolchain for shipping JavaScript as **Bare bundles** and (where applicable) **Pear**-style drives. This note ties upstream packages to operator workflows.
|
||||
|
||||
## Upstream primitives
|
||||
|
||||
| Package | Role |
|
||||
|---------|------|
|
||||
| **bare-pack** / **bare-bundle** | Resolve module graph → single bundle artifact (`imports`, `resolutions`, addons, assets). |
|
||||
| **bare-build** | Platform packaging (desktop/mobile) around Bare runtimes. |
|
||||
| **bare-run** | Cross-target execution of packed graphs for CI and device labs. |
|
||||
| **pear-pack** / **pear-bundle** | Pear drive staging; prebuild maps for multi-arch. |
|
||||
| **pear-runtime** (+ **pear-runtime-updater**) | Embeddable OTA patterns (experimental upstream; mirror concepts in boot policy). |
|
||||
|
||||
## Bare OS integration
|
||||
|
||||
- **System image**: `kernel/` is staged to the **system Hyperdrive** by **`bare-os-seeder`**; the booter never falls back to a git checkout for production boot.
|
||||
- **Ctx / API semver**: bump **`BARE_OS_CTX_API_VERSION`** when guest-visible `ctx` behavior changes; record it in [compatibility-matrix.md](../reference/compatibility-matrix.md).
|
||||
- **Offline / LKG**: document **`BARE_OS_OFFLINE_LKG_BOOT`** and related env in [environment appendix](../reference/environment-and-posix-appendix.md).
|
||||
|
||||
## Reproducibility checklist
|
||||
|
||||
1. Pin workspace dependency versions (lockfile).
|
||||
2. Run **`npm run pretest`** before tag (bundle kernel, verify seeder parity, manifest smoke).
|
||||
3. Record **`bareOsCtxApiVersion`**, **`BARE_OS_KERNEL_FEATURE_BITS_DOC`**, and **`BARE_OS_LIFECYCLE_SCHEMA_VERSION`** in release notes (see compatibility matrix).
|
||||
|
||||
## Future work
|
||||
|
||||
Delta OTA, A/B slots, and signed rollback indices are **roadmap** items; track against [kernel program](../../handbook/11-kernel-program-and-research.md) batches and capability words.
|
||||
@@ -12,6 +12,9 @@ This directory holds the split **file-by-file inventory** that used to live in t
|
||||
| Day-to-day use | [Users manual](../../users-manual/README.md) |
|
||||
| File-level inventory | This directory (`docs/reference/`) |
|
||||
| JSON Schemas | [`docs/schemas/`](../schemas/) |
|
||||
| Kernel contract (boundaries) | [`docs/architecture/KERNEL_CONTRACT.md`](../architecture/KERNEL_CONTRACT.md) |
|
||||
| Audit baseline | [`docs/audit/PLACEHOLDER_BASELINE.md`](../audit/PLACEHOLDER_BASELINE.md) |
|
||||
| OTA / bundles (operators) | [`docs/deployment/OTA_AND_BUNDLES.md`](../deployment/OTA_AND_BUNDLES.md) |
|
||||
| CI / verifiers | [`scripts/README.md`](../../scripts/README.md) |
|
||||
|
||||
---
|
||||
@@ -32,6 +35,9 @@ This directory holds the split **file-by-file inventory** that used to live in t
|
||||
- **Package: bare-os-booter** (former §§12.1–12.9) — [Package: bare-os-booter](package-bare-os-booter.md)
|
||||
- **bare-os-coreutils, tests, and seeder build hook** (former §§12.10–12.12) — [bare-os-coreutils, tests, and seeder build hook](package-bare-os-coreutils-and-ci.md)
|
||||
- **Architecture: end-to-end data flow** (former §13) — [Architecture: end-to-end data flow](architecture-data-flow.md)
|
||||
- **Kernel architecture contract** (booter vs image, boot steps) — [KERNEL_CONTRACT.md](../architecture/KERNEL_CONTRACT.md)
|
||||
- **Placeholder / stub audit baseline** — [PLACEHOLDER_BASELINE.md](../audit/PLACEHOLDER_BASELINE.md)
|
||||
- **OTA and Bare/Pear bundles** — [OTA_AND_BUNDLES.md](../deployment/OTA_AND_BUNDLES.md)
|
||||
- **Environment variables and POSIX appendix** (former §14, §14a) — [Environment variables and POSIX appendix](environment-and-posix-appendix.md)
|
||||
- **Kernel feature bits and handshake** — [Kernel extensions](kernel-extensions.md)
|
||||
- **Bits, env, `/proc`, and `ctx` map** — [Kernel capabilities index](kernel-capabilities-index.md)
|
||||
|
||||
@@ -14,7 +14,7 @@ Single place to compare **protocol**, **booter `ctx` API**, **feature-bit docume
|
||||
|
||||
## Version artifacts
|
||||
|
||||
**`bareOsCtxApiVersion`** (current stock: **`1.25.0`**) — Defined in [`packages/bare-os-booter/lib/bare-os-ctx-api.js`](../../packages/bare-os-booter/lib/bare-os-ctx-api.js). This is the semver string for the documented **`ctx`** contract; bump it when stable guest-visible behavior changes.
|
||||
**`bareOsCtxApiVersion`** (current stock: **`1.28.0`**) — Defined in [`packages/bare-os-booter/lib/bare-os-ctx-api.js`](../../packages/bare-os-booter/lib/bare-os-ctx-api.js). This is the semver string for the documented **`ctx`** contract; bump it when stable guest-visible behavior changes.
|
||||
|
||||
**`BARE_OS_KERNEL_FEATURE_BITS_DOC`** (current stock: **`15`**) — Exported from [`packages/bare-os-protocol/lib/kernel-feature-bits.js`](../../packages/bare-os-protocol/lib/kernel-feature-bits.js). It versions the feature-bit documentation and related governance; keep it aligned with [`developer-guide/adr/001-kernel-feature-bits-governance.md`](../../developer-guide/adr/001-kernel-feature-bits-governance.md).
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ Former **DOCUMENTATION.md** §§12.1–12.9 (runtime, VFS, shell, identity). [Re
|
||||
|
||||
**`runBinCommand(ctx, argv)`**
|
||||
|
||||
- **Host delegates first** — [`host-delegate-registry.js`](../../packages/bare-os-booter/lib/host-delegate-registry.js) registers **`git`**, **`curl`**, **`wget`**, and **`systemctl`** / **`bare-initctl`** / **`journalctl`** with **static** imports of the CLI modules (Pear-safe). Each delegate checks **`BARE_OS_DELEGATE_ALLOW`**; denied kinds exit **126**. **`curl`** and **`wget`** are Fetch-based subsets (not libcurl / full GNU wget); **`/bin/curl`** and **`/bin/wget`** on the image are **stubs** for manifest parity—see [HTTP: curl and wget](http-curl-and-wget.md).
|
||||
- **Host delegates first** — [`host-delegate-registry.js`](../../packages/bare-os-booter/lib/host-delegate-registry.js) registers **`git`**, **`curl`**, **`wget`**, **`openssl`**, **`ssh-keygen`**, **`tar`**, **`systemctl`** / **`bare-initctl`** / **`journalctl`**, **`warc`**, and **`archive`** (ustar front-end) with **static** imports (Pear-safe). Each delegate checks **`BARE_OS_DELEGATE_ALLOW`**; denied kinds exit **126**. **`curl`** and **`wget`** are Fetch-based subsets (not libcurl / full GNU wget); **`/bin/curl`** and **`/bin/wget`** on the image call **`ctx.bareOsRunCurlCli`** / **`ctx.bareOsRunWgetCli`** when present—see [HTTP: curl and wget](http-curl-and-wget.md). **`/bin/systemctl`** and **`/bin/journalctl`** call **`ctx.bareOsRunSystemctlCli`** when present (same backend as the host delegate).
|
||||
- If **`argv[0]`** is **`git`** (or a POSIX path whose basename is `git`, but not `./git` or `../git`), **delegates** to **`runGitCli`** in [`git-cli.js`](../../packages/bare-os-booter/lib/git-cli.js).
|
||||
- If **`argv[0]`** is **`curl`** under the same basename rules, **delegates** to **`runCurlCli`** in [`curl-cli.js`](../../packages/bare-os-booter/lib/curl-cli.js).
|
||||
- If **`argv[0]`** is **`wget`** under the same basename rules, **delegates** to **`runWgetCli`** in [`wget-cli.js`](../../packages/bare-os-booter/lib/wget-cli.js).
|
||||
|
||||
@@ -91,6 +91,25 @@ The **important** path for boot is **0/1** plus **Hyperdrive replication** on th
|
||||
|
||||
---
|
||||
|
||||
## Booter `disk.os` bridge (after initd)
|
||||
|
||||
Once **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:
|
||||
|
||||
- **`searchLocal(query)`** — case-insensitive **substring** match over **system Hyperdrive** paths (recursive list, capped), returned on **message 4**.
|
||||
- **`execRpc(module, method, args)`** — whitelisted **`bare_os.*`** calls only, UTF-8 result string on **message 6**:
|
||||
- **`bare_os.ping`** → `pong`
|
||||
- **`bare_os.ctx_api_version`** → `BARE_OS_CTX_API_VERSION`
|
||||
- **`bare_os.uptime_ms`** → ms since booter VFS construction started
|
||||
- **`bare_os.system_revision`** → JSON of `ctx.bareOsSystemRevision`
|
||||
- **`bare_os.ipc_list`** → JSON array of FIFO channel names
|
||||
- **`bare_os.service_names`** → JSON array of **initd** unit names
|
||||
- **`bare_os.echo`** → JSON `{"args":[…]}` (debug)
|
||||
- Unknown pairs throw **`BareOsKernelError`** with code **`BARE_OS_EXEC_RPC_UNKNOWN`** (surfaced as RPC error text).
|
||||
|
||||
Implementation: [`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).
|
||||
|
||||
---
|
||||
|
||||
## Kernel feature bitmask (documentation)
|
||||
|
||||
The package **`bare-os-protocol`** exports **`lib/kernel-feature-bits.js`** (re-exported from **`index.js`**) with **versioned capability words** describing optional booter / image capabilities (word 1: **`bits`**, word 2: **`bits2`**, word 3: **`bits3`**, word 4: **`bits4`**, word 5: **`bits5`**; 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`**, **`bits2`**, **`bits3`**, **`bits4`**, **`bits5`**, **`protocolPackageVersion`**, **`role`**, **`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.
|
||||
|
||||
@@ -212,6 +212,12 @@ Prettier config: **no semicolons**, **single quotes** (`.prettierrc`).
|
||||
|
||||
---
|
||||
|
||||
## Security, ACL, and observability hooks
|
||||
|
||||
The booter exposes **`ctx.bareOsAclEvaluate`**, audit toggles (**`BARE_OS_AUDIT`**, **`BARE_OS_AUDIT_JSON`**), and append-only style logging under **`/var/log/`** (see environment appendix). Subsystem-oriented error classes with stable **`code`** fields live in **[`packages/bare-os-booter/lib/bare-os-errors.js`](../packages/bare-os-booter/lib/bare-os-errors.js)**. After initd, **`disk.os.execRpc`** accepts only **whitelisted** **`bare_os.*`** methods—see [Chapter 3 — `disk.os` bridge](03-protocol-and-disk.md).
|
||||
|
||||
---
|
||||
|
||||
## Further reading
|
||||
|
||||
- **[docs/reference/README.md](../docs/reference/README.md)** — file-by-file reference (authoritative for paths)
|
||||
|
||||
@@ -26,6 +26,8 @@ This project is **experimental research software**, not a production OS. It is l
|
||||
|
||||
**[docs/reference/README.md](../docs/reference/README.md)** — File-by-file inventory, environment variables, data-flow diagram.
|
||||
|
||||
**[docs/architecture/KERNEL_CONTRACT.md](../docs/architecture/KERNEL_CONTRACT.md)** — Single-page contract: subsystems, boot steps, `ctx` semver, typed errors.
|
||||
|
||||
**[developer-guide/README.md](../developer-guide/README.md)** — How to write `run(ctx, argv)` / `start(ctx)`, extend `/bin`, and test under Pear.
|
||||
|
||||
**[Kernel extensions](../docs/reference/kernel-extensions.md)** — Kernel feature bitmask, seed-channel RPC, and capability bits.
|
||||
|
||||
+177
-4
@@ -87,6 +87,8 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
return false
|
||||
}
|
||||
|
||||
const B32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
|
||||
|
||||
function bareHexEncode(u8) {
|
||||
let s = ''
|
||||
for (let i = 0; i < u8.length; i++) {
|
||||
@@ -106,16 +108,94 @@ function bareHexDecode(s) {
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB32EncodeBytes(u8) {
|
||||
let out = ''
|
||||
let i = 0
|
||||
let buf = 0
|
||||
let bits = 0
|
||||
for (; i < u8.length; i++) {
|
||||
buf = (buf << 8) | u8[i]
|
||||
bits += 8
|
||||
while (bits >= 5) {
|
||||
bits -= 5
|
||||
out += B32[(buf >> bits) & 31]
|
||||
}
|
||||
}
|
||||
if (bits > 0) out += B32[(buf << (5 - bits)) & 31]
|
||||
while (out.length % 8 !== 0) out += '='
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB32DecodeToU8(s) {
|
||||
const t = String(s).replace(/\s+/g, '').replace(/=+$/, '')
|
||||
let buf = 0
|
||||
let bits = 0
|
||||
const bytes = []
|
||||
for (let i = 0; i < t.length; i++) {
|
||||
const c = t[i]
|
||||
const v = B32.indexOf(c)
|
||||
if (v < 0) throw new Error('invalid base32 character')
|
||||
buf = (buf << 5) | v
|
||||
bits += 5
|
||||
if (bits >= 8) {
|
||||
bits -= 8
|
||||
bytes.push((buf >> bits) & 255)
|
||||
}
|
||||
}
|
||||
return new Uint8Array(bytes)
|
||||
}
|
||||
|
||||
function bareB64EncodeBytes(u8) {
|
||||
const B =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
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 += B[(n >> 18) & 63] + B[(n >> 12) & 63] + B[(n >> 6) & 63] + B[n & 63]
|
||||
}
|
||||
const rest = u8.length - i
|
||||
if (rest === 1) {
|
||||
const n = u8[i] << 16
|
||||
out += B[(n >> 18) & 63] + B[(n >> 12) & 63] + '=='
|
||||
} else if (rest === 2) {
|
||||
const n = (u8[i] << 16) | (u8[i + 1] << 8)
|
||||
out += B[(n >> 18) & 63] + B[(n >> 12) & 63] + B[(n >> 6) & 63] + '='
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB64DecodeToU8(s) {
|
||||
const t = String(s).replace(/\s+/g, '')
|
||||
if (typeof globalThis.Buffer !== 'undefined') {
|
||||
return new Uint8Array(globalThis.Buffer.from(t, 'base64'))
|
||||
}
|
||||
if (typeof globalThis.atob === 'function') {
|
||||
const bin = globalThis.atob(t)
|
||||
const out = new Uint8Array(bin.length)
|
||||
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i) & 255
|
||||
return out
|
||||
}
|
||||
throw new Error('base64 decode requires Buffer or atob')
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
let decode = false
|
||||
let base16 = false
|
||||
let base32 = false
|
||||
let base64 = false
|
||||
let wrap = 0
|
||||
const paths = []
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
const a = argv[i]
|
||||
if (a === '-h' || a === '--help') {
|
||||
ctx.console.log(
|
||||
'usage: basenc --base16 [-d] [FILE]\n' +
|
||||
'Encode or decode hex (Base16). Other bases are not implemented.'
|
||||
'usage: basenc [--base16 | --base32 | --base64] [-d] [-w COLS] [FILE]\n' +
|
||||
' --base16 hex (default when no base flag)\n' +
|
||||
' --base32 RFC 4648 Base32\n' +
|
||||
' --base64 RFC 4648 Base64\n' +
|
||||
' -d decode from text to raw bytes (stdout)\n' +
|
||||
' -w COLS wrap encoded output (base64/base32 only; 0 = no wrap)'
|
||||
)
|
||||
ctx.exitCode = 0
|
||||
return
|
||||
@@ -128,6 +208,19 @@ async function run(ctx, argv) {
|
||||
base16 = true
|
||||
continue
|
||||
}
|
||||
if (a === '--base32') {
|
||||
base32 = true
|
||||
continue
|
||||
}
|
||||
if (a === '--base64') {
|
||||
base64 = true
|
||||
continue
|
||||
}
|
||||
if ((a === '-w' || a === '--wrap') && argv[i + 1]) {
|
||||
wrap = Number.parseInt(argv[++i], 10)
|
||||
if (!Number.isFinite(wrap) || wrap < 0) wrap = 0
|
||||
continue
|
||||
}
|
||||
if (a.startsWith('-')) {
|
||||
ctx.console.error('basenc: unsupported option ' + a)
|
||||
ctx.exitCode = 1
|
||||
@@ -135,11 +228,15 @@ async function run(ctx, argv) {
|
||||
}
|
||||
paths.push(a)
|
||||
}
|
||||
if (!base16) {
|
||||
ctx.console.error('basenc: requires --base16')
|
||||
|
||||
const modeCount = (base16 ? 1 : 0) + (base32 ? 1 : 0) + (base64 ? 1 : 0)
|
||||
if (modeCount > 1) {
|
||||
ctx.console.error('basenc: specify at most one of --base16, --base32, --base64')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (modeCount === 0) base16 = true
|
||||
|
||||
const b4 = ctx.b4a
|
||||
let buf
|
||||
if (!paths.length || paths[0] === '-') {
|
||||
@@ -153,6 +250,8 @@ async function run(ctx, argv) {
|
||||
}
|
||||
buf = b instanceof Uint8Array ? b : new Uint8Array(b)
|
||||
}
|
||||
|
||||
if (base16) {
|
||||
if (decode) {
|
||||
const text = b4.toString(buf)
|
||||
let raw
|
||||
@@ -172,4 +271,78 @@ async function run(ctx, argv) {
|
||||
return
|
||||
}
|
||||
ctx.console.log(bareHexEncode(buf))
|
||||
return
|
||||
}
|
||||
|
||||
if (base32) {
|
||||
if (decode) {
|
||||
const text = b4.toString(buf)
|
||||
let raw
|
||||
try {
|
||||
raw = bareB32DecodeToU8(text)
|
||||
} catch (e) {
|
||||
ctx.console.error('basenc: ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (!bareOsEmitRaw(ctx, raw)) {
|
||||
ctx.console.error(
|
||||
'basenc: decode output requires process.stdout.write or ctx.bareOsBinWrite'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
let enc = bareB32EncodeBytes(buf)
|
||||
if (wrap > 0) {
|
||||
const lines = []
|
||||
for (let i = 0; i < enc.length; i += wrap) {
|
||||
lines.push(enc.slice(i, i + wrap))
|
||||
}
|
||||
enc = lines.join('\n')
|
||||
}
|
||||
ctx.console.log(enc)
|
||||
return
|
||||
}
|
||||
|
||||
if (base64) {
|
||||
if (decode) {
|
||||
const text = new TextDecoder().decode(buf)
|
||||
let raw
|
||||
try {
|
||||
raw = bareB64DecodeToU8(text)
|
||||
} catch (e) {
|
||||
ctx.console.error('basenc: ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (!bareOsEmitRaw(ctx, raw)) {
|
||||
ctx.console.error(
|
||||
'basenc: decode output requires process.stdout.write or ctx.bareOsBinWrite'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
let enc
|
||||
if (typeof globalThis.btoa === 'function') {
|
||||
let s = ''
|
||||
const step = 0x8000
|
||||
for (let i = 0; i < buf.length; i += step) {
|
||||
const chunk = buf.subarray(i, i + step)
|
||||
s += String.fromCharCode.apply(null, chunk)
|
||||
}
|
||||
enc = globalThis.btoa(s)
|
||||
} else {
|
||||
enc = bareB64EncodeBytes(buf)
|
||||
}
|
||||
if (wrap > 0) {
|
||||
const lines = []
|
||||
for (let i = 0; i < enc.length; i += wrap) {
|
||||
lines.push(enc.slice(i, i + wrap))
|
||||
}
|
||||
enc = lines.join('\n')
|
||||
}
|
||||
ctx.console.log(enc)
|
||||
}
|
||||
}
|
||||
|
||||
+17
-1
@@ -90,7 +90,9 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
async function run(ctx, argv) {
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
if (argv[i] === '-h' || argv[i] === '--help') {
|
||||
ctx.console.log('usage: hostid\nPrint a numeric host identifier (session-derived stub).')
|
||||
ctx.console.log(
|
||||
'usage: hostid\nPrint an 8-digit hex host identifier: HOSTID env, else identity public key hash, else session-derived.'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (argv[i].startsWith('-')) {
|
||||
@@ -104,6 +106,20 @@ async function run(ctx, argv) {
|
||||
ctx.console.log(e.HOSTID.toLowerCase())
|
||||
return
|
||||
}
|
||||
const id = ctx.identity
|
||||
const pk =
|
||||
id &&
|
||||
id.state === 'unlocked' &&
|
||||
id.publicKey instanceof Uint8Array &&
|
||||
id.publicKey.length
|
||||
? id.publicKey
|
||||
: null
|
||||
if (pk) {
|
||||
let h = 0
|
||||
for (let i = 0; i < pk.length; i++) h = (Math.imul(31, h) + pk[i]) >>> 0
|
||||
ctx.console.log(h.toString(16).padStart(8, '0'))
|
||||
return
|
||||
}
|
||||
const seed = e.BARE_OS_SESSION_ID || e.HOSTNAME || 'bare-os'
|
||||
let h = 0
|
||||
for (let i = 0; i < seed.length; i++)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/* BARE_OS_BIN_API 1.0.0 — stub; booter delegates to systemctl-cli (kernel-runner). */
|
||||
/** Booter delegates journalctl to systemctl-cli.js (kernel-runner). */
|
||||
/* BARE_OS_BIN_API 1.0.0 — delegates to booter systemctl-cli when ctx exposes bareOsRunSystemctlCli. */
|
||||
async function run(ctx, argv) {
|
||||
if (typeof ctx.bareOsRunSystemctlCli === 'function') {
|
||||
await ctx.bareOsRunSystemctlCli(argv)
|
||||
return
|
||||
}
|
||||
ctx.console.error(
|
||||
'journalctl: not executed in host booter (delegation missing)'
|
||||
'journalctl: ctx.bareOsRunSystemctlCli missing — run under host booter / upgrade ctx API'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/* BARE_OS_BIN_API 1.0.0 — stub; booter delegates to systemctl-cli (kernel-runner). */
|
||||
/** Booter delegates systemctl to systemctl-cli.js (kernel-runner). */
|
||||
/* BARE_OS_BIN_API 1.0.0 — delegates to booter systemctl-cli when ctx exposes bareOsRunSystemctlCli. */
|
||||
async function run(ctx, argv) {
|
||||
if (typeof ctx.bareOsRunSystemctlCli === 'function') {
|
||||
await ctx.bareOsRunSystemctlCli(argv)
|
||||
return
|
||||
}
|
||||
ctx.console.error(
|
||||
'systemctl: not executed in host booter (delegation missing)'
|
||||
'systemctl: ctx.bareOsRunSystemctlCli missing — run under host booter / upgrade ctx API'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
|
||||
+3
-1
@@ -90,7 +90,9 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
async function run(ctx, argv) {
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
if (argv[i] === '-h' || argv[i] === '--help') {
|
||||
ctx.console.log('usage: users\nPrint login names (single-session stub).')
|
||||
ctx.console.log(
|
||||
'usage: users\nPrint login names for the active Bare OS session (USER / LOGNAME from VFS env).'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (argv[i].startsWith('-')) {
|
||||
|
||||
+184
-184
@@ -2,9 +2,9 @@
|
||||
"version": 1,
|
||||
"bundles": [
|
||||
{
|
||||
"path": "/lib/bare/bundles/safetyCatch.js",
|
||||
"path": "/lib/bare/bundles/hypercoreIdEncoding.js",
|
||||
"keys": [
|
||||
"safetyCatch"
|
||||
"hypercoreIdEncoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -14,9 +14,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/hypercoreIdEncoding.js",
|
||||
"path": "/lib/bare/bundles/safetyCatch.js",
|
||||
"keys": [
|
||||
"hypercoreIdEncoding"
|
||||
"safetyCatch"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -25,6 +25,12 @@
|
||||
"compactEncoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/protomux.js",
|
||||
"keys": [
|
||||
"protomux"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUrl.js",
|
||||
"keys": [
|
||||
@@ -32,9 +38,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/protomux.js",
|
||||
"path": "/lib/bare/bundles/bareEvents.js",
|
||||
"keys": [
|
||||
"protomux"
|
||||
"bareEvents"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -49,24 +55,12 @@
|
||||
"barePath"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareEvents.js",
|
||||
"keys": [
|
||||
"bareEvents"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAbort.js",
|
||||
"keys": [
|
||||
"bareAbort"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAbortController.js",
|
||||
"keys": [
|
||||
"bareAbortController"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAnsiEscapes.js",
|
||||
"keys": [
|
||||
@@ -74,9 +68,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareReadline.js",
|
||||
"path": "/lib/bare/bundles/bareAbortController.js",
|
||||
"keys": [
|
||||
"bareReadline"
|
||||
"bareAbortController"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -92,9 +86,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareApk.js",
|
||||
"path": "/lib/bare/bundles/bareReadline.js",
|
||||
"keys": [
|
||||
"bareApk"
|
||||
"bareReadline"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -104,9 +98,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/fetch.js",
|
||||
"path": "/lib/bare/bundles/bareAppKit.js",
|
||||
"keys": [
|
||||
"fetch"
|
||||
"bareAppKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -122,9 +116,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAppKit.js",
|
||||
"path": "/lib/bare/bundles/bareApk.js",
|
||||
"keys": [
|
||||
"bareAppKit"
|
||||
"bareApk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/fetch.js",
|
||||
"keys": [
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -140,9 +140,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBluetoothApple.js",
|
||||
"path": "/lib/bare/bundles/bareBundle.js",
|
||||
"keys": [
|
||||
"bareBluetoothApple"
|
||||
"bareBundle"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -152,9 +152,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBundle.js",
|
||||
"path": "/lib/bare/bundles/bareBluetoothApple.js",
|
||||
"keys": [
|
||||
"bareBundle"
|
||||
"bareBluetoothApple"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -169,12 +169,6 @@
|
||||
"bareBoot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDebugLog.js",
|
||||
"keys": [
|
||||
"bareDebugLog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareConsole.js",
|
||||
"keys": [
|
||||
@@ -199,6 +193,12 @@
|
||||
"bareDelta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDebugLog.js",
|
||||
"keys": [
|
||||
"bareDebugLog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDaemon.js",
|
||||
"keys": [
|
||||
@@ -241,12 +241,6 @@
|
||||
"bareDgram"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFfmpegEncodings.js",
|
||||
"keys": [
|
||||
"bareFfmpegEncodings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFfmpeg.js",
|
||||
"keys": [
|
||||
@@ -254,15 +248,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareGif.js",
|
||||
"path": "/lib/bare/bundles/bareFfmpegEncodings.js",
|
||||
"keys": [
|
||||
"bareGif"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFormat.js",
|
||||
"keys": [
|
||||
"bareFormat"
|
||||
"bareFfmpegEncodings"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -271,6 +259,12 @@
|
||||
"bareFormData"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFormat.js",
|
||||
"keys": [
|
||||
"bareFormat"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFileLogger.js",
|
||||
"keys": [
|
||||
@@ -278,21 +272,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareGtk.js",
|
||||
"path": "/lib/bare/bundles/bareGif.js",
|
||||
"keys": [
|
||||
"bareGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFs.js",
|
||||
"keys": [
|
||||
"bareFs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHeif.js",
|
||||
"keys": [
|
||||
"bareHeif"
|
||||
"bareGif"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -301,12 +283,30 @@
|
||||
"bareHrtime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHeif.js",
|
||||
"keys": [
|
||||
"bareHeif"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareGtk.js",
|
||||
"keys": [
|
||||
"bareGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHttpParser.js",
|
||||
"keys": [
|
||||
"bareHttpParser"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFs.js",
|
||||
"keys": [
|
||||
"bareFs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareIco.js",
|
||||
"keys": [
|
||||
@@ -320,15 +320,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspect.js",
|
||||
"path": "/lib/bare/bundles/bareHttps.js",
|
||||
"keys": [
|
||||
"bareInspect"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareIntl.js",
|
||||
"keys": [
|
||||
"bareIntl"
|
||||
"bareHttps"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -337,6 +331,12 @@
|
||||
"bareHttp1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspect.js",
|
||||
"keys": [
|
||||
"bareInspect"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareJpeg.js",
|
||||
"keys": [
|
||||
@@ -344,15 +344,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHttps.js",
|
||||
"path": "/lib/bare/bundles/bareIntl.js",
|
||||
"keys": [
|
||||
"bareHttps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspector.js",
|
||||
"keys": [
|
||||
"bareInspector"
|
||||
"bareIntl"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -361,18 +355,24 @@
|
||||
"bareIpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLogger.js",
|
||||
"keys": [
|
||||
"bareLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLief.js",
|
||||
"keys": [
|
||||
"bareLief"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspector.js",
|
||||
"keys": [
|
||||
"bareInspector"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLogger.js",
|
||||
"keys": [
|
||||
"bareLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLink.js",
|
||||
"keys": [
|
||||
@@ -385,18 +385,18 @@
|
||||
"bareMake"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModuleLexer.js",
|
||||
"keys": [
|
||||
"bareModuleLexer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModuleResolve.js",
|
||||
"keys": [
|
||||
"bareModuleResolve"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModuleLexer.js",
|
||||
"keys": [
|
||||
"bareModuleLexer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModule.js",
|
||||
"keys": [
|
||||
@@ -451,12 +451,6 @@
|
||||
"bareMedia"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePack.js",
|
||||
"keys": [
|
||||
"barePack"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePerformance.js",
|
||||
"keys": [
|
||||
@@ -470,9 +464,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePipe.js",
|
||||
"path": "/lib/bare/bundles/barePack.js",
|
||||
"keys": [
|
||||
"barePipe"
|
||||
"barePack"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -482,15 +476,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareNodeRuntime.js",
|
||||
"path": "/lib/bare/bundles/barePipe.js",
|
||||
"keys": [
|
||||
"bareNodeRuntime"
|
||||
"barePipe"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePrebuild.js",
|
||||
"path": "/lib/bare/bundles/bareNodeRuntime.js",
|
||||
"keys": [
|
||||
"barePrebuild"
|
||||
"bareNodeRuntime"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -499,18 +493,24 @@
|
||||
"barePunycode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDev.js",
|
||||
"keys": [
|
||||
"bareDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQuerystring.js",
|
||||
"keys": [
|
||||
"bareQuerystring"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQueueMicrotask.js",
|
||||
"keys": [
|
||||
"bareQueueMicrotask"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePrebuild.js",
|
||||
"keys": [
|
||||
"barePrebuild"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRealm.js",
|
||||
"keys": [
|
||||
@@ -518,9 +518,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQueueMicrotask.js",
|
||||
"path": "/lib/bare/bundles/bareDev.js",
|
||||
"keys": [
|
||||
"bareQueueMicrotask"
|
||||
"bareDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -553,12 +553,6 @@
|
||||
"bareSemver"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRpc.js",
|
||||
"keys": [
|
||||
"bareRpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRepl.js",
|
||||
"keys": [
|
||||
@@ -566,9 +560,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRun.js",
|
||||
"path": "/lib/bare/bundles/bareRpc.js",
|
||||
"keys": [
|
||||
"bareRun"
|
||||
"bareRpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -583,12 +577,24 @@
|
||||
"bareSidecar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRun.js",
|
||||
"keys": [
|
||||
"bareRun"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStringDecoder.js",
|
||||
"keys": [
|
||||
"bareStringDecoder"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStdio.js",
|
||||
"keys": [
|
||||
"bareStdio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStorage.js",
|
||||
"keys": [
|
||||
@@ -602,9 +608,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStdio.js",
|
||||
"path": "/lib/bare/bundles/bareStructuredClone.js",
|
||||
"keys": [
|
||||
"bareStdio"
|
||||
"bareStructuredClone"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -613,36 +619,12 @@
|
||||
"bareSvg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStructuredClone.js",
|
||||
"keys": [
|
||||
"bareStructuredClone"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSystemLogger.js",
|
||||
"keys": [
|
||||
"bareSystemLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSubprocess.js",
|
||||
"keys": [
|
||||
"bareSubprocess"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTcp.js",
|
||||
"keys": [
|
||||
"bareTcp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTap.js",
|
||||
"keys": [
|
||||
"bareTap"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTiff.js",
|
||||
"keys": [
|
||||
@@ -650,9 +632,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareThread.js",
|
||||
"path": "/lib/bare/bundles/bareSystemLogger.js",
|
||||
"keys": [
|
||||
"bareThread"
|
||||
"bareSystemLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTap.js",
|
||||
"keys": [
|
||||
"bareTap"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -662,9 +650,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareType.js",
|
||||
"path": "/lib/bare/bundles/bareTcp.js",
|
||||
"keys": [
|
||||
"bareType"
|
||||
"bareTcp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareThread.js",
|
||||
"keys": [
|
||||
"bareThread"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -674,9 +668,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUiKit.js",
|
||||
"path": "/lib/bare/bundles/bareType.js",
|
||||
"keys": [
|
||||
"bareUiKit"
|
||||
"bareType"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -685,6 +679,12 @@
|
||||
"bareTls"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUiKit.js",
|
||||
"keys": [
|
||||
"bareUiKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTty.js",
|
||||
"keys": [
|
||||
@@ -697,12 +697,6 @@
|
||||
"bareUnpack"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareVm.js",
|
||||
"keys": [
|
||||
"bareVm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareV8.js",
|
||||
"keys": [
|
||||
@@ -715,6 +709,18 @@
|
||||
"bareWalkHandles"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareVm.js",
|
||||
"keys": [
|
||||
"bareVm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWebKit.js",
|
||||
"keys": [
|
||||
"bareWebKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUnionBundle.js",
|
||||
"keys": [
|
||||
@@ -727,30 +733,12 @@
|
||||
"bareWebp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWebKit.js",
|
||||
"keys": [
|
||||
"bareWebKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWebKitGtk.js",
|
||||
"keys": [
|
||||
"bareWebKitGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUtils.js",
|
||||
"keys": [
|
||||
"bareUtils"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareV8ToIstanbul.js",
|
||||
"keys": [
|
||||
"bareV8ToIstanbul"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWhich.js",
|
||||
"keys": [
|
||||
@@ -758,9 +746,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareXdiff.js",
|
||||
"path": "/lib/bare/bundles/bareWebKitGtk.js",
|
||||
"keys": [
|
||||
"bareXdiff"
|
||||
"bareWebKitGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -770,15 +758,27 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZlib.js",
|
||||
"path": "/lib/bare/bundles/bareV8ToIstanbul.js",
|
||||
"keys": [
|
||||
"bareZlib"
|
||||
"bareV8ToIstanbul"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWs.js",
|
||||
"path": "/lib/bare/bundles/bareXdiff.js",
|
||||
"keys": [
|
||||
"bareWs"
|
||||
"bareXdiff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZmq.js",
|
||||
"keys": [
|
||||
"bareZmq"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZlib.js",
|
||||
"keys": [
|
||||
"bareZlib"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -788,9 +788,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZmq.js",
|
||||
"path": "/lib/bare/bundles/bareWs.js",
|
||||
"keys": [
|
||||
"bareZmq"
|
||||
"bareWs"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"atMs": 1775339424020,
|
||||
"atMs": 1775340363610,
|
||||
"commands": [
|
||||
"arch",
|
||||
"awk",
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -15,7 +15,7 @@
|
||||
"sync:bare-manifest": "node scripts/sync-bare-module-manifest-from-catalog.mjs",
|
||||
"smoke:bare-manifest": "node scripts/smoke-bare-manifest-imports.mjs",
|
||||
"bundle:kernel": "node scripts/bundle-kernel-init.mjs",
|
||||
"pretest": "npm run build -w bare-os-coreutils && npm run build -w bare-os-bare-libs && npm run bundle:kernel && node scripts/gen-kernel-extensions-index.mjs && node scripts/verify-kernel-seeder-parity.mjs && node scripts/verify-banned-terminology.mjs && node scripts/verify-naming-alias-matrix.mjs && node scripts/verify-feature-roadmap-canonical.mjs && node scripts/verify-no-new-giant-phase-identifiers.mjs && node scripts/verify-runtime-no-incomplete-markers.mjs && node scripts/gen-ctx-client-stub.mjs > /dev/null && node scripts/verify-extension-manifest-schema.mjs && node scripts/verify-ctx-api-feature-bits.mjs && node scripts/verify-kernel-capabilities-contract.mjs && node scripts/verify-kernel-capabilities-word-6.mjs && node scripts/verify-kernel-capabilities-word-7.mjs && node scripts/verify-kernel-capabilities-word-8.mjs && node scripts/verify-kernel-capabilities-word-9.mjs && node scripts/verify-kernel-capabilities-word-10.mjs && node scripts/verify-kernel-capabilities-word-11.mjs && node scripts/verify-ctx-dts.mjs && node scripts/validate-example-schemas.mjs && node scripts/verify-doc-links.mjs && node scripts/verify-man-coverage.mjs && node scripts/verify-compat-matrix.mjs && node scripts/verify-kernel-program-doc.mjs && node scripts/verify-kernel-program-proc-schema.mjs && node scripts/verify-kernel-program-roadmap-table.mjs && node scripts/verify-pear-no-static-node-import.mjs && npm run smoke:bare-manifest",
|
||||
"pretest": "npm run build -w bare-os-coreutils && npm run build -w bare-os-bare-libs && npm run bundle:kernel && node scripts/gen-kernel-extensions-index.mjs && node scripts/verify-kernel-seeder-parity.mjs && node scripts/verify-banned-terminology.mjs && node scripts/verify-naming-alias-matrix.mjs && node scripts/verify-feature-roadmap-canonical.mjs && node scripts/verify-no-new-giant-phase-identifiers.mjs && node scripts/verify-runtime-no-incomplete-markers.mjs && node scripts/verify-booter-boot-steps-alignment.mjs && node scripts/gen-ctx-client-stub.mjs > /dev/null && node scripts/verify-extension-manifest-schema.mjs && node scripts/verify-ctx-api-feature-bits.mjs && node scripts/verify-kernel-capabilities-contract.mjs && node scripts/verify-kernel-capabilities-word-6.mjs && node scripts/verify-kernel-capabilities-word-7.mjs && node scripts/verify-kernel-capabilities-word-8.mjs && node scripts/verify-kernel-capabilities-word-9.mjs && node scripts/verify-kernel-capabilities-word-10.mjs && node scripts/verify-kernel-capabilities-word-11.mjs && node scripts/verify-ctx-dts.mjs && node scripts/validate-example-schemas.mjs && node scripts/verify-doc-links.mjs && node scripts/verify-man-coverage.mjs && node scripts/verify-compat-matrix.mjs && node scripts/verify-kernel-program-doc.mjs && node scripts/verify-kernel-program-proc-schema.mjs && node scripts/verify-kernel-program-roadmap-table.mjs && node scripts/verify-pear-no-static-node-import.mjs && npm run smoke:bare-manifest",
|
||||
"test": "npm run test --workspaces --if-present",
|
||||
"verify-kernel-seeder": "node scripts/verify-kernel-seeder-parity.mjs",
|
||||
"release-checklist": "node scripts/release-checklist.mjs",
|
||||
|
||||
@@ -12,6 +12,7 @@ Authoritative **version alignment** with protocol and telemetry schema numbers l
|
||||
|
||||
| Version | Booter (workspace) | Notes |
|
||||
| ------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| 1.28.0 | 0.1.0 | **`ctx.bareOsRunSystemctlCli`**: drive-resident **`systemctl`** / **`journalctl`** call the same backend as host delegates when the booter exposes this method. **`disk.os`**: **`createBareOsDiskOsBridge`** — Hyperdrive path **`searchLocal`**, whitelisted **`bare_os.*`** **`execRpc`** (typed **`BareOsKernelError`** on unknown). Host delegates: **`warc`** (WARC 1.0 list/write-response), **`archive`** (ustar tar front-end); **`ssh-keygen`** passphrase → **`bareOsKeySchema: 2`** (PBKDF2 + ChaCha20-Poly1305). New **`lib/bare-os-boot-phases.js`**, **`lib/bare-os-errors.js`**. CI: **`verify-booter-boot-steps-alignment.mjs`**. Docs: **`docs/architecture/KERNEL_CONTRACT.md`**, **`docs/deployment/OTA_AND_BUNDLES.md`**, **`docs/audit/PLACEHOLDER_BASELINE.md`**, handbook §3 **`disk.os`**. |
|
||||
| 1.25.0 | 0.1.0 | Kernel program proc: primary **`/proc/bare_os/kernel_program.json`** + proc id **`kernel_program`** (legacy **`giant_phase_program`** unchanged); JSON uses **`operatorSketches`** and **`program: bare-os-kernel-program`**; env **`BARE_OS_KERNEL_PROGRAM_PROC_JSON`** (legacy **`BARE_OS_GIANT_PHASE_PROGRAM_JSON`**); **`subsystems.kernel.programProc`** on **`bareOsPublishBootReady`** (replaces **`giantPhase`**). CI: **`verify-kernel-program-doc.mjs`**, **`verify-kernel-program-proc-schema.mjs`**, **`verify-kernel-program-roadmap-table.mjs`**. Module **`bare-os-giant-phase.js`** removed in favor of **`bare-os-kernel-program-proc.js`**. |
|
||||
| 1.24.0 | 0.1.0 | **`bareOsEmitKernelEvent`** / **`bareOsSubscribeKernelEvent`**, **`bareOsAcquireKeyHandle`** sketch; **`/run/bare-os/services.json`** seed; optional **`BARE_OS_LOADER_AUDIT`** → **`loader-audit.ndjson`**; proc **schema 2** + operator env sketches (historically documented as giant-phase / **`gp2`**); runtime caps **`kernelEventSubscribe`**, **`keyBrokerHandleSketch`**. Stock kernel: boot stages, dry-run, policy fallbacks, ABI min, services registry consumers. |
|
||||
| 1.23.0 | 0.1.0 | Operator program snapshot: **`/proc/bare_os/giant_phase_program.json`** (+ flat alias), **`bareOsReadBareTopSnapshot`** + **`baretop`** proc entry; stock kernel **`BARE_OS_BOOT_SAFE_MODE`**, boot transaction journal + checkpoint under **`/run/bare-os/`**; **`kernel.ext.d`** **`requires`** / **`after`** / **`before`** ordering; optional **`subsystems.kernel.giantPhase`** on **`bareOsPublishBootReady`**. Governance doc since renamed to **`developer-guide/kernel-program.md`**. |
|
||||
|
||||
@@ -59,6 +59,8 @@ import { runWgetCli } from './lib/wget-cli.js'
|
||||
import { runOpensslCli } from './lib/openssl-cli.js'
|
||||
import { runSshKeygenCli } from './lib/ssh-keygen-cli.js'
|
||||
import { runTarCli } from './lib/tar-cli.js'
|
||||
import { runSystemctlCli } from './lib/systemctl-cli.js'
|
||||
import { createBareOsDiskOsBridge } from './lib/bare-os-disk-os-bridge.js'
|
||||
import { verifyBootManifestEd25519 } from '#bare-os-boot-manifest-sig'
|
||||
import { getBareInitdJournalNdjson } from './lib/bare-initd-journal.js'
|
||||
import { createBareOsSandboxContext } from './lib/bare-os-sandbox.js'
|
||||
@@ -2900,6 +2902,10 @@ async function executeKernel(disk, store, swarm, initSource) {
|
||||
async bareOsRunTarCli(argv) {
|
||||
return runTarCli(ctx, argv)
|
||||
},
|
||||
/** systemctl, bare-initctl, journalctl (bare-initd backend). */
|
||||
async bareOsRunSystemctlCli(argv) {
|
||||
return runSystemctlCli(ctx, argv)
|
||||
},
|
||||
bareOsEmitPearStageHint(payload = {}) {
|
||||
if (typeof globalThis.process?.emit !== 'function') return false
|
||||
try {
|
||||
@@ -3789,14 +3795,13 @@ async function executeKernel(disk, store, swarm, initSource) {
|
||||
|
||||
emitBooterBootPhase('initd')
|
||||
|
||||
disk.os = {
|
||||
async searchLocal() {
|
||||
return []
|
||||
},
|
||||
async execRpc() {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
disk.os = createBareOsDiskOsBridge({
|
||||
drive: disk.drive,
|
||||
bareOsIpc,
|
||||
ctxApiVersion: BARE_OS_CTX_API_VERSION,
|
||||
systemRevision: ctx.bareOsSystemRevision,
|
||||
bootStartedMs
|
||||
})
|
||||
|
||||
emitBooterBootPhase('kernel_invoke')
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* BSD-style `archive` front-end to the stock ustar `tar` delegate (create/list/extract).
|
||||
* Maps common `archive c|t|x` invocations to `tar -cf|-tf|-xf`.
|
||||
*/
|
||||
|
||||
import { runTarCli } from './tar-cli.js'
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string[]} argv argv[0] is `archive`
|
||||
*/
|
||||
export async function runArchiveCli(ctx, argv) {
|
||||
const args = argv.slice(1)
|
||||
if (
|
||||
!args.length ||
|
||||
args[0] === '-h' ||
|
||||
args[0] === '--help' ||
|
||||
args[0] === 'help'
|
||||
) {
|
||||
ctx.console.log(
|
||||
'usage: archive c ARCHIVE PATH [PATH...]\n' +
|
||||
' archive t ARCHIVE\n' +
|
||||
' archive x ARCHIVE\n' +
|
||||
'Maps to ustar tar -cf / -tf / -xf (see tar --help in handbook).'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const op = args[0]
|
||||
if (op === 'c') {
|
||||
const arch = args[1]
|
||||
const rest = args.slice(2)
|
||||
if (!arch || !rest.length) {
|
||||
ctx.console.error('archive c: need ARCHIVE and at least one PATH')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
await runTarCli(ctx, ['tar', '-cf', arch, ...rest])
|
||||
return
|
||||
}
|
||||
if (op === 't') {
|
||||
const arch = args[1]
|
||||
if (!arch) {
|
||||
ctx.console.error('archive t: need ARCHIVE')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
await runTarCli(ctx, ['tar', '-tf', arch])
|
||||
return
|
||||
}
|
||||
if (op === 'x') {
|
||||
const arch = args[1]
|
||||
if (!arch) {
|
||||
ctx.console.error('archive x: need ARCHIVE')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
await runTarCli(ctx, ['tar', '-xf', arch])
|
||||
return
|
||||
}
|
||||
|
||||
ctx.console.error('archive: first argument must be c, t, or x')
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Canonical booter boot-step identifiers emitted through {@link emitBooterBootStep}
|
||||
* (lifecycle / diagnostics). Keep in sync with `emitBooterBootPhase` call sites in `index.js`.
|
||||
*/
|
||||
export const BARE_OS_BOOTER_BOOT_STEPS = Object.freeze([
|
||||
'vfs',
|
||||
'ctx',
|
||||
'repl',
|
||||
'initd',
|
||||
'kernel_invoke'
|
||||
])
|
||||
|
||||
/**
|
||||
* @param {string} step
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isKnownBareOsBooterBootStep(step) {
|
||||
return BARE_OS_BOOTER_BOOT_STEPS.includes(String(step))
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
* Semantic version of the booter `ctx` contract for custom kernels.
|
||||
* Bump when adding/removing/renaming documented `ctx` fields or changing behavior.
|
||||
*/
|
||||
export const BARE_OS_CTX_API_VERSION = '1.27.0'
|
||||
export const BARE_OS_CTX_API_VERSION = '1.28.0'
|
||||
|
||||
@@ -203,6 +203,7 @@ export interface BareOsKernelContext {
|
||||
bareOsRunOpensslCli?(argv: string[]): Promise<unknown>
|
||||
bareOsRunSshKeygenCli?(argv: string[]): Promise<unknown>
|
||||
bareOsRunTarCli?(argv: string[]): Promise<unknown>
|
||||
bareOsRunSystemctlCli?(argv: string[]): Promise<unknown>
|
||||
bareOsRegisterBareDiagnosticsTap?(
|
||||
fn: (ev: Record<string, unknown>) => void
|
||||
): () => void
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Swarm-disk peer RPC bridge: local Hyperdrive path search and whitelisted OS RPC.
|
||||
* Wired onto {@link import('./swarm-disk.js').SwarmDisk} as `disk.os` after initd bring-up.
|
||||
*/
|
||||
|
||||
import { listBareServices } from './bare-initd.js'
|
||||
import { BareOsKernelError } from './bare-os-errors.js'
|
||||
|
||||
const MAX_SEARCH_RESULTS = 256
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* drive: import('hyperdrive').default | null | undefined
|
||||
* bareOsIpc: { list?: () => string[] } | null | undefined
|
||||
* ctxApiVersion: string
|
||||
* systemRevision: Readonly<{ currentId?: string; pendingId?: string; slot?: string }> | null | undefined
|
||||
* bootStartedMs: number
|
||||
* }} opts
|
||||
*/
|
||||
export function createBareOsDiskOsBridge(opts) {
|
||||
return {
|
||||
/**
|
||||
* @param {string} query
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
async searchLocal(query) {
|
||||
const drive = opts.drive
|
||||
const q = String(query || '').trim().toLowerCase()
|
||||
if (!q || !drive || typeof drive.list !== 'function') return []
|
||||
/** @type {string[]} */
|
||||
const matches = []
|
||||
try {
|
||||
for await (const ent of drive.list('/', { recursive: true })) {
|
||||
const key = String(ent.key || '')
|
||||
if (!key) continue
|
||||
const norm = key.startsWith('/') ? key : `/${key}`
|
||||
if (norm.toLowerCase().includes(q)) {
|
||||
matches.push(norm)
|
||||
if (matches.length >= MAX_SEARCH_RESULTS) break
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
return matches
|
||||
}
|
||||
return matches
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} module
|
||||
* @param {string} method
|
||||
* @param {string[]} args
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async execRpc(module, method, args) {
|
||||
const mod = String(module || '').trim()
|
||||
const meth = String(method || '').trim()
|
||||
const a = Array.isArray(args) ? args.map((x) => String(x)) : []
|
||||
|
||||
if (mod === 'bare_os' && meth === 'ping') return 'pong'
|
||||
|
||||
if (mod === 'bare_os' && meth === 'ctx_api_version') {
|
||||
return String(opts.ctxApiVersion || '')
|
||||
}
|
||||
|
||||
if (mod === 'bare_os' && meth === 'uptime_ms') {
|
||||
const t = Date.now() - (Number(opts.bootStartedMs) || 0)
|
||||
return String(Math.max(0, t))
|
||||
}
|
||||
|
||||
if (mod === 'bare_os' && meth === 'system_revision') {
|
||||
const rev = opts.systemRevision || {}
|
||||
return JSON.stringify({
|
||||
currentId: String(rev.currentId || ''),
|
||||
pendingId: String(rev.pendingId || ''),
|
||||
slot: String(rev.slot || '')
|
||||
})
|
||||
}
|
||||
|
||||
if (mod === 'bare_os' && meth === 'ipc_list') {
|
||||
try {
|
||||
const ipc = opts.bareOsIpc
|
||||
const list = typeof ipc?.list === 'function' ? ipc.list() : []
|
||||
return JSON.stringify(list)
|
||||
} catch (e) {
|
||||
return JSON.stringify({
|
||||
error: (e && /** @type {Error} */ (e).message) || String(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (mod === 'bare_os' && meth === 'service_names') {
|
||||
try {
|
||||
const names = listBareServices().map((s) => s.name)
|
||||
return JSON.stringify(names)
|
||||
} catch {
|
||||
return '[]'
|
||||
}
|
||||
}
|
||||
|
||||
if (mod === 'bare_os' && meth === 'echo') {
|
||||
return JSON.stringify({ args: a })
|
||||
}
|
||||
|
||||
throw new BareOsKernelError(
|
||||
'BARE_OS_EXEC_RPC_UNKNOWN',
|
||||
`execRpc: unknown module/method: ${mod}.${meth}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Typed errors for kernel / booter subsystems (stable `code` for guests and IPC).
|
||||
*/
|
||||
|
||||
export class BareOsKernelError extends Error {
|
||||
/**
|
||||
* @param {string} code
|
||||
* @param {string} message
|
||||
* @param {unknown} [cause]
|
||||
*/
|
||||
constructor(code, message, cause) {
|
||||
super(message)
|
||||
this.name = 'BareOsKernelError'
|
||||
/** @type {string} */
|
||||
this.code = code
|
||||
if (cause !== undefined) this.cause = cause
|
||||
}
|
||||
}
|
||||
|
||||
export class BareOsBootError extends BareOsKernelError {
|
||||
/**
|
||||
* @param {string} code
|
||||
* @param {string} message
|
||||
* @param {unknown} [cause]
|
||||
*/
|
||||
constructor(code, message, cause) {
|
||||
super(code, message, cause)
|
||||
this.name = 'BareOsBootError'
|
||||
}
|
||||
}
|
||||
|
||||
export class BareOsVfsError extends BareOsKernelError {
|
||||
/**
|
||||
* @param {string} code
|
||||
* @param {string} message
|
||||
* @param {unknown} [cause]
|
||||
*/
|
||||
constructor(code, message, cause) {
|
||||
super(code, message, cause)
|
||||
this.name = 'BareOsVfsError'
|
||||
}
|
||||
}
|
||||
|
||||
export class BareOsSecurityError extends BareOsKernelError {
|
||||
/**
|
||||
* @param {string} code
|
||||
* @param {string} message
|
||||
* @param {unknown} [cause]
|
||||
*/
|
||||
constructor(code, message, cause) {
|
||||
super(code, message, cause)
|
||||
this.name = 'BareOsSecurityError'
|
||||
}
|
||||
}
|
||||
|
||||
export class BareOsNetError extends BareOsKernelError {
|
||||
/**
|
||||
* @param {string} code
|
||||
* @param {string} message
|
||||
* @param {unknown} [cause]
|
||||
*/
|
||||
constructor(code, message, cause) {
|
||||
super(code, message, cause)
|
||||
this.name = 'BareOsNetError'
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Host-backed CLI delegates (git, curl, wget, systemctl family) with optional allowlist.
|
||||
* When `BARE_OS_DELEGATE_ALLOW` is unset or empty, all registered delegates are allowed.
|
||||
* When set (comma-separated), only listed kinds run: `git`, `curl`, `wget`, `openssl`, `ssh-keygen`, `tar`, `systemctl`, `hrpc` (audit-only).
|
||||
* When set (comma-separated), only listed kinds run: `git`, `curl`, `wget`, `openssl`, `ssh-keygen`, `tar`, `systemctl`, `warc`, `archive`, `hrpc` (audit-only), etc.
|
||||
*/
|
||||
|
||||
import path from 'path'
|
||||
@@ -10,7 +10,9 @@ import { runGitCli } from './git-cli.js'
|
||||
import { runOpensslCli } from './openssl-cli.js'
|
||||
import { runSystemctlCli } from './systemctl-cli.js'
|
||||
import { runSshKeygenCli } from './ssh-keygen-cli.js'
|
||||
import { runArchiveCli } from './archive-cli.js'
|
||||
import { runTarCli } from './tar-cli.js'
|
||||
import { runWarcCli } from './warc-cli.js'
|
||||
import { runWgetCli } from './wget-cli.js'
|
||||
|
||||
/** @typedef {{ kind: string, describe: () => string, shouldDelegate: (cmd: string) => boolean, run: (ctx: Record<string, unknown>, argv: string[]) => Promise<unknown> }} BareOsHostDelegate */
|
||||
@@ -107,74 +109,74 @@ export function loadBareOsHostDelegates() {
|
||||
},
|
||||
{
|
||||
kind: 'hrpc',
|
||||
describe: () => 'hrpc (capability-word-6 audit-only; no guest RPC execution)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error('hrpc delegate is audit-only; host must wire Holepunch RPC bridge')
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'bundlebee',
|
||||
describe: () => 'bundlebee (capability-word-8 audit-only)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error('bundlebee delegate is audit-only; host wires bundlebee-cli staging')
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'warc',
|
||||
describe: () => 'WARC delegate placeholder (doc-only)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error('warc delegate not implemented in stock booter (documentation placeholder)')
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'archive',
|
||||
describe: () => 'archive delegate placeholder (doc-only)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error('archive delegate not implemented in stock booter (documentation placeholder)')
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'sidecar',
|
||||
describe: () => 'sidecar resource cap (word 11 audit-only)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error('sidecar delegate is audit-only; host wires bare-sidecar bridges')
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'pear_runtime_matrix',
|
||||
describe: () => 'pear-runtime matrix (word 11 audit-only)',
|
||||
describe: () =>
|
||||
'hrpc (capability-word-6; host must expose Holepunch RPC — no stock guest execution)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
'pear_runtime_matrix delegate is audit-only; see ctx.bareOsPearRuntimeMatrixProbe'
|
||||
'hrpc: stock booter does not execute guest Holepunch RPC; configure a host hrpc bridge or use seed RPC surfaces'
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'bundlebee',
|
||||
describe: () =>
|
||||
'bundlebee (capability-word-8; host must wire bundlebee staging — not executed in stock booter)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
'bundlebee: stock booter has no bundlebee pipeline; host must wire bundlebee-cli staging'
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'warc',
|
||||
describe: () => 'warc (WARC 1.0 list / write-response via VFS)',
|
||||
shouldDelegate(cmd) {
|
||||
return matchBasename(cmd, 'warc')
|
||||
},
|
||||
run: (ctx, argv) => runWarcCli(ctx, argv)
|
||||
},
|
||||
{
|
||||
kind: 'archive',
|
||||
describe: () => 'archive (ustar tar compatibility front-end)',
|
||||
shouldDelegate(cmd) {
|
||||
return matchBasename(cmd, 'archive')
|
||||
},
|
||||
run: (ctx, argv) => runArchiveCli(ctx, argv)
|
||||
},
|
||||
{
|
||||
kind: 'sidecar',
|
||||
describe: () => 'sidecar resource cap (word 11; host bare-sidecar bridge required)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
'sidecar: stock booter does not spawn sidecars; use ctx hooks / host bare-sidecar integration'
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
kind: 'pear_runtime_matrix',
|
||||
describe: () => 'pear-runtime matrix (word 11; introspect via ctx.bareOsPearRuntimeMatrixProbe)',
|
||||
shouldDelegate() {
|
||||
return false
|
||||
},
|
||||
run() {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
'pear_runtime_matrix: use ctx.bareOsPearRuntimeMatrixProbe; no shell delegate in stock booter'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
* Writes OpenSSH-compatible `.pub` line + a Bare-OS JSON private envelope.
|
||||
*
|
||||
* Usage: ssh-keygen -t ed25519 -f PATH [-N pass] [-C comment]
|
||||
* Encrypted private keys use bareOsKeySchema 2 (PBKDF2-SHA256 + ChaCha20-Poly1305), aligned with account crypto profile.
|
||||
*/
|
||||
import bareCrypto from 'bare-crypto'
|
||||
import b4a from 'b4a'
|
||||
import { PBKDF2_ITERATIONS, sealBytes } from './identity-account.js'
|
||||
|
||||
const { pbkdf2Sync, randomFillSync } = bareCrypto
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
@@ -55,7 +59,8 @@ export async function runSshKeygenCli(ctx, argv) {
|
||||
) {
|
||||
ctx.console.log(
|
||||
'Usage: ssh-keygen -t ed25519 -f KEYFILE [-N passphrase] [-C comment]\n' +
|
||||
'Bare OS: writes KEYFILE (JSON private envelope) and KEYFILE.pub (ssh-ed25519 line).\n'
|
||||
'Bare OS: writes KEYFILE (JSON private envelope) and KEYFILE.pub (ssh-ed25519 line).\n' +
|
||||
'Passphrase: schema 2 sealed key (PBKDF2 + ChaCha20-Poly1305); empty -N for plaintext schema 1.\n'
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -87,14 +92,6 @@ export async function runSshKeygenCli(ctx, argv) {
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (pass !== '') {
|
||||
ctx.console.error(
|
||||
'ssh-keygen: encrypted private keys are not implemented; use -N "" only'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
const vfs = ctx.vfs
|
||||
const b4 = ctx.b4a
|
||||
if (!vfs || typeof vfs.resolveLogical !== 'function' || !b4) {
|
||||
@@ -111,19 +108,46 @@ export async function runSshKeygenCli(ctx, argv) {
|
||||
const pubLine =
|
||||
'ssh-ed25519 ' + b64(blob) + ' ' + (comment || 'bare-os-ed25519') + '\n'
|
||||
|
||||
const privJson =
|
||||
JSON.stringify(
|
||||
{
|
||||
/** @type {Record<string, unknown>} */
|
||||
let privEnvelope
|
||||
if (pass !== '') {
|
||||
const salt = new Uint8Array(16)
|
||||
randomFillSync(salt)
|
||||
const dk = pbkdf2Sync(
|
||||
utf8Bytes(pass),
|
||||
salt,
|
||||
PBKDF2_ITERATIONS,
|
||||
32,
|
||||
'sha256'
|
||||
)
|
||||
const inner = JSON.stringify({
|
||||
sk: b64(secRaw),
|
||||
pk: b64(pubRaw)
|
||||
})
|
||||
const sealed = sealBytes(dk, utf8Bytes(inner))
|
||||
privEnvelope = {
|
||||
bareOsKeySchema: 2,
|
||||
kty: 'ed25519',
|
||||
kdf: 'pbkdf2-sha256',
|
||||
aead: 'chacha20-poly1305',
|
||||
iterations: PBKDF2_ITERATIONS,
|
||||
salt: b64(salt),
|
||||
sealed: b64(sealed),
|
||||
comment: comment || 'bare-os-ed25519',
|
||||
atMs: Date.now()
|
||||
}
|
||||
} else {
|
||||
privEnvelope = {
|
||||
bareOsKeySchema: 1,
|
||||
kty: 'ed25519',
|
||||
sk: b64(secRaw),
|
||||
pk: b64(pubRaw),
|
||||
comment: comment || 'bare-os-ed25519',
|
||||
atMs: Date.now()
|
||||
},
|
||||
null,
|
||||
2
|
||||
) + '\n'
|
||||
}
|
||||
}
|
||||
|
||||
const privJson = JSON.stringify(privEnvelope, null, 2) + '\n'
|
||||
|
||||
const absKey = vfs.resolveLogical(keyPath)
|
||||
const absPub = vfs.resolveLogical(keyPath + '.pub')
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Minimal WARC 1.0 tooling for Bare OS (no external WARC libraries).
|
||||
* Supports listing record summaries and appending a single response record from a VFS file.
|
||||
*/
|
||||
|
||||
import b4a from 'b4a'
|
||||
|
||||
const CRLF = '\r\n'
|
||||
|
||||
/**
|
||||
* @param {Record<string, string>} fields
|
||||
*/
|
||||
function warcHeaderBlock(fields) {
|
||||
const lines = ['WARC/1.0']
|
||||
for (const [k, v] of Object.entries(fields)) {
|
||||
const val = String(v).replace(/\r?\n/g, ' ')
|
||||
lines.push(`${k}: ${val}`)
|
||||
}
|
||||
lines.push('')
|
||||
lines.push('')
|
||||
return b4a.from(lines.join(CRLF), 'utf8')
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse WARC file buffer: yield { type, targetUri, contentLength } per record (best-effort).
|
||||
* @param {Uint8Array} buf
|
||||
*/
|
||||
function* iterateWarcRecords(buf) {
|
||||
let off = 0
|
||||
const u8 = buf instanceof Uint8Array ? buf : new Uint8Array(buf)
|
||||
while (off < u8.length) {
|
||||
const start = off
|
||||
const idx = indexOfHeaderEnd(u8, off)
|
||||
if (idx < 0) break
|
||||
const headerBytes = u8.subarray(off, idx)
|
||||
off = idx + 4
|
||||
const headerText = b4a.toString(headerBytes, 'utf8')
|
||||
const cl = parseWarcHeaderNumber(headerText, 'Content-Length')
|
||||
const warcType = parseWarcHeaderString(headerText, 'WARC-Type')
|
||||
const targetUri = parseWarcHeaderString(headerText, 'WARC-Target-URI')
|
||||
if (cl > 0 && off + cl <= u8.length) {
|
||||
yield {
|
||||
type: warcType || 'unknown',
|
||||
targetUri: targetUri || '',
|
||||
contentLength: cl,
|
||||
headerOffset: start
|
||||
}
|
||||
off += cl
|
||||
if (off < u8.length) {
|
||||
const pad = (4 - (cl % 4 || 4)) % 4
|
||||
off += pad
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Uint8Array} u8
|
||||
* @param {number} from
|
||||
*/
|
||||
function indexOfHeaderEnd(u8, from) {
|
||||
for (let i = from; i + 3 < u8.length; i++) {
|
||||
if (
|
||||
u8[i] === 0xd &&
|
||||
u8[i + 1] === 0xa &&
|
||||
u8[i + 2] === 0xd &&
|
||||
u8[i + 3] === 0xa
|
||||
) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} headerText
|
||||
* @param {string} name
|
||||
*/
|
||||
function parseWarcHeaderNumber(headerText, name) {
|
||||
const re = new RegExp('^' + name + ':\\s*(\\d+)\\s*$', 'mi')
|
||||
const m = headerText.match(re)
|
||||
return m ? Number.parseInt(m[1], 10) : 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} headerText
|
||||
* @param {string} name
|
||||
*/
|
||||
function parseWarcHeaderString(headerText, name) {
|
||||
const re = new RegExp('^' + name + ':\\s*(.+)\\s*$', 'mi')
|
||||
const m = headerText.match(re)
|
||||
return m ? m[1].trim() : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string[]} argv
|
||||
*/
|
||||
export async function runWarcCli(ctx, argv) {
|
||||
const args = argv.slice(1)
|
||||
if (
|
||||
!args.length ||
|
||||
args[0] === '-h' ||
|
||||
args[0] === '--help' ||
|
||||
args[0] === 'help'
|
||||
) {
|
||||
ctx.console.log(
|
||||
'Usage:\n' +
|
||||
' warc list FILE.warc — summarize WARC records\n' +
|
||||
' warc write-response -o OUT -u URI -i INPUT — append one response record (VFS paths)\n'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const vfs = ctx.vfs
|
||||
if (!vfs || typeof vfs.readFile !== 'function' || typeof vfs.writeFile !== 'function') {
|
||||
ctx.console.error('warc: vfs unavailable')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
if (args[0] === 'list' && args[1]) {
|
||||
const p = String(args[1])
|
||||
const abs = vfs.resolveLogical(p)
|
||||
const buf = await vfs.readFile(abs)
|
||||
if (!buf) {
|
||||
ctx.console.error('warc: cannot read ' + p)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
const u8 = buf instanceof Uint8Array ? buf : new Uint8Array(buf)
|
||||
let n = 0
|
||||
for (const rec of iterateWarcRecords(u8)) {
|
||||
n++
|
||||
ctx.console.log(
|
||||
`${n}\t${rec.type}\t${rec.targetUri || '-'}\t${rec.contentLength}b`
|
||||
)
|
||||
}
|
||||
if (n === 0) ctx.console.log('(no records parsed)')
|
||||
return
|
||||
}
|
||||
|
||||
if (args[0] === 'write-response') {
|
||||
let outPath = ''
|
||||
let uri = ''
|
||||
let inPath = ''
|
||||
for (let i = 1; i < args.length; i++) {
|
||||
const a = args[i]
|
||||
if (a === '-o') outPath = String(args[++i] || '')
|
||||
else if (a === '-u') uri = String(args[++i] || '')
|
||||
else if (a === '-i') inPath = String(args[++i] || '')
|
||||
else {
|
||||
ctx.console.error('warc: unknown argument ' + a)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!outPath || !uri || !inPath) {
|
||||
ctx.console.error('warc: write-response requires -o OUT -u URI -i INPUT')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
const absIn = vfs.resolveLogical(inPath)
|
||||
const body = await vfs.readFile(absIn)
|
||||
if (!body) {
|
||||
ctx.console.error('warc: cannot read input ' + inPath)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
const payload = body instanceof Uint8Array ? body : new Uint8Array(body)
|
||||
const date = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z')
|
||||
const recordId = `<urn:uuid:${hexRandom(32)}>`
|
||||
const fields = {
|
||||
'WARC-Type': 'response',
|
||||
'WARC-Target-URI': uri,
|
||||
'WARC-Date': date,
|
||||
'WARC-Record-ID': recordId,
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'Content-Length': String(payload.length)
|
||||
}
|
||||
const head = warcHeaderBlock(fields)
|
||||
const absOut = vfs.resolveLogical(outPath)
|
||||
let existing = new Uint8Array(0)
|
||||
try {
|
||||
const prev = await vfs.readFile(absOut)
|
||||
if (prev) existing = prev instanceof Uint8Array ? prev : new Uint8Array(prev)
|
||||
} catch {
|
||||
/* new file */
|
||||
}
|
||||
const pad = (4 - (payload.length % 4 || 4)) % 4
|
||||
const tail = new Uint8Array(pad)
|
||||
const merged = new Uint8Array(
|
||||
existing.length + head.length + payload.length + tail.length
|
||||
)
|
||||
merged.set(existing, 0)
|
||||
merged.set(head, existing.length)
|
||||
merged.set(payload, existing.length + head.length)
|
||||
merged.set(tail, existing.length + head.length + payload.length)
|
||||
await vfs.writeFile(absOut, merged)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.console.error('warc: unknown subcommand (try warc --help)')
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
|
||||
function hexRandom(nibbles) {
|
||||
const bytes = Math.ceil(nibbles / 2)
|
||||
const u = new Uint8Array(bytes)
|
||||
if (typeof globalThis.crypto?.getRandomValues === 'function') {
|
||||
globalThis.crypto.getRandomValues(u)
|
||||
} else {
|
||||
for (let i = 0; i < bytes; i++) u[i] = (Math.random() * 256) | 0
|
||||
}
|
||||
let s = ''
|
||||
for (let i = 0; i < bytes; i++) s += u[i].toString(16).padStart(2, '0')
|
||||
return s.slice(0, nibbles)
|
||||
}
|
||||
@@ -3,12 +3,36 @@
|
||||
"section": 1,
|
||||
"title": "basenc",
|
||||
"synopsis": [
|
||||
"basenc [OPTION]... [OPERAND]..."
|
||||
"basenc [--base16 | --base32 | --base64] [OPTION]... [OPERAND]..."
|
||||
],
|
||||
"description": "Encode or decode binary data. Default base is --base16 (hex). --base32 and --base64 follow RFC 4648. -d decodes text input to raw bytes on stdout. -w wraps encoded output (base32/base64). Defined in packages/bare-os-coreutils/src/basenc.js.",
|
||||
"options": [
|
||||
{
|
||||
"flag": "--base16",
|
||||
"meaning": "Hexadecimal (default when no base flag is given)."
|
||||
},
|
||||
{
|
||||
"flag": "--base32",
|
||||
"meaning": "RFC 4648 Base32."
|
||||
},
|
||||
{
|
||||
"flag": "--base64",
|
||||
"meaning": "RFC 4648 Base64."
|
||||
},
|
||||
{
|
||||
"flag": "-d, --decode",
|
||||
"meaning": "Decode from text to raw bytes."
|
||||
},
|
||||
{
|
||||
"flag": "-w, --wrap COLS",
|
||||
"meaning": "Wrap encoded lines (0 = no wrap)."
|
||||
}
|
||||
],
|
||||
"description": "Bare OS implementation of basenc. Full behavior is defined in packages/bare-os-coreutils/src/basenc.js.",
|
||||
"options": [],
|
||||
"keywords": [
|
||||
"basenc",
|
||||
"base16",
|
||||
"base32",
|
||||
"base64",
|
||||
"bare-os",
|
||||
"coreutils"
|
||||
]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
const B32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
|
||||
|
||||
function bareHexEncode(u8) {
|
||||
let s = ''
|
||||
for (let i = 0; i < u8.length; i++) {
|
||||
@@ -17,16 +19,94 @@ function bareHexDecode(s) {
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB32EncodeBytes(u8) {
|
||||
let out = ''
|
||||
let i = 0
|
||||
let buf = 0
|
||||
let bits = 0
|
||||
for (; i < u8.length; i++) {
|
||||
buf = (buf << 8) | u8[i]
|
||||
bits += 8
|
||||
while (bits >= 5) {
|
||||
bits -= 5
|
||||
out += B32[(buf >> bits) & 31]
|
||||
}
|
||||
}
|
||||
if (bits > 0) out += B32[(buf << (5 - bits)) & 31]
|
||||
while (out.length % 8 !== 0) out += '='
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB32DecodeToU8(s) {
|
||||
const t = String(s).replace(/\s+/g, '').replace(/=+$/, '')
|
||||
let buf = 0
|
||||
let bits = 0
|
||||
const bytes = []
|
||||
for (let i = 0; i < t.length; i++) {
|
||||
const c = t[i]
|
||||
const v = B32.indexOf(c)
|
||||
if (v < 0) throw new Error('invalid base32 character')
|
||||
buf = (buf << 5) | v
|
||||
bits += 5
|
||||
if (bits >= 8) {
|
||||
bits -= 8
|
||||
bytes.push((buf >> bits) & 255)
|
||||
}
|
||||
}
|
||||
return new Uint8Array(bytes)
|
||||
}
|
||||
|
||||
function bareB64EncodeBytes(u8) {
|
||||
const B =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
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 += B[(n >> 18) & 63] + B[(n >> 12) & 63] + B[(n >> 6) & 63] + B[n & 63]
|
||||
}
|
||||
const rest = u8.length - i
|
||||
if (rest === 1) {
|
||||
const n = u8[i] << 16
|
||||
out += B[(n >> 18) & 63] + B[(n >> 12) & 63] + '=='
|
||||
} else if (rest === 2) {
|
||||
const n = (u8[i] << 16) | (u8[i + 1] << 8)
|
||||
out += B[(n >> 18) & 63] + B[(n >> 12) & 63] + B[(n >> 6) & 63] + '='
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB64DecodeToU8(s) {
|
||||
const t = String(s).replace(/\s+/g, '')
|
||||
if (typeof globalThis.Buffer !== 'undefined') {
|
||||
return new Uint8Array(globalThis.Buffer.from(t, 'base64'))
|
||||
}
|
||||
if (typeof globalThis.atob === 'function') {
|
||||
const bin = globalThis.atob(t)
|
||||
const out = new Uint8Array(bin.length)
|
||||
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i) & 255
|
||||
return out
|
||||
}
|
||||
throw new Error('base64 decode requires Buffer or atob')
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
let decode = false
|
||||
let base16 = false
|
||||
let base32 = false
|
||||
let base64 = false
|
||||
let wrap = 0
|
||||
const paths = []
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
const a = argv[i]
|
||||
if (a === '-h' || a === '--help') {
|
||||
ctx.console.log(
|
||||
'usage: basenc --base16 [-d] [FILE]\n' +
|
||||
'Encode or decode hex (Base16). Other bases are not implemented.'
|
||||
'usage: basenc [--base16 | --base32 | --base64] [-d] [-w COLS] [FILE]\n' +
|
||||
' --base16 hex (default when no base flag)\n' +
|
||||
' --base32 RFC 4648 Base32\n' +
|
||||
' --base64 RFC 4648 Base64\n' +
|
||||
' -d decode from text to raw bytes (stdout)\n' +
|
||||
' -w COLS wrap encoded output (base64/base32 only; 0 = no wrap)'
|
||||
)
|
||||
ctx.exitCode = 0
|
||||
return
|
||||
@@ -39,6 +119,19 @@ async function run(ctx, argv) {
|
||||
base16 = true
|
||||
continue
|
||||
}
|
||||
if (a === '--base32') {
|
||||
base32 = true
|
||||
continue
|
||||
}
|
||||
if (a === '--base64') {
|
||||
base64 = true
|
||||
continue
|
||||
}
|
||||
if ((a === '-w' || a === '--wrap') && argv[i + 1]) {
|
||||
wrap = Number.parseInt(argv[++i], 10)
|
||||
if (!Number.isFinite(wrap) || wrap < 0) wrap = 0
|
||||
continue
|
||||
}
|
||||
if (a.startsWith('-')) {
|
||||
ctx.console.error('basenc: unsupported option ' + a)
|
||||
ctx.exitCode = 1
|
||||
@@ -46,11 +139,15 @@ async function run(ctx, argv) {
|
||||
}
|
||||
paths.push(a)
|
||||
}
|
||||
if (!base16) {
|
||||
ctx.console.error('basenc: requires --base16')
|
||||
|
||||
const modeCount = (base16 ? 1 : 0) + (base32 ? 1 : 0) + (base64 ? 1 : 0)
|
||||
if (modeCount > 1) {
|
||||
ctx.console.error('basenc: specify at most one of --base16, --base32, --base64')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (modeCount === 0) base16 = true
|
||||
|
||||
const b4 = ctx.b4a
|
||||
let buf
|
||||
if (!paths.length || paths[0] === '-') {
|
||||
@@ -64,6 +161,8 @@ async function run(ctx, argv) {
|
||||
}
|
||||
buf = b instanceof Uint8Array ? b : new Uint8Array(b)
|
||||
}
|
||||
|
||||
if (base16) {
|
||||
if (decode) {
|
||||
const text = b4.toString(buf)
|
||||
let raw
|
||||
@@ -83,4 +182,78 @@ async function run(ctx, argv) {
|
||||
return
|
||||
}
|
||||
ctx.console.log(bareHexEncode(buf))
|
||||
return
|
||||
}
|
||||
|
||||
if (base32) {
|
||||
if (decode) {
|
||||
const text = b4.toString(buf)
|
||||
let raw
|
||||
try {
|
||||
raw = bareB32DecodeToU8(text)
|
||||
} catch (e) {
|
||||
ctx.console.error('basenc: ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (!bareOsEmitRaw(ctx, raw)) {
|
||||
ctx.console.error(
|
||||
'basenc: decode output requires process.stdout.write or ctx.bareOsBinWrite'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
let enc = bareB32EncodeBytes(buf)
|
||||
if (wrap > 0) {
|
||||
const lines = []
|
||||
for (let i = 0; i < enc.length; i += wrap) {
|
||||
lines.push(enc.slice(i, i + wrap))
|
||||
}
|
||||
enc = lines.join('\n')
|
||||
}
|
||||
ctx.console.log(enc)
|
||||
return
|
||||
}
|
||||
|
||||
if (base64) {
|
||||
if (decode) {
|
||||
const text = new TextDecoder().decode(buf)
|
||||
let raw
|
||||
try {
|
||||
raw = bareB64DecodeToU8(text)
|
||||
} catch (e) {
|
||||
ctx.console.error('basenc: ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (!bareOsEmitRaw(ctx, raw)) {
|
||||
ctx.console.error(
|
||||
'basenc: decode output requires process.stdout.write or ctx.bareOsBinWrite'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
let enc
|
||||
if (typeof globalThis.btoa === 'function') {
|
||||
let s = ''
|
||||
const step = 0x8000
|
||||
for (let i = 0; i < buf.length; i += step) {
|
||||
const chunk = buf.subarray(i, i + step)
|
||||
s += String.fromCharCode.apply(null, chunk)
|
||||
}
|
||||
enc = globalThis.btoa(s)
|
||||
} else {
|
||||
enc = bareB64EncodeBytes(buf)
|
||||
}
|
||||
if (wrap > 0) {
|
||||
const lines = []
|
||||
for (let i = 0; i < enc.length; i += wrap) {
|
||||
lines.push(enc.slice(i, i + wrap))
|
||||
}
|
||||
enc = lines.join('\n')
|
||||
}
|
||||
ctx.console.log(enc)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
async function run(ctx, argv) {
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
if (argv[i] === '-h' || argv[i] === '--help') {
|
||||
ctx.console.log('usage: hostid\nPrint a numeric host identifier (session-derived stub).')
|
||||
ctx.console.log(
|
||||
'usage: hostid\nPrint an 8-digit hex host identifier: HOSTID env, else identity public key hash, else session-derived.'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (argv[i].startsWith('-')) {
|
||||
@@ -15,6 +17,20 @@ async function run(ctx, argv) {
|
||||
ctx.console.log(e.HOSTID.toLowerCase())
|
||||
return
|
||||
}
|
||||
const id = ctx.identity
|
||||
const pk =
|
||||
id &&
|
||||
id.state === 'unlocked' &&
|
||||
id.publicKey instanceof Uint8Array &&
|
||||
id.publicKey.length
|
||||
? id.publicKey
|
||||
: null
|
||||
if (pk) {
|
||||
let h = 0
|
||||
for (let i = 0; i < pk.length; i++) h = (Math.imul(31, h) + pk[i]) >>> 0
|
||||
ctx.console.log(h.toString(16).padStart(8, '0'))
|
||||
return
|
||||
}
|
||||
const seed = e.BARE_OS_SESSION_ID || e.HOSTNAME || 'bare-os'
|
||||
let h = 0
|
||||
for (let i = 0; i < seed.length; i++)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
async function run(ctx, argv) {
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
if (argv[i] === '-h' || argv[i] === '--help') {
|
||||
ctx.console.log('usage: users\nPrint login names (single-session stub).')
|
||||
ctx.console.log(
|
||||
'usage: users\nPrint login names for the active Bare OS session (USER / LOGNAME from VFS env).'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (argv[i].startsWith('-')) {
|
||||
|
||||
@@ -87,6 +87,8 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
return false
|
||||
}
|
||||
|
||||
const B32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
|
||||
|
||||
function bareHexEncode(u8) {
|
||||
let s = ''
|
||||
for (let i = 0; i < u8.length; i++) {
|
||||
@@ -106,16 +108,94 @@ function bareHexDecode(s) {
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB32EncodeBytes(u8) {
|
||||
let out = ''
|
||||
let i = 0
|
||||
let buf = 0
|
||||
let bits = 0
|
||||
for (; i < u8.length; i++) {
|
||||
buf = (buf << 8) | u8[i]
|
||||
bits += 8
|
||||
while (bits >= 5) {
|
||||
bits -= 5
|
||||
out += B32[(buf >> bits) & 31]
|
||||
}
|
||||
}
|
||||
if (bits > 0) out += B32[(buf << (5 - bits)) & 31]
|
||||
while (out.length % 8 !== 0) out += '='
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB32DecodeToU8(s) {
|
||||
const t = String(s).replace(/\s+/g, '').replace(/=+$/, '')
|
||||
let buf = 0
|
||||
let bits = 0
|
||||
const bytes = []
|
||||
for (let i = 0; i < t.length; i++) {
|
||||
const c = t[i]
|
||||
const v = B32.indexOf(c)
|
||||
if (v < 0) throw new Error('invalid base32 character')
|
||||
buf = (buf << 5) | v
|
||||
bits += 5
|
||||
if (bits >= 8) {
|
||||
bits -= 8
|
||||
bytes.push((buf >> bits) & 255)
|
||||
}
|
||||
}
|
||||
return new Uint8Array(bytes)
|
||||
}
|
||||
|
||||
function bareB64EncodeBytes(u8) {
|
||||
const B =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
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 += B[(n >> 18) & 63] + B[(n >> 12) & 63] + B[(n >> 6) & 63] + B[n & 63]
|
||||
}
|
||||
const rest = u8.length - i
|
||||
if (rest === 1) {
|
||||
const n = u8[i] << 16
|
||||
out += B[(n >> 18) & 63] + B[(n >> 12) & 63] + '=='
|
||||
} else if (rest === 2) {
|
||||
const n = (u8[i] << 16) | (u8[i + 1] << 8)
|
||||
out += B[(n >> 18) & 63] + B[(n >> 12) & 63] + B[(n >> 6) & 63] + '='
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
function bareB64DecodeToU8(s) {
|
||||
const t = String(s).replace(/\s+/g, '')
|
||||
if (typeof globalThis.Buffer !== 'undefined') {
|
||||
return new Uint8Array(globalThis.Buffer.from(t, 'base64'))
|
||||
}
|
||||
if (typeof globalThis.atob === 'function') {
|
||||
const bin = globalThis.atob(t)
|
||||
const out = new Uint8Array(bin.length)
|
||||
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i) & 255
|
||||
return out
|
||||
}
|
||||
throw new Error('base64 decode requires Buffer or atob')
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
let decode = false
|
||||
let base16 = false
|
||||
let base32 = false
|
||||
let base64 = false
|
||||
let wrap = 0
|
||||
const paths = []
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
const a = argv[i]
|
||||
if (a === '-h' || a === '--help') {
|
||||
ctx.console.log(
|
||||
'usage: basenc --base16 [-d] [FILE]\n' +
|
||||
'Encode or decode hex (Base16). Other bases are not implemented.'
|
||||
'usage: basenc [--base16 | --base32 | --base64] [-d] [-w COLS] [FILE]\n' +
|
||||
' --base16 hex (default when no base flag)\n' +
|
||||
' --base32 RFC 4648 Base32\n' +
|
||||
' --base64 RFC 4648 Base64\n' +
|
||||
' -d decode from text to raw bytes (stdout)\n' +
|
||||
' -w COLS wrap encoded output (base64/base32 only; 0 = no wrap)'
|
||||
)
|
||||
ctx.exitCode = 0
|
||||
return
|
||||
@@ -128,6 +208,19 @@ async function run(ctx, argv) {
|
||||
base16 = true
|
||||
continue
|
||||
}
|
||||
if (a === '--base32') {
|
||||
base32 = true
|
||||
continue
|
||||
}
|
||||
if (a === '--base64') {
|
||||
base64 = true
|
||||
continue
|
||||
}
|
||||
if ((a === '-w' || a === '--wrap') && argv[i + 1]) {
|
||||
wrap = Number.parseInt(argv[++i], 10)
|
||||
if (!Number.isFinite(wrap) || wrap < 0) wrap = 0
|
||||
continue
|
||||
}
|
||||
if (a.startsWith('-')) {
|
||||
ctx.console.error('basenc: unsupported option ' + a)
|
||||
ctx.exitCode = 1
|
||||
@@ -135,11 +228,15 @@ async function run(ctx, argv) {
|
||||
}
|
||||
paths.push(a)
|
||||
}
|
||||
if (!base16) {
|
||||
ctx.console.error('basenc: requires --base16')
|
||||
|
||||
const modeCount = (base16 ? 1 : 0) + (base32 ? 1 : 0) + (base64 ? 1 : 0)
|
||||
if (modeCount > 1) {
|
||||
ctx.console.error('basenc: specify at most one of --base16, --base32, --base64')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (modeCount === 0) base16 = true
|
||||
|
||||
const b4 = ctx.b4a
|
||||
let buf
|
||||
if (!paths.length || paths[0] === '-') {
|
||||
@@ -153,6 +250,8 @@ async function run(ctx, argv) {
|
||||
}
|
||||
buf = b instanceof Uint8Array ? b : new Uint8Array(b)
|
||||
}
|
||||
|
||||
if (base16) {
|
||||
if (decode) {
|
||||
const text = b4.toString(buf)
|
||||
let raw
|
||||
@@ -172,4 +271,78 @@ async function run(ctx, argv) {
|
||||
return
|
||||
}
|
||||
ctx.console.log(bareHexEncode(buf))
|
||||
return
|
||||
}
|
||||
|
||||
if (base32) {
|
||||
if (decode) {
|
||||
const text = b4.toString(buf)
|
||||
let raw
|
||||
try {
|
||||
raw = bareB32DecodeToU8(text)
|
||||
} catch (e) {
|
||||
ctx.console.error('basenc: ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (!bareOsEmitRaw(ctx, raw)) {
|
||||
ctx.console.error(
|
||||
'basenc: decode output requires process.stdout.write or ctx.bareOsBinWrite'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
let enc = bareB32EncodeBytes(buf)
|
||||
if (wrap > 0) {
|
||||
const lines = []
|
||||
for (let i = 0; i < enc.length; i += wrap) {
|
||||
lines.push(enc.slice(i, i + wrap))
|
||||
}
|
||||
enc = lines.join('\n')
|
||||
}
|
||||
ctx.console.log(enc)
|
||||
return
|
||||
}
|
||||
|
||||
if (base64) {
|
||||
if (decode) {
|
||||
const text = new TextDecoder().decode(buf)
|
||||
let raw
|
||||
try {
|
||||
raw = bareB64DecodeToU8(text)
|
||||
} catch (e) {
|
||||
ctx.console.error('basenc: ' + (e.message || e))
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
if (!bareOsEmitRaw(ctx, raw)) {
|
||||
ctx.console.error(
|
||||
'basenc: decode output requires process.stdout.write or ctx.bareOsBinWrite'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
let enc
|
||||
if (typeof globalThis.btoa === 'function') {
|
||||
let s = ''
|
||||
const step = 0x8000
|
||||
for (let i = 0; i < buf.length; i += step) {
|
||||
const chunk = buf.subarray(i, i + step)
|
||||
s += String.fromCharCode.apply(null, chunk)
|
||||
}
|
||||
enc = globalThis.btoa(s)
|
||||
} else {
|
||||
enc = bareB64EncodeBytes(buf)
|
||||
}
|
||||
if (wrap > 0) {
|
||||
const lines = []
|
||||
for (let i = 0; i < enc.length; i += wrap) {
|
||||
lines.push(enc.slice(i, i + wrap))
|
||||
}
|
||||
enc = lines.join('\n')
|
||||
}
|
||||
ctx.console.log(enc)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
async function run(ctx, argv) {
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
if (argv[i] === '-h' || argv[i] === '--help') {
|
||||
ctx.console.log('usage: hostid\nPrint a numeric host identifier (session-derived stub).')
|
||||
ctx.console.log(
|
||||
'usage: hostid\nPrint an 8-digit hex host identifier: HOSTID env, else identity public key hash, else session-derived.'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (argv[i].startsWith('-')) {
|
||||
@@ -104,6 +106,20 @@ async function run(ctx, argv) {
|
||||
ctx.console.log(e.HOSTID.toLowerCase())
|
||||
return
|
||||
}
|
||||
const id = ctx.identity
|
||||
const pk =
|
||||
id &&
|
||||
id.state === 'unlocked' &&
|
||||
id.publicKey instanceof Uint8Array &&
|
||||
id.publicKey.length
|
||||
? id.publicKey
|
||||
: null
|
||||
if (pk) {
|
||||
let h = 0
|
||||
for (let i = 0; i < pk.length; i++) h = (Math.imul(31, h) + pk[i]) >>> 0
|
||||
ctx.console.log(h.toString(16).padStart(8, '0'))
|
||||
return
|
||||
}
|
||||
const seed = e.BARE_OS_SESSION_ID || e.HOSTNAME || 'bare-os'
|
||||
let h = 0
|
||||
for (let i = 0; i < seed.length; i++)
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/* BARE_OS_BIN_API 1.0.0 — stub; booter delegates to systemctl-cli (kernel-runner). */
|
||||
/** Booter delegates journalctl to systemctl-cli.js (kernel-runner). */
|
||||
/* BARE_OS_BIN_API 1.0.0 — delegates to booter systemctl-cli when ctx exposes bareOsRunSystemctlCli. */
|
||||
async function run(ctx, argv) {
|
||||
if (typeof ctx.bareOsRunSystemctlCli === 'function') {
|
||||
await ctx.bareOsRunSystemctlCli(argv)
|
||||
return
|
||||
}
|
||||
ctx.console.error(
|
||||
'journalctl: not executed in host booter (delegation missing)'
|
||||
'journalctl: ctx.bareOsRunSystemctlCli missing — run under host booter / upgrade ctx API'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/* BARE_OS_BIN_API 1.0.0 — stub; booter delegates to systemctl-cli (kernel-runner). */
|
||||
/** Booter delegates systemctl to systemctl-cli.js (kernel-runner). */
|
||||
/* BARE_OS_BIN_API 1.0.0 — delegates to booter systemctl-cli when ctx exposes bareOsRunSystemctlCli. */
|
||||
async function run(ctx, argv) {
|
||||
if (typeof ctx.bareOsRunSystemctlCli === 'function') {
|
||||
await ctx.bareOsRunSystemctlCli(argv)
|
||||
return
|
||||
}
|
||||
ctx.console.error(
|
||||
'systemctl: not executed in host booter (delegation missing)'
|
||||
'systemctl: ctx.bareOsRunSystemctlCli missing — run under host booter / upgrade ctx API'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
async function run(ctx, argv) {
|
||||
for (let i = 1; i < argv.length; i++) {
|
||||
if (argv[i] === '-h' || argv[i] === '--help') {
|
||||
ctx.console.log('usage: users\nPrint login names (single-session stub).')
|
||||
ctx.console.log(
|
||||
'usage: users\nPrint login names for the active Bare OS session (USER / LOGNAME from VFS env).'
|
||||
)
|
||||
return
|
||||
}
|
||||
if (argv[i].startsWith('-')) {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"version": 1,
|
||||
"bundles": [
|
||||
{
|
||||
"path": "/lib/bare/bundles/safetyCatch.js",
|
||||
"path": "/lib/bare/bundles/hypercoreIdEncoding.js",
|
||||
"keys": [
|
||||
"safetyCatch"
|
||||
"hypercoreIdEncoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -14,9 +14,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/hypercoreIdEncoding.js",
|
||||
"path": "/lib/bare/bundles/safetyCatch.js",
|
||||
"keys": [
|
||||
"hypercoreIdEncoding"
|
||||
"safetyCatch"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -25,6 +25,12 @@
|
||||
"compactEncoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/protomux.js",
|
||||
"keys": [
|
||||
"protomux"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUrl.js",
|
||||
"keys": [
|
||||
@@ -32,9 +38,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/protomux.js",
|
||||
"path": "/lib/bare/bundles/bareEvents.js",
|
||||
"keys": [
|
||||
"protomux"
|
||||
"bareEvents"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -49,24 +55,12 @@
|
||||
"barePath"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareEvents.js",
|
||||
"keys": [
|
||||
"bareEvents"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAbort.js",
|
||||
"keys": [
|
||||
"bareAbort"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAbortController.js",
|
||||
"keys": [
|
||||
"bareAbortController"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAnsiEscapes.js",
|
||||
"keys": [
|
||||
@@ -74,9 +68,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareReadline.js",
|
||||
"path": "/lib/bare/bundles/bareAbortController.js",
|
||||
"keys": [
|
||||
"bareReadline"
|
||||
"bareAbortController"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -92,9 +86,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareApk.js",
|
||||
"path": "/lib/bare/bundles/bareReadline.js",
|
||||
"keys": [
|
||||
"bareApk"
|
||||
"bareReadline"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -104,9 +98,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/fetch.js",
|
||||
"path": "/lib/bare/bundles/bareAppKit.js",
|
||||
"keys": [
|
||||
"fetch"
|
||||
"bareAppKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -122,9 +116,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareAppKit.js",
|
||||
"path": "/lib/bare/bundles/bareApk.js",
|
||||
"keys": [
|
||||
"bareAppKit"
|
||||
"bareApk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/fetch.js",
|
||||
"keys": [
|
||||
"fetch"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -140,9 +140,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBluetoothApple.js",
|
||||
"path": "/lib/bare/bundles/bareBundle.js",
|
||||
"keys": [
|
||||
"bareBluetoothApple"
|
||||
"bareBundle"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -152,9 +152,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareBundle.js",
|
||||
"path": "/lib/bare/bundles/bareBluetoothApple.js",
|
||||
"keys": [
|
||||
"bareBundle"
|
||||
"bareBluetoothApple"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -169,12 +169,6 @@
|
||||
"bareBoot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDebugLog.js",
|
||||
"keys": [
|
||||
"bareDebugLog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareConsole.js",
|
||||
"keys": [
|
||||
@@ -199,6 +193,12 @@
|
||||
"bareDelta"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDebugLog.js",
|
||||
"keys": [
|
||||
"bareDebugLog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDaemon.js",
|
||||
"keys": [
|
||||
@@ -241,12 +241,6 @@
|
||||
"bareDgram"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFfmpegEncodings.js",
|
||||
"keys": [
|
||||
"bareFfmpegEncodings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFfmpeg.js",
|
||||
"keys": [
|
||||
@@ -254,15 +248,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareGif.js",
|
||||
"path": "/lib/bare/bundles/bareFfmpegEncodings.js",
|
||||
"keys": [
|
||||
"bareGif"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFormat.js",
|
||||
"keys": [
|
||||
"bareFormat"
|
||||
"bareFfmpegEncodings"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -271,6 +259,12 @@
|
||||
"bareFormData"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFormat.js",
|
||||
"keys": [
|
||||
"bareFormat"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFileLogger.js",
|
||||
"keys": [
|
||||
@@ -278,21 +272,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareGtk.js",
|
||||
"path": "/lib/bare/bundles/bareGif.js",
|
||||
"keys": [
|
||||
"bareGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFs.js",
|
||||
"keys": [
|
||||
"bareFs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHeif.js",
|
||||
"keys": [
|
||||
"bareHeif"
|
||||
"bareGif"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -301,12 +283,30 @@
|
||||
"bareHrtime"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHeif.js",
|
||||
"keys": [
|
||||
"bareHeif"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareGtk.js",
|
||||
"keys": [
|
||||
"bareGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHttpParser.js",
|
||||
"keys": [
|
||||
"bareHttpParser"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareFs.js",
|
||||
"keys": [
|
||||
"bareFs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareIco.js",
|
||||
"keys": [
|
||||
@@ -320,15 +320,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspect.js",
|
||||
"path": "/lib/bare/bundles/bareHttps.js",
|
||||
"keys": [
|
||||
"bareInspect"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareIntl.js",
|
||||
"keys": [
|
||||
"bareIntl"
|
||||
"bareHttps"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -337,6 +331,12 @@
|
||||
"bareHttp1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspect.js",
|
||||
"keys": [
|
||||
"bareInspect"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareJpeg.js",
|
||||
"keys": [
|
||||
@@ -344,15 +344,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareHttps.js",
|
||||
"path": "/lib/bare/bundles/bareIntl.js",
|
||||
"keys": [
|
||||
"bareHttps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspector.js",
|
||||
"keys": [
|
||||
"bareInspector"
|
||||
"bareIntl"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -361,18 +355,24 @@
|
||||
"bareIpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLogger.js",
|
||||
"keys": [
|
||||
"bareLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLief.js",
|
||||
"keys": [
|
||||
"bareLief"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareInspector.js",
|
||||
"keys": [
|
||||
"bareInspector"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLogger.js",
|
||||
"keys": [
|
||||
"bareLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareLink.js",
|
||||
"keys": [
|
||||
@@ -385,18 +385,18 @@
|
||||
"bareMake"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModuleLexer.js",
|
||||
"keys": [
|
||||
"bareModuleLexer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModuleResolve.js",
|
||||
"keys": [
|
||||
"bareModuleResolve"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModuleLexer.js",
|
||||
"keys": [
|
||||
"bareModuleLexer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareModule.js",
|
||||
"keys": [
|
||||
@@ -451,12 +451,6 @@
|
||||
"bareMedia"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePack.js",
|
||||
"keys": [
|
||||
"barePack"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePerformance.js",
|
||||
"keys": [
|
||||
@@ -470,9 +464,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePipe.js",
|
||||
"path": "/lib/bare/bundles/barePack.js",
|
||||
"keys": [
|
||||
"barePipe"
|
||||
"barePack"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -482,15 +476,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareNodeRuntime.js",
|
||||
"path": "/lib/bare/bundles/barePipe.js",
|
||||
"keys": [
|
||||
"bareNodeRuntime"
|
||||
"barePipe"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePrebuild.js",
|
||||
"path": "/lib/bare/bundles/bareNodeRuntime.js",
|
||||
"keys": [
|
||||
"barePrebuild"
|
||||
"bareNodeRuntime"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -499,18 +493,24 @@
|
||||
"barePunycode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareDev.js",
|
||||
"keys": [
|
||||
"bareDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQuerystring.js",
|
||||
"keys": [
|
||||
"bareQuerystring"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQueueMicrotask.js",
|
||||
"keys": [
|
||||
"bareQueueMicrotask"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/barePrebuild.js",
|
||||
"keys": [
|
||||
"barePrebuild"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRealm.js",
|
||||
"keys": [
|
||||
@@ -518,9 +518,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareQueueMicrotask.js",
|
||||
"path": "/lib/bare/bundles/bareDev.js",
|
||||
"keys": [
|
||||
"bareQueueMicrotask"
|
||||
"bareDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -553,12 +553,6 @@
|
||||
"bareSemver"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRpc.js",
|
||||
"keys": [
|
||||
"bareRpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRepl.js",
|
||||
"keys": [
|
||||
@@ -566,9 +560,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRun.js",
|
||||
"path": "/lib/bare/bundles/bareRpc.js",
|
||||
"keys": [
|
||||
"bareRun"
|
||||
"bareRpc"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -583,12 +577,24 @@
|
||||
"bareSidecar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareRun.js",
|
||||
"keys": [
|
||||
"bareRun"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStringDecoder.js",
|
||||
"keys": [
|
||||
"bareStringDecoder"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStdio.js",
|
||||
"keys": [
|
||||
"bareStdio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStorage.js",
|
||||
"keys": [
|
||||
@@ -602,9 +608,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStdio.js",
|
||||
"path": "/lib/bare/bundles/bareStructuredClone.js",
|
||||
"keys": [
|
||||
"bareStdio"
|
||||
"bareStructuredClone"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -613,36 +619,12 @@
|
||||
"bareSvg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareStructuredClone.js",
|
||||
"keys": [
|
||||
"bareStructuredClone"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSystemLogger.js",
|
||||
"keys": [
|
||||
"bareSystemLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareSubprocess.js",
|
||||
"keys": [
|
||||
"bareSubprocess"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTcp.js",
|
||||
"keys": [
|
||||
"bareTcp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTap.js",
|
||||
"keys": [
|
||||
"bareTap"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTiff.js",
|
||||
"keys": [
|
||||
@@ -650,9 +632,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareThread.js",
|
||||
"path": "/lib/bare/bundles/bareSystemLogger.js",
|
||||
"keys": [
|
||||
"bareThread"
|
||||
"bareSystemLogger"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTap.js",
|
||||
"keys": [
|
||||
"bareTap"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -662,9 +650,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareType.js",
|
||||
"path": "/lib/bare/bundles/bareTcp.js",
|
||||
"keys": [
|
||||
"bareType"
|
||||
"bareTcp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareThread.js",
|
||||
"keys": [
|
||||
"bareThread"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -674,9 +668,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUiKit.js",
|
||||
"path": "/lib/bare/bundles/bareType.js",
|
||||
"keys": [
|
||||
"bareUiKit"
|
||||
"bareType"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -685,6 +679,12 @@
|
||||
"bareTls"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUiKit.js",
|
||||
"keys": [
|
||||
"bareUiKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareTty.js",
|
||||
"keys": [
|
||||
@@ -697,12 +697,6 @@
|
||||
"bareUnpack"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareVm.js",
|
||||
"keys": [
|
||||
"bareVm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareV8.js",
|
||||
"keys": [
|
||||
@@ -715,6 +709,18 @@
|
||||
"bareWalkHandles"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareVm.js",
|
||||
"keys": [
|
||||
"bareVm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWebKit.js",
|
||||
"keys": [
|
||||
"bareWebKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUnionBundle.js",
|
||||
"keys": [
|
||||
@@ -727,30 +733,12 @@
|
||||
"bareWebp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWebKit.js",
|
||||
"keys": [
|
||||
"bareWebKit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWebKitGtk.js",
|
||||
"keys": [
|
||||
"bareWebKitGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareUtils.js",
|
||||
"keys": [
|
||||
"bareUtils"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareV8ToIstanbul.js",
|
||||
"keys": [
|
||||
"bareV8ToIstanbul"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWhich.js",
|
||||
"keys": [
|
||||
@@ -758,9 +746,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareXdiff.js",
|
||||
"path": "/lib/bare/bundles/bareWebKitGtk.js",
|
||||
"keys": [
|
||||
"bareXdiff"
|
||||
"bareWebKitGtk"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -770,15 +758,27 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZlib.js",
|
||||
"path": "/lib/bare/bundles/bareV8ToIstanbul.js",
|
||||
"keys": [
|
||||
"bareZlib"
|
||||
"bareV8ToIstanbul"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareWs.js",
|
||||
"path": "/lib/bare/bundles/bareXdiff.js",
|
||||
"keys": [
|
||||
"bareWs"
|
||||
"bareXdiff"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZmq.js",
|
||||
"keys": [
|
||||
"bareZmq"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZlib.js",
|
||||
"keys": [
|
||||
"bareZlib"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -788,9 +788,9 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "/lib/bare/bundles/bareZmq.js",
|
||||
"path": "/lib/bare/bundles/bareWs.js",
|
||||
"keys": [
|
||||
"bareZmq"
|
||||
"bareWs"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"atMs": 1775339424020,
|
||||
"atMs": 1775340363610,
|
||||
"commands": [
|
||||
"arch",
|
||||
"awk",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -77,6 +77,12 @@ Appends one NDJSON trend row (`schema: 1`) to **`BARE_OS_BENCHMARK_TREND_NDJSON`
|
||||
|
||||
Ensures [docs/reference/naming-alias-matrix.md](../docs/reference/naming-alias-matrix.md) lists canonical **`ctx`** boot-hook names and boot-policy key aliases. Root **`pretest`**.
|
||||
|
||||
## `verify-booter-boot-steps-alignment.mjs`
|
||||
|
||||
**Usage:** `node scripts/verify-booter-boot-steps-alignment.mjs`
|
||||
|
||||
Ensures every **`emitBooterBootPhase('…')`** in **`packages/bare-os-booter/index.js`** matches **`BARE_OS_BOOTER_BOOT_STEPS`** in **`packages/bare-os-booter/lib/bare-os-boot-phases.js`** (no drift). Root **`pretest`**.
|
||||
|
||||
## `verify-runtime-no-incomplete-markers.mjs`
|
||||
|
||||
**Usage:** `node scripts/verify-runtime-no-incomplete-markers.mjs`
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* CI: every emitBooterBootPhase('…') in the booter matches BARE_OS_BOOTER_BOOT_STEPS.
|
||||
*/
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const indexPath = path.join(root, 'packages', 'bare-os-booter', 'index.js')
|
||||
const phasesPath = path.join(
|
||||
root,
|
||||
'packages',
|
||||
'bare-os-booter',
|
||||
'lib',
|
||||
'bare-os-boot-phases.js'
|
||||
)
|
||||
|
||||
function extractArray(src) {
|
||||
const m = src.match(
|
||||
/export const BARE_OS_BOOTER_BOOT_STEPS = Object\.freeze\(\[([\s\S]*?)\]\)/
|
||||
)
|
||||
if (!m) return null
|
||||
const inner = m[1]
|
||||
const steps = []
|
||||
for (const q of inner.matchAll(/'([^']+)'/g)) steps.push(q[1])
|
||||
return steps
|
||||
}
|
||||
|
||||
function main() {
|
||||
const phaseSrc = fs.readFileSync(phasesPath, 'utf8')
|
||||
const declared = extractArray(phaseSrc)
|
||||
if (!declared || !declared.length) {
|
||||
console.error('verify-booter-boot-steps-alignment: could not parse boot phases')
|
||||
process.exit(1)
|
||||
}
|
||||
const idx = fs.readFileSync(indexPath, 'utf8')
|
||||
const used = new Set()
|
||||
for (const m of idx.matchAll(/emitBooterBootPhase\(\s*'([^']+)'\s*\)/g)) {
|
||||
used.add(m[1])
|
||||
}
|
||||
const declSet = new Set(declared)
|
||||
for (const u of used) {
|
||||
if (!declSet.has(u)) {
|
||||
console.error(
|
||||
'verify-booter-boot-steps-alignment: index.js uses unknown step:',
|
||||
u,
|
||||
'— add to bare-os-boot-phases.js or fix typo'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
for (const d of declared) {
|
||||
if (!used.has(d)) {
|
||||
console.error(
|
||||
'verify-booter-boot-steps-alignment: declared step unused in index.js:',
|
||||
d
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
console.log('verify-booter-boot-steps-alignment: OK')
|
||||
}
|
||||
|
||||
main()
|
||||
@@ -35,6 +35,7 @@ const needles = [
|
||||
'bareOsRunOpensslCli',
|
||||
'bareOsRunSshKeygenCli',
|
||||
'bareOsRunTarCli',
|
||||
'bareOsRunSystemctlCli',
|
||||
'bareOsReleaseKeyHandle',
|
||||
'bareOsAuditLogAppend',
|
||||
'bareOsAclEvaluate',
|
||||
|
||||
Reference in New Issue
Block a user