Take the catalogue's composition rules into the node-engine

ADR 0593 §7: the composer with its refusals leaves mesh-sdk, so mesh-sdk
carries no composition rule. The catalogue functions only the
node-engine's composition reaches (Resolve, Resolution's Compose,
Declaration, DataItems, LeftOut, Rules and the rest, the settings,
placeholder and template refusals, the rendering helpers) are copied
with their tests into internal/compose/resolution; a method of a
mesh-sdk shape becomes a function taking it first. The composition
calls its own copies, and the captured catalogue its tests read lives
here now, shared by mesh-compose's tests.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 19:15:55 +01:00
parent be0226b624
commit d68e241724
686 changed files with 35703 additions and 80 deletions
@@ -0,0 +1,41 @@
#!/bin/sh
# clipmenud as the operator's user unit starts it, written by the mesh (module clipmenu). Replaced at every push.
#
# The account's service manager starts before the X server does, and has a DISPLAY only once the session's
# xinitrc has handed it over (module xorg). So this waits, quietly, until the display is known, and exits
# only when the session ends with it: a quick exit would run the unit into its start limit. DISPLAY, when
# the manager has it, wins. Without it, exactly one X socket names the display; none or several (a
# second server beside the session) wait for the session's own to arrive.
# A running process does not see what the session hands the manager later, so each pass asks the manager.
until [ -n "$DISPLAY" ]; do
for pair in $(systemctl --user show-environment 2>/dev/null | grep -E '^(DISPLAY|XAUTHORITY)='); do
export "$pair"
done
[ -n "$DISPLAY" ] && break
set -- /tmp/.X11-unix/X*
if [ $# -eq 1 ] && [ -S "$1" ]; then
DISPLAY=":${1##*/X}"
export DISPLAY
else
sleep 1
fi
done
if [ -z "$XAUTHORITY" ] && [ -r "$HOME/.Xauthority" ]; then
XAUTHORITY="$HOME/.Xauthority"
export XAUTHORITY
fi
# clipmenud allows one daemon per account: it takes an exclusive flock on its session_lock file and exits
# with status 2 when that is held. After a delivery without a new login, the session's older clipmenud (from
# its xinitrc) still holds it, and a start would run the unit round its restart loop. So this waits, quietly,
# until the lock is free: it looks at the same file clipmenud locks (the directory is clipmenud's own rule)
# and lets go at once. Exit status 1 is "held" for util-linux and BusyBox flock alike (no -E: BusyBox lacks it); any other outcome starts clipmenud, which says its own
# error. Another daemon winning the gap between look and start costs one restart, not a loop.
lock="${CM_DIR:-${XDG_RUNTIME_DIR-${TMPDIR-/tmp}}}/clipmenu.6.$USER/session_lock"
while [ -e "$lock" ]; do
flock -n "$lock" true
[ $? -eq 1 ] || break
sleep 2
done
PATH="/usr/local/lib/mesh-clipmenu:$PATH"
export PATH
exec clipmenud
+20
View File
@@ -0,0 +1,20 @@
#!/bin/sh
# xsel as clipmenud sees it, written by the mesh (module clipmenu). Replaced at every push.
#
# clipmenud records text, and reads a selection with `timeout 1 xsel -o`. A selection holding an
# image (a screenshot copied as image/png) is sent in pieces; one second is too short for megabytes,
# timeout kills xsel half way, and the program owning the image waits for ever for a reader that is
# gone. From then on nothing can ask the clipboard anything: pastes hang, and an Electron app that
# asks on its main thread freezes. So a read goes ahead only when the selection offers text.
case " $* " in
*" -o "* | *" --output "*)
selection=clipboard
case " $* " in
*" --primary "* | *" -p "*) selection=primary ;;
*" --secondary "* | *" -s "*) selection=secondary ;;
esac
targets=$(timeout 1 xclip -selection "$selection" -t TARGETS -o 2>/dev/null) || exit 1
printf '%s\n' "$targets" | grep -qxE 'UTF8_STRING|STRING|TEXT|text/plain(;charset=utf-8)?' || exit 1
;;
esac
exec /usr/bin/xsel "$@"
@@ -0,0 +1 @@
15
@@ -0,0 +1 @@
500
@@ -0,0 +1 @@
clipboard
@@ -0,0 +1,5 @@
# The clipboard's history key (module clipmenu, novox/hq ADR 0208). Owned by the mesh: replaced at
# every push. clipmenu shows the history through `dmenu`, the node's dmenu-compatible command, which
# the holder of node-launcher answers (rofi on the workstations); the chosen entry is put back on the
# clipboard.
bindsym $mod+period exec --no-startup-id clipmenu -p Clipboard
@@ -0,0 +1,14 @@
# clipmenud in the operator's account (module clipmenu, novox/hq ADR 0208). Owned by the mesh: replaced at every push.
# The package's unit starts clipmenud with no DISPLAY; the module's launcher finds the display and puts the
# text-only xsel first on the PATH. The settings repeat the module's environment, which the account's
# service manager does not read.
[Unit]
StartLimitIntervalSec=0
[Service]
RestartSec=2s
Environment=CM_SELECTIONS=clipboard
Environment=CM_MAX_CLIPS=500
Environment=CM_HISTLENGTH=15
ExecStart=
ExecStart=/usr/local/lib/mesh-clipmenu/clipmenud-session
@@ -0,0 +1,135 @@
{
"module": "clipmenu",
"version": "1",
"moved": true,
"capabilities": [
"package-manager"
],
"requires": [
"x11-display"
],
"claims": [
{
"name": "node-clipboard",
"scope": "node",
"serves": [
"history",
"copy"
]
}
],
"tools": [
"clipmenu_paste",
"clipmenu_clear",
"clipmenu_delete"
],
"items": [
{
"collection": "environment",
"name": "cm-selections",
"attributes": {
"kind": "variable",
"name": "CM_SELECTIONS"
},
"template": "files/env-cm-selections"
},
{
"collection": "environment",
"name": "cm-max-clips",
"attributes": {
"kind": "variable",
"name": "CM_MAX_CLIPS"
},
"template": "files/env-cm-max-clips"
},
{
"collection": "environment",
"name": "cm-histlength",
"attributes": {
"kind": "variable",
"name": "CM_HISTLENGTH"
},
"template": "files/env-cm-histlength"
},
{
"collection": "contribution:node-display-session:config",
"name": "display-session",
"template": "files/i3/50-clipmenu.conf"
}
],
"resources": [
{
"id": "package",
"type": "package",
"package": "clipmenu"
},
{
"id": "greenclip",
"type": "package",
"package": "rofi-greenclip",
"absent": true
},
{
"id": "text-only",
"type": "file",
"path": "/usr/local/lib/mesh-clipmenu/xsel",
"mode": "0755",
"template": "files/bin/xsel"
},
{
"id": "daemon-dropins",
"type": "directory",
"path": "${machine:account-home}/.config/systemd/user/clipmenud.service.d",
"owner": "${machine:account}",
"mode": "0755",
"unknown": "move-out"
},
{
"id": "daemon-dropin",
"type": "file",
"path": "${machine:account-home}/.config/systemd/user/clipmenud.service.d/mesh.conf",
"owner": "${machine:account}",
"mode": "0644",
"template": "files/systemd/clipmenud-mesh.conf"
},
{
"id": "launcher",
"type": "file",
"path": "/usr/local/lib/mesh-clipmenu/clipmenud-session",
"mode": "0755",
"template": "files/bin/clipmenud-session"
},
{
"id": "daemon",
"type": "service",
"unit": "clipmenud.service",
"scope": "user",
"user": "${machine:account}",
"state": "running",
"boot": "enabled",
"health": {
"kind": "unit"
}
}
],
"build": {
"artifacts": [
{
"name": "tools",
"kind": "bundle",
"language": "go",
"system": "arch",
"from": "cmd/clipmenu-tools",
"binary": "clipmenu-tools",
"loads": [
"clipmenu-tools"
]
},
{
"name": "files",
"kind": "archive",
"from": "files"
}
]
}
}