Skip to main content

CREATE AND PUBLISH AN EXTENSION

This guide shows you how to create a TypeScript extension, publish it to the swamp registry, and install it in another repo.

Prerequisites

  • A swamp repository (swamp repo init)
  • A swamp account (swamp auth login)

Write the extension model

Create the extension file at extensions/models/disk_usage.ts:

import { z } from "npm:zod@4";

export const model = {
  type: "@mycollective/disk-usage",
  version: "2026.04.03.1",

  globalArguments: z.object({
    path: z.string().describe("Filesystem path to check"),
  }),

  resources: {
    result: {
      description: "Disk usage statistics",
      schema: z.object({
        path: z.string(),
        totalBytes: z.number(),
        usedBytes: z.number(),
        availableBytes: z.number(),
        usedPercent: z.number(),
      }),
      lifetime: "infinite" as const,
      garbageCollection: 10,
    },
  },

  methods: {
    check: {
      description: "Check disk usage at the configured path",
      arguments: z.object({}),
      execute: async (
        _args: Record<string, unknown>,
        context: Record<string, unknown>,
      ) => {
        const globalArgs = context.globalArgs as { path: string };

        const cmd = new Deno.Command("df", {
          args: ["-B1", globalArgs.path],
          stdout: "piped",
          stderr: "piped",
        });
        const output = await cmd.output();
        const stdout = new TextDecoder().decode(output.stdout);
        const lines = stdout.trim().split("\n");
        const parts = lines[1].split(/\s+/);

        const totalBytes = parseInt(parts[1]);
        const usedBytes = parseInt(parts[2]);
        const availableBytes = parseInt(parts[3]);
        const usedPercent = Math.round((usedBytes / totalBytes) * 100);

        const writeResource = context.writeResource as (
          spec: string,
          name: string,
          data: Record<string, unknown>,
        ) => Promise<{ name: string }>;
        const resultHandle = await writeResource("result", "result", {
          path: globalArgs.path,
          totalBytes,
          usedBytes,
          availableBytes,
          usedPercent,
        });

        return { dataHandles: [resultHandle] };
      },
    },
  },
};

Replace @mycollective with your collective name. Run swamp auth whoami to check your username and collectives.

Test the model locally

Create a model definition from the new type:

$ swamp model create @mycollective/disk-usage home-disk --global-arg path=/home

The output confirms the model was created and lists its global arguments and methods.

Run the method to confirm it executes:

$ swamp model method run home-disk check

The report at the end shows succeeded and the number of resources produced.

Create the manifest

Create extensions/models/manifest.yaml:

manifestVersion: 1

name: "@mycollective/disk-usage"
version: "2026.04.03.1"
description: "Check disk usage statistics for a filesystem path"

models:
  - disk_usage.ts

labels:
  - monitoring
  - filesystem

The name must start with your collective prefix (@username/ or @org/).

Format, lint, and validate

Format the extension source:

$ swamp extension fmt extensions/models/manifest.yaml

To check without modifying files, add --check.

Validate with a dry run before publishing:

$ swamp extension push extensions/models/manifest.yaml --dry-run

The dry run shows extension metadata and archive size without making API calls. If the push reports safety warnings (e.g., Deno.Command() usage), you will be prompted to confirm.

Publish to the registry

$ swamp extension push extensions/models/manifest.yaml

You will see output like:

info    extension·push Pushed "@mycollective/disk-usage"@"2026.04.03.1"
info    extension·push Extension ID: "bbc4f071-..."
info    extension·push Archive size: "1.4KB"
info    extension·push "Models: 1, Workflows: 0, Vaults: 0, Bundles: 1"

If the version already exists, the CLI offers to bump the MICRO component.

Add --release-notes "description of changes" to attach release notes, or add a releaseNotes field to the manifest.

Install the extension in another repo

In a different swamp repo, pull the extension:

$ swamp extension pull @mycollective/disk-usage

The model type is now available. Create definitions from it with swamp model create @mycollective/disk-usage <name>.

To restore pulled extensions after cloning (e.g., in CI), run swamp extension install.