Implementation plan for the design at docs/superpowers/specs/2026-05-09-core-
package-generator-design.md. Eight phases (numbered Phase 0..7 in the plan; Phase
0 is the read-first orientation, Phases 1-7 implement spec phases 0-5 plus a
final cross-doc sweep).
Phase 1 ships BindContext with bounded generics over protocol types in core-
shared. Phase 2 ships the generator framework (entry, prompt, dispatch table —
empty). Phases 3-6 each capture one optional package as a verbatim template,
ship the generator action, and remove the package from main with byte-identical
reconstruction verified via a snapshot. Phase 7 is the final cross-doc sweep
(template-tiers.md, README updates, HTML explainer pass).
Companion ADR will be assigned at implementation time (expected ADR-017).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6-phase design for slimming the default template to a minimal kernel
and providing turbo generators that scaffold optional core packages
(realtime, events, trpc, ui) back when needed.
Phase 0 introduces a BindContext object in core-shared with bounded
generics over minimal protocol types; optional packages keep their full
interfaces but extends-link to the protocols. This lets feature binders
take a single ctx arg and lets optional packages disappear without
breaking typechecks. Phases 1-5 ship the generator framework + per-
package templates + per-package removal from main.
Companion ADR will be assigned at implementation time (expected ADR-017).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five fixes surfaced by the branch-wide code review on the realtime layer:
- server.ts: replace dynamic `import("@repo/auth/di/container")` with a
static top-of-file import. The dynamic-import workaround from 6a0ac63 is
no longer needed once the root tsconfig + TSX_TSCONFIG_PATH expose
decorator metadata to tsx; verified by booting `pnpm dev` clean.
- server.ts: correct the inline structural type for `validateSession` to
match the real `IAuthenticationService` contract (non-nullable, throws
on invalid session) and wrap the call in try/catch so unauthenticated
bubbles to a `null` return instead of dead-code `result ? ... : null`.
- bind-production.ts: extract `maybeRegisterRealtimePing()` that wraps the
built-in ping inbound handler in the same `withSpan(withCapture(...))`
sandwich the realtime-handler generator emits (R41–R44), so the
proof-of-life channel models the convention rather than registering raw.
- bind-production.test.ts: add 4 tests for the `REALTIME_PING_DISABLED`
env-gate (registered when unset in both binders, not registered when
"true", treated as enabled when "1").
- docs/guides/realtime.md: correct the integration-test reference at
line 285 — the test does not call `bindAllDevSeed()`; it builds the
Socket.IO server inline and exercises gates 1+2 only (gates 3+4 live in
socket-io-realtime-server.test.ts).
- adr-016: add a "Known follow-ups" section recording 6 lower-priority
refinements deferred from this branch (bridge stub test scaffolding,
registry register/registerChannel precedence, channel-template dot
constraint, server bare catch{}, BindAllDeps Partial widening, AGENTS.md
anchor count phrasing).
CI gates: lint 0 errors / 4 warnings (pre-existing turbo.json warnings),
typecheck clean, 24 web-next tests pass (was 20; 4 new env-gate tests),
boundaries 0 issues across 504 files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- no-direct-socket-io: extend allowlist to cover apps/*/src/**/*.test.ts so
the realtime-ping e2e integration test can import socket.io/socket.io-client
directly; add two valid test cases to keep the rule's own test suite green
- tsconfig.json (root): add root-level tsconfig with experimentalDecorators +
emitDecoratorMetadata and no "include" so tsx 4.21.0's createFilesMatcher
resolves decorator config for all workspace packages, not just web-next's
own source tree
- web-next dev script: pass TSX_TSCONFIG_PATH=../../tsconfig.json so the
custom Node server uses the root tsconfig for all modules it loads
- next.config.mjs: add @repo/core-events and @repo/core-realtime to
transpilePackages so Next.js webpack can resolve their workspace source files
- server.ts: replace static authContainer import with a dynamic import inside
IRealtimeAuthenticator.authenticate so Inversify decorators are applied only
after bindAll() has already populated the container
All CI gates pass: lint (0 errors), typecheck, 20 tests (incl. realtime-ping
e2e), boundaries (0 issues).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add 4 new test cases to RealtimeHandlerRegistry test suite
- registerChannel stores outbound-only descriptors distinct from inbound
- listChannels() includes both inbound (from register) and outbound-only channels
- Validates backward-compat guarantee and re-registration behavior
Test count: 4 → 8 in realtime-handler-registry.test.ts
All 35 tests in core-realtime pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends bindAll/bindAllProduction/bindAllDevSeed to accept BindAllDeps
and thread realtime + realtimeRegistry as the 6th and 7th positional args
into each per-feature binder. Adds bindRealtimeBridge stub (empty allowlist
in v1). bindAll accepts optional deps with InMemoryRealtimeBroadcaster
fallback so existing page-level callers stay type-safe.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces `next dev` / `next start` with a custom Node http server that
co-hosts Next.js and Socket.IO on the same port, wiring in the
RealtimeHandlerRegistry and session-cookie-based IRealtimeAuthenticator.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend bindProductionAuth and bindDevSeedAuth to 7-arg signatures.
Fix RecordingRealtimeBroadcaster scope type to structurally match ChannelScope.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Type socket.data.user via AppSocketData/AppSocket generics (no more any)
- Wrap Gate 1 authenticator call in try/catch so exceptions reject the
connection with connect_error instead of being swallowed
- Fix Gate 3 userScoped channel authorize: derive params.userId from the
authenticated socket user so owner-inbound is accepted
- Await io.close(callback) in stop() to ensure full shutdown
- Remove unused httpServer field from constructor (io already holds the ref)
- Extract CHANNEL_ROOM_PREFIX/channelRoom helper to channel-room.ts;
replace three `ch:${name}` magic strings; re-export from index
- Add JSDoc to ChannelScope explaining userScoped params/template convention
- Fix "allows subscribe + invokes handler with ctx" test: hoist received
outside beforeEach and assert ctx shape
- New test: rejects connection when authenticator throws
- New test: userScoped channel accepts inbound from owner, rejects from anon