harnex 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/lib/harnex/cli.rb +1 -1
- data/lib/harnex/commands/skills.rb +33 -38
- data/lib/harnex/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3ef69aafbfe0af98bf7e56fe9dfc0a8c320095a44bea1d682a5c582f9b6569f6
|
|
4
|
+
data.tar.gz: 9a3ac05697910d91beeb66f7abd463ad2b51c2e9355d5ddc6a60a8687a66472d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 00315bc8e09e631799a76ce8a3569f8ff4ed512cd62cae5b9cf8ac9092c173f5636893ffe2cfd8ee0ed06305509dba240d0272489d1949c3b7f141268f8f0043
|
|
7
|
+
data.tar.gz: 0e3425f79503c76e7d0e09edad5782efc784806cdc93cc096071be851782e27f73bf8a0ca7704330f9d45f86a0cc9684262da230650078152e556e4017888d93
|
data/README.md
CHANGED
|
@@ -15,11 +15,11 @@ Requires **Ruby 3.x**. No other dependencies.
|
|
|
15
15
|
Then install workflow skills into your repo so agents can use them:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
harnex skills install
|
|
18
|
+
harnex skills install
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
This adds orchestration skills (
|
|
22
|
-
|
|
21
|
+
This adds orchestration skills (dispatch, chain-implement) that Claude
|
|
22
|
+
Code and Codex pick up automatically.
|
|
23
23
|
|
|
24
24
|
## What it does
|
|
25
25
|
|
|
@@ -100,7 +100,7 @@ Harnex ships workflow skills that automate this pattern:
|
|
|
100
100
|
Install skills into your repo so agents can use them:
|
|
101
101
|
|
|
102
102
|
```bash
|
|
103
|
-
harnex skills install
|
|
103
|
+
harnex skills install
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
## All commands
|
data/lib/harnex/cli.rb
CHANGED
|
@@ -3,36 +3,28 @@ require "fileutils"
|
|
|
3
3
|
module Harnex
|
|
4
4
|
class Skills
|
|
5
5
|
SKILLS_ROOT = File.expand_path("../../../../skills", __FILE__)
|
|
6
|
-
|
|
6
|
+
INSTALL_SKILLS = %w[dispatch chain-implement].freeze
|
|
7
7
|
|
|
8
8
|
def self.usage
|
|
9
9
|
<<~TEXT
|
|
10
|
-
Usage: harnex skills install [
|
|
10
|
+
Usage: harnex skills install [--local]
|
|
11
11
|
|
|
12
12
|
Subcommands:
|
|
13
|
-
install Install bundled skills
|
|
13
|
+
install Install bundled skills (globally by default)
|
|
14
14
|
|
|
15
15
|
Options:
|
|
16
|
-
--
|
|
17
|
-
instead of the current repo
|
|
16
|
+
--local Install to the current repo instead of globally
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
Installs: #{INSTALL_SKILLS.join(', ')}
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
By default, copies each skill to ~/.claude/skills/<skill>/
|
|
21
|
+
and symlinks ~/.codex/skills/<skill> to it.
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
With --local, copies each skill to .claude/skills/<skill>/
|
|
25
24
|
in the current repo and symlinks .codex/skills/<skill> to it.
|
|
26
|
-
|
|
27
|
-
With --global, symlinks both ~/.claude/skills/<skill> and
|
|
28
|
-
~/.codex/skills/<skill> to the bundled source.
|
|
29
25
|
TEXT
|
|
30
26
|
end
|
|
31
27
|
|
|
32
|
-
def self.bundled_skill_names
|
|
33
|
-
Dir.children(SKILLS_ROOT).select { |name| File.directory?(File.join(SKILLS_ROOT, name)) }.sort
|
|
34
|
-
end
|
|
35
|
-
|
|
36
28
|
def initialize(argv)
|
|
37
29
|
@argv = argv.dup
|
|
38
30
|
end
|
|
@@ -41,7 +33,7 @@ module Harnex
|
|
|
41
33
|
subcommand = @argv.shift
|
|
42
34
|
case subcommand
|
|
43
35
|
when "install"
|
|
44
|
-
skill_names,
|
|
36
|
+
skill_names, local, help = parse_install_args(@argv)
|
|
45
37
|
if help
|
|
46
38
|
puts self.class.usage
|
|
47
39
|
return 0
|
|
@@ -53,7 +45,7 @@ module Harnex
|
|
|
53
45
|
return missing_skill(skill_name)
|
|
54
46
|
end
|
|
55
47
|
|
|
56
|
-
result =
|
|
48
|
+
result = local ? install_local(skill_name, skill_source) : install_global(skill_name, skill_source)
|
|
57
49
|
return result unless result == 0
|
|
58
50
|
end
|
|
59
51
|
0
|
|
@@ -70,38 +62,33 @@ module Harnex
|
|
|
70
62
|
private
|
|
71
63
|
|
|
72
64
|
def parse_install_args(args)
|
|
73
|
-
|
|
74
|
-
global = false
|
|
65
|
+
local = false
|
|
75
66
|
help = false
|
|
76
67
|
|
|
77
68
|
args.each do |arg|
|
|
78
69
|
case arg
|
|
79
|
-
when "--
|
|
80
|
-
|
|
70
|
+
when "--local"
|
|
71
|
+
local = true
|
|
81
72
|
when "-h", "--help"
|
|
82
73
|
help = true
|
|
83
74
|
when /\A-/
|
|
84
75
|
raise "harnex skills: unknown option #{arg.inspect}"
|
|
85
76
|
else
|
|
86
|
-
|
|
77
|
+
warn("harnex skills install: unexpected argument #{arg.inspect}")
|
|
78
|
+
raise "harnex skills install takes no positional arguments"
|
|
87
79
|
end
|
|
88
80
|
end
|
|
89
81
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
[skill_names, global, help]
|
|
82
|
+
[INSTALL_SKILLS, local, help]
|
|
93
83
|
end
|
|
94
84
|
|
|
95
85
|
def resolve_skill_source(skill_name)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
File.join(SKILLS_ROOT, skill_name)
|
|
86
|
+
path = File.join(SKILLS_ROOT, skill_name)
|
|
87
|
+
File.directory?(path) ? path : nil
|
|
99
88
|
end
|
|
100
89
|
|
|
101
90
|
def missing_skill(skill_name)
|
|
102
|
-
warn("harnex skills:
|
|
103
|
-
available = self.class.bundled_skill_names
|
|
104
|
-
warn("available skills: #{available.join(', ')}") unless available.empty?
|
|
91
|
+
warn("harnex skills: bundled skill #{skill_name.inspect} not found at #{SKILLS_ROOT}")
|
|
105
92
|
1
|
|
106
93
|
end
|
|
107
94
|
|
|
@@ -136,13 +123,21 @@ module Harnex
|
|
|
136
123
|
claude_dir = File.expand_path("~/.claude/skills/#{skill_name}")
|
|
137
124
|
codex_dir = File.expand_path("~/.codex/skills/#{skill_name}")
|
|
138
125
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
FileUtils.rm_rf(
|
|
143
|
-
File.symlink(skill_source, dir)
|
|
144
|
-
puts "symlinked #{dir} -> #{skill_source}"
|
|
126
|
+
# Copy skill to ~/.claude/skills/<skill>/
|
|
127
|
+
if Dir.exist?(claude_dir)
|
|
128
|
+
warn("harnex skills: #{claude_dir} already exists, overwriting")
|
|
129
|
+
FileUtils.rm_rf(claude_dir)
|
|
145
130
|
end
|
|
131
|
+
FileUtils.mkdir_p(File.dirname(claude_dir))
|
|
132
|
+
FileUtils.cp_r(skill_source, claude_dir)
|
|
133
|
+
puts "installed #{claude_dir}"
|
|
134
|
+
|
|
135
|
+
# Symlink ~/.codex/skills/<skill> -> ~/.claude/skills/<skill>
|
|
136
|
+
codex_parent = File.dirname(codex_dir)
|
|
137
|
+
FileUtils.mkdir_p(codex_parent)
|
|
138
|
+
FileUtils.rm_rf(codex_dir) if File.exist?(codex_dir) || File.symlink?(codex_dir)
|
|
139
|
+
File.symlink(claude_dir, codex_dir)
|
|
140
|
+
puts "symlinked #{codex_dir} -> #{claude_dir}"
|
|
146
141
|
|
|
147
142
|
0
|
|
148
143
|
end
|
data/lib/harnex/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: harnex
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jikku Jose
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 2026-03-31 00:00:00.000000000 Z
|
|
@@ -66,7 +66,7 @@ metadata:
|
|
|
66
66
|
homepage_uri: https://github.com/jikkuatwork/harnex
|
|
67
67
|
source_code_uri: https://github.com/jikkuatwork/harnex
|
|
68
68
|
bug_tracker_uri: https://github.com/jikkuatwork/harnex/issues
|
|
69
|
-
post_install_message:
|
|
69
|
+
post_install_message:
|
|
70
70
|
rdoc_options: []
|
|
71
71
|
require_paths:
|
|
72
72
|
- lib
|
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
82
82
|
version: '0'
|
|
83
83
|
requirements: []
|
|
84
84
|
rubygems_version: 3.5.3
|
|
85
|
-
signing_key:
|
|
85
|
+
signing_key:
|
|
86
86
|
specification_version: 4
|
|
87
87
|
summary: PTY harness for terminal AI agents
|
|
88
88
|
test_files: []
|