KB LabsDocs

Migration Guide

Last updated April 7, 2026


Version-to-version upgrade notes for @kb-labs/sdk.

The SDK follows semantic versioning. This page documents breaking changes between major versions and the steps needed to migrate. For non-breaking additions, check the changelog.

@kb-labs/sdk is at 1.5.x today. The full 1.x line is backward-compatible — no breaking changes since 1.0.0. Migration entries below are placeholders for future major versions.

Golden rule for migration

Every migration in KB Labs follows the same principle: plugins should only ever import from @kb-labs/sdk and its subpaths. If a version bump breaks your plugin, the first question is usually "are you importing from an internal package instead of the SDK?"

Internal packages (@kb-labs/core-platform, @kb-labs/plugin-contracts, @kb-labs/studio-hooks, @kb-labs/studio-ui-kit, etc.) are versioned independently and may break at any time. The SDK absorbs those breaks and maintains a stable surface. If you follow the import rule, most upgrades are just pnpm update @kb-labs/sdk and you're done.

From v0.x to v1.0.0

If your plugin is still on a pre-1.0 version of the SDK, migrate to 1.0+ immediately. The pre-1.0 line never had a schema version for its plugin manifest — the kb.plugin/3 schema is a 1.0+ feature.

The big change: kb.plugin/3 manifest schema

Every manifest now carries schema: 'kb.plugin/3' as a literal string. Before 1.0, the field didn't exist. If you have an old plugin manifest without this field, the marketplace refuses to load it and the platform's validator produces a clear error.

Fix: add the schema field to the top of your manifest:

TypeScript
export const manifest = {
  schema: 'kb.plugin/3',       // ← add this
  id: '@your-scope/your-plugin',
  version: '0.1.0',
  // ...
};

Manifest permissions now required

Pre-1.0 plugins could declare handlers without any permissions and the runtime would run them with full system access. From 1.0, the runtime enforces permissions at every syscall — omitting permissions means your handler gets the minimum (read cwd, write outdir, nothing else).

Fix: use combinePermissions() and the presets from @kb-labs/sdk:

TypeScript
import { combinePermissions, minimalPreset, kbPlatformPreset } from '@kb-labs/sdk';
 
const permissions = combinePermissions()
  .with(minimalPreset)
  .with(kbPlatformPreset)
  .withPlatform({ llm: true, cache: true })
  .build();
 
// In the manifest:
permissions: permissions,

See Plugins → Permissions for the full model.

Handler exports must use defineCommand / defineRoute / etc.

Before 1.0, the runtime would call any exported function with the execute name. From 1.0, the runtime expects the helper-wrapped shape — specifically the object returned by defineCommand, defineRoute, etc., which includes host guards and a wrapped execute.

Fix: wrap your handler with the right define* helper for its host:

TypeScript
// Before (v0.x):
export default {
  async execute(ctx, input) { ... },
};
 
// After (v1.0+):
import { defineCommand } from '@kb-labs/sdk';
 
export default defineCommand({
  id: 'my-plugin:my-command',
  handler: {
    async execute(ctx, input) { ... },
  },
});

Build output path format

Before 1.0, manifest handler paths sometimes pointed at source files (.ts). From 1.0, they must point at built files (.js) because the runtime dynamically imports them without a transpiler.

Fix: update every handler path in your manifest to point at dist/ paths or whatever your build output directory is.

From v1.x to v2.0 (future)

No 2.0 release yet. When one ships, this section will cover:

  • Any removed exports.
  • Renamed hooks.
  • Manifest schema bump (if kb.plugin/3 evolves to kb.plugin/4).
  • Handler signature changes.

The general principle: 2.0 won't ship until breaking changes pile up that can't be handled through the golden rule alone. We prefer additive, backward-compatible changes whenever possible.

Studio SDK subpath (pre-1.5)

Before SDK 1.5, Studio plugin pages imported hooks from @kb-labs/studio-hooks directly. The 1.5 release introduced the @kb-labs/sdk/studio subpath and made direct imports of internal studio packages forbidden — they still work today for backward compatibility, but a future minor version will stop re-exporting them from under their old locations.

Fix: update Studio page imports to use the SDK subpath:

TypeScript
// Before (pre-1.5):
import { useData, useNotification } from '@kb-labs/studio-hooks';
import { Card, Button } from '@kb-labs/studio-ui-kit';
 
// After (1.5+):
import {
  useData,
  useNotification,
  Card,
  Button,
} from '@kb-labs/sdk/studio';

See Plugins → Studio Pages for the full set of imports available through the subpath.

Studio build subpath (1.5+)

SDK 1.5 also added @kb-labs/sdk/studio-build — a new subpath that wraps @kb-labs/studio-plugin-tools. The helper createStudioRemoteConfig used in your rspack.studio.config.mjs should now come from this subpath, not from the internal package.

Fix:

TypeScript
// Before:
import { createStudioRemoteConfig } from '@kb-labs/studio-plugin-tools';
 
// After:
import { createStudioRemoteConfig } from '@kb-labs/sdk/studio-build';

The function signature is identical — only the import path changed.

Upgrading the SDK version

Bash
# In your plugin repository:
pnpm update @kb-labs/sdk
 
# Or pin to a specific version:
pnpm add @kb-labs/sdk@^1.5.0

After upgrading:

  1. pnpm build — catch any TypeScript errors from renamed types.
  2. pnpm kb plugin:validate --manifest ./path/to/manifest.ts — catch manifest schema violations.
  3. pnpm test — make sure mocks still behave as expected.
  4. Run the plugin in dev mode via pnpm kb marketplace link and smoke-test it.

If everything passes, commit the bump and publish a new version of your plugin. Consumers who pnpm kb marketplace update will pick it up automatically.

Handling deprecations

The SDK emits deprecation warnings at runtime for APIs that are on their way out. These show up in logs (at warn level) with a deprecatedSince field indicating which version deprecated them. Treat them as "fix before the next major" — they won't break your plugin today, but they will break when the deprecation becomes a removal.

Common deprecation lifecycle:

  1. Minor X.1: API introduced as the replacement.
  2. Minor X.2–X.n: old API emits deprecation warning, new API works alongside.
  3. Major (X+1).0: old API removed, only new API remains.

Subscribe to the changelog or watch the repo for deprecation announcements ahead of major bumps.

Migration Guide — KB Labs Docs