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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33c38b43c188b222f3e5c7f7fb31faa40dfdafb915cd7701c30e0d99a061536f
4
- data.tar.gz: 39fc5c7f891d0afe34369e45c6dfaef0b7f6a2529424e8e77a9074dc37d5e913
3
+ metadata.gz: 3ef69aafbfe0af98bf7e56fe9dfc0a8c320095a44bea1d682a5c582f9b6569f6
4
+ data.tar.gz: 9a3ac05697910d91beeb66f7abd463ad2b51c2e9355d5ddc6a60a8687a66472d
5
5
  SHA512:
6
- metadata.gz: dcdeb08358531f7454c9c5cafc36d8dcb70a03fd08d0eb67193dafaed17bc369331a761111280ce90df0b2ec524b00b2222805bdd0cd0d2a7ba8af519500819c
7
- data.tar.gz: 4369820425e0509a48af6b7e1c9c5f6a8aaf834da91e8be382cb70d5fc35ec602fb70cbc955c5999ad5b3587c42c48d9dc6f42b77dde611c970a04a78857d9d2
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 dispatch chain-implement open close
18
+ harnex skills install
19
19
  ```
20
20
 
21
- This adds orchestration skills (fire-and-watch, chain-implement, session
22
- lifecycle) that Claude Code and Codex pick up automatically.
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 dispatch chain-implement
103
+ harnex skills install
104
104
  ```
105
105
 
106
106
  ## All commands
data/lib/harnex/cli.rb CHANGED
@@ -108,7 +108,7 @@ module Harnex
108
108
  harnex logs --id main --follow
109
109
  harnex pane --id main --lines 40
110
110
  harnex send --id main --message "Summarize current progress."
111
- harnex skills install close
111
+ harnex skills install
112
112
  TEXT
113
113
  end
114
114
  end
@@ -3,36 +3,28 @@ require "fileutils"
3
3
  module Harnex
4
4
  class Skills
5
5
  SKILLS_ROOT = File.expand_path("../../../../skills", __FILE__)
6
- DEFAULT_SKILL = "harnex"
6
+ INSTALL_SKILLS = %w[dispatch chain-implement].freeze
7
7
 
8
8
  def self.usage
9
9
  <<~TEXT
10
- Usage: harnex skills install [SKILL...] [--global]
10
+ Usage: harnex skills install [--local]
11
11
 
12
12
  Subcommands:
13
- install Install bundled skills into the current repo
13
+ install Install bundled skills (globally by default)
14
14
 
15
15
  Options:
16
- --global Install to ~/.claude/skills and ~/.codex/skills
17
- instead of the current repo
16
+ --local Install to the current repo instead of globally
18
17
 
19
- Available skills: #{bundled_skill_names.join(', ')}
18
+ Installs: #{INSTALL_SKILLS.join(', ')}
20
19
 
21
- With no SKILL argument, installs #{DEFAULT_SKILL.inspect}.
22
- Pass one or more skill names to install specific skills.
20
+ By default, copies each skill to ~/.claude/skills/<skill>/
21
+ and symlinks ~/.codex/skills/<skill> to it.
23
22
 
24
- Without --global, copies the skill to .claude/skills/<skill>/
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, global, help = parse_install_args(@argv)
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 = global ? install_global(skill_name, skill_source) : install_local(skill_name, skill_source)
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
- skill_names = []
74
- global = false
65
+ local = false
75
66
  help = false
76
67
 
77
68
  args.each do |arg|
78
69
  case arg
79
- when "--global"
80
- global = true
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
- skill_names << arg
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
- skill_names = [DEFAULT_SKILL] if skill_names.empty?
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
- return nil unless self.class.bundled_skill_names.include?(skill_name)
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: unknown skill #{skill_name.inspect}")
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
- [claude_dir, codex_dir].each do |dir|
140
- parent = File.dirname(dir)
141
- FileUtils.mkdir_p(parent)
142
- FileUtils.rm_rf(dir) if File.exist?(dir) || File.symlink?(dir)
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
@@ -1,3 +1,3 @@
1
1
  module Harnex
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.3"
3
3
  end
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.1
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: []