10 KiB
To Do
Planned work, in order of priority. Each item names what to build, how it fits the existing seams, and how to verify it. Finished items move to the design doc they belong to.
1. Packaging: AUR, FreeBSD ports, Debian
The foundation exists:
- The
lwbinary name, free in Arch (official repositories and AUR), Ubuntu 24.04 and 26.04, and the FreeBSD 15.1 ports tree. - The canonical module path
github.com/lixenwraith/logwisp, whichgo install, FreeBSD'sUSES=go:modulesand Debian's dh-golang expect. make installwithDESTDIR,PREFIX,SYSCONFDIRandSERVICE: the binary, thedoc/lw.1manual, bash, zsh and fish completion generated fromcmd/lw'sshortsandcommandstables, and the service files indeploy/package/(systemd unit, sysusers, tmpfiles, FreeBSD rc.d script) with the configuration, kept on reinstall.make deb, a binary package built withdpkg-deb, andmake arch, the PKGBUILD built from the working tree.- Skeletons in
deploy/package/arch/anddeploy/package/freebsd/. .github/workflows/package.yml:make arch, the.deband BSD make on FreeBSD 15.1, each reinstalled over an edited configuration; the systemd and rc.d services run; a home install withSERVICE=noandlw config init; andmake image image-check.
What remains is the maintainer's: it needs push rights, an identity or a release tag, and both skeletons download the tagged source.
- Tag the release on the merged main commit,
vX.Y.Z:git tag -a vX.Y.Z -m vX.Y.Z # git tag -s signs it with your key git push origin vX.Y.Zmakethen stampsvX.Y.Z(fromgit describe), andgo install github.com/lixenwraith/logwisp/cmd/lw@vX.Y.Zworks.- A GitHub release for the tag is optional; the tag alone serves
archive/vX.Y.Z.tar.gz, which the PKGBUILD downloads.
- Arch (AUR),
deploy/package/arch/PKGBUILD:pkgver=X.Y.Zand the# Maintainer: Name <email>line.updpkgsums(pacman-contrib) replacessha256sums=('SKIP')with the tarball's checksum.namcap PKGBUILD, thenmakepkg -si(builds, runscheck(), installs), thenmakepkg --printsrcinfo > .SRCINFO.- Push
PKGBUILDand.SRCINFOtossh://aur@aur.archlinux.org/logwisp.git; optionally alogwisp-gitpackage built from the main branch.
- FreeBSD,
deploy/package/freebsd/(sysutils/logwisp):DISTVERSION=X.Y.ZandMAINTAINER=your address.make makesumwritesdistinfo: the module zip that the Go proxy serves forGO_MODULEat the tag.- The
logwispuser needs an ID registered in the ports tree. Take a number below 1000 that is free in both/usr/ports/UIDsand/usr/ports/GIDs, and add to the same patch:UIDs: logwisp:*:NNN:NNN::0:0:LogWisp daemon:/nonexistent:/usr/sbin/nologin GIDs: logwisp:*:NNN: portlint -AC,poudriere testporton 14.x and 15.x jails, then a Bugzilla report with the port directory and the UIDs/GIDs diff.
- Debian:
make debserves direct installs. A PPA builds from a signed source package without network access: adebian/directory (changelog, control, rules) and the Go modules vendored into the source tarball.- The archive wants every Go dependency packaged (dh-golang); the four
lixenwraithlibraries are not. lintianon themake debpackage reportsno-changelog(a source package'sdebian/changelogprovides it),statically-linked-binary(lw is static by design) andmaintainer-script-calls-systemctl(dh's scripts usedeb-systemd-helperinstead).
- With a tag, the packaging workflow's FreeBSD job can build the port itself
from a ports tree (
make stage check-plistin a copy ofdeploy/package/freebsd/), rather than BSD make on the checkout.
2. lw --tui and the configuration engine it shares with lixen.com
lw --tui composes pipelines in a full-screen terminal UI, runs them under
the screen with a live view (t), and on exit runs them at once or prints one
form of them: a command line, environment variables, or a configuration file.
Its logic is a pure engine that lixen.com's planned Configure tab (lixencom
doc/todo.md) runs as WebAssembly, so no part of LogWisp is rewritten in
JavaScript.
What exists:
- Option structs with toml tags for every plugin and flow stage
(
internal/config/config.go), presets as rows with typed parameters (preset.go), the command-line and environment grammar (spec.go),ValidateConfig,--checkand--dump. - The option schema, in
internal/config:default:,help:andlw:tags on the option structs, one catalogue row per plugin type,Decode(every constructor decodes through it and keeps only I/O),Coercefor typed command-line values, and aValidateConfigthat decodes every plugin offline and names the first problem of each part by its key's path. internal/configalready compiles forGOOS=js; it links no net/http, crypto/tls or terminal code.- The engine,
internal/compose: starts empty, from a preset (whose pathconfig.IsDirresolves, from answers off the host), a loaded configuration or pasted text of any form; adds, removes and moves sources, sinks and filters, sets and unsets keys, validates; writes a command line, environment variables or a file, each reading back to the same pipelines. Its test fails when it links TLS, HTTP, process, signal or terminal code. lw --schema: settings, pipeline flags, flow stages in order with what turns each on, sources and sinks with their tables' keys of their side, presets and forms, as one JSON document.github.com/lixenwraith/terminal(pinned) and itstuipackage: regions, layout, boxes, List, Tree, TabBar, StatusBar, TextField, Form, Modal, ConfirmDialog, scrolling, mouse; themed Radio, Field, TextInput, OptionList and menus, Frame, Rule, Wires and Window, whichlw --tuidraws with.github.com/lixenwraith/color: RGB, blending, RGBTo256, RGBTo16.
Steps:
-
Schema, in
internal/config: done. -
Engine,
internal/compose: done. -
lw --schema: done. The site generates its catalogue from it. -
lixenwraith/terminalv0.2.0: done: 16 and no color, the terminal's default colors,/dev/tty, bracketed paste, themed form controls. Still optional, incolor: export the 16 xterm reference shades (RGBTo16 maps the site's hues badly, so the 16-color tier is chosen by hand). v0.2.1: radio buttons, narrow form fields and option lists, menus, frames, rules, wires and windows, moved fromlw --tui. Pinned at the untagged v0.2.2 commit: one glyph per cell at output, a reverse cursor bar in one style. -
lw --tui: done (doc/cli.md). -
WebAssembly: done.
make wasmwritesbin/lwconf/, which a site drops in whole:lwconf.wasm, version stamped: 7.1 MB, 1.9 MB at gzip -9.wasm_exec.js, the toolchain's, which uses no eval: the page needs only'wasm-unsafe-eval'in itsscript-src.lwconf.js, one dependency-free ES module that knows the calls and shapes, never a key:load({execURL, execSRI, wasmURL, wasmSRI})fetches both by their integrity and resolves to the engine;fields(schema, role, type)is a node's form rows, a table's a group;value,atandgroupread a node's value and sort problems by node.schema.json, equal toschema(), andlwconf.json, the manifest: version, commit, Go version and each file's sha256.
The engine's calls take strings (
lwconf.jswrites objects as JSON) and answer{"value": ...}or{"error", "path", "pipeline", "node", "key"}, as far as the engine places the refusal:schema(): whatlw --schemaprints.preset(name, values, dirs): a preset's pipelines;valuesmaps a key to a string, a list key to strings.parse(text, form, dirs): the pipelines of a form's pasted text.validate(pipelines):{pipelines, problems}, the pipelines settled (defaults, kinds, ids) and the first problem of each part (a value of the wrong kind too) as{path, pipeline, node, key, text}.emit(pipelines, form): the text ofcommand,environmentorfile.edit(pipelines, op):{pipelines, node}, the node left chosen.opis{op, pipeline, ...}:add_pipelineandrename_pipeline(name),remove_pipeline,add(role,type),retype(node,type),remove(node),move_filter(from,to),set(node,key,values),unset(node,key).dirsanswers whether a path a preset names is a directory,{"/var/log/app.log": false}; unanswered, a path ending in/is one, one with a glob a pattern, and any other is refused atpath.- Pipelines are a JSON list in the file's shape (
name,flow,plugin_sources,plugin_sinks); a misspelled key is refused. A node is{role, id, index}: a source's or sink's id, a filter's index.
-
t, the tap: done (doc/cli.md):core.Taptakes each flow verdict,internal/loglinereads any line shape, and the live view shows them under the diagram.
Not yet:
- Pins and export in the live view, as vif-log has them: pinned rows survive filter changes and show alone on a key; the pins or the shown rows go to a new file.
- Per-sink taps: what each sink took, where the tap at the flow's exit shows what dispatch offered (a full sink input drops for that sink only).
- Live filter patching: a filter edited while
truns takes effect throughFilter.UpdatePatterns(unused), not a rerun that rebinds every listener. - The wide-rune table
internal/tui/view.gocopies fromlixenwraith/terminal's one-cell rule goes once terminal exports that rule. - A scripted session on a pseudo-terminal for Run, each output and
t(keys, the password dialog,SIGHUP), on a text console and over ssh. AuthOptions.Checkalone limitsauth.node_bindingto chain sources andauth.trusted_proxiesto the http sink, so the schema lists both on every listener; a side tag naming those sides would filter them ashttpfilters HTTP's keys.