Liking cljdoc? Tell your friends :D

toolnexus.skill


apply-skills-filterclj/s

(apply-skills-filter by-name filter-map)

SPEC §3 S2 — the per-agent allowlist, semantics IDENTICAL to the MCP per-server tools filter: nil or empty ⇒ every skill; at least one true ⇒ an allowlist of exactly the true-mapped names; only false values ⇒ a drop-list over the all-on baseline. Unknown names are ignored.

Returns [filtered-by-name unmatched-names]. The unmatched list is RETURNED rather than only logged so the requirement is testable without capturing stdout — the warn line is emitted from load-skills.

SPEC §3 S2 — the per-agent allowlist, semantics IDENTICAL to the MCP
per-server tools filter: nil or empty ⇒ every skill; at least one `true` ⇒ an
allowlist of exactly the true-mapped names; only `false` values ⇒ a drop-list
over the all-on baseline. Unknown names are ignored.

Returns `[filtered-by-name unmatched-names]`. The unmatched list is RETURNED
rather than only logged so the requirement is testable without capturing
stdout — the warn line is emitted from `load-skills`.
sourceraw docstring

candidatesclj/s

(candidates root)

Every SKILL.md under root, in DISCOVERY ORDER, as a parsed skill or a typed skip.

Discovery order is whatever koine.fs/find-files returns, and find-files SORTS (koine/fs.cljc: "Every file under root whose path ends with suffix, SORTED"). Every port's first-name-wins rule is order-dependent, so that sort is the only reason two hosts cannot disagree about which duplicate survives. We rely on it and deliberately do not re-sort.

Note find-files takes a SUFFIX, not a glob, so the suffix is "/SKILL.md" — a bare "SKILL.md" would also match a file named MYSKILL.md.

Every SKILL.md under `root`, in DISCOVERY ORDER, as a parsed skill or a typed
skip.

Discovery order is whatever `koine.fs/find-files` returns, and find-files
SORTS (koine/fs.cljc: "Every file under `root` whose path ends with `suffix`,
SORTED"). Every port's first-name-wins rule is order-dependent, so that sort
is the only reason two hosts cannot disagree about which duplicate survives.
We rely on it and deliberately do not re-sort.

Note find-files takes a SUFFIX, not a glob, so the suffix is "/SKILL.md" —
a bare "SKILL.md" would also match a file named MYSKILL.md.
sourceraw docstring

default-sample-limitclj/s

source

execute-skillclj/s

(execute-skill loaded skill-name)
(execute-skill loaded skill-name limit)

The skill tool's execute, as a plain fn over a loaded map.

An unknown name is NOT a throw — SPEC §3 step 1 makes it ToolResult{isError:true}, so the model sees it and can retry.

DIVERGENCE, following the ports: SPEC §3 prose says "Available: ", while golang/skill.go, js, python, java, csharp and elixir all emit "Available skills: " (and the literal none when there are no skills). We match the ports. SPEC §3 should be corrected.

The `skill` tool's execute, as a plain fn over a loaded map.

An unknown name is NOT a throw — SPEC §3 step 1 makes it
`ToolResult{isError:true}`, so the model sees it and can retry.

DIVERGENCE, following the ports: SPEC §3 prose says `"Available: "`, while
golang/skill.go, js, python, java, csharp and elixir all emit
`"Available skills: "` (and the literal `none` when there are no skills).
We match the ports. SPEC §3 should be corrected.
sourceraw docstring

file-nameclj/s

(file-name path)

The last segment of path. NOT named base-name/basename — nothing in clojure.core collides, but the name is kept explicit for readability.

The last segment of `path`. NOT named `base-name`/`basename` — nothing in
clojure.core collides, but the name is kept explicit for readability.
sourceraw docstring

list-skillsclj/s

(list-skills input)

SPEC §3 S3 — list/validate inventory: {:skills … :skipped …}, no toolkit wired, nothing left open.

DELIBERATELY UNFILTERED, following js/src/skill.ts listSkills, which ignores opts.filter entirely: the inventory is what you AUTHOR an allowlist from, so filtering it would be circular.

SPEC §3 S3 — list/validate inventory: `{:skills … :skipped …}`, no toolkit
wired, nothing left open.

DELIBERATELY UNFILTERED, following js/src/skill.ts `listSkills`, which ignores
`opts.filter` entirely: the inventory is what you AUTHOR an allowlist from, so
filtering it would be circular.
sourceraw docstring

load-optsclj/s

(load-opts input)

load-skills accepts every shape js/src/skill.ts' loadSkills accepts, plus the two data shapes: a root string, a seq of roots, a seq of skill defs, one skill def, or the full options map.

`load-skills` accepts every shape js/src/skill.ts' `loadSkills` accepts, plus
the two data shapes: a root string, a seq of roots, a seq of skill defs, one
skill def, or the full options map.
sourceraw docstring

load-skillsclj/s

(load-skills input)

Discover skills from every source §3 offers and shape them into one loaded map.

input is a root string, a seq of roots, a seq of skill DEFS, or an options map {:dirs … :skills … :filter … :sample-limit …} — the same union js/src/skill.ts' loadSkills takes. Directory roots are collected first, in the order given, then the data defs, so the existing first-name-wins rule resolves collisions ACROSS sources without needing a second rule.

Returns {:skills [info…] :by-name {} :skipped [] :filter-unmatched [] :sample-limit n}. A caller passing only roots gets byte-identical behaviour to before this option existed.

Discover skills from every source §3 offers and shape them into one loaded
map.

`input` is a root string, a seq of roots, a seq of skill DEFS, or an options
map `{:dirs … :skills … :filter … :sample-limit …}` — the same union
js/src/skill.ts' `loadSkills` takes. Directory roots are collected first, in
the order given, then the data defs, so the existing first-name-wins rule
resolves collisions ACROSS sources without needing a second rule.

Returns `{:skills [info…] :by-name {} :skipped [] :filter-unmatched []
:sample-limit n}`. A caller passing only roots gets byte-identical behaviour
to before this option existed.
sourceraw docstring

merge-candidatesclj/s

(merge-candidates cands)

Dedupe by name, FIRST WINS; later duplicates become typed skips. Returns {:skills [info …] :by-name {name info} :skipped [skip …]}.

Dedupe by name, FIRST WINS; later duplicates become typed skips.
Returns `{:skills [info …] :by-name {name info} :skipped [skip …]}`.
sourceraw docstring

no-skills-messageclj/s

source

parent-dirclj/s

(parent-dir path)

The directory part of path, or "." when there is no separator.

The directory part of `path`, or "." when there is no separator.
sourceraw docstring

sample-sibling-filesclj/s

(sample-sibling-files dir limit)

Up to limit files under the skill's directory, EXCLUDING every SKILL.md.

The exclusion is the detail that moves bytes and that spike s15 got wrong: golang/skill.go:217 and js/src/skill.ts:198 both guard the sampler with entry.Name() != "SKILL.md". Leaving SKILL.md in adds one <file> line and the shared hello-world output stops matching the other ports.

limit: 0 ⇒ default 10 · n>0 ⇒ cap at n · -1 ⇒ nil, i.e. sampling disabled (SPEC §3 S5).

ORDER — deliberate divergence. SPEC §3 does not pin the sample's order, and no shipped port sorts: js/go/python all walk a DFS stack over raw readdir order and slice the first limit entries. Go's os.ReadDir sorts, Python's os.scandir does not, so with >1 sibling the shipped ports are not guaranteed to agree with each other. WE SORT, because a port whose whole claim is byte-identical output on two hosts cannot depend on readdir order. Pending a SPEC fix that pins the sampler's order for everyone; recorded here rather than smuggled in.

Up to `limit` files under the skill's directory, EXCLUDING every SKILL.md.

The exclusion is the detail that moves bytes and that spike s15 got wrong:
`golang/skill.go:217` and `js/src/skill.ts:198` both guard the sampler with
`entry.Name() != "SKILL.md"`. Leaving SKILL.md in adds one `<file>` line and
the shared hello-world output stops matching the other ports.

`limit`: 0 ⇒ default 10 · n>0 ⇒ cap at n · -1 ⇒ nil, i.e. sampling disabled
(SPEC §3 S5).

ORDER — deliberate divergence. SPEC §3 does not pin the sample's order, and no
shipped port sorts: js/go/python all walk a DFS stack over raw readdir order
and slice the first `limit` entries. Go's os.ReadDir sorts, Python's
os.scandir does not, so with >1 sibling the shipped ports are not guaranteed
to agree with each other. WE SORT, because a port whose whole claim is
byte-identical output on two hosts cannot depend on readdir order. Pending a
SPEC fix that pins the sampler's order for everyone; recorded here rather than
smuggled in.
sourceraw docstring

skill-filesclj/s

(skill-files info limit)

The <skill_files> list for one skill, or nil when there is no block.

Two sources, one rule, following js/src/skill.ts' execute:

  • an on-disk skill samples its siblings and ALWAYS emits the block (even empty) unless sampling is off — that is the shipped byte-exact behaviour;
  • a data/provider skill lists its SUPPLIED logical resources, in the order supplied, and omits the block entirely when it has none (an instruction-only skill has nothing to disclose).
The `<skill_files>` list for one skill, or nil when there is no block.

Two sources, one rule, following js/src/skill.ts' execute:
  * an on-disk skill samples its siblings and ALWAYS emits the block (even
    empty) unless sampling is off — that is the shipped byte-exact behaviour;
  * a data/provider skill lists its SUPPLIED logical resources, in the order
    supplied, and omits the block entirely when it has none (an
    instruction-only skill has nothing to disclose).
sourceraw docstring

skill-outputclj/s

(skill-output skill files)

SPEC §0.6. Built by explicit concatenation, never a template: every newline here is part of the contract, and there is no trailing newline (the ports join lines). files = nil disables sampling (S5 -1): the <skill_files> block AND its "Note: file list is sampled." line are both omitted.

SPEC §0.6. Built by explicit concatenation, never a template: every newline
here is part of the contract, and there is no trailing newline (the ports join
lines). `files` = nil disables sampling (S5 `-1`): the `<skill_files>` block
AND its "Note: file list is sampled." line are both omitted.
sourceraw docstring

skill-toolclj/s

(skill-tool loaded)
(skill-tool loaded {:keys [sample-limit]})

The single skill tool (SPEC §3), shipped by default alongside the skills.

The single `skill` tool (SPEC §3), shipped by default alongside the skills.
sourceraw docstring

skill-tool-descriptionclj/s

SPEC §3 skill.txt — verbatim from opencode.

SPEC §3 skill.txt — verbatim from opencode.
sourceraw docstring

skill-tool-input-schemaclj/s

source

skills-promptclj/s

(skills-prompt loaded)

preamble + "\n\n" + "## Available Skills" + one line per DESCRIBED skill, sorted by name. No described skill at all ⇒ the no-skills message, with NO preamble (SPEC §3).

preamble + "\n\n" + "## Available Skills" + one line per DESCRIBED skill,
sorted by name. No described skill at all ⇒ the no-skills message, with NO
preamble (SPEC §3).
sourceraw docstring

skills-prompt-preambleclj/s

SPEC §3 — the fixed instruction preamble, copied verbatim from golang/skill.go's SkillsPromptPreamble. Do not reword.

SPEC §3 — the fixed instruction preamble, copied verbatim from
`golang/skill.go`'s `SkillsPromptPreamble`. Do not reword.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close