Field report 2026-08-18, Windows host on 0.30: PunktfunkScripting task Running, Playnite and Steam plugins installed, library empty, and "no logs at all for plugins" — nowhere on the box. That is by construction, not by accident. The runner's only log door is the log shipper, which tees console output to `POST /plugins/logs` over the mgmt API; the scheduled task itself had no console and no file. So every failure that stops the runner reaching the host — LocalService lost its read grant on plugin-token / native-cert.pem, a moved mgmt bind, a TLS pin miss, a 401 — is exactly the failure the shipper cannot report, and it leaves the same picture: task Running, plugins never registering, an empty grid, and nothing to send when asked for logs. `scripting-run.cmd` now redirects the runner's stdout+stderr to `%ProgramData%\punktfunk\plugin-state\runner.log`, keeping the previous run as `runner.log.1`. plugin-state is the one directory `plugins enable` makes writable for LocalService, and it inherits Users-read from the config dir, so the operator can `type` it from any prompt. Writability is probed with `copy /y nul` first; if the dir is not writable (the task was started by the installer before `plugins enable` ever ran) the runner starts unlogged as before rather than not at all. No `goto`: the file is stored LF and cmd's label scan is unreliable there. The console's empty-Plugins hint (en/de) and the plugin docs now name the file; the log-ship header no longer claims the task writes no file. Verified by reading only — no Windows box reachable from here; the cmd semantics used (`copy nul` as a write probe, `if defined` blocks, leading redirect on `echo`) are the boring ones.
48 lines
2.4 KiB
Batchfile
48 lines
2.4 KiB
Batchfile
@echo off
|
|
rem punktfunk plugin/script runner launcher - the action the PunktfunkScripting scheduled task runs.
|
|
rem
|
|
rem OPT-IN: the installer registers that task DISABLED (the runner is inert until you add automation).
|
|
rem Enable it once you have scripts/plugins: Enable-ScheduledTask -TaskName PunktfunkScripting
|
|
rem
|
|
rem Lays out next to the installed payload: {app}\scripting\scripting-run.cmd + runner-cli.js and
|
|
rem {app}\bun\bun.exe (so %~dp0 = {app}\scripting\). The runner discovers the operator's units under
|
|
rem %ProgramData%\punktfunk\{scripts,plugins}; a plugin's connect() auto-wires to the host's SCOPED
|
|
rem plugin-token + identity cert in %ProgramData%\punktfunk\ (written by the host's `serve`). The
|
|
rem task runs as NT AUTHORITY\LocalService - `plugins enable` grants it read on exactly those two
|
|
rem files. No env editing.
|
|
setlocal EnableExtensions
|
|
|
|
set "BUN=%~dp0..\bun\bun.exe"
|
|
set "RUNNER=%~dp0runner-cli.js"
|
|
|
|
if not exist "%RUNNER%" (
|
|
echo [punktfunk-scripting] runner bundle missing at "%RUNNER%".
|
|
exit /b 1
|
|
)
|
|
if not exist "%BUN%" (
|
|
echo [punktfunk-scripting] bundled bun missing at "%BUN%".
|
|
exit /b 1
|
|
)
|
|
|
|
rem The runner import()s the operator's .ts plugin files, so it runs on the bundled bun. SIGTERM (task
|
|
rem End) interrupts the whole unit tree structurally so plugin finalizers run before exit.
|
|
rem
|
|
rem Its stdout/stderr go to a file: a scheduled task has no console, and the runner's other log door
|
|
rem (shipping lines to the host's Logs page) needs the very connection whose failure is what you'd
|
|
rem be trying to read about - a runner that can't reach the host was silent everywhere (field report
|
|
rem 2026-08-18: task Running, plugins installed, "no logs at all"). plugin-state is the one dir
|
|
rem `plugins enable` makes writable for LocalService; the file inherits Users-read from the config
|
|
rem dir, so `type` it from any prompt. One previous run is kept as runner.log.1. If the dir isn't
|
|
rem writable (task started before `plugins enable` ever ran), start unlogged rather than not at all.
|
|
rem ponytail: no size cap within one run - rotate on size if a chatty plugin ever fills a disk.
|
|
set "LOG=%ProgramData%\punktfunk\plugin-state\runner.log"
|
|
set "LOGGED="
|
|
if exist "%LOG%" move /y "%LOG%" "%LOG%.1" >nul 2>&1
|
|
copy /y nul "%LOG%" >nul 2>&1 && set "LOGGED=1"
|
|
if defined LOGGED (
|
|
>> "%LOG%" echo [punktfunk-scripting] %DATE% %TIME% starting "%BUN%" "%RUNNER%" as %USERNAME%
|
|
"%BUN%" "%RUNNER%" >> "%LOG%" 2>&1
|
|
) else (
|
|
"%BUN%" "%RUNNER%"
|
|
)
|