@taskclan/platform
v0.2.2
Published
Typed client for the Taskclan platform — track events, check entitlements, resolve identity/roles, discover Hivemind agents/skills/workflows, and dispatch Hive intents from any product.
Downloads
81
Maintainers
Readme
@taskclan/platform
One typed client for the Taskclan platform. Instead of copy-pasting a ~30-line SSE wrapper into every product, import this and get:
trackEvent— fire events into the unified events spine (platform_events)checkEntitlement/hasAccess— read who-can-do-what from the entitlements APIdispatchIntent— call any Hive intent with one typed method
It talks to Hive's only endpoint (POST /api/hive/v1/intent) and resolves the
intent's intent-final result. Zero runtime dependencies.
Install
Published privately to GitHub Packages under the taskclan org. Consumers
point the @taskclan scope at GitHub's registry and authenticate with a token
that has read:packages:
# .npmrc (in the consuming repo)
@taskclan:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}// package.json
{ "dependencies": { "@taskclan/platform": "^0.1.0" } }For local dev across the monorepo you can still use the path link instead:
{ "@taskclan/platform": "file:../packages/hive-sdk-ts" }.
Quickstart
import { createPlatformClient } from '@taskclan/platform';
import { supabase } from './supabase';
export const platform = createPlatformClient({
baseUrl: process.env.NEXT_PUBLIC_API_URL!, // engine origin
product: 'gamenova', // your apps.slug
getToken: async () => (await supabase.auth.getSession()).data.session?.access_token ?? null,
getUserId: async () => (await supabase.auth.getSession()).data.session?.user?.id ?? null,
});
// 1. Analytics (best-effort, never throws)
await platform.trackEvent('gamenova.game_published', { game_id, title });
// 2. Feature gating
if (await platform.hasAccess('gamenova', 'team_seats')) {
// …show the team panel
}
// 3. Any intent
const result = await platform.dispatchIntent('subscription.get_plan', {});API
| Method | Description |
| --- | --- |
| dispatchIntent<T>(type, input, opts?) | Dispatch a Hive intent, resolve its result. Throws PlatformError on fatal/timeout/HTTP error. |
| trackEvent(type, payload?) | One event into the spine. Best-effort — swallows errors. |
| trackEvents(events[]) | Batch of events. |
| checkEntitlement(product, feature?) | The entitlements.check result ({ plan, active, features, has_feature, … }). |
| hasAccess(product, feature) | Boolean gate; returns false on any error. |
opts: { householdId, idempotencyKey (UUID), timeoutMs, context, signal }.
Known event types autocomplete (KnownEventType); custom strings are still
accepted — the platform is permissive.
Portability
The client streams the SSE response where res.body.getReader() exists
(browsers, Node 18+). React Native's fetch has no streaming reader, so it
falls back to a buffered parse — fine, because Hive closes the stream right
after intent-final for one-shot intents. Pass your own fetch via config if
needed. (Nani's existing src/lib/hive.ts adds offline read-caching on top of
react-native-sse; it can keep that and adopt this package's types +
trackEvent incrementally.)
Build
npm install
npm run build # tsc → dist/ (JS + .d.ts)Publishing
Published privately to GitHub Packages (npm.pkg.github.com) under the
taskclan GitHub org — free for private packages, scope matches the repo owner.
CI (the normal path): push a tag and the
.github/workflows/publish-platform-sdk.yml workflow publishes using the
built-in GITHUB_TOKEN (no secret to configure):
git tag platform-sdk-v0.1.0
git push origin platform-sdk-v0.1.0Bump version in package.json for each release and tag to match.
Local (optional): create a GitHub PAT with write:packages, then:
npm config set //npm.pkg.github.com/:_authToken <PAT>
npm publish # publishConfig already points at GitHub PackagesThen swap the file: dependency for "@taskclan/platform": "^0.1.0" in each
consumer (which needs the .npmrc from Install).
Adoption plan
- gamenova-web / taskclan-web / Labs (web + Node) — replace the inline
trackEventwrapper insrc/lib/hive.tswithcreatePlatformClient. These get full streaming. - nani — adopt the shared types +
trackEventfirst; keep the RN SSE + cache layer until a streaming-capable transport is wired. - Once stable, publish and pin a version instead of the
file:link.
