Skip to content

Extension reference

Migrate from 0.x

Version 1 replaces the experimental raw channel with one shared, schema-validated protocol and consistent renderer context names. Update both package entries together.

Migration checklist

  1. Add the literal apiVersion: 1 to defineRenderer.
  2. Define one protocol with defineProtocol.
  3. Pass that protocol to both defineRenderer and connect.
  4. Replace individual raw method registration with the complete handler table passed to connect.
  5. Rename NativePiContext to RendererContext.
  6. Rename renderer prop ctx to context.
  7. Move ctx.call and ctx.on under context.channel.
  8. Rename array contribution key fields to id.
  9. Read project, session, and agent state from their dedicated context fields.
  10. Delete guards that duplicate the new runtime schemas.

Replace the raw channel

src/protocol.ts
import { defineProtocol } from "@nativepi/extension-api";
import { z } from "@nativepi/extension-api/schema";

export const protocol = defineProtocol({
  methods: {
    state: { result: z.object({ enabled: z.boolean() }) },
    setEnabled: {
      params: z.object({ enabled: z.boolean() }),
      result: z.object({ enabled: z.boolean() }),
    },
  },
  events: {
    changed: z.object({ enabled: z.boolean() }),
  },
});

Replace method registration

Instead of registering methods one at a time, connect the whole table. A reload then replaces removed methods rather than leaving them behind.

0.x
const channel = connect("@acme/package");
channel.method("state", () => state);
channel.method("setEnabled", update);
1.x
const host = connect("@acme/package", protocol, {
  state: () => state,
  setEnabled: update,
});

Update renderer context

0.x
render: (ctx) => {
  ctx.call("state");
  ctx.on("changed", update);
  return <Panel project={ctx.session?.cwd} />;
}
1.x
render: (context) => {
  context.channel.call("state");
  context.channel.on("changed", update);
  return <Panel project={context.project.path} />;
}

The old nullable session object is now a stable shape. A new chat uses context.session.file: null. The old dark flag was removed because renderers style against semantic color variables, which update with NativePi's light, dark, and custom appearances.

Load behavior

NativePi rejects a 0.x renderer before running any contribution and reports a compatibility error. The package's ordinary Pi extension still loads, so terminal behavior and non-graphical tools remain available during migration.