bundler-skills 0.1.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efdb922b385805d47a3b9d255b160810300f0b6e98157213f6a4587d1d2475dc
4
- data.tar.gz: da6868ab55f898967fe52c7699512898c4a4df2e5ccb7e278cd5882b6c0219f1
3
+ metadata.gz: 439aafda99d985a5bd8da3676ad50a82f17d1e8bf01a895d193998ae1faf885d
4
+ data.tar.gz: 0050bcd8e99963aecc9b847bba9697e2b88b8d55ecee0f3c8d6a7340a6b0ad9c
5
5
  SHA512:
6
- metadata.gz: f931afeb29f6d9e263b6f9d39ddbbd0ae157fed3bdc9aa45ccacefd6c64d4e0ca3d14732619f91d964dd81c4e5f88c7367bb26a5ebe11da93b82ae91274843d1
7
- data.tar.gz: cacd1cf9954366a41d0edfeecb13fee38ba865ad4ac8c7b9ae45eb966e44ca8982f5a8e8e1e443c18395475a44ca06b1c1899466b5e5ee7c5aa0c2ee6fff5262
6
+ metadata.gz: de83628fb2e88ab3388afd068d0c478eb901fac43df5858ca280af1012dfaa64363599a4e640874d3d8e392b4189dd7f3962420a0e44d458cb5c5893d6880409
7
+ data.tar.gz: 46029390766998a7ede9dc14546d6fbbff54810973196a8e8626ce653b905cbcd43dec302d63f1b21e88915c74703296d5ac22881dd9b3ac2e6930b14b3b29a0
data/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.3.0] - 2026-06-21
6
+
7
+ ### Changed
8
+
9
+ - Post-install summary now highlights runs that actually changed something:
10
+ when skills are created, relinked (after a gem update), or pruned, the summary
11
+ line is printed in green (`confirm`) instead of plain text, and the count of
12
+ relinked skills is now shown alongside linked/pruned.
13
+ - A changed run additionally lists each affected skill grouped by kind
14
+ (created / relinked / pruned), showing the path to its `SKILL.md`, so the
15
+ third-party skill contents linked into your project are easy to review.
16
+
17
+ ## [0.2.0] - 2026-06-18
18
+
19
+ ### Added
20
+
21
+ - `bundle skills init` command: creates a `bundler-skills.yml` config file with
22
+ all keys commented out, so users can enable only the options they need.
23
+
5
24
  ## [0.1.0] - 2026-06-18
6
25
 
7
26
  ### Added
data/README.md CHANGED
@@ -56,7 +56,22 @@ bundle install
56
56
  That's it. On install you'll see something like:
57
57
 
58
58
  ```
59
- [bundler-skills] 3 skill(s) discovered, 3 linked, 0 pruned across 1 dir(s) (agents: claude)
59
+ [bundler-skills] 3 skill(s) discovered, 3 linked, 0 relinked, 0 pruned across 1 dir(s) (agents: claude)
60
+ ```
61
+
62
+ When a run actually changes something (links created, relinked after a gem
63
+ update, or stale links pruned) the summary is printed in green so it stands out;
64
+ a run with nothing to do prints the same line in plain text. A changed run also
65
+ lists each affected skill, grouped by kind, with the path to its `SKILL.md` so
66
+ you can review the (third-party) skill contents now linked into your project:
67
+
68
+ ```
69
+ [bundler-skills] 3 skill(s) discovered, 2 linked, 1 relinked, 0 pruned across 1 dir(s) (agents: claude)
70
+ created:
71
+ .claude/skills/gem-rubocop--style -> /path/to/gems/rubocop/skills/style
72
+ .claude/skills/gem-rubocop--lint -> /path/to/gems/rubocop/skills/lint
73
+ relinked:
74
+ .claude/skills/gem-rspec--matchers -> /path/to/gems/rspec/skills/matchers
60
75
  ```
61
76
 
62
77
  > Alternatively, install it globally with `bundle plugin install bundler-skills`.
@@ -72,6 +87,7 @@ Use the command to sync manually, or to inspect/clean:
72
87
  bundle skills # (or: bundle skills sync) re-create symlinks
73
88
  bundle skills list # show discovered skills and target agents (no changes)
74
89
  bundle skills clean # remove all gem-*--* symlinks this plugin created
90
+ bundle skills init # create a bundler-skills.yml config file with defaults
75
91
  bundle skills <cmd> --dry-run # show what would change without writing
76
92
  ```
77
93
 
@@ -9,14 +9,32 @@ module BundlerSkills
9
9
  class Command < Bundler::Plugin::API
10
10
  command "skills"
11
11
 
12
+ INIT_TEMPLATE = <<~YAML
13
+ # bundler-skills.yml — all keys are optional
14
+ #
15
+ # enabled: # nil (auto) | false (off) | [development] (env list)
16
+ # agents: # omit = auto-detect; or list: [claude, cursor]; or "*"
17
+ # - claude
18
+ # - cursor
19
+ # gitignore: true # manage .gitignore (default true)
20
+ # cleanup: true # prune stale gem-*--* links when a gem is removed (default true)
21
+ # recursive: false # also scan skills/**/SKILL.md (default false)
22
+ # include: # only these gems (empty = all). fnmatch on "gem" or "gem/skill"
23
+ # - rubocop
24
+ # - "rails-*"
25
+ # exclude: # exclude these (wins over include)
26
+ # - some-noisy-gem
27
+ YAML
28
+
12
29
  def exec(_command_name, args)
13
- dry_run = args.delete("--dry-run") ? true : false
30
+ dry_run = !!args.delete("--dry-run")
14
31
  subcommand = args.shift || "sync"
15
32
 
16
33
  case subcommand
17
34
  when "sync" then run_sync(dry_run)
18
35
  when "list" then run_list
19
36
  when "clean" then run_clean(dry_run)
37
+ when "init" then run_init
20
38
  when "help", "-h", "--help" then print_help
21
39
  else
22
40
  Bundler.ui.error("[bundler-skills] unknown subcommand: #{subcommand}")
@@ -51,6 +69,17 @@ module BundlerSkills
51
69
  end
52
70
  end
53
71
 
72
+ def run_init
73
+ path = Bundler.root / Config::CONFIG_FILENAME
74
+ if File.exist?(path)
75
+ Bundler.ui.warn("[bundler-skills] #{Config::CONFIG_FILENAME} already exists")
76
+ return
77
+ end
78
+
79
+ File.write(path, INIT_TEMPLATE)
80
+ Bundler.ui.info("[bundler-skills] created #{Config::CONFIG_FILENAME}")
81
+ end
82
+
54
83
  def run_clean(dry_run)
55
84
  removed = synchronizer(dry_run: dry_run).clean
56
85
  total = removed.values.sum(&:size)
@@ -68,6 +97,7 @@ module BundlerSkills
68
97
  sync (default) discover skills and (re)create symlinks
69
98
  list show discovered skills and target agents (no changes)
70
99
  clean remove all gem-*--* symlinks this plugin created
100
+ init create a bundler-skills.yml config file with defaults
71
101
 
72
102
  Options:
73
103
  --dry-run show what would change without writing
@@ -22,6 +22,11 @@ module BundlerSkills
22
22
  @skipped = []
23
23
  @pruned = []
24
24
  end
25
+
26
+ # Did this run actually mutate the filesystem? kept/skipped are no-ops.
27
+ def changed?
28
+ created.any? || relinked.any? || pruned.any?
29
+ end
25
30
  end
26
31
 
27
32
  def initialize(skills_dir:, config: Config.new(Config::DEFAULTS), logger: nil)
@@ -83,12 +83,42 @@ module BundlerSkills
83
83
  end
84
84
 
85
85
  created = links_by_dir.values.sum { |r| r.created.size }
86
+ relinked = links_by_dir.values.sum { |r| r.relinked.size }
86
87
  pruned = links_by_dir.values.sum { |r| r.pruned.size }
87
- @logger.info(
88
+
89
+ message =
88
90
  "[bundler-skills] #{skills.size} skill(s) discovered, " \
89
- "#{created} linked, #{pruned} pruned across #{links_by_dir.size} dir(s) " \
90
- "(agents: #{agents.map(&:key).join(', ')})"
91
- )
91
+ "#{created} linked, #{relinked} relinked, #{pruned} pruned " \
92
+ "across #{links_by_dir.size} dir(s) (agents: #{agents.map(&:key).join(', ')})"
93
+
94
+ # Make a run that actually changed something stand out (green) so it is
95
+ # noticed amid bundle's output; an unchanged run stays plain.
96
+ if links_by_dir.values.any?(&:changed?)
97
+ @logger.confirm(message)
98
+ # List the skills that changed so the user can review the (third-party)
99
+ # SKILL.md contents now linked into their project. created/relinked are
100
+ # in the discovery set so we can show their source path; pruned skills
101
+ # are already gone, so we show the name only.
102
+ log_changed_skills(skills, links_by_dir)
103
+ else
104
+ @logger.info(message)
105
+ end
106
+ end
107
+
108
+ def log_changed_skills(skills, links_by_dir)
109
+ source_by_link = skills.to_h { |s| [s.link_name, s.source_path] }
110
+
111
+ %i[created relinked pruned].each do |kind|
112
+ entries = links_by_dir.flat_map do |subdir, result|
113
+ result.public_send(kind).map { |name| [File.join(subdir, name), source_by_link[name]] }
114
+ end
115
+ next if entries.empty?
116
+
117
+ @logger.info(" #{kind}:")
118
+ entries.each do |path, source|
119
+ @logger.info(source ? " #{path} -> #{source}" : " #{path}")
120
+ end
121
+ end
92
122
  end
93
123
  end
94
124
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BundlerSkills
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
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.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - aki77