Commit Graph

646 Commits

Author SHA1 Message Date
4b390e028d refactor(core-shared): delete SentryTracer (replaced by OtelTracer)
sentry/sentry-tracer.ts and its test removed. OtelTracer is now the active
ITracer implementation. Spans flow to Sentry via @sentry/opentelemetry's
SentrySpanProcessor wired in bindOtelInstrumentation → initOtelServerNode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 11:43:26 +02:00
149f91255c refactor(apps): call sites use bindOtelInstrumentation by name
apps/web-next/bind-production.ts imports bindOtelInstrumentation instead
of bindSentryInstrumentation. Test mock tracks both names via the same
spy so existing assertions on bindSentryInstrumentation still pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 11:43:03 +02:00
53bfe727b4 refactor(core-shared): rename bindSentryInstrumentation → bindOtelInstrumentation
git mv bind-sentry-instrumentation → bind-otel-instrumentation; function
renamed; new impl calls initOtelServerNode and binds OtelTracer (SentryLogger
kept for Phase 3). Barrel re-exports both new name and deprecated alias
bindSentryInstrumentation for one release. ESLint allowlist updated to the
new filename. init-server-node opts gains release? field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 11:42:07 +02:00
b61e9d2091 feat(core-shared): OtelTracer impl using @opentelemetry/api
Implements OtelTracer as ITracer replacement for SentryTracer. Uses
@opentelemetry/api's trace.getTracer + startActiveSpan, maps span.op to
a span attribute, catches exceptions via recordException + setStatus(ERROR),
and filters null attribute values. Five Vitest tests covering name/attributes,
nesting, exception recording, status mapping, and null filtering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 11:40:43 +02:00
4c628022ce fix(core-shared): align OTel type imports to sdk-node re-exports to resolve version conflict 2026-05-11 11:28:07 +02:00
f94f09a9fa feat(core-shared): OTel barrel + ESLint allowlist for SDK packages 2026-05-11 11:25:29 +02:00
e85b8b12cf feat(core-shared): OTel NodeSDK init helper with Sentry exporter wiring 2026-05-11 11:24:55 +02:00
3a32838c71 feat(core-shared): Sentry-as-OTel-exporter bridge module 2026-05-11 11:23:49 +02:00
12aeb8bf37 feat(core-shared): OTel resource builder 2026-05-11 11:23:19 +02:00
80e765c074 feat(core-shared): add OpenTelemetry SDK dependencies 2026-05-11 11:22:09 +02:00
76870816d1 docs(plan): OpenTelemetry migration (5 phases, ~30 tasks, ~25 commits)
Implementation plan for the spec at docs/superpowers/specs/2026-05-11-
opentelemetry-migration-design.md. Five phases:

- Phase 1: OTel SDK infrastructure (resource builder + Sentry-as-exporter
  bridge + NodeSDK init helper + ESLint allowlist for OTel SDK packages).
  No behavior swap yet.
- Phase 2 (TDD): OtelTracer impl using @opentelemetry/api; bind-sentry-
  instrumentation renamed to bind-otel-instrumentation with deprecation
  alias; delete SentryTracer.
- Phase 3 (TDD): OtelLogger impl using @opentelemetry/api-logs;
  LogRecordProcessor wired into init helper; delete SentryLogger.
  Breadcrumbs become span events; setUser sets user.id span attribute.
- Phase 4 (TDD): New IMetrics interface + Noop/Otel/Recording impls;
  MetricsProtocol added to bind-protocols; BindContext.metrics? optional
  field. Sentry metrics exporter deferred (experimental).
- Phase 5 (TDD): HTTP/undici/pg auto-instrumentations; PII scrub
  processors (PiiScrubSpanProcessor + PiiScrubLogRecordProcessor) run
  FIRST in OTel pipeline; delete sentry/scrub.ts + orphaned init files;
  core-testing/setup/no-sentry.ts → no-instrumentation.ts (mocks both
  Sentry and OTel SDK); ADR-017 + ADR-014 status header; doc refreshes.

Total: ~30 tasks across 6 phases (including Phase 0 read-first), ~25
expected commits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 11:15:33 +02:00
cb0e33b0e8 docs(spec): OpenTelemetry migration design
Five-phase migration of server-side instrumentation from Sentry-direct
SDK calls to OpenTelemetry SDK with @sentry/opentelemetry as the (initial)
exporter. Vendor neutrality: swap vendors = swap exporters, never rewrite
tracer/logger/metrics impls.

Phase 1: OTel SDK infrastructure (no behavior swap).
Phase 2: OtelTracer replaces SentryTracer (uses @opentelemetry/api).
Phase 3: OtelLogger replaces SentryLogger (pure OTel Logs API via
  @opentelemetry/api-logs; breadcrumbs become span events; user.id as
  span attribute).
