Skip to content

@thoremin/sdk: the pure extension SDK as a workspace package (ADR follow-up c, part 1) - #298

Merged
thorwhalen merged 3 commits into
mainfrom
adr/sdk-package
Oct 5, 2026
Merged

thorwhalen merged 3 commits into
mainfrom
adr/sdk-package

Conversation

@thorwhalen

Copy link
Copy Markdown
Owner

Follow-up (c), part 1 of the instruments-as-graphs ADR (#268): the pure half of the extension SDK becomes a workspace package, @thoremin/sdk. It is the base the next two PRs build on: @thoremin/sdk-ui (the app half, host-injected), then @thoremin/ext-air.

What moved

38 files moved with git mv into packages/sdk/src/<same path>. That set is what the air extension's pure side imports, closed over its own imports. 363 specifiers were rewritten mechanically: @thoremin/sdk/<path> from outside the package, relative inside it.

  • instruments/{extension,branch,trunk,derive}. TRUNK/TRUNK_ID are split out of the branch table into instruments/trunk.ts, so wiring to the trunk no longer pulls the trunk's node implementations (score, pose chord, indirect map) into the SDK.
  • nodes/domain, nodes/music/drum_{pads,anchor}
  • music/{theory,sounds,notes,fingerings,drum_patterns,gm_drums}, enroll/* (the trainer's pure core), features/{catalog,demand,labConfig,types,...}, drums/*, score/schema

The air extension is these libraries' second consumer, which is the rule that made ictus a package (ADR §4.4).

Guards

  • test/packages_purity.test.ts now covers @thoremin/sdk (no @/ import, only declared dependencies).
  • The boundary guard drops the pure half of SDK_SURFACE: an extension's pure side may import only packages. The SDK→settings cycle walker is replaced by the package boundary.

Verified

  • npm run typecheck, npm test (217 files / 2438 tests), npm run build, npm run test:core (2350 passed / 68 skipped, bundle check clean) are all green.
  • The deploy is unchanged: npm ci && npm run build at the root links the new workspace (the lockfile gains the link entry only).

Refs #268.

…low-up c, part 1)

packages/sdk holds what an extension's pure side imports, closed over what those modules
import: 38 files moved by git mv, 363 specifiers rewritten mechanically (@thoremin/sdk/<path>
from outside, relative inside). The manifest and branch types, the trunk's names (split
into instruments/trunk.ts so wiring to the trunk no longer pulls node implementations into
the SDK), the port kinds, and the music / trainer / feature / drum libraries the air
extension shares with core.

- the boundary guard drops the pure half of SDK_SURFACE: packages_purity enforces the
  package, and an extension's pure side imports only packages
- tsconfig includes, CLAUDE.md paths and comment paths follow the move
- the deploy is unchanged (npm ci && npm run build at the root links the workspace)
…ore machinery back in the app

- drum patterns, GM drums, pattern fit/play, note names and fingering charts move from the
  SDK into src/extensions/air/lib (no core consumer once the store stops naming air state)
- TransientPort carries its value type (transientPort<T>()); the hot store's transient
  fields and setTransient are typed from the manifests like the dials, and the per-field
  air setters are gone
- the flute and guitar starter sequences move to the extension (starterSequences.ts);
  core's sequence store keeps the collection and starterSequence()
- the branch derivation and the Feature Lab config stay in the app; Extension.derive takes
  the settings opaquely
- stale comment paths follow the moves
@thorwhalen
thorwhalen merged commit 61661ea into main Oct 5, 2026
3 checks passed
@thorwhalen
thorwhalen deleted the adr/sdk-package branch October 5, 2026 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant