Protocol: canonical seed RPC registry (seed-rpc-methods.js), bits5 on capabilities, typed seed RPC errors, richer replication_queue and staging_slot hints. Booter: /proc host_os (bare-module on Bare, node:os on Node), sync_window, debug.json, net_summary transport stats, HDMS hints/correlation, warm profile reload, subprocess bridge snapshot helpers, boot policy v5 hooks, BARE_OS_BIN_WORKER_ALLOW pattern groups, VFS symlink/union alignment, OTel JSONL schema version 2 in var-log. Seeder: pass staging/replication hints into seed channel; mirror kernel init and boot policy example. Kernel: enforce requireFeatureBits5 / requireInitJsSha256 when configured; selftests for new proc surfaces. CI/pretest: verify-doc-links, verify-man-coverage, verify-compat-matrix; extend roadmap/ctx/dts verifiers. Add otel-bare-os-jsonl schema. Docs: Wave 5 roadmap, kernel-extensions, handbook/devguide updates; bare-module manifest tier/risk sample; bare-libs README.
98 lines
2.8 KiB
JavaScript
98 lines
2.8 KiB
JavaScript
/**
|
||
* Build `/proc/bare_os/host_os.json` text (Holepunch `bare-os`-shaped snapshot).
|
||
*
|
||
* Pear/Bare cannot resolve `node:module`. On Bare we load `bare-os` via
|
||
* `bare-module`’s `createRequire`. On Node (brittle-node tests, etc.) we use
|
||
* `node:os` instead so we never static-import `node:module` in this file.
|
||
*/
|
||
|
||
/**
|
||
* @param {Record<string, string>} env
|
||
* @returns {Promise<string>}
|
||
*/
|
||
export async function buildBareOsHostProcJsonText(env) {
|
||
const rawInject = String(env.BARE_OS_HOST_OS_JSON || '').trim()
|
||
if (rawInject) {
|
||
try {
|
||
const parsed = JSON.parse(rawInject)
|
||
return `${JSON.stringify({
|
||
schema: 1,
|
||
source: 'BARE_OS_HOST_OS_JSON',
|
||
host: parsed,
|
||
atMs: Date.now()
|
||
})}\n`
|
||
} catch {
|
||
return `${JSON.stringify({
|
||
schema: 1,
|
||
error: 'invalid BARE_OS_HOST_OS_JSON',
|
||
atMs: Date.now()
|
||
})}\n`
|
||
}
|
||
}
|
||
const probe =
|
||
env.BARE_OS_HOST_BARE_OS_PROC === '1' ||
|
||
env.BARE_OS_HOST_BARE_OS_PROC === 'true'
|
||
if (!probe) {
|
||
return `${JSON.stringify({
|
||
schema: 1,
|
||
note: 'Set BARE_OS_HOST_BARE_OS_PROC=1 or inject BARE_OS_HOST_OS_JSON.',
|
||
atMs: Date.now()
|
||
})}\n`
|
||
}
|
||
try {
|
||
if (typeof Bare !== 'undefined') {
|
||
const bm = await import('bare-module')
|
||
const createRequire = bm.createRequire || bm.default?.createRequire
|
||
if (typeof createRequire !== 'function') {
|
||
throw new Error('bare-module createRequire unavailable')
|
||
}
|
||
const _require = createRequire(import.meta.url)
|
||
const os = _require('bare-os')
|
||
return `${JSON.stringify(hostPayloadFromBareOsLike(os, 'bare-os'))}\n`
|
||
}
|
||
const nodeOs = await import('node:os')
|
||
return `${JSON.stringify(hostPayloadFromBareOsLike(nodeOs, 'node:os'))}\n`
|
||
} catch {
|
||
return `${JSON.stringify({
|
||
schema: 1,
|
||
note: 'Host OS probe failed; use BARE_OS_HOST_OS_JSON on this runtime.',
|
||
atMs: Date.now()
|
||
})}\n`
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param {Record<string, unknown>} os
|
||
* @param {string} source
|
||
*/
|
||
function hostPayloadFromBareOsLike(os, source) {
|
||
const snap = {
|
||
platform: typeof os.platform === 'function' ? os.platform() : null,
|
||
arch: typeof os.arch === 'function' ? os.arch() : null,
|
||
hostname: typeof os.hostname === 'function' ? os.hostname() : null,
|
||
release: typeof os.release === 'function' ? os.release() : null
|
||
}
|
||
let ifaces = null
|
||
try {
|
||
if (typeof os.networkInterfaces === 'function') {
|
||
const n = os.networkInterfaces()
|
||
if (n && typeof n === 'object') {
|
||
ifaces = Object.keys(n)
|
||
.slice(0, 32)
|
||
.map((name) => ({
|
||
name,
|
||
count: Array.isArray(n[name]) ? n[name].length : 0
|
||
}))
|
||
}
|
||
}
|
||
} catch {
|
||
ifaces = null
|
||
}
|
||
return {
|
||
schema: 1,
|
||
source,
|
||
host: { ...snap, networkInterfaceNames: ifaces },
|
||
atMs: Date.now()
|
||
}
|
||
}
|