Phase 4: New IMetrics interface + Noop/Otel/Recording impls; added to
  BindContext as metrics? with corresponding MetricsProtocol in
  core-shared/di/bind-protocols.ts.
Phase 5: HTTP/undici/pg auto-instrumentations; PII scrubbing migrates
  from Sentry beforeSend hooks to OTel SpanProcessor/LogRecordProcessor;
  delete remaining Sentry-direct files; ADR-017 supersedes ADR-014's
  impl section while keeping R31-R51 interface decisions authoritative.

Server-only scope. Browser keeps Sentry SDK directly (replay + native
error UX); future spec extends to browser when OTel-Browser matures.

Companion ADR will be assigned at implementation time (expected ADR-017).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 11:04:37 +02:00
7f90f1f1c0 Merge branch 'worktree-core-ui-component-generator': core-ui component generator 2026-05-11 09:42:30 +02:00
4977617c94 fix(generators): mention core-ui-component generator in core-ui template AGENTS.md
The template's AGENTS.md.hbs describes the 4-file component pattern under
`## Structure` but didn't tell agents how to scaffold one. After Phase 4
shipped the generator, an agent reading core-ui's AGENTS.md still wouldn't
discover `pnpm turbo gen core-ui-component` and would build files manually.

Added a one-line note immediately under the Structure heading pointing at
the generator. Snapshot hash for AGENTS.md updated to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 09:41:39 +02:00
ef5ec1c1ca docs(agents): Key Commands entry for core-ui-component generator 2026-05-11 09:22:06 +02:00
a8454c9b5f docs(claude): Quick Start entry for core-ui-component generator 2026-05-11 09:22:00 +02:00
5f9a43441f docs(scaffolding): core-ui component generator reference 2026-05-11 09:21:52 +02:00
47627f1a54 feat(generators): core-ui-component generator + action helpers + tests
Adds the setGenerator("core-ui-component") block, coreUiComponentActions
helper (2 guards + 4 add + 1 modify + 1 print = 8 actions), and
printCoreUiComponentNextSteps to config.ts; covers all three paths with
3 new unit tests in config.test.ts (registration shape, action shape per
tier, PascalCase validator). Generator test count: 17 → 20.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 09:20:38 +02:00
9108122d00 feat(generators): core-ui-component template files (component + stories + test + barrel) 2026-05-11 09:16:41 +02:00
76e7242c3d feat(generators): regenerate ui snapshot for new tier-barrel anchors 2026-05-11 09:14:07 +02:00
c50dd96113 feat(generators): add splice anchors to core-ui tier barrels 2026-05-11 09:12:17 +02:00
09ac0bba6c docs(plan): core-ui component generator (5 phases, ~7 commits)
Implementation plan for the spec at docs/superpowers/specs/2026-05-11-core-
ui-component-generator-design.md. Five phases:

- Phase 1: add splice anchors to core-ui tier barrel templates +
  regenerate the byte-identical ui snapshot
- Phase 2: create the 4 Handlebars template files
  (component.tsx + stories + test + index)
- Phase 3 (TDD): register the setGenerator block, implement
  coreUiComponentActions + printCoreUiComponentNextSteps, add unit
  tests for registration shape, action sequence, and PascalCase
  validation
- Phase 4: scaffolding reference doc + CLAUDE.md Quick Start +
  AGENTS.md Key Commands
- Phase 5: manual smoke test (scaffold one component per tier, verify
  file layout + spliced barrels + core-ui gates) + final repo gates

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 08:51:53 +02:00
5878b8f493 docs(spec): core-ui component generator design
2-phase design for `pnpm turbo gen core-ui-component`. Prompts for tier
(atom/molecule/organism) + name (PascalCase) and emits the established
4-file component pattern (component.tsx, component.stories.tsx,
component.test.tsx, index.ts) into the matching `packages/core-ui/src/<tier>s/`
folder. Splices the new export into the tier barrel via `// <gen:<tier>s>`
anchors.

Phase A adds the anchors to the core-ui template's three tier barrels and
regenerates the byte-identical reconstruction snapshot. Phase B ships the
generator, templates, tests, and docs. Refuses to run if core-ui isn't
scaffolded; doesn't touch Storybook config (existing stories glob covers
new component stories).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 08:47:27 +02:00
b593bea8ca fix(generators): wire lint+typecheck into pipeline and fix uncovered errors
The turbo/generators package shipped without `lint` or `typecheck` scripts,
so `pnpm lint` / `pnpm typecheck` at the root silently skipped it. This
masked 2 ESLint errors (unused imports) and 11 TypeScript errors (relative
imports missing the `.js` extension required by `moduleResolution: NodeNext`,
plus JSON imports missing the `with { type: "json" }` attribute).

- Add `lint` and `typecheck` scripts to turbo/generators/package.json so the
  turbo pipeline picks them up (lint: 14/14, was 13/13).
- Add `.js` extensions to 7 relative imports across config.test.ts,
  lib/core-package-utils.test.ts, lib/snapshot.test.ts, and the 4 e2e tests.
- Add `with { type: "json" }` attributes to 4 snapshot JSON imports in the
  e2e tests.
- Remove unused `existsSync` and `splicePluginImportsAt` imports from
  lib/core-package-utils.test.ts.
- Declare `@repo/core-typescript` + `typescript` devDependencies so the
  generators package can run `tsc --noEmit` for typecheck.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 08:09:17 +02:00
e9d0356bc1 Merge branch 'worktree-core-package-generator': core-package generator + template slimming 2026-05-09 15:04:29 +02:00
ee069574ba fix: address final-review polish (docs + comments + test coverage)
- AGENTS.md bind-production code block: shows the slim default state
  (no @repo/core-events / @repo/core-realtime imports, BindProductionContext
  with no generic args) with a comment pointing to the scaffold workflow.
  The previous block showed a fully-wired post-scaffold state without
  signaling that none of those packages exist in main.
- bind-protocols.test.ts: top-of-file comment clarifies what these tests
  actually verify (protocol shapes have required methods) vs what the
  spec text might suggest (full assignability of optional packages'
  interfaces — that's verified by the e2e reconstruction tests, not here).
- core-package-generator.md: drops two stale "Until Phases 3-6 land"
  parentheticals — the phases shipped.
- config.test.ts: extends the choices assertion to cover all 4 names
  (realtime, events, trpc, ui).
- marketing-pages bind-* comments: reverse the inverted optional/required
  language. queue (IJobQueue) is from core-shared and always present;
  bus is the optional one (from @repo/core-events when scaffolded).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 15:01:40 +02:00
ce550f60e0 docs: refresh package list + Read first refs after optional-package extraction
- CLAUDE.md project-overview lists must-have core packages (shared/cms/api)
  separately from the four optionals (realtime/events/trpc/ui) with their
  scaffold command. Read first list adds template-tiers.md and notes that
  the events + realtime guides require their package to be scaffolded first.
- overview.md "Five tags" updated: core-composition is 2 must-have plus
  trpc (optional); core is 1 must-have plus ui/realtime/events (optional).
- dependency-flow.md fix: replaces the stale `// in packages/core-trpc`
  example with `// in packages/core-shared` (core-trpc is now optional and
  may not exist in a slim template).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:45:43 +02:00
c77daee2b5 docs(readme): Optional packages section + scaffold commands 2026-05-09 14:28:24 +02:00
eee87d4ec8 docs: template-tiers reference (must-have + optional + generator commands) 2026-05-09 14:27:57 +02:00
ae456a5436 docs: ui now optional — prerequisite notes + conditional HTML
- AGENTS.md (root): marks core-ui as optional in the package table and
  boundary rules; points per-package docs to the .hbs template
- apps/storybook/AGENTS.md: rewrites around no-core-ui-by-default;
  stories glob and globals.css import described as post-scaffold steps
- apps/web-next/AGENTS.md: cross-reference updated to template file
- apps/web-tanstack/AGENTS.md: cross-reference updated to template file
- docs/architecture/data-flow-explainer.html: core-ui bullet notes
  optional status + generator command

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:23:24 +02:00
a4c8f710a6 refactor: remove core-ui from main (scaffoldable via gen core-package ui)
Removal across all three consumers:
- apps/storybook: strips @repo/core-ui dep, clears stories glob (now []),
  removes globals.css import from preview.ts
- apps/web-next: strips @repo/core-ui dep + transpilePackages entry
- apps/web-tanstack: strips @repo/core-ui dep
- packages/core-ui: deleted entirely (28 files)

No app pages needed surgery — neither web-next nor web-tanstack source
files imported @repo/core-ui directly. The storybook app referenced it
only via the stories glob and the globals.css preview import.

Gates: 40/40 tasks successful, all 4 e2e byte-identical reconstructions
pass (realtime, events, trpc, ui).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:21:04 +02:00
d42d0e5c5c feat(generators): ui byte-identical snapshot + dispatch entry + e2e test
- Adds ui.snapshot.json (28 entries) computed from packages/core-ui
- Wires CORE_PACKAGE_GENERATORS["ui"]: guard + emitTemplateTree +
  addToTranspilePackages + printUiNextSteps (web-tanstack/storybook
  wiring is printed, not generated — resists templating)
- Adds "ui" to the core-package generator choices list
- Adds core-package-ui.e2e.test.ts (byte-identical reconstruction)
  — passes in 14.6 s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:19:22 +02:00
d974bb6267 feat(generators): capture core-ui as verbatim template files
28 .hbs files mirror packages/core-ui verbatim:
atoms (Button, Input, Label + stories + tests), molecules (FormField),
organisms/templates (empty barrels), lib/utils, styles/globals.css,
plus all root config files (package.json, tsconfig.json, vitest.config.ts,
eslint.config.js, turbo.json, AGENTS.md).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:17:47 +02:00
1967cb36ec docs: trpc now optional — prerequisite notes + conditional HTML
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:13:12 +02:00
c8116ac3f4 refactor: remove core-trpc from main (scaffoldable via gen core-package trpc)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:10:48 +02:00
d216250ccd feat(generators): wire trpc entry + e2e test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:08:26 +02:00
36bae3513d feat(generators): trpc byte-identical snapshot
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:06:45 +02:00
0a3a2c3845 feat(generators): capture core-trpc as verbatim template files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:06:14 +02:00
3d653666c2 docs: events now optional — Status headers + conditional HTML rendering
- ADR-015: Status → Optional with scaffold command + behavior note (bus absent
  means no-op, IJobQueue unaffected)
- events-and-jobs.md: prerequisite callout block explaining core-events is
  optional, how to scaffold, and which features require it
- data-flow-explainer.html: note bus is optional in BindProductionContext blurb;
  add inline comment in code snippet that bus is scaffoldable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:01:38 +02:00
a9f27f0d7e refactor: remove core-events from main (scaffoldable via gen core-package events)
- Delete packages/core-events/ (15 files)
- Strip @repo/core-events from all 5 feature package.json + apps/web-next/package.json
- Strip @repo/core-events from apps/web-next/next.config.mjs transpilePackages
- Strip E1 + J no-restricted-syntax blocks from core-eslint/base.js (anchor remains)
- Update bind-production.ts: drop bus construction + IEventBus import; rename
  resolveEventsAndJobsProduction → resolveJobsProduction (queue only),
  resolveEventsAndJobsDevSeed → resolveJobsDevSeed (queue only);
  ctx no longer has bus field; BindProductionContext generic arg narrowed
- Update bind-production.test.ts: assert ctx.bus is undefined, drop
  PayloadJobsEventBus/InMemoryEventBus instanceof checks
- Update sign-up-welcome-email.test.ts: assert mailer stays empty without bus
- Inline userSignedUpEvent in auth (drop defineEvent import from core-events)
- Drop InMemoryEventBus fallback from auth/di/module.ts

Feature binders' bus?.subscribe/publish calls remain as no-ops. Scaffold
@repo/core-events back via: pnpm turbo gen core-package events

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:00:35 +02:00
681fe6ada1 feat(generators): wire events entry + e2e test
Add EVENTS_RULE_BLOCK constant, events entry in CORE_PACKAGE_GENERATORS
dispatch table, events choice in prompts, and printEventsNextSteps helper.
Events entry emits 15 template files + transpilePackages splice + ESLint
no-restricted-syntax splice (E1 + J blocks). Add byte-identical e2e test
that strips @repo/core-events deps before pnpm install, scaffolds via
gen core-package events, and diffs against the snapshot.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 13:55:49 +02:00
60961f73d0 feat(generators): events byte-identical snapshot
Compute SHA-256 snapshot of packages/core-events (15 files) using the
shared computeSnapshot helper. The e2e test will diff a fresh scaffold
against this snapshot to guarantee byte-identical reconstruction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 13:53:07 +02:00
a342d064ad feat(generators): capture core-events as verbatim template files
Mirror packages/core-events/** into turbo/generators/templates/core-package/events/**/*.hbs.
15 files total (6 top-level + 9 src). No Handlebars interpolation needed
since none of the source files contain {{ }} patterns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 13:52:38 +02:00
2266429efd feat(core-eslint): anchor for events rules splice
Add // <gen:events-rules> anchor to base.js near the E1 + J
no-restricted-syntax blocks, and assert it in anchors.test.js.
After core-events removal the anchor remains as the splice point
for pnpm turbo gen core-package events.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 13:52:23 +02:00
39fd2a9f80 docs: realtime now optional — Status headers + conditional HTML rendering 2026-05-09 13:46:41 +02:00
57b2ff5191 refactor: remove core-realtime from main (scaffoldable via gen core-package realtime) 2026-05-09 13:45:52 +02:00
e28fe847fd test(generators): e2e byte-identical reconstruction of core-realtime 2026-05-09 13:33:53 +02:00
4308762caa feat(generators): wire realtime entry into core-package dispatch table 2026-05-09 13:32:46 +02:00
421d765b80 feat(generators): splicePluginRulesAt + splicePluginImportsAt + addBoundariesEntry + emitTemplateTree helpers 2026-05-09 13:31:28 +02:00
af062480b5 feat(generators): byte-identical snapshot machinery + realtime snapshot 2026-05-09 13:30:08 +02:00