wick

command module
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 3 Imported by: 0

README

Wick

Just Prompt. AI Does the Rest.

Stop copy-pasting AI output into black-box editors. Wick gives AI a real Go project — you own everything it builds.

Overview

A Go-based platform for building internal tools, admin panels, and background jobs. Provides a standardized structure with self-registering tool modules, a configurable admin UI, tag-based access control, and a themeable design system. The app name and branding are configurable at runtime via the admin Configs panel — no code changes needed to rebrand.

This boilerplate is designed for projects of medium to large complexity. For simpler cases that only handle one or a few processes, it is not necessary to use this structure — a single main.go or flat architecture works fine.

The codebase is organized by module rather than by function. This approach offers several advantages:

  • Single Responsibility Principle: One of the SOLID principles of object-oriented design, states that a class or module should have only one reason to change.
  • Reusability: Modules become more reusable across different clients, promoting code sharing and reducing duplication.
  • Loose Coupling, High Cohesion: Two words that describe how easy or difficult it is to change a piece of software. Grouping by module enforces loose coupling between different parts of the code while promoting high cohesion within each module.
  • Faster Contribution: Developers can contribute to specific modules without causing collateral damage in unrelated areas, speeding up the development process.
  • Ease of Understanding: The codebase becomes more accessible and understandable as it's organized around modules and use cases. A use case repository clarifies what each module does.
Create New Module/API

This section guides you through creating a new API module following the established patterns in this codebase.

Architecture Overview

This project follows "Clean" Architecture principles with these layers:

  • Handler (internal/{module}/handler.go) - HTTP layer that handles requests/responses
  • Service (internal/{module}/service.go) - Business logic layer
  • Repository (internal/{module}/repo.go) - Data access layer
  • Entity (internal/entity/{module}.go) - Domain models
Step-by-Step Guide

1. Create the Entity

Create your domain model in internal/entity/{module}.go:

package entity

import "time"

type YourModule struct {
    ID        int64     `json:"id"`
    Name      string    `json:"name" gorm:"index"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
}

2. Create the Repository

Create internal/{module}/repo.go:

package yourmodule

import (
    "context"
    "github.com/yogasw/wick/internal/entity"
    "gorm.io/gorm"
)

type repo struct {
    db *gorm.DB
}

func NewRepository(db *gorm.DB) *repo {
    return &repo{db: db}
}

func (r *repo) Save(ctx context.Context, item *entity.YourModule) error {
    return r.db.WithContext(ctx).Save(item).Error
}

func (r *repo) FindByID(ctx context.Context, id int64) (*entity.YourModule, error) {
    var item entity.YourModule
    err := r.db.WithContext(ctx).First(&item, id).Error
    if err != nil {
        return nil, err
    }
    return &item, nil
}

3. Create the Service

Create internal/{module}/service.go:

package yourmodule

import (
    "context"
    "errors"
    "fmt"
    "github.com/yogasw/wick/internal/entity"
    "gorm.io/gorm"
)

//go:generate mockery --with-expecter --case snake --name Repository
type Repository interface {
    Save(ctx context.Context, item *entity.YourModule) error
    FindByID(ctx context.Context, id int64) (*entity.YourModule, error)
}

type Service struct {
    repo Repository
}

func NewService(repo Repository) *Service {
    return &Service{repo: repo}
}

func (s *Service) GetByID(ctx context.Context, id int64) (*entity.YourModule, error) {
    item, err := s.repo.FindByID(ctx, id)
    if err != nil {
        if errors.Is(err, gorm.ErrRecordNotFound) {
            return nil, fmt.Errorf("item not found")
        }
        return nil, fmt.Errorf("failed to find item: %w", err)
    }
    return item, nil
}

func (s *Service) Create(ctx context.Context, req *CreateRequest) error {
    item := &entity.YourModule{
        Name: req.Name,
    }

    if err := s.repo.Save(ctx, item); err != nil {
        return fmt.Errorf("failed to save item: %w", err)
    }

    return nil
}

type CreateRequest struct {
    Name string `json:"name" validate:"required"`
}

4. Create the Handler

Create internal/{module}/handler.go:

package yourmodule

import (
    "encoding/json"
    "github.com/yogasw/wick/internal/pkg/api/resp"
    "net/http"
    "strconv"

    "github.com/rs/zerolog/log"
)

type httpHandler struct {
    svc *Service
}

func NewHttpHandler(svc *Service) *httpHandler {
    return &httpHandler{svc: svc}
}

func (h *httpHandler) GetByID(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    id, err := strconv.Atoi(r.PathValue("id"))
    if err != nil {
        resp.WriteJSONFromError(w, err)
        return
    }

    item, err := h.svc.GetByID(ctx, int64(id))
    if err != nil {
        log.Ctx(ctx).Error().Msgf("failed to get item: %s", err.Error())
        resp.WriteJSONFromError(w, err)
        return
    }

    resp.WriteJSON(w, http.StatusOK, item)
}

func (h *httpHandler) Create(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    var req CreateRequest
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        resp.WriteJSONFromError(w, err)
        return
    }

    if err := h.svc.Create(ctx, &req); err != nil {
        log.Ctx(ctx).Error().Msgf("failed to create item: %s", err.Error())
        resp.WriteJSONFromError(w, err)
        return
    }

    resp.WriteJSON(w, http.StatusCreated, "created")
}

5. Register Routes in Server

Add your module to internal/api/server.go in the NewServer() function:

// YourModule
yourModuleRepo := yourmodule.NewRepository(db)
yourModuleSvc := yourmodule.NewService(yourModuleRepo)
yourModuleHandler := yourmodule.NewHttpHandler(yourModuleSvc)

// Add routes
r.Handle("GET /api/v1/yourmodule/{id}", authMidd.StaticToken(http.HandlerFunc(yourModuleHandler.GetByID)))
r.Handle("POST /api/v1/yourmodule", authMidd.StaticToken(http.HandlerFunc(yourModuleHandler.Create)))

6. Add Database Migration (if needed)

If your entity needs database tables, add migration to internal/postgres/migrate.go:

func Migrate(db *gorm.DB) {
    db.AutoMigrate(
        &entity.Room{},
        &entity.YourModule{}, // Add your entity here
    )
}
Key Patterns to Follow
  • Error Handling: Use resp.WriteJSONFromError(w, err) for consistent error responses
  • Logging: Use log.Ctx(ctx).Error().Msgf() for contextual logging
  • Validation: Use struct tags with validate for request validation
  • Database: Always use WithContext(ctx) for database operations
  • Mocking: Add //go:generate mockery comments for interfaces that need mocks
Available Response Utilities
  • resp.WriteJSON(w, statusCode, data) - Standard JSON response
  • resp.WriteJSONFromError(w, err) - Error response with proper status codes
  • resp.WriteJSONWithPaginate(w, statusCode, data, total, page, limit) - Paginated response
Sample Use Case

Example: building a tool that generates reports from a database, a background job that cleans up expired sessions on a schedule, and an admin page to manage tool access per team via tags.

Adding a UI Tool Module

Tool modules (internal/tools/{tool}/) follow a lighter pattern than API modules — a handler.go + view.templ + service.go, wired up in internal/tools/registry.go (or a downstream main.go). Each tool package exposes one top-level Register(r tool.Router) function plus, if it has runtime-editable config, a Config struct. There is no per-module state-bearing struct — handlers are plain functions that read per-instance metadata via c.Meta() and config values via c.Cfg(...).

Register an instance from main.go:

app.RegisterTool(
    tool.Tool{Key: "convert-text", Name: "Convert Text", Icon: "Aa"},
    converttext.Config{InitText: "hello world", InitType: "uppercase"},
    converttext.Register,
)

One app.RegisterTool call = one card on the home grid. Register again with a different meta.Key (and, if you want, a different Config) to get a second card backed by the same Register function. Tools with no runtime-editable knobs (e.g. external redirect links) use app.RegisterToolNoConfig(meta, register) instead.

Key-driven paths. Every tool.Tool declares a Key (lowercase slug, no slashes). Wick mounts the instance at /tools/{Key} and fills in meta.Path before invoking Register — modules never set Path themselves and never hardcode /tools/.... Inside Register, declare routes relative to the base: r.GET("/"), r.POST("/api/foo"), r.Static("/static/"). Handlers then read the active instance from *tool.Ctx: c.Base() returns the absolute /tools/{Key} path, c.Meta() returns the full tool.Tool (Name, Icon, ExternalURL, …). Use those inside handlers instead of closing over values from Register.

Handlers receive a *tool.Ctx — a thin wrapper around http.ResponseWriter / *http.Request with helpers for the common shape (c.Form(k), c.Query(k), c.BindJSON(&v), c.HTML(body), c.JSON(status, v), c.Redirect(url, code)). Wick owns the mux, injects the page renderer, and fails the boot with a pointed error if any two tools share a Key or if any two routes collide on METHOD PATH. Tools never import net/http for mounting.

Per-module static assets (JS/CSS). Each module embeds its own assets so the codebase doesn't accumulate one huge app.js:

  1. Create internal/tools/{tool}/js/ and drop your JS files in it (e.g. mytool.js).

  2. Create internal/tools/{tool}/static.go:

    package mytool
    
    import "embed"
    
    //go:embed js
    var StaticFS embed.FS
    
  3. Mount the static tree via the Router inside Register — path is relative:

    func Register(r tool.Router) {
        r.GET("/", index)
        r.Static("/static/", StaticFS)
    }
    
  4. Reference the script from your templ page — use the base path read via c.Base() and threaded into the template:

    <script src={ base + "/static/js/mytool.js" }></script>
    

Footgun: //go:embed js fails to compile if the js/ directory doesn't exist. Always create the directory (with at least one file) before building.

r.Static blocks directory listings automatically — embedded asset trees can't be browsed.

Runtime-editable config (typed Config + wick tags). If a tool needs knobs that admins can edit without a redeploy — seed text, API base URLs, feature toggles, credentials — declare a typed Config struct and pass a seed value to app.RegisterTool:

type Config struct {
    InitText string `wick:"desc=Seed dropped into the textarea."`
    InitType string `wick:"desc=Seed conversion type.;dropdown=uppercase|lowercase|titlecase"`
    APIKey   string `wick:"desc=External API key.;secret;required"`
}

Wick reflects the struct into configs rows once at register time via entity.StructToConfigs — the tool itself never implements a Configs() method. Each exported field with a wick:"..." tag becomes one row. Tag fields are split by ;: desc=... describes the row; bare keys are flags (required, secret, locked, regen, textarea, checkbox, number, email, url, color, date, datetime); dropdown=a|b|c renders a <select> with the given options. When no widget flag is set, the framework picks one from the Go type: bool → checkbox, int/float → number, string → text. Field names are snake-cased into keys (InitTextinit_text) — override with key=custom_name if you need a specific column name.

Rows are reconciled at boot with composite primary key (owner, key), where owner = meta.Key. The Go value passed to app.RegisterTool is the first-boot seed; once a row exists it wins (admin edits stick). Handlers read the current value via c.Cfg("init_text") — scoped automatically to this instance's Meta.Key. Typed accessors: c.CfgInt("max_items"), c.CfgBool("enable_cache"). For explicit cross-tool reads use c.CfgOf(owner, key) (rare, intentional). Tag a field required when there's no sensible default; c.Missing() returns the keys still unset so the page can show a "setup required" prompt.

Because the seed is pulled from the cfg argument at register time, a single tool registered as multiple cards each seed their own defaults — meta = {Key: "default"} + cfg = {InitText: "hello world"} and meta = {Key: "convert-text-alt"} + cfg = {InitText: "HELLO WORLD"} give two cards with different initial state but shared logic.

Adding a Background Job Module

Job modules (internal/jobs/{job}/) follow the same stateless pattern as tools — a top-level Run(ctx) (string, error) function plus, if the job has knobs, a typed Config struct. There is no NewJob() constructor, no Handler struct, no Meta() method. Metadata lives at the register call site.

Register an instance from main.go:

app.RegisterJob(
    job.Meta{
        Key:         "auto-get-data",
        Name:        "Auto Get Data",
        Description: "Fetch a remote endpoint on a schedule.",
        Icon:        "🌐",
        DefaultCron: "*/30 * * * *",
        DefaultTags: []tool.DefaultTag{tags.Job},
    },
    autogetdata.Config{},
    autogetdata.Run,
)

One app.RegisterJob call = one row in the jobs table = one card on the home grid. Call again with a different meta.Key + Config to get a second scheduled instance backed by the same Run func. Jobs with no runtime knobs use app.RegisterJobNoConfig(meta, run).

Two surfaces per job. A registered job gets two pages with clearly split audiences:

  • /jobs/{key}operator surface. Run Now button, last-run status, recent run history. What end users see.
  • /manager/jobs/{key}admin surface. Schedule (cron) + runtime Config editor. What admins see. Non-admin users who land here get a 404.

Both pages share manager.Service so run history and setup-required banners stay in sync.

Reading config inside Run. Run is a plain function — no struct to attach methods to. Read runtime config via the ctx:

func Run(ctx context.Context) (string, error) {
    c := job.FromContext(ctx)
    url := c.Cfg("url")
    if url == "" {
        return "", errors.New("url not configured")
    }
    body, err := fetchRemote(ctx, url)
    if err != nil {
        return "", err
    }
    return body, nil
}

The returned string is stored on the run row as the result summary; the error (if any) marks the run as failed. Same wick:"..." tag grammar as tools — required, secret, dropdown=a|b|c, textarea, url, number, etc. Wick reflects the Config struct into configs rows at register time via entity.StructToConfigs.

Worker vs web. The web process (go run main.go server) mounts both surfaces; the worker process (go run main.go worker) owns the cron ticker that invokes Run on schedule. Both read from the same configs table, so admin edits land everywhere on the next tick.

Environment Variables

Set up the environment file by copying .env.example:

Mac/Linux: cp .env.example .env

Windows: copy .env.example .env

Alternatively, you can create a copy of .env.example and rename it to .env in your project's root directory

Run Locally

First time only:

make setup         # downloads the Tailwind CLI into ./bin/ (OS-detected)

Development (with CSS + templ watching):

Two terminals, run in parallel:

# Terminal 1 — Tailwind in watch mode
make css/watch

# Terminal 2 — the server
go run main.go server

Or use the combined target that runs both (Unix-like shells):

make dev

One-shot run (no watch): useful for quick verification, CI-style checks, or when an agent (e.g. Claude Code) needs to boot the server.

make css            # rebuild CSS once (minified)
go run main.go server

The server listens on http://localhost:9425.

See AGENTS.md for the rules coding agents follow (one-shot flow, process cleanup, Tailwind binary check).

Other useful targets live in the Makefilemake test, make tidy, make generate (runs templ generate + go generate + make css), make run/live (Air-powered live reload).

Generate Mock from Interface
  • Install Mockery:

    go install github.com/vektra/mockery/v2@v2.53.4
    

    Note: In this repo, we use Mockery v2.

  • Add the following code in the interface code file: //go:generate mockery --case snake --name XXXX

  • Run go generate using make generate

Handle HTTP Client Exceptions

client.Error complies with Go standard error. which support Error, Unwrap, Is, As

// Sample using errors.As
err := s.api.CreateResource(ctx, payload)
if err != nil {
    var cerr *client.Error
    if errors.As(err, &cerr) {
        fmt.Println(cerr.Message)          // General error message
        fmt.Println(cerr.StatusCode)       // HTTP status code e.g: 400, 401 etc.
        fmt.Println(cerr.RawError)         // Raw Go error object
        fmt.Println(cerr.RawAPIResponse)   // Raw API response body in byte
    }
}

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package app is the public entry point for downstream projects that want to embed wick as a library.
Package app is the public entry point for downstream projects that want to embed wick as a library.
cmd
cli
gate command
Command gate is the small binary claude's PreToolUse hook invokes before every Bash tool call.
Command gate is the small binary claude's PreToolUse hook invokes before every Bash tool call.
lab command
internal
accesstoken
Package accesstoken manages Personal Access Tokens — static bearer credentials a user generates from /profile/tokens and pastes into a remote MCP client (Claude Desktop, Cursor, VSCode plugin, custom CLI).
Package accesstoken manages Personal Access Tokens — static bearer credentials a user generates from /profile/tokens and pastes into a remote MCP client (Claude Desktop, Cursor, VSCode plugin, custom CLI).
accesstoken/view
templ: version: v0.3.1020
templ: version: v0.3.1020
admin/view
templ: version: v0.3.1020
templ: version: v0.3.1020
agents/askuser
Package askuser holds the daemon-side coordinator for the ask_user MCP tool.
Package askuser holds the daemon-side coordinator for the ask_user MCP tool.
agents/capability
Package capability declares per-provider hook-support metadata and a self-registering registry for it.
Package capability declares per-provider hook-support metadata and a self-registering registry for it.
agents/channels
Package channels provides message channel implementations for the Agents subsystem.
Package channels provides message channel implementations for the Agents subsystem.
agents/channels/rest
Package rest implements an OpenAI Chat Completions compatible HTTP channel for the agents pool.
Package rest implements an OpenAI Chat Completions compatible HTTP channel for the agents pool.
agents/channels/setup
Package setup composes channel implementations into a registry.
Package setup composes channel implementations into a registry.
agents/channels/slack
Package slack implements the Slack transport for the agents channel registry.
Package slack implements the Slack transport for the agents channel registry.
agents/channels/telegram
Package telegram implements the Telegram transport for the agents channel registry.
Package telegram implements the Telegram transport for the agents channel registry.
agents/config
Package config holds the runtime-editable Agents config (General / Slack / Workspace structs reflected into the configs DB table) plus the on-disk Layout — the single source of truth for path math under the platform default data directory (~/.<app>/agents).
Package config holds the runtime-editable Agents config (General / Slack / Workspace structs reflected into the configs DB table) plus the on-disk Layout — the single source of truth for path math under the platform default data directory (~/.<app>/agents).
agents/event
Package event holds the CLI-agnostic event abstraction.
Package event holds the CLI-agnostic event abstraction.
agents/gate
Package gate is the command whitelist enforcement layer.
Package gate is the command whitelist enforcement layer.
agents/pool
Package pool manages the global agent subprocess slot count + FIFO queue.
Package pool manages the global agent subprocess slot count + FIFO queue.
agents/preset
Package preset manages reusable agent templates stored at `<BaseDir>/presets/<name>/agent.md`.
Package preset manages reusable agent templates stored at `<BaseDir>/presets/<name>/agent.md`.
agents/provider
Package runtime owns the per-AI-CLI runtime layer for agents:
Package runtime owns the per-AI-CLI runtime layer for agents:
agents/provider/claude
Package claude is the Claude-CLI specific Spawner implementation.
Package claude is the Claude-CLI specific Spawner implementation.
agents/provider/codex
Package codex will hold the Codex-CLI specific Spawner implementation.
Package codex will hold the Codex-CLI specific Spawner implementation.
agents/provider/gemini
Package gemini will hold the Gemini-CLI specific Spawner implementation.
Package gemini will hold the Gemini-CLI specific Spawner implementation.
agents/providersync
Package providersync syncs provider credential files to/from the DB.
Package providersync syncs provider credential files to/from the DB.
agents/registry
Package registry holds the in-memory cache of on-disk Agents state (Registry) plus a mutator wrapper (Manager) and the boot entrypoint (Bootstrap).
Package registry holds the in-memory cache of on-disk Agents state (Registry) plus a mutator wrapper (Manager) and the boot entrypoint (Bootstrap).
agents/session
Package session manages on-disk session entries at `<BaseDir>/sessions/<id>/`.
Package session manages on-disk session entries at `<BaseDir>/sessions/<id>/`.
agents/state
Package state holds the per-agent runtime state machine.
Package state holds the per-agent runtime state machine.
agents/storage
Package storage holds the filesystem primitives used by every other agents subpackage: atomic JSON write, JSONL append/read/tail/truncate, directory scan, and identifier validation.
Package storage holds the filesystem primitives used by every other agents subpackage: atomic JSON write, JSONL append/read/tail/truncate, directory scan, and identifier validation.
agents/store
Package store is the agents pipeline sink: it consumes AgentEvent values produced by a Parser and writes them to the on-disk session folder (conversation.jsonl, raw.jsonl, agents.json cli_session_id).
Package store is the agents pipeline sink: it consumes AgentEvent values produced by a Parser and writes them to the on-disk session folder (conversation.jsonl, raw.jsonl, agents.json cli_session_id).
agents/transport
Package transport defines the boundary between Agents and message sources (Slack, UI, future API).
Package transport defines the boundary between Agents and message sources (Slack, UI, future API).
agents/transport/api
Package api will hold the HTTP API transport — external integrations that POST messages directly into a session, bypassing UI / Slack.
Package api will hold the HTTP API transport — external integrations that POST messages directly into a session, bypassing UI / Slack.
agents/transport/slack
Package slack will hold the Slack transport: socket-mode (default) or HTTP Event API listener, reaction lifecycle, chunked replies, access control, and meta-command routing.
Package slack will hold the Slack transport: socket-mode (default) or HTTP Event API listener, reaction lifecycle, chunked replies, access control, and meta-command routing.
agents/transport/ui
Package ui will hold the UI transport: an HTTP handler glue layer that turns POST /tools/agents/sessions/{id}/send into an IncomingMessage and pumps it through the pool.
Package ui will hold the UI transport: an HTTP handler glue layer that turns POST /tools/agents/sessions/{id}/send into an IncomingMessage and pumps it through the pool.
agents/workspace
Package workspace manages on-disk workspace entries at `<BaseDir>/workspaces/<name>/` (managed) or any user-supplied absolute path (custom).
Package workspace manages on-disk workspace entries at `<BaseDir>/workspaces/<name>/` (managed) or any user-supplied absolute path (custom).
appname
Package appname is the single source of truth for the running app's *path-safe identifier* — the slug used in `~/.<app>/` for DB, logs, agents Layout, gate spec/socket.
Package appname is the single source of truth for the running app's *path-safe identifier* — the slug used in `~/.<app>/` for DB, logs, agents Layout, gate spec/socket.
autostart
Package autostart registers the running binary to launch at OS user login.
Package autostart registers the running binary to launch at OS user login.
builder
Package builder compiles a wick app into a raw Go binary plus the platform-native distributable that ships with each release:
Package builder compiles a wick app into a raw Go binary plus the platform-native distributable that ships with each release:
builder/darwin
Package darwin handles macOS-specific build steps — wrapping the raw binary into a .app bundle and (host-darwin only) further wrapping that into a .dmg disk image.
Package darwin handles macOS-specific build steps — wrapping the raw binary into a .app bundle and (host-darwin only) further wrapping that into a .dmg disk image.
builder/linux
Package linux handles Linux-specific build steps — wrapping the raw binary into a Debian binary package (.deb).
Package linux handles Linux-specific build steps — wrapping the raw binary into a Debian binary package (.deb).
builder/windows
Package windows handles Windows-specific build steps — currently the .syso resource that embeds the brand icon plus version metadata into the .exe.
Package windows handles Windows-specific build steps — currently the .syso resource that embeds the brand icon plus version metadata into the .exe.
configs
Package configs manages runtime-editable configuration stored in the `configs` table.
Package configs manages runtime-editable configuration stored in the `configs` table.
connectors
Package connectors is the central registry for every connector definition wick will expose via MCP.
Package connectors is the central registry for every connector definition wick will expose via MCP.
connectors/crudcrud
Package crudcrud is a sample connector that wraps the crudcrud.com REST sandbox — a free, throwaway JSON store useful for demos and integration smoke tests.
Package crudcrud is a sample connector that wraps the crudcrud.com REST sandbox — a free, throwaway JSON store useful for demos and integration smoke tests.
connectors/github
Package github wraps the GitHub REST API v3 as a wick connector.
Package github wraps the GitHub REST API v3 as a wick connector.
connectors/httprest
Package httprest is a generic HTTP/REST connector that lets an LLM call any JSON API without writing a custom connector.
Package httprest is a generic HTTP/REST connector that lets an LLM call any JSON API without writing a custom connector.
connectors/slack
Package slack wraps Slack's Web API as a wick connector.
Package slack wraps Slack's Web API as a wick connector.
connectors/wickmanager
Package wickmanager exposes wick's own management plane (apps, jobs, tools, connectors, lifecycle server/worker) as a fixed single- instance connector.
Package wickmanager exposes wick's own management plane (apps, jobs, tools, connectors, lifecycle server/worker) as a fixed single- instance connector.
enc
Package enc implements wick's encrypted-fields layer: a per-user AES-256-GCM cipher that lets credentials and other sensitive values flow between an LLM and a connector without ever appearing as plaintext in the LLM's context window or in audit logs.
Package enc implements wick's encrypted-fields layer: a per-user AES-256-GCM cipher that lets credentials and other sensitive values flow between an LLM and a connector without ever appearing as plaintext in the LLM's context window or in audit logs.
home
templ: version: v0.3.1020
templ: version: v0.3.1020
initcreds
Package initcreds writes / clears the initial-admin credentials file.
Package initcreds writes / clears the initial-admin credentials file.
jobrunner
Package jobrunner mounts the operator-facing /jobs/{key} surface where users can run a job and see its recent history.
Package jobrunner mounts the operator-facing /jobs/{key} surface where users can run a job and see its recent history.
jobrunner/view
templ: version: v0.3.1020
templ: version: v0.3.1020
jobs
Package jobs is the single place to register all background job modules.
Package jobs is the single place to register all background job modules.
jobs/connector-runs-purge
Package connectorrunspurge is wick's built-in maintenance job that trims old rows from the connector_runs audit table.
Package connectorrunspurge is wick's built-in maintenance job that trims old rows from the connector_runs audit table.
jobs/provider-storage-retention
Package providerstorageretention purges expired provider_storage file rows and old history rows on a daily schedule.
Package providerstorageretention purges expired provider_storage file rows and old history rows on a daily schedule.
jobs/provider-storage-sync
Package providerstoragesync is a background job that backs up all enabled provider-storage sources from disk to DB on a fixed interval.
Package providerstoragesync is a background job that backs up all enabled provider-storage sources from disk to DB on a fixed interval.
jobs/sample-post
Package samplepost is a sample job that fetches a post from a JSONPlaceholder-compatible API and returns the result as markdown.
Package samplepost is a sample job that fetches a post from a JSONPlaceholder-compatible API and returns the result as markdown.
login/view
templ: version: v0.3.1020
templ: version: v0.3.1020
manager/view
templ: version: v0.3.1020
templ: version: v0.3.1020
manager/view/type
templ: version: v0.3.1020
templ: version: v0.3.1020
mcp
Package mcp implements the Model Context Protocol JSON-RPC 2.0 transport that LLM clients (Claude Desktop, Cursor, Claude.ai web) call to discover and invoke wick connectors as tools.
Package mcp implements the Model Context Protocol JSON-RPC 2.0 transport that LLM clients (Claude Desktop, Cursor, Claude.ai web) call to discover and invoke wick connectors as tools.
mcpconfig
Package mcpconfig writes MCP server entries into client config files (Claude Desktop, Cursor, Gemini CLI, Codex CLI, Claude Code) and detects which clients are installed on the host.
Package mcpconfig writes MCP server entries into client config files (Claude Desktop, Cursor, Gemini CLI, Codex CLI, Claude Code) and detects which clients are installed on the host.
metrics
Package metrics defines the Recorder interface that connectors.Service uses to emit telemetry.
Package metrics defines the Recorder interface that connectors.Service uses to emit telemetry.
oauth
Package oauth implements the minimal OAuth 2.1 authorization server every spec-compliant MCP client (notably Claude.ai web) requires.
Package oauth implements the minimal OAuth 2.1 authorization server every spec-compliant MCP client (notably Claude.ai web) requires.
oauth/view
templ: version: v0.3.1020
templ: version: v0.3.1020
pkg/render
Package render builds the tool.RenderFunc that wraps a body fragment in wick's page shell (Layout + Navbar).
Package render builds the tool.RenderFunc that wraps a body fragment in wick's page shell (Layout + Navbar).
pkg/ui
templ: version: v0.3.1020
templ: version: v0.3.1020
processctl
Package processctl owns the in-process lifecycle of the HTTP server and background worker: Start/Stop/IsRunning + a per-process IsManaged flag that says whether wick was launched via the system tray (and is therefore allowed to mutate its own server/worker state).
Package processctl owns the in-process lifecycle of the HTTP server and background worker: Start/Stop/IsRunning + a per-process IsManaged flag that says whether wick was launched via the system tray (and is therefore allowed to mutate its own server/worker state).
sso
Package sso manages SSO provider credentials (currently Google OAuth).
Package sso manages SSO provider credentials (currently Google OAuth).
systemtray
Package systemtray runs the OS system tray UI for a wick-powered app: start/stop the local HTTP server and the background job worker (both in-process via cancellable goroutines), and install or uninstall the app's MCP entry into detected MCP clients (Claude Desktop, Cursor, etc).
Package systemtray runs the OS system tray UI for a wick-powered app: start/stop the local HTTP server and the background job worker (both in-process via cancellable goroutines), and install or uninstall the app's MCP entry into detected MCP clients (Claude Desktop, Cursor, etc).
tools
Package tools is the central registry for every tool instance wick will mount.
Package tools is the central registry for every tool instance wick will mount.
tools/agents
Package agents backs /tools/agents — the Agents UI Manager.
Package agents backs /tools/agents — the Agents UI Manager.
tools/agents/view
templ: version: v0.3.1020
templ: version: v0.3.1020
tools/convert-text
Package converttext is a stateless text-conversion tool.
Package converttext is a stateless text-conversion tool.
tools/encfields
Package encfields backs /tools/encfields — the in-app form for minting and reversing wick_enc_ tokens.
Package encfields backs /tools/encfields — the in-app form for minting and reversing wick_enc_ tokens.
tools/external
Package external wraps third-party links as tool.Module entries so they show up on the home grid and palette alongside in-app tools.
Package external wraps third-party links as tool.Module entries so they show up on the home grid and palette alongside in-app tools.
tools/provider-storage
Package providerstorage mounts a Provider Storage Manager UI under /tools/provider-storage.
Package providerstorage mounts a Provider Storage Manager UI under /tools/provider-storage.
tools/webtty
Package webtty mounts a browser-based terminal under /tools/webtty.
Package webtty mounts a browser-based terminal under /tools/webtty.
tty
updater
Package updater downloads, verifies, and applies new release binaries from GitHub.
Package updater downloads, verifies, and applies new release binaries from GitHub.
userconfig
Package userconfig persists per-machine user preferences for the system tray (auto-start toggles, default project, self-update state) in a single JSON file under a hidden app directory in the user's home.
Package userconfig persists per-machine user preferences for the system tray (auto-start toggles, default project, self-update state) in a single JSON file under a hidden app directory in the user's home.
pkg
connector
Package connector defines the public contract every connector module must satisfy.
Package connector defines the public contract every connector module must satisfy.
conntest
Package conntest provides lightweight test helpers for writing connector unit tests.
Package conntest provides lightweight test helpers for writing connector unit tests.
entity
Package entity exposes shared entity types used in the public wick contract (tool/job registration).
Package entity exposes shared entity types used in the public wick contract (tool/job registration).
job
Package job defines the public contract every background job module must implement.
Package job defines the public contract every background job module must implement.
tool
Package tool defines the public contract every tool module must satisfy.
Package tool defines the public contract every tool module must satisfy.
connectors/crudcrud
Package crudcrud is the example connector shipped with the template.
Package crudcrud is the example connector shipped with the template.
jobs/auto-get-data
Package autogetdata is a template job that fetches a remote endpoint on a schedule.
Package autogetdata is a template job that fetches a remote endpoint on a schedule.
tools/convert-text
Package converttext is a stateless text-conversion tool.
Package converttext is a stateless text-conversion tool.
tools/external
Package external wraps third-party links as tool.Module entries so they show up on the home grid and palette alongside in-app tools.
Package external wraps third-party links as tool.Module entries so they show up on the home grid and palette alongside in-app tools.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL