`- name: Repair the file: dependency (…)` is not valid YAML — the unquoted
`file: ` reads as a second mapping key — so the workflow has been unparseable
since it was added, which is why re-pushing the tag never triggered a run and a
manual dispatch 500'd. I had put that down to a Gitea tag quirk; it was this.
The failure is invisible from the repo side: nothing validates workflow YAML on
push, and an unparseable workflow simply never runs.
The publish workflow has been failing at Typecheck with "cannot find module
'@punktfunk/host'" — every import of the SDK, in a job whose previous step built
that very SDK successfully.
bun 1.3 installs a `file:` dependency by copying its DIRECTORIES but symlinking
each top-level FILE to itself: `node_modules/@punktfunk/host/package.json ->
package.json`, a dangling self-reference. So `dist/index.d.ts` arrives intact
while the manifest that points at it does not, and resolution dies at the first
step it takes. The types were never missing; nothing could find the front door.
Replacing that tree with a real copy is the whole fix, and the step no-ops
itself the moment bun links `file:` deps correctly again.
Not a regression from anything in the kit — it has been broken since bun
updated, and went unnoticed because nothing has been published since 0.1.4.
Verified from a clean node_modules: install → repair → typecheck → 20 tests →
build, all green.
The ~80% of every plugin that was copy-pasted (rom-manager ↔ playnite),
extracted as one Effect-v4 package:
- runtime: definePluginKit — async-main boundary hiding a ManagedRuntime
(two-effect-instances discipline), signal-driven interruption with a
bounded shutdown grace
- config: Schema-driven raw round-trip (defaults only in the Schema via
withDecodingDefaultKey + encodingStrategy omit; file stays authored-shape),
atomic writes, world-writable refusal, changes stream
- cache-store: disposable derived state, corrupt→empty, write-through
- reconcile: kit-owned provider wire schemas + typed client over the
skew-safe untyped pf.request seam
- sync-engine: generic poll/watch/debounce/single-flight-coalesce/
fingerprint-skip engine with a status PubSub (the SSE feed)
- ui-server + sse: effect/unstable/httpapi behind servePluginUi with
core-only env layers (validated by the phase-0 spikes); raw SSE route
(httpapi has no event-stream media type)
- cli: minimal command dispatcher reusing the plugin layer graph
(deliberately not effect/unstable/cli — it needs platform packages)
- react subpath: plugin router (path→hash→fallback deep-link restore +
pf-ui:navigate bridge), ResultGate, sseAtom, resolvePluginBase
- theme.css: the console's violet identity packaged for plugin UIs
18 bun tests incl. the two phase-0 spikes; publish workflow mirrors
sdk-publish (tag plugin-kit-v*; 0.1.0 published manually).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>