Pivit

Settings

Declare a settings schema for your Pivit plugin and read values back at runtime.

Declare what your plugin needs configuring and Pivit renders the settings interface for you. You do not build a settings screen.

Declaring a schema

import { defineSettings, definePlugin } from "@pivit/api";

type MySettings = {
  apiToken: string;
  resultLimit: number;
  includeArchived: boolean;
  sortBy: "updated" | "created";
};

const settings = defineSettings<MySettings>({
  schema: {
    title: "GitHub",
    description: "Connect Pivit to your GitHub account.",
    fields: [
      {
        key: "apiToken",
        label: "Personal access token",
        description: "Needs the repo scope.",
        type: "text"
      },
      {
        key: "resultLimit",
        label: "Results to show",
        type: "number",
        min: 1,
        max: 50,
        step: 1
      },
      {
        key: "includeArchived",
        label: "Include archived repositories",
        type: "switch"
      },
      {
        key: "sortBy",
        label: "Sort by",
        type: "select",
        options: [
          { label: "Recently updated", value: "updated" },
          { label: "Recently created", value: "created" }
        ]
      }
    ]
  },
  defaults: {
    resultLimit: 10,
    includeArchived: false,
    sortBy: "updated"
  }
});

export default definePlugin({ settings, commands: [] });

Field keys are checked against your settings type, so a typo in key fails to compile rather than silently reading undefined at runtime.

Field types

TypeRenders as
textSingle-line input
textareaMulti-line input
numberNumeric input, with optional min, max and step
switchToggle
selectDropdown built from options

Conditional fields

Hide a field until another one makes it relevant:

{
  key: "customEndpoint",
  label: "Enterprise URL",
  type: "text",
  condition: { key: "useEnterprise", equals: true }
}

Reading settings

Settings reads the current values at runtime:

import { Settings } from "@pivit/api";

const limit = Settings.get<number>("resultLimit") ?? 10;
const all = Settings.getAll<MySettings>();

Read settings inside execute or resolve rather than at module scope. A value captured when the plugin loaded will not reflect a change the user made afterwards.

Storage versus settings

Settings are user-facing configuration. For data your plugin manages itself — caches, tokens you obtained through a flow, recent selections — use Storage:

import { Storage } from "@pivit/api";

await Storage.set("recent-repos", repos);
const recent = await Storage.get<string[]>("recent-repos");

Storage is asynchronous and scoped to your plugin. Nothing you write there appears in the settings UI.

A custom settings interface

If the declarative schema is not enough, provide render and build the panel yourself with the UI primitives:

defineSettings({
  hasInterface: true,
  render: ({ settings, setSettings }) => (
    <ConnectionPanel value={settings} onChange={setSettings} />
  )
});

Reach for this only when you need it. The declarative schema stays consistent with the rest of Pivit's settings for free.

On this page