feat(webui): read-only Queue, Business and Settings views (#1543, row 54)
The Console gains three read-only views. Queue lists every row from
rows() in packages/queue (lead decision 83: the same lock-free read as
`queue list`, writing nothing), run in a child with a timeout and an
output cap; a row page shows the full row. Business shows names, an
allowlist of vars, arbiters, authority per action and credential
metadata (service, account, role, date, never a value, file or
variable). Settings shows RELEASE, the board origin and the notifier
binding. Every route is GET only, and every string in a body or
refusal passes a redactor: the config directory and dataRoot become
<config> and <dataRoot>, other absolute, ~/ and file:// paths <path>,
and 17 to 20 digit runs <id>. A queue-read that fails to start sends a
fixed message, never node's stderr.
Four fixes to HEAD behaviour, each with a test: the bus view's refresh
timer is cleared at render, a same-page refresh keeps focus on the H1,
#conv-pick is emptied when a conversation opens, and error() returns
focus to <main> only when something had focus. Filbert's T8 tests the
failed first read.
Dewey built it in two rounds. Round 1 (dba2429e) got changes from
Filbert (27185: After rendered [object Object], ~/ and :/ paths leaked)
and Darkwing (27186: Arbiters always none, queue-read import failure
leaked a file:// path and stack). Round 2 (afb2ae0e) was approved by
Filbert (27190) and Darkwing (27191, correction 27192). Sage's gate on
d64f434f plus the candidate: 13 package node suites 0 failed (queue
149, webui 39), every scripts/test-*.sh 0 failed (task 98/0 with
Docker, 26/0 without; release 14/0), build-tokens --check current.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
import { startServer, DEFAULT_BOARD } from './serve.mjs';
|
||||
import { busReader } from './bus.mjs';
|
||||
import { loadSystem, socketPath } from '../../cli/src/config.mjs';
|
||||
import { loadSystem, socketPath, REPO, rolesDir } from '../../cli/src/config.mjs';
|
||||
import { configDir } from '../../business/src/business.mjs';
|
||||
import { consoleReads, redactor } from './reads.mjs';
|
||||
import { ID_PATTERN } from '../../business/src/vocabulary.mjs';
|
||||
const args = process.argv.slice(2);
|
||||
const usage = 'node packages/webui/src/cli.mjs serve [--port N] [--board http://127.0.0.1:7331] [--business ID]';
|
||||
@@ -24,13 +26,18 @@ try {
|
||||
}
|
||||
// The bus views (slice 1 S5) need the system config. Without it the
|
||||
// board still serves and the bus routes answer not-configured.
|
||||
let bus = null, busLine;
|
||||
// The Queue, Business and Settings reads (row 54) need no bus; without
|
||||
// the system config, Business can't resolve authority and Settings has
|
||||
// no notifier. A refusal printed here names no path (redactor).
|
||||
let bus = null, busLine, system = null;
|
||||
try {
|
||||
const { dataRoot } = loadSystem();
|
||||
system = loadSystem();
|
||||
const { dataRoot } = system;
|
||||
bus = busReader({ dataRoot, socket: socketPath(dataRoot), business: options.business ?? null });
|
||||
busLine = `Bus: ${options.business ?? 'the running bus host\'s business'}`;
|
||||
} catch (err) { busLine = `Bus: not configured (${err.message})`; }
|
||||
const server = await startServer({ board: options.board, port: options.port, bus });
|
||||
} catch (err) { busLine = `Bus: not configured (${redactor({ configDir: configDir() })(err.message)})`; }
|
||||
const reads = consoleReads({ root: REPO, system, configDir: configDir(), rolesDir: rolesDir(), business: options.business ?? null });
|
||||
const server = await startServer({ board: options.board, port: options.port, bus, reads });
|
||||
console.log(`Mosaic Console: http://127.0.0.1:${server.address().port}/\nBoard: ${options.board}\n${busLine}\nCtrl-C stops this server.`);
|
||||
for (const signal of ['SIGINT', 'SIGTERM']) process.once(signal, () => server.close());
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user