chat-v1
This commit is contained in:
+157
@@ -0,0 +1,157 @@
|
||||
/* BARE_OS_BIN_API 1.0.0 — bump when staged /bin script semantics change (see developer guide). */
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
/** @param {number} mode @param {'file' | 'directory' | 'symlink'} type */
|
||||
function bareFormatModeString(mode, type) {
|
||||
const typeChar = type === 'directory' ? 'd' : type === 'symlink' ? 'l' : '-'
|
||||
const perm = mode & 0o777
|
||||
const r = (bit) => (perm & bit ? 'r' : '-')
|
||||
const w = (bit) => (perm & bit ? 'w' : '-')
|
||||
const x = (bit) => (perm & bit ? 'x' : '-')
|
||||
return (
|
||||
typeChar +
|
||||
r(0o400) +
|
||||
w(0o200) +
|
||||
x(0o100) +
|
||||
r(0o040) +
|
||||
w(0o020) +
|
||||
x(0o010) +
|
||||
r(0o004) +
|
||||
w(0o002) +
|
||||
x(0o001)
|
||||
)
|
||||
}
|
||||
|
||||
/** @param {number} mtimeMs @param {number} [nowMs] */
|
||||
function bareFormatLsMtime(mtimeMs, nowMs) {
|
||||
const now = nowMs != null ? nowMs : Date.now()
|
||||
const d = new Date(mtimeMs)
|
||||
const months = [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
'Oct',
|
||||
'Nov',
|
||||
'Dec'
|
||||
]
|
||||
const mon = months[d.getMonth()]
|
||||
const day = String(d.getDate()).padStart(2, ' ')
|
||||
const sixMo = 180 * 24 * 3600 * 1000
|
||||
if (Math.abs(now - mtimeMs) > sixMo) {
|
||||
const yr = String(d.getFullYear()).padStart(4, ' ')
|
||||
return mon + ' ' + day + ' ' + yr
|
||||
}
|
||||
const hh = String(d.getHours()).padStart(2, '0')
|
||||
const mm = String(d.getMinutes()).padStart(2, '0')
|
||||
return mon + ' ' + day + ' ' + hh + ':' + mm
|
||||
}
|
||||
|
||||
/** @param {number} size */
|
||||
function barePosixBlocks(size) {
|
||||
return Math.ceil(Number(size) / 512) || 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw stdout for NUL/binary when **`process.stdout.write`** is missing.
|
||||
* If **`ctx.bareOsBinWrite(Uint8Array|string)`** is set (tests / host), use it.
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string | Uint8Array} chunk
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function bareOsEmitRaw(ctx, chunk) {
|
||||
if (typeof ctx.bareOsBinWrite === 'function') {
|
||||
const b4 = ctx.b4a
|
||||
const u8 =
|
||||
typeof chunk === 'string'
|
||||
? b4 && typeof b4.from === 'function'
|
||||
? b4.from(chunk)
|
||||
: new TextEncoder().encode(chunk)
|
||||
: chunk
|
||||
ctx.bareOsBinWrite(u8 instanceof Uint8Array ? u8 : new Uint8Array(u8))
|
||||
return true
|
||||
}
|
||||
const w = globalThis.process?.stdout?.write
|
||||
if (typeof w === 'function') {
|
||||
w.call(globalThis.process.stdout, chunk)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Swarm chat CLI — uses ctx.bareOsChat* when the booter exposes swarm chat (bare-os-chat-v1).
|
||||
*/
|
||||
async function run(ctx, argv) {
|
||||
const cs = ctx.bareOsChatSend
|
||||
const sub = argv[1] || ''
|
||||
const rest = argv.slice(2).join(' ').trim()
|
||||
|
||||
if (sub === 'send' && rest) {
|
||||
if (typeof cs !== 'function') {
|
||||
ctx.console.error(
|
||||
'chat: bareOsChatSend unavailable — stock hosts enable swarm chat unless BARE_OS_PROTOMUX_CHAT_CHANNEL=0'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
const r = cs.call(ctx, rest)
|
||||
if (r && r.ok === false) ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
if (sub === 'history') {
|
||||
const n = argv[2] ? Number.parseInt(argv[2], 10) : 20
|
||||
const hist =
|
||||
typeof ctx.vfs?.readFile === 'function'
|
||||
? await ctx.vfs.readFile('/proc/bare_os/chat.json')
|
||||
: null
|
||||
if (hist) ctx.console.log(ctx.b4a.toString(hist).trimEnd())
|
||||
else if (typeof ctx.bareOsReadProcMetricsLive === 'function') {
|
||||
ctx.console.log(JSON.stringify(ctx.bareOsReadProcMetricsLive(), null, 2))
|
||||
}
|
||||
void n
|
||||
return
|
||||
}
|
||||
|
||||
if (sub === 'who') {
|
||||
ctx.console.log(JSON.stringify(ctx.bareOsChatPresence?.() ?? {}, null, 2))
|
||||
return
|
||||
}
|
||||
|
||||
if (sub === 'join') {
|
||||
ctx.console.log(
|
||||
'chat join: only the general room is implemented; you are already in general when chat is enabled.'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof ctx.readLine !== 'function' || typeof cs !== 'function') {
|
||||
ctx.console.error(
|
||||
'chat: interactive mode requires bareOsChatSend and readLine (host booter; chat off if BARE_OS_PROTOMUX_CHAT_CHANNEL=0)'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
ctx.console.log('[chat] general room — type a line; /quit to exit')
|
||||
while (true) {
|
||||
const line = await ctx.readLine('chat> ')
|
||||
if (line == null) break
|
||||
const t = line.trim()
|
||||
if (t === '/quit' || t === '/exit') break
|
||||
if (!t) continue
|
||||
const r = cs.call(ctx, t)
|
||||
if (r && r.ok === false) {
|
||||
ctx.console.error('chat: send failed')
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -87,7 +87,7 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
return false
|
||||
}
|
||||
|
||||
var BARE_OS_HELP_BIN_SPACED = "arch awk baresay baretop base32 base64 basename basenc btop bundlebee cat chgrp chmod chown cksum clear cmp comm cp crontab curl cut date dd df diff dir dircolors dirname du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help holesail hostid hostname hrpc iconv id install join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill link ln logger login logname logout ls man md5sum mkdir mkfifo mktemp mount mv nano nice nl nohup nproc numfmt od oidc-publish openssl openssl paste patch pathcap-verify pathchk pear-runtime-matrix pkg-swarm-index pr printenv printf procstat ps pwd readlink realpath rev rm rmdir savevault say sed seq setfacl sh sha1sum sha224sum sha256sum sha384sum sha512sum shuf sidecar sleep sort split ssh-keygen ssh-keygen sshd sshd stat sum sync systemctl tac tail tar tar tee test theme time timeout touch tr true truncate tsort tty ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami xargs xattr yes"
|
||||
var BARE_OS_HELP_BIN_SPACED = "arch awk baresay baretop base32 base64 basename basenc btop bundlebee cat chat chgrp chmod chown cksum clear cmp comm cp crontab curl cut date dd df diff dir dircolors dirname du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help holesail hostid hostname hrpc iconv id install join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill link ln logger login logname logout ls man md5sum mkdir mkfifo mktemp mount mv nano nice nl nohup nproc numfmt od oidc-publish openssl openssl paste patch pathcap-verify pathchk pear-runtime-matrix pkg-swarm-index pr printenv printf procstat ps pwd readlink realpath rev rm rmdir savevault say sed seq setfacl sh sha1sum sha224sum sha256sum sha384sum sha512sum shuf sidecar sleep sort split ssh-keygen ssh-keygen sshd sshd stat sum sync systemctl tac tail tar tar tee test theme time timeout touch tr true truncate tsort tty ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami xargs xattr yes"
|
||||
async function run(ctx, argv) {
|
||||
ctx.console.log(
|
||||
'Bare OS — default user: guest | shell builtins: alias, barerc, cd, command, export, exit, login, logout, readonly, type, umask, unalias, unset, : | /bin: ' +
|
||||
|
||||
Reference in New Issue
Block a user