bundler-skills 0.5.0 → 0.6.0
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/CHANGELOG.md +17 -1
- data/PROPOSAL.md +24 -16
- data/README.md +78 -41
- data/lib/bundler_skills/cli.rb +2 -3
- data/lib/bundler_skills/config.rb +2 -2
- data/lib/bundler_skills/synchronizer.rb +9 -39
- data/lib/bundler_skills/version.rb +1 -1
- data/lib/bundler_skills.rb +0 -1
- metadata +4 -8
- data/lib/bundler_skills/disabling.rb +0 -28
- data/lib/bundler_skills/rubygems_hook.rb +0 -51
- data/lib/rubygems_plugin.rb +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 30d4136893f0cc4bdead5248b1ee7d4df3768b536d67bf3cd243c1e91da454a2
|
|
4
|
+
data.tar.gz: 6e4739d9bc290347d3af00377e3bfee89ea6e293560b23019ee855feb781907c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 70fe208a60b6b8f1168a4b8d554ed82ae659c87a3b38763d80c81b54e94f7821b45a640339ad421f84f2c17266cc673d4a769b3e29516f10c2308c0182f1102c
|
|
7
|
+
data.tar.gz: c16486c4b5ffd489a68f74ab7d2c4111c03790845bc08302ce925e58887fc3aa9d732250b1fd9146a521aedce4e2c99018ec6f6c867c8646713ff54d7d995a85
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [0.6.0] - 2026-07-03
|
|
4
|
+
|
|
5
|
+
### Changed (breaking)
|
|
6
|
+
|
|
7
|
+
- **Removed the RubyGems `post_install` hook entirely.** bundler-skills no
|
|
8
|
+
longer hooks into `bundle install`; skills are synced only when you run the
|
|
9
|
+
command (`bundle exec skills`). This removes the global side effect where the
|
|
10
|
+
hook was loaded and evaluated for every `bundle install` of every project
|
|
11
|
+
sharing the Ruby. Wire the command into a git hook (post-merge / post-checkout)
|
|
12
|
+
or a hook manager (husky / lefthook / overcommit) to run it automatically —
|
|
13
|
+
see the README.
|
|
14
|
+
|
|
15
|
+
### Removed
|
|
16
|
+
|
|
17
|
+
- `lib/rubygems_plugin.rb`, the `RubygemsHook` module, and the `Disabling`
|
|
18
|
+
module — including the `BUNDLER_SKILLS_DISABLED` environment variable (with no
|
|
19
|
+
hook there is nothing to disable).
|
|
4
20
|
|
|
5
21
|
## [0.5.0] - 2026-06-27
|
|
6
22
|
|
data/PROPOSAL.md
CHANGED
|
@@ -76,19 +76,27 @@ even for gems like `rails-html-sanitizer`.
|
|
|
76
76
|
linked too (the directory is symlinked as a whole), so reference relative
|
|
77
77
|
files normally.
|
|
78
78
|
|
|
79
|
-
## Why
|
|
80
|
-
|
|
81
|
-
bundler-skills
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
`Bundler::Plugin::Index::CommandConflict` — and it recurred on every
|
|
91
|
-
`bundle` run until `bundler plugin uninstall`. This is unavoidable
|
|
92
|
-
that registers a command.
|
|
93
|
-
|
|
94
|
-
|
|
79
|
+
## Why an explicit command (not a Bundler plugin or a `post_install` hook)
|
|
80
|
+
|
|
81
|
+
bundler-skills is a regular gem that ships a plain executable (`bundle exec
|
|
82
|
+
skills`). Syncing happens only when you run that command — it hooks into nothing.
|
|
83
|
+
|
|
84
|
+
Two earlier designs were tried and rejected:
|
|
85
|
+
|
|
86
|
+
- **A Bundler plugin** that registered a `bundle skills` command via
|
|
87
|
+
`Bundler::Plugin::API.command`. When `bundle update` bumped bundler-skills
|
|
88
|
+
itself, Bundler re-registered the `skills` command while the previous
|
|
89
|
+
registration was still in its plugin index, raising
|
|
90
|
+
`Bundler::Plugin::Index::CommandConflict` — and it recurred on every
|
|
91
|
+
subsequent `bundle` run until `bundler plugin uninstall`. This is unavoidable
|
|
92
|
+
for any plugin that registers a command.
|
|
93
|
+
- **A RubyGems `post_install` hook** (`lib/rubygems_plugin.rb` +
|
|
94
|
+
`Gem.post_install`). RubyGems auto-loads any `rubygems_plugin.rb` on the load
|
|
95
|
+
path, so once bundler-skills is installed anywhere in a Ruby, its hook is
|
|
96
|
+
loaded and evaluated for **every** `bundle install` of **every** project
|
|
97
|
+
sharing that Ruby — a global side effect that is hard to scope cleanly.
|
|
98
|
+
|
|
99
|
+
Providing only a command removes both problems: there is no command
|
|
100
|
+
registration to conflict, and nothing runs unless the user invokes it. Wire it
|
|
101
|
+
into a git hook or a hook manager to run it automatically — see
|
|
102
|
+
[README.md](README.md) for consumer details.
|
data/README.md
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
# bundler-skills
|
|
2
2
|
|
|
3
|
-
A gem that
|
|
4
|
-
|
|
3
|
+
A gem that symlinks **AI agent skills bundled in your gems** into your project.
|
|
4
|
+
The Ruby/Bundler counterpart of
|
|
5
5
|
[antfu/skills-npm](https://github.com/antfu/skills-npm).
|
|
6
6
|
|
|
7
|
-
Gems ship `skills/<name>/SKILL.md`;
|
|
8
|
-
directory so the skill version always matches the gem version
|
|
9
|
-
team gets them just by running `bundle install`.
|
|
7
|
+
Gems ship `skills/<name>/SKILL.md`; running `bundle exec skills` links them into
|
|
8
|
+
the right agent directory so the skill version always matches the gem version.
|
|
10
9
|
|
|
11
10
|
## How it works
|
|
12
11
|
|
|
13
|
-
bundler-skills ships a
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
bundler-skills is a regular gem that ships a `bundle exec skills` command.
|
|
13
|
+
**Nothing runs automatically** — there is no `bundle install` hook. Sync happens
|
|
14
|
+
only when you run the command (manually, or from a git hook you set up). Each run:
|
|
16
15
|
|
|
17
|
-
1. Scans **
|
|
16
|
+
1. Scans **all dependency gems** for `skills/*/SKILL.md`.
|
|
18
17
|
2. Detects which agents you use (by marker directories) and symlinks each skill
|
|
19
18
|
into the right place, named `gem-<gem>--<skill>`.
|
|
20
|
-
3. Prunes
|
|
21
|
-
updates correctly)
|
|
19
|
+
3. Prunes stale `gem-*--*` links (so a gem that renames, drops, or is removed
|
|
20
|
+
updates correctly).
|
|
22
21
|
4. Adds the generated symlink patterns to `.gitignore` (they are machine-local).
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
Run it whenever your dependencies change — right after `bundle install` /
|
|
24
|
+
`bundle update` — either by hand or from a git hook (see
|
|
25
|
+
[Running automatically](#running-automatically-git-hooks--hook-managers)).
|
|
27
26
|
|
|
28
27
|
### Supported agents
|
|
29
28
|
|
|
@@ -36,8 +35,8 @@ work — only freshly installed gems are processed. To re-sync everything at onc
|
|
|
36
35
|
|
|
37
36
|
`.agents/skills/` is the cross-tool standard shared by Cursor / Codex / Copilot;
|
|
38
37
|
Claude Code needs its own `.claude/skills/` because it does not read
|
|
39
|
-
`.agents/skills/` yet.
|
|
40
|
-
|
|
38
|
+
`.agents/skills/` yet. It links into a directory only when that agent's marker
|
|
39
|
+
exists, so nothing is created in projects that don't use these tools.
|
|
41
40
|
|
|
42
41
|
## Installation
|
|
43
42
|
|
|
@@ -55,13 +54,14 @@ end
|
|
|
55
54
|
gem "some-gem-that-ships-skills"
|
|
56
55
|
```
|
|
57
56
|
|
|
58
|
-
Then:
|
|
57
|
+
Then install and run the command:
|
|
59
58
|
|
|
60
59
|
```sh
|
|
61
60
|
bundle install
|
|
61
|
+
bundle exec skills
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
When a skill-bearing gem is present you'll see something like:
|
|
65
65
|
|
|
66
66
|
```
|
|
67
67
|
[bundler-skills] 1 skill(s) discovered, 1 linked, 0 relinked, 0 pruned across 1 dir(s) (agents: claude)
|
|
@@ -70,9 +70,8 @@ That's it. When a skill-bearing gem is installed you'll see something like:
|
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
> In production / CI you typically run `bundle install` with the `development`
|
|
73
|
-
> group excluded (`bundle config set --local without development`),
|
|
74
|
-
>
|
|
75
|
-
> `BUNDLER_SKILLS_DISABLED=1`.
|
|
73
|
+
> group excluded (`bundle config set --local without development`), and you
|
|
74
|
+
> simply don't run `bundle exec skills` there — nothing happens unless you invoke it.
|
|
76
75
|
|
|
77
76
|
When a run actually changes something (links created, relinked after a gem
|
|
78
77
|
update, or stale links pruned) the summary is printed in green so it stands out;
|
|
@@ -80,23 +79,68 @@ a run with nothing to do prints the same line in plain text. A changed run also
|
|
|
80
79
|
lists each affected skill, grouped by kind, with the path to its `SKILL.md` so
|
|
81
80
|
you can review the (third-party) skill contents now linked into your project.
|
|
82
81
|
|
|
82
|
+
## Running automatically (git hooks / hook managers)
|
|
83
|
+
|
|
84
|
+
Sync is manual by design, but you'll usually want it to run right after your
|
|
85
|
+
dependencies change (`bundle install` / `bundle update`, i.e. whenever
|
|
86
|
+
`Gemfile.lock` changes). Wire the one-liner into a git hook or hook manager:
|
|
87
|
+
|
|
88
|
+
Plain git hook — create `.git/hooks/post-merge` (also useful as `post-checkout`
|
|
89
|
+
/ `post-rewrite`) and `chmod +x` it. Note `.git/hooks` is not committed, so this
|
|
90
|
+
is per-clone:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
#!/bin/sh
|
|
94
|
+
bundle exec skills
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
[lefthook](https://github.com/evilmartians/lefthook) — committed, shared with
|
|
98
|
+
the team:
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
# lefthook.yml
|
|
102
|
+
post-merge:
|
|
103
|
+
commands:
|
|
104
|
+
skills: { run: bundle exec skills }
|
|
105
|
+
post-checkout:
|
|
106
|
+
commands:
|
|
107
|
+
skills: { run: bundle exec skills }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
[husky](https://typicode.github.io/husky/) — for JS-mixed projects, create
|
|
111
|
+
`.husky/post-merge`:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
#!/usr/bin/env sh
|
|
115
|
+
bundle exec skills
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
[overcommit](https://github.com/sds/overcommit) — for Ruby projects:
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
# .overcommit.yml
|
|
122
|
+
PostCheckout:
|
|
123
|
+
BundlerSkills:
|
|
124
|
+
enabled: true
|
|
125
|
+
command: ['bundle', 'exec', 'skills']
|
|
126
|
+
```
|
|
127
|
+
|
|
83
128
|
## The `bundle exec skills` command
|
|
84
129
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
installs nothing), or just to inspect/clean — run the command:
|
|
130
|
+
Sync happens only when you run this command. Run it after your dependencies
|
|
131
|
+
change, or just to inspect / clean up:
|
|
88
132
|
|
|
89
133
|
```sh
|
|
90
|
-
bundle exec skills # (
|
|
134
|
+
bundle exec skills # (sync) re-scan ALL gems and (re)create symlinks — the default
|
|
135
|
+
bundle exec skills sync # explicit form of the default
|
|
91
136
|
bundle exec skills list # show discovered skills and target agents (no changes)
|
|
92
137
|
bundle exec skills clean # remove all gem-*--* symlinks this gem created
|
|
93
138
|
bundle exec skills init # create a bundler-skills.yml config file with defaults
|
|
94
139
|
bundle exec skills <cmd> --dry-run # show what would change without writing
|
|
95
140
|
```
|
|
96
141
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
and ignores `BUNDLER_SKILLS_DISABLED`, since invoking it is an explicit action.
|
|
142
|
+
`sync` scans every resolved gem and prunes any stale `gem-*--*` link, so it also
|
|
143
|
+
cleans up after a removed gem.
|
|
100
144
|
|
|
101
145
|
## Configuration
|
|
102
146
|
|
|
@@ -119,14 +163,8 @@ exclude: # exclude these (wins over include)
|
|
|
119
163
|
Notes:
|
|
120
164
|
|
|
121
165
|
- The link target is the gem's path on your machine; that's why the symlinks are
|
|
122
|
-
gitignored and re-created on each machine
|
|
123
|
-
|
|
124
|
-
### Disabling
|
|
125
|
-
|
|
126
|
-
Set `BUNDLER_SKILLS_DISABLED` to a truthy value (`1`/`true`/`yes`/`on`) to turn
|
|
127
|
-
the `post_install` hook off. There is no production/CI auto-detection: with the
|
|
128
|
-
recommended `development`-group install the gem isn't present in production/CI in
|
|
129
|
-
the first place. The manual `bundle exec skills` command ignores this switch.
|
|
166
|
+
gitignored and re-created on each machine (run `bundle exec skills` after
|
|
167
|
+
`bundle install`).
|
|
130
168
|
|
|
131
169
|
## Naming: `gem-<gem>--<skill>`
|
|
132
170
|
|
|
@@ -159,11 +197,10 @@ reviewing any dependency.
|
|
|
159
197
|
- POSIX symlinks are assumed; Windows is not supported yet.
|
|
160
198
|
- Whether Cursor / Codex / Copilot follow symlinked `SKILL.md` during their own
|
|
161
199
|
directory scans is not formally documented; verified working with Claude Code.
|
|
162
|
-
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
until the next `bundle exec skills` (full sync prunes them).
|
|
200
|
+
- Syncing is not automatic. Run `bundle exec skills` after your dependencies
|
|
201
|
+
change (manually, or from a git hook — see above).
|
|
202
|
+
- Removing a gem leaves its `gem-*--*` links until the next `bundle exec skills`,
|
|
203
|
+
which prunes them.
|
|
167
204
|
|
|
168
205
|
## Development
|
|
169
206
|
|
data/lib/bundler_skills/cli.rb
CHANGED
|
@@ -5,9 +5,8 @@ require "optparse"
|
|
|
5
5
|
module BundlerSkills
|
|
6
6
|
# `bundle exec skills [sync|list|clean|init] [--dry-run]`
|
|
7
7
|
#
|
|
8
|
-
# The
|
|
9
|
-
#
|
|
10
|
-
# explicit user action — and it reuses the same Synchronizer logic.
|
|
8
|
+
# The entry point (a plain executable, not a Bundler plugin command). Syncing
|
|
9
|
+
# happens only when this command is run — there is no automatic hook.
|
|
11
10
|
class CLI
|
|
12
11
|
INIT_TEMPLATE = <<~YAML
|
|
13
12
|
# bundler-skills.yml — all keys are optional
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module BundlerSkills
|
|
4
4
|
# Loads bundler-skills.yml and merges it with defaults.
|
|
5
5
|
#
|
|
6
|
-
# The file is optional: a missing file yields an all-defaults Config
|
|
7
|
-
#
|
|
6
|
+
# The file is optional: a missing file yields an all-defaults Config.
|
|
7
|
+
# Supported keys:
|
|
8
8
|
# agents nil(auto-detect) | "*" | [keys] | "key"
|
|
9
9
|
# gitignore bool (default true)
|
|
10
10
|
# cleanup bool (default true) — prune stale gem-*--* links
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module BundlerSkills
|
|
4
|
-
# Orchestrates discovery -> linking across the resolved agents.
|
|
5
|
-
# point for
|
|
6
|
-
# command.
|
|
4
|
+
# Orchestrates discovery -> linking across the resolved agents. The entry
|
|
5
|
+
# point for the `bundle exec skills` command.
|
|
7
6
|
#
|
|
8
7
|
# Discovery runs once (agent-independent); linking runs once per distinct
|
|
9
|
-
# output directory (.claude/skills and/or .agents/skills)
|
|
10
|
-
#
|
|
8
|
+
# output directory (.claude/skills and/or .agents/skills), then the .gitignore
|
|
9
|
+
# is updated.
|
|
11
10
|
class Synchronizer
|
|
12
11
|
Result = Struct.new(:discovered, :agents, :links_by_dir, :gitignore_changed, keyword_init: true)
|
|
13
12
|
|
|
@@ -38,37 +37,8 @@ module BundlerSkills
|
|
|
38
37
|
)
|
|
39
38
|
end
|
|
40
39
|
|
|
41
|
-
# Sync the skills of a SINGLE gem (used by the RubyGems post_install hook).
|
|
42
|
-
#
|
|
43
|
-
# Only links belonging to this gem (gem-<name>--*) are added/updated, and
|
|
44
|
-
# only this gem's stale links are pruned — every other gem's links are left
|
|
45
|
-
# untouched. So when a gem's new version drops or renames a skill, its old
|
|
46
|
-
# link is removed, but unrelated gems are never disturbed.
|
|
47
|
-
#
|
|
48
|
-
# @param spec [#name, #full_gem_path] a Gem::Specification (or compatible)
|
|
49
|
-
def sync_gem(spec)
|
|
50
|
-
skills = Discoverer.new(specs: [spec], config: @config, logger: @logger).discover
|
|
51
|
-
agents = AgentRegistry.resolve(@root, @config)
|
|
52
|
-
subdirs = AgentRegistry.output_subdirs(agents)
|
|
53
|
-
scope = ["#{DiscoveredSkill::LINK_PREFIX}#{spec.name}#{DiscoveredSkill::BOUNDARY}"]
|
|
54
|
-
|
|
55
|
-
links_by_dir = subdirs.to_h do |subdir|
|
|
56
|
-
skills_dir = File.join(@root.to_s, subdir)
|
|
57
|
-
linker = Linker.new(skills_dir: skills_dir, config: @config, logger: @logger)
|
|
58
|
-
[subdir, linker.link(skills, prune_scope: scope)]
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
gitignore_changed = update_gitignore(subdirs)
|
|
62
|
-
|
|
63
|
-
log_summary(skills, agents, links_by_dir)
|
|
64
|
-
Result.new(
|
|
65
|
-
discovered: skills, agents: agents,
|
|
66
|
-
links_by_dir: links_by_dir, gitignore_changed: gitignore_changed
|
|
67
|
-
)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
40
|
# Discover skills and the agents/dirs that would receive them, without
|
|
71
|
-
# touching the filesystem. Used by `bundle skills list`.
|
|
41
|
+
# touching the filesystem. Used by `bundle exec skills list`.
|
|
72
42
|
def plan
|
|
73
43
|
skills = Discoverer.new(specs: @specs, config: @config, logger: @logger).discover
|
|
74
44
|
agents = AgentRegistry.resolve(@root, @config)
|
|
@@ -79,7 +49,7 @@ module BundlerSkills
|
|
|
79
49
|
end
|
|
80
50
|
|
|
81
51
|
# Remove every gem-*--* symlink we own across all known output dirs.
|
|
82
|
-
# Used by `bundle skills clean`. Returns { subdir => [removed names] }.
|
|
52
|
+
# Used by `bundle exec skills clean`. Returns { subdir => [removed names] }.
|
|
83
53
|
def clean
|
|
84
54
|
AgentRegistry.all.map(&:skills_subdir).uniq.to_h do |subdir|
|
|
85
55
|
skills_dir = File.join(@root.to_s, subdir)
|
|
@@ -104,9 +74,9 @@ module BundlerSkills
|
|
|
104
74
|
def log_summary(skills, agents, links_by_dir)
|
|
105
75
|
return unless @logger
|
|
106
76
|
|
|
107
|
-
# Nothing discovered and nothing changed -> stay silent.
|
|
108
|
-
#
|
|
109
|
-
#
|
|
77
|
+
# Nothing discovered and nothing changed -> stay silent. Most dependency
|
|
78
|
+
# gems ship no skills, so emitting a "0 skill(s) discovered, 0 linked ..."
|
|
79
|
+
# line when there is nothing to report is just noise.
|
|
110
80
|
changed = links_by_dir.values.any?(&:changed?)
|
|
111
81
|
return if skills.empty? && !changed
|
|
112
82
|
|
data/lib/bundler_skills.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bundler-skills
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- aki77
|
|
@@ -11,8 +11,7 @@ date: 1980-01-02 00:00:00.000000000 Z
|
|
|
11
11
|
dependencies: []
|
|
12
12
|
description: A gem that discovers skills/ directories bundled in your dependency gems
|
|
13
13
|
and symlinks them into your project's agent skill directories (.claude/skills, .agents/skills)
|
|
14
|
-
|
|
15
|
-
of antfu/skills-npm.
|
|
14
|
+
via the `bundle exec skills` command. The Ruby/Bundler counterpart of antfu/skills-npm.
|
|
16
15
|
email:
|
|
17
16
|
- aki77@users.noreply.github.com
|
|
18
17
|
executables:
|
|
@@ -29,15 +28,12 @@ files:
|
|
|
29
28
|
- lib/bundler_skills/agent_registry.rb
|
|
30
29
|
- lib/bundler_skills/cli.rb
|
|
31
30
|
- lib/bundler_skills/config.rb
|
|
32
|
-
- lib/bundler_skills/disabling.rb
|
|
33
31
|
- lib/bundler_skills/discovered_skill.rb
|
|
34
32
|
- lib/bundler_skills/discoverer.rb
|
|
35
33
|
- lib/bundler_skills/gitignore_updater.rb
|
|
36
34
|
- lib/bundler_skills/linker.rb
|
|
37
|
-
- lib/bundler_skills/rubygems_hook.rb
|
|
38
35
|
- lib/bundler_skills/synchronizer.rb
|
|
39
36
|
- lib/bundler_skills/version.rb
|
|
40
|
-
- lib/rubygems_plugin.rb
|
|
41
37
|
homepage: https://github.com/aki77/bundler-skills
|
|
42
38
|
licenses:
|
|
43
39
|
- MIT
|
|
@@ -60,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
60
56
|
- !ruby/object:Gem::Version
|
|
61
57
|
version: '0'
|
|
62
58
|
requirements: []
|
|
63
|
-
rubygems_version: 4.0.
|
|
59
|
+
rubygems_version: 4.0.15
|
|
64
60
|
specification_version: 4
|
|
65
|
-
summary:
|
|
61
|
+
summary: Symlink AI agent skills bundled in your gems via the bundle exec skills command.
|
|
66
62
|
test_files: []
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module BundlerSkills
|
|
4
|
-
# Decides whether the post_install hook should run.
|
|
5
|
-
#
|
|
6
|
-
# The hook only fires when a gem is actually installed, and in the
|
|
7
|
-
# recommended development-group setup the gem isn't even present in
|
|
8
|
-
# production / CI — so there is no environment auto-detection here. The single
|
|
9
|
-
# escape hatch is the BUNDLER_SKILLS_DISABLED env var. The manual CLI ignores
|
|
10
|
-
# this entirely (running it is an explicit user action).
|
|
11
|
-
module Disabling
|
|
12
|
-
TRUTHY = %w[1 true yes on].freeze
|
|
13
|
-
|
|
14
|
-
module_function
|
|
15
|
-
|
|
16
|
-
# @param env [Hash] environment variables (defaults to ENV)
|
|
17
|
-
# @return [Boolean] true when the hook must not run
|
|
18
|
-
def disabled?(env: ENV)
|
|
19
|
-
truthy?(env["BUNDLER_SKILLS_DISABLED"])
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def truthy?(value)
|
|
23
|
-
return false if value.nil?
|
|
24
|
-
|
|
25
|
-
TRUTHY.include?(value.to_s.strip.downcase)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module BundlerSkills
|
|
4
|
-
# Entry point for the RubyGems `Gem.post_install` hook (registered in
|
|
5
|
-
# lib/rubygems_plugin.rb). Fires once per gem actually installed during a
|
|
6
|
-
# `bundle install` / `bundle update`, and syncs THAT gem's skills only.
|
|
7
|
-
#
|
|
8
|
-
# Like the old Bundler hook, it holds no real logic: it guards on context and
|
|
9
|
-
# the disable switch, then delegates to Synchronizer#sync_gem. Any error is
|
|
10
|
-
# swallowed as a warning so it never aborts the user's install.
|
|
11
|
-
module RubygemsHook
|
|
12
|
-
module_function
|
|
13
|
-
|
|
14
|
-
# @param installer [#spec] a Gem::Installer (or anything exposing #spec)
|
|
15
|
-
def install(installer)
|
|
16
|
-
spec = installer.spec
|
|
17
|
-
return unless bundle_context?
|
|
18
|
-
return if Disabling.disabled?
|
|
19
|
-
|
|
20
|
-
Synchronizer.new(config: Config.load).sync_gem(spec)
|
|
21
|
-
rescue StandardError => e
|
|
22
|
-
warn("[bundler-skills] skipped #{safe_name(installer)}: #{e.class}: #{e.message}")
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Only act inside a `bundle install` for a project with a Gemfile. This
|
|
26
|
-
# keeps a plain `gem install foo` (no project context) from creating
|
|
27
|
-
# symlinks in whatever directory the user happens to be in.
|
|
28
|
-
def bundle_context?
|
|
29
|
-
return false unless defined?(Bundler)
|
|
30
|
-
|
|
31
|
-
root = Bundler.root
|
|
32
|
-
root.join("Gemfile").file? || root.join("gems.rb").file?
|
|
33
|
-
rescue StandardError
|
|
34
|
-
false
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def safe_name(installer)
|
|
38
|
-
installer.spec.name
|
|
39
|
-
rescue StandardError
|
|
40
|
-
"(unknown gem)"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def warn(message)
|
|
44
|
-
if defined?(Bundler)
|
|
45
|
-
Bundler.ui.warn(message)
|
|
46
|
-
else
|
|
47
|
-
Kernel.warn(message)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
data/lib/rubygems_plugin.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# RubyGems loads this file automatically (it is on the require path and named
|
|
4
|
-
# by the rubygems_plugin convention) during `bundle install` / `gem install`.
|
|
5
|
-
# We register a post_install hook that syncs each freshly installed gem's
|
|
6
|
-
# skills. This replaces the old Bundler plugin (`command "skills"` caused a
|
|
7
|
-
# CommandConflict whenever the plugin updated itself).
|
|
8
|
-
require_relative "bundler_skills"
|
|
9
|
-
require_relative "bundler_skills/rubygems_hook"
|
|
10
|
-
|
|
11
|
-
Gem.post_install do |installer|
|
|
12
|
-
BundlerSkills::RubygemsHook.install(installer)
|
|
13
|
-
end
|