smithery.ai

config-plugin

Implement a config plugin/provider in pkg/providers/config/. Use when creating a new config provider, implementing the config.Plugin interface, or working on config plugin gRPC integration.

First seen Apr 20, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 2,867 B
  • docs SUMMARY.md 210 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Config Plugin Implementation Guide

Interface (pkg/zhiplugin/config/plugin.go)

type Plugin interface {
    List(ctx context.Context) ([]string, error)
    Get(ctx context.Context, path string) (Value, bool, error)
    Set(ctx context.Context, path string, v Value) error
    Validate(ctx context.Context, path string, tree TreeReader) ([]ValidationResult, error)
}

Key Types (pkg/zhiplugin/config/config.go)

type Value struct {
    Val        any               // JSON/YAML-compatible data
    Metadata   map[string]any    // Optional metadata
    Validators []ValidateFunc    // Local only, NEVER crosses gRPC wire
}

type TreeReader interface {
    Get(path string) (Value, bool)  // Returns copy
    List() []string
}

type ValidationResult struct {
    Severity Severity       // Info (0), Warning (1), Blocking (2)
    Message  string
    Metadata map[string]any // Optional, useful for UI hints
}

Path format: slash-delimited, segments match [a-z][a-z0-9._-]*[a-z0-9]. Use config.ValidatePath() to check.

Registration Boilerplate

package main

import (
    goplugin "github.com/hashicorp/go-plugin"
    "github.com/MrWong99/zhi/pkg/zhiplugin"
    "github.com/MrWong99/zhi/pkg/zhiplugin/config"
)

func main() {
    goplugin.Serve(&goplugin.ServeConfig{
        HandshakeConfig: zhiplugin.Handshake, // ZHI_PLUGIN=zhiplugin-v1, protocol v1
        Plugins: map[string]goplugin.Plugin{
            "config": &config.GRPCPlugin{Impl: &MyPlugin{}},
        },
        GRPCServer: goplugin.DefaultGRPCServer,
    })
}

Implementation Patterns

  • Thread safety: Protect shared state with sync.RWMutex (RLock for List/Get/Validate, Lock for Set).
  • Get returns copies: Return *v not v when storing pointers internally.
  • Validate with tree context: Use tree.Get(otherPath) for cross-value validation. Return multiple ValidationResult entries with appropriate severity.
  • Validators field: Value.Validators are closures and never serialize over gRPC. Only use them for local (in-process) validation. Plugin-side validation goes in the Validate method.
  • Wire format: Values are JSON-encoded (Val and Metadata separately). Ensure Val holds JSON-compatible types.

Reference Files

  • Interface & types: pkg/zhiplugin/config/plugin.go, pkg/zhiplugin/config/config.go
  • gRPC layer: pkg/zhiplugin/config/grpcclient.go, pkg/zhiplugin/config/grpcserver.go
  • Proto: api/proto/zhiplugin/v1/config.proto
  • Existing provider: pkg/providers/config/structuredfile/structuredfile.go
  • Example: examples/zhi-config-pokedex/main.go