Skip to content

plugin-harness-kind

Placement compiled-in (in-process)
Source github.com/opencharly/plugin-harness-kind/candy/plugin-harness-kind
Version 2026.218.1200
Candy plugin-harness-kind

This plugin is listed in charly/charly.yml’s compiled_plugins:, so its providers are compiled into the charly binary and register in-process.

The reserved words this plugin serves:

  • hook — kind class
  • marketplace — kind class
  • skill — kind class

The skill / hook / marketplace HARNESS-SURFACE kinds — the plugins→candies migration’s first-class entities. A skill: node is a sibling top-level entity in a candy’s charly.yml carrying the FULL inline skill definition (metadata + markdown content); a hook: node carries a .claude/hooks/* gate script; a marketplace: node carries the single harness/marketplace config (families + settings). All three are FLAT kinds (Structural:false — no deploy members): their self-contained values ride op.Params, are validated at load against this plugin’s served #SkillInput/#HookInput/ #MarketplaceInput schemas (validateAuthoredPluginInput), and fold into uf.PluginKinds[“skill”|“hook”|“marketplace”][name] as opaque JSON.

COMPILED-IN (in the embedded compiled_plugins:) — the plugin-candy-kind placement, because the words must be recognized on every parse (validate/build/deploy) without an out-of-process build. The skill bodies feed BOTH the ai.opencharly.skills OCI label (CollectSkills → charly box labels) and the regenerated marketplace corpus (candy/plugin-marketplace, command:marketplace); hook bodies feed the .claude/hooks/* emission + settings.json wiring; the marketplace body feeds the plugin.json / marketplace.json / profiles.json / settings.json generated surface.

The CUE schema below is the authoritative grammar for this plugin’s input. It is the same single source that generates the plugin’s Go parameter types and answers the runtime Describe RPC, so this page cannot disagree with either.

// schema/hook.cue — the SELF-CONTAINED CUE schema validating the `hook` KIND's authored VALUE
// (the harness gate scripts). Self-contained per the group/agent reproduction contract — the
// same authored wire keys as the core #Hook (spec/schema/hook.cue, the single source that
// generates spec.Hook); the host validates against #HookInput at load and this plugin's Invoke
// canonicalises through spec.Hook. trigger/matcher absent ⇒ an AUX file (gitcmd.py, gate_test.py)
// emitted to .claude/hooks/ but not wired into settings.json.
#HookInput: close({
name: string & =~"^[a-z][a-z0-9._-]*$" // file stem incl. extension (.sh/.py)
content: string & !="" // inline script (block scalar)
trigger?: string & !="" // "PreToolUse" … (settings.json hooks.<trigger>)
matcher?: string & !="" // "Bash" … (required iff trigger present)
when?: string & !="" // optional settings.json when clause
mode?: *"0755" | "0644" // emitted file mode (chmod +x for .sh by default)
})
// schema/marketplace.cue — the SELF-CONTAINED CUE schema validating the `marketplace` KIND's
// authored VALUE (the single harness/marketplace config entity per repo). Self-contained per the
// group/agent reproduction contract — the same authored wire keys as the core #Marketplace
// (spec/schema/marketplace.cue, the single source that generates spec.Marketplace); the host
// validates against #MarketplaceInput at load and this plugin's Invoke canonicalises through
// spec.Marketplace.
#MarketplaceInput: close({
name: string & =~"^[a-z][a-z0-9-]*$" // "charly-plugins" (the marketplace name)
version: string & =~"^[0-9]+[.][0-9]+[.][0-9]+$" // marketplace.json metadata.version
description?: string & !="" // marketplace.json metadata.description
families: {[string]: #MarketplaceFamilyInput} // family name → its metadata (plugins/ dir = family)
settings?: #MarketplaceSettingsInput // the harness wiring data
})
#MarketplaceFamilyInput: close({
category?: *"images" | "commands" | "kind" | "development" // the README four-bucket classification
description?: string & !="" // plugin.json + marketplace.json description
keywords?: [...(string & !="")] // marketplace.json keywords
version?: string & =~"^[0-9]+[.][0-9]+[.][0-9]+$" // plugin.json version (default: family candy CalVer)
profiles?: [...("developer" | "user" | "container")] // profiles.json membership
mcp_servers?: [...#MarketplaceMCPServerInput] // plugins/<family>/.mcp.json entries
})
#MarketplaceMCPServerInput: close({
name: string & !=""
type?: *"http" | "stdio"
url?: string & !="" // http type (e.g. http://localhost:8888/mcp)
command?: string & !="" // stdio type (e.g. github-mcp-server)
args?: [...(string & !="")]
})
#MarketplaceSettingsInput: close({
enabled_plugins?: [...(string & !="")] // .claude/settings.json enabledPlugins (charly-*)
source_path?: *"./plugins" | string & !="" // extraKnownMarketplaces.<name>.source.path
hooks?: [...string] // hook entity names to wire into settings.json
})
// schema/skill.cue — the SELF-CONTAINED CUE schema validating the `skill` KIND's authored VALUE.
// Ships over Describe (schema_cue); references NO base def so it compiles standalone
// (BuildCapabilities compiles it alone, failing loudly if broken) AND splices onto the base
// (the base ++ plugin splice detects a def-name collision, not resolves base refs).
//
// It is a FAITHFUL reproduction of the core #Skill (spec/schema/skill.cue — the single source
// that generates spec.Skill via gengotypes), following the group/agent/… externalized-kind
// pattern: the SAME authored WIRE keys, so the host validates a real skill entity against
// #SkillInput (validateAuthoredPluginInput, the load gate) and this plugin's Invoke canonicalises
// the body back through the core spec.Skill type.
#SkillInput: close({
name: string & =~"^[a-z][a-z0-9-]*$" // marketplace-globally-unique skill id (SKILL.md folder name)
family: string & =~"^[a-z][a-z0-9-]*$" // marketplace family → plugins/<family>/
owner: string & =~"^[a-z][a-z0-9-]*$" // owning candy/concept-candy entity name
description: string & !="" // SKILL.md frontmatter description (Skill-tool dispatch keyword)
content: string & !="" // SKILL.md markdown body
type?: *"skill" | "agent" // "agent" ⇒ a sub-agent definition
model?: string & !="" // agent type: frontmatter model
tools?: [...(string & !="")] // agent type: allowed tool set
references?: [...#SkillReferenceInput] // SKILL.md references/<stem>.md split files
triggers?: [...(string & !="")] // R0-dispatcher trigger phrases
category?: *"development" | "commands" | "kind" | "images"
})
#SkillReferenceInput: close({
name: string & =~"^[a-z0-9][a-z0-9-]*$" // file stem (references/<name>.md)
content: string & !=""
})

See also the candy reference for this candy’s install surface.