Class: OKF::Skill

Inherits:
Object
  • Object
show all
Defined in:
lib/okf/skill.rb

Overview

Installs this gem's companion agent skill — the SKILL.md + reference/ + templates/ that teach an agent to author, maintain, and consume OKF bundles and to drive the okf executable — into a destination directory.

The skill ships inside the gem (under lib/okf/skill), so gem install okf provides both the CLI and the skill that uses it, and the two can never drift apart in version: the skill's own reference/cli.md always matches the CLI it was released with.

Defined Under Namespace

Classes: Error

Constant Summary collapse

ASSETS =

The canonical skill tree, bundled in the sibling skill/ directory.

File.expand_path("skill", __dir__)
NAME =

An agent discovers a skill as //SKILL.md, so by default (nest: true) the tree lands in a skills/okf/ folder under the destination:

okf skill .claude         -> .claude/skills/okf   (adds skills/ then okf/)
okf skill .agents/skills  -> .agents/skills/okf   (already a skills dir)
okf skill .../skills/okf  -> .../skills/okf        (already the skill dir)

Point it at a project or skills directory and the skill settles in its own folder instead of splattering its files loose among the others. Pass nest: false (--here) to install straight into the destination, wherever it is.

"okf"
SKILLS_DIR =
"skills"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dest, force: false, nest: true) ⇒ Skill

Returns a new instance of Skill.



39
40
41
42
43
# File 'lib/okf/skill.rb', line 39

def initialize(dest, force: false, nest: true)
  @dest = nest ? resolve(dest.to_s) : dest.to_s
  @path = File.expand_path(@dest)
  @force = force
end

Instance Attribute Details

#destObject (readonly)

Returns the value of attribute dest.



37
38
39
# File 'lib/okf/skill.rb', line 37

def dest
  @dest
end

Class Method Details

.install(dest, force: false, nest: true) ⇒ Object



33
34
35
# File 'lib/okf/skill.rb', line 33

def self.install(dest, force: false, nest: true)
  new(dest, force: force, nest: nest).install
end

Instance Method Details

#filesObject

Relative paths of every file in the bundled skill, sorted for stable output.



62
63
64
65
66
67
# File 'lib/okf/skill.rb', line 62

def files
  Dir.glob(File.join(ASSETS, "**", "*"))
     .select { |path| File.file?(path) }
     .map { |path| path[(ASSETS.length + 1)..-1] }
     .sort
end

#installObject

Copy the skill tree into dest, creating it if needed. Refuses to write over a non-empty directory unless forced, so an existing (possibly customized) skill is never silently clobbered. Returns the relative paths written.



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/okf/skill.rb', line 48

def install
  if File.exist?(@path) && !File.directory?(@path)
    raise Error, "destination #{@dest} exists and is not a directory"
  end
  if File.directory?(@path) && !Dir.empty?(@path) && !@force
    raise Error, "destination #{@dest} is not empty (pass --force to overwrite)"
  end

  FileUtils.mkdir_p(@path)
  FileUtils.cp_r(File.join(ASSETS, "."), @path)
  files
end