refactor(tile-preload): auto-initialize at module load, remove call-order trap
The preload required every tile entrypoint to call
await api.initialize() before any capability-gated api.method.
Forgetting this was a silent-halt bug class: subscribes no-op'd,
cap checks threw strings that halted module evaluation, and
widgets sat looking fine but dead. We have hit it six times now
(page.js, cmd/panel.js, hud.js, 4 widget tiles) and an audit
surfaced 47 more files that never call initialize at all — every
features background.js, most features home.js, several shared
app/ libs. Fixing them one-by-one is a treadmill.
Root cause: api.initialize was the only call site that kicked
off validateToken, so tokenValid stayed false until the caller
remembered to explicitly await it.
Fix: validation now fires eagerly at preload load (token args
are already on process.additionalArguments, no caller action
needed). Every cap-gated method now awaits the shared
validationPromise internally before doing its work. If
validation fails the method rejects with the existing error.
api.initialize remains as a thin public wrapper so callers
that want to surface init failures explicitly still can — it
just returns the already-running promise.
Method changes (all gated methods converted to async plus await
validationPromise): publishImpl, subscribeImpl, commands register,
commands list, invoke, window surface, datastoreStrict surface,
network fetch, filesystem surface, theme surface, settings get/set
and getExtKey, context surface, izui surface, shortcuts surface,
oauth surface.
subscribeImpl is careful: the local ipcRenderer.on listener
registers synchronously so messages arriving during validation
are not dropped. Upstream tile:pubsub:subscribe defers until
validation completes.
Tests: Module Health 2/2, HUD Extension 10/10, Command Execution
8/8, Cmd State Machine 12/12 all pass. Page Layout 13/14 (one
pre-existing flake unrelated to this change).