Casset Apps
Build apps for artist worlds.
Create a focused interface inside a living Profile World or let a visual experience move with one host-authorized Track. The SDK, fixtures, and starters are real today; production distribution is still curated and internal.
@casset/apps is repository-local and vendored into each ZIP. It is not published to npm, and there is no public submit flow.
Apps receive
- Bounded artist, theme, catalog, and release data
- Explicit loading, empty, denied, and unavailable states
- Synchronized Track seconds and lifecycle
- Narrow host capability checks
Casset retains
- Installation, entitlement, and launch authority
- The global player and canonical audio clock
- Routes, runtime dispatch, and raw media delivery
- Disablement, exit, and production integration
Available now
Two runtimes, one product model.
Five-minute start
Download, verify, then make it yours.
Choose a Profile or Track starter and enter its root folder.
Install dependencies, run tests, and build before changing the contract.
Change the manifest and interface; keep host authority and state handling intact.
curl -LO https://casset.fm/downloads/casset-apps/casset-minimal-profile-app-v0.1.0-alpha.0.zip
unzip casset-minimal-profile-app-v0.1.0-alpha.0.zip
cd casset-minimal-profile-app
pnpm install
pnpm test
pnpm devSDK and imports
A real package, a declaration, and a narrow host.
@casset/appsvendored host contracttypescriptcontract checkingvitelocal buildvitestfixture and state testsreactReact starter onlyManifest
- Identity and version
- Profile or Track context
- Placements and permissions
- Track kinds when applicable
Context
- Short-lived launch lifecycle
- Minimized public DTOs
- Explicit Profile data states
- URL-free Track resource references
Host
- Capability detection
- Profile-only PLAY_TRACK request
- Lifecycle subscriptions
- Fail-closed close and invalid requests
import {
hasCassetPermission,
hostSupports,
isCassetDataReady,
type CassetAppHost,
} from "@casset/apps"
export async function playFirstTrack(host: CassetAppHost) {
const { context } = host.getSnapshot()
if (context.kind !== "PROFILE_SURFACE") return
if (!isCassetDataReady(context.catalog)) return
if (!hasCassetPermission(context, "playback.control")) return
if (!hostSupports(host, "PROFILE_PLAY_TRACK")) return
const track = context.catalog.data.tracks[0]
if (track) await host.request({ type: "PLAY_TRACK", trackId: track.id })
}{
"schema": "casset.app-manifest.v1",
"id": "studio.afterglow-room",
"slug": "afterglow-room",
"name": "Afterglow Room",
"shortDescription": "A quiet release room inside the Profile World.",
"description": "Stages an approved release and requests playback through Casset.",
"developer": { "name": "Your studio" },
"version": "0.1.0",
"icon": "/icon.svg",
"screenshots": [],
"category": "IDENTITY",
"context": "PROFILE_SURFACE",
"placements": ["ARTIST_APP_ROUTE"],
"permissions": [
"artist.profile.read",
"artist.theme.read",
"catalog.tracks.read",
"playback.read",
"playback.control"
],
"supportedFanAccess": ["FREE"],
"compatibility": { "mobile": true, "desktop": true, "pwa": true },
"trackApplicability": null
}@casset/apps is not published to npm. The starter ZIPs include the exact pre-release source and install it through a local file: dependency, so the imports above are real without implying an open package or marketplace.
Agent-ready Markdown
Give Codex or Claude a bounded creative brief.
AGENTS.md
- Canonical Casset doctrine
- Files the agent may change
- Runtime authority rules
- Required validation commands
CLAUDE.md
- The same host boundary
- Sparse-state expectations
- Mobile and reduced-motion rules
- No second player or private data
PROMPT.md
- A reusable task brief
- Creative intent and interaction
- Acceptance criteria
- Test and build handoff
# Build brief for Codex or Claude Code
## Objective
Turn the artist's active release into a quiet afterglow room inside
the existing Profile World.
## Use
- The vendored `@casset/apps` package
- The provided fixture and host lifecycle
- The starter's existing test and build commands
## Preserve
- Casset owns artist identity, authorization, playback, and exit
- Request playback through the host; never mount an `<audio>` element
- Handle loading, empty, unavailable, and permission-denied states
- Keep the interface calm, mobile-first, and artist-specific
## Verify
- `pnpm test`
- `pnpm build`Runnable projects
Begin at the right level of abstraction.
Truth before scale
A real SDK is not an open marketplace.
Use now
- Repository-local @casset/apps
- Three standalone starter ZIPs
- Strict parsers and fixtures
- Trusted production Track contract
Casset only
- Registry and runtime keys
- Installation and entitlement truth
- Playback stores and MediaFooter
- Raw media and server authorization
Not shipped
- npm publication
- Public submit or review API
- Arbitrary bundle isolation
- Live revocation and resource delivery