hello-worker #
The smallest possible Peek worker: a manifest whose worker entry names a
JavaScript module (not an HTML file), a module that says hello, and a host
script that runs it with no Electron and no window — the shape
docs/workers-design.md §2–§5 describes, proved on something simpler than
feeds. See tools/feeds-worker-spike/ for the harness this one reuses
pieces of (installNetworkGuard(), memory-store.mjs) rather than forking.
Files #
manifest.json—manifestVersion: 3, anid, aworker: { url, entry, schedule }block, and the two capabilities the worker uses (datastore,network).tiles: []because this worker has no window half.worker.js— the entry functionhello(api): logs a greeting throughapi.log, then makes one read-only call —api.datastore.describe(), mapped straight toPeekStore.describe()/GET /mcp/session— and logs what it returns. It only ever touchesapi.logandapi.datastore; every other namespace is absent, not stubbed, so a call to e.g.api.windowfails with aTypeErrorat the line responsible rather than continuing past a plausible-looking no-op.run.mjs— the host: readsmanifest.json, builds the API object over either store mode below, holds the sync credential in a closureworker.jscannot reach, importsworker.js, runs its entry function once, and exits non-zero on any throw.
Running it #
Offline, against an in-memory store, no network:
node tools/hello-worker/run.mjs --memory
Against the deployed sync server:
PEEK_SYNC_URL=<the deployed server URL> node tools/hello-worker/run.mjs
The credential is resolved the same way tools/feeds-worker-spike/run.mjs
resolves one: the 0600 file at $HOME/.config/peek/mcp-credentials.json,
keyed "<PEEK_SYNC_URL>#peek". If no usable credential resolves, the run
stops with an error naming the missing key rather than minting a grant. The
token itself is never printed, logged, or handed to worker.js — only
store.describe()'s result crosses that boundary.
Sample output #
Offline:
--memory: no network, the in-memory store stands in for the deployed one.
[worker] hello from hello-worker
[worker] sync server reports scope "socket-proof" (readonly: false, profile: memory, backend: memory)
--- network
manifest allows: *
hello-worker ok.
Against the deployed server:
[worker] hello from hello-worker
[worker] sync server reports scope "peek" (readonly: false, profile: <profile id>, backend: remote)
--- network
manifest allows: *
allow <server host> https://<server host>/mcp/session
hello-worker ok.
The network log at the end lists every request the process made — one GET /mcp/session, nothing else — which is the evidence that the run made no
writes against the deployed store.
What this does not do #
No init()/onShutdown lifecycle: docs/workers-design.md §4 says a worker
is stateless between invocations, and hello-worker holds no state for a
shutdown callback to tear down, so run.mjs imports worker.js and calls
its entry function directly. No pubsub, no commands, no scheduler — the
manifest's worker.schedule is declarative only; nothing in this directory
honors it, because there is no runtime here to honor it against (§9 of the
design document is exactly the list of what a real runtime would still have
to provide).