source_monitor 0.3.0 → 0.3.2

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/sm-architecture/SKILL.md +233 -0
  3. data/.claude/skills/sm-architecture/reference/extraction-patterns.md +192 -0
  4. data/.claude/skills/sm-architecture/reference/module-map.md +194 -0
  5. data/.claude/skills/sm-configuration-setting/SKILL.md +264 -0
  6. data/.claude/skills/sm-configuration-setting/reference/settings-catalog.md +248 -0
  7. data/.claude/skills/sm-configuration-setting/reference/settings-pattern.md +297 -0
  8. data/.claude/skills/sm-configure/SKILL.md +153 -0
  9. data/.claude/skills/sm-configure/reference/configuration-reference.md +321 -0
  10. data/.claude/skills/sm-dashboard-widget/SKILL.md +344 -0
  11. data/.claude/skills/sm-dashboard-widget/reference/dashboard-patterns.md +304 -0
  12. data/.claude/skills/sm-domain-model/SKILL.md +188 -0
  13. data/.claude/skills/sm-domain-model/reference/model-graph.md +114 -0
  14. data/.claude/skills/sm-domain-model/reference/table-structure.md +348 -0
  15. data/.claude/skills/sm-engine-migration/SKILL.md +395 -0
  16. data/.claude/skills/sm-engine-migration/reference/migration-conventions.md +255 -0
  17. data/.claude/skills/sm-engine-test/SKILL.md +302 -0
  18. data/.claude/skills/sm-engine-test/reference/test-helpers.md +259 -0
  19. data/.claude/skills/sm-engine-test/reference/test-patterns.md +411 -0
  20. data/.claude/skills/sm-event-handler/SKILL.md +265 -0
  21. data/.claude/skills/sm-event-handler/reference/events-api.md +229 -0
  22. data/.claude/skills/sm-health-rule/SKILL.md +327 -0
  23. data/.claude/skills/sm-health-rule/reference/health-system.md +269 -0
  24. data/.claude/skills/sm-host-setup/SKILL.md +223 -0
  25. data/.claude/skills/sm-host-setup/reference/initializer-template.md +195 -0
  26. data/.claude/skills/sm-host-setup/reference/setup-checklist.md +134 -0
  27. data/.claude/skills/sm-job/SKILL.md +263 -0
  28. data/.claude/skills/sm-job/reference/job-conventions.md +245 -0
  29. data/.claude/skills/sm-model-extension/SKILL.md +287 -0
  30. data/.claude/skills/sm-model-extension/reference/extension-api.md +317 -0
  31. data/.claude/skills/sm-pipeline-stage/SKILL.md +254 -0
  32. data/.claude/skills/sm-pipeline-stage/reference/completion-handlers.md +152 -0
  33. data/.claude/skills/sm-pipeline-stage/reference/entry-processing.md +191 -0
  34. data/.claude/skills/sm-pipeline-stage/reference/feed-fetcher-architecture.md +198 -0
  35. data/.claude/skills/sm-scraper-adapter/SKILL.md +284 -0
  36. data/.claude/skills/sm-scraper-adapter/reference/adapter-contract.md +167 -0
  37. data/.claude/skills/sm-scraper-adapter/reference/example-adapter.md +274 -0
  38. data/.vbw-planning/.notification-log.jsonl +102 -0
  39. data/.vbw-planning/.session-log.jsonl +505 -0
  40. data/AGENTS.md +20 -57
  41. data/CHANGELOG.md +19 -0
  42. data/CLAUDE.md +44 -1
  43. data/CONTRIBUTING.md +5 -5
  44. data/Gemfile.lock +20 -21
  45. data/README.md +18 -5
  46. data/VERSION +1 -0
  47. data/docs/deployment.md +1 -1
  48. data/docs/setup.md +4 -4
  49. data/lib/source_monitor/setup/skills_installer.rb +94 -0
  50. data/lib/source_monitor/setup/workflow.rb +17 -2
  51. data/lib/source_monitor/version.rb +1 -1
  52. data/lib/tasks/source_monitor_setup.rake +58 -0
  53. data/source_monitor.gemspec +1 -0
  54. metadata +39 -1
data/CLAUDE.md CHANGED
@@ -45,7 +45,7 @@ Run /vbw:help for all commands.
45
45
 
46
46
  | Layer | Technology |
47
47
  |-------|------------|
48
- | Ruby | 3.4+ |
48
+ | Ruby | 4.0+ |
49
49
  | Rails | 8.x |
50
50
  | Testing | Minitest (no fixtures -- uses factory helpers + WebMock/VCR) |
51
51
  | Authorization | Host app responsibility (mountable engine) |
@@ -177,3 +177,46 @@ These skills are available in `.claude/skills/`:
177
177
  | `performance-optimization` | Performance tuning patterns |
178
178
  | `i18n-patterns` | Internationalization patterns |
179
179
  | `active-storage-setup` | Active Storage configuration |
180
+
181
+ ## Source Monitor Skills
182
+
183
+ Engine-specific skills (`sm-*` prefix). Consumer skills install by default; contributor skills are opt-in.
184
+
185
+ ### Consumer Skills (default install)
186
+
187
+ | Skill | Purpose |
188
+ |-------|---------|
189
+ | `sm-host-setup` | Full host app setup walkthrough |
190
+ | `sm-configure` | DSL configuration across all sub-sections |
191
+ | `sm-scraper-adapter` | Custom scraper inheriting `Scrapers::Base` |
192
+ | `sm-event-handler` | Lifecycle callbacks (after_item_created, etc.) |
193
+ | `sm-model-extension` | Extend engine models from host app |
194
+ | `sm-dashboard-widget` | Dashboard queries, presenters, Turbo broadcasts |
195
+
196
+ ### Contributor Skills (opt-in)
197
+
198
+ | Skill | Purpose |
199
+ |-------|---------|
200
+ | `sm-domain-model` | Model graph, relationships, state values, scopes |
201
+ | `sm-architecture` | Module map, autoload tree, extraction patterns |
202
+ | `sm-engine-test` | Engine test helpers, VCR/WebMock, parallel caveats |
203
+ | `sm-configuration-setting` | Add settings to config sub-sections |
204
+ | `sm-pipeline-stage` | Add/modify fetch or scrape pipeline stages |
205
+ | `sm-engine-migration` | Migrations with `sourcemon_` prefix conventions |
206
+ | `sm-job` | Solid Queue jobs with shallow delegation |
207
+ | `sm-health-rule` | Health status rules, circuit breaker, auto-pause |
208
+
209
+ ### Skills Distribution
210
+
211
+ Host apps can install `sm-*` skills via rake:
212
+
213
+ ```bash
214
+ bin/rails source_monitor:skills:install # Consumer skills (default)
215
+ bin/rails source_monitor:skills:contributor # Contributor skills
216
+ bin/rails source_monitor:skills:all # All skills
217
+ bin/rails source_monitor:skills:remove # Remove all sm-* skills
218
+ ```
219
+
220
+ ## Maintenance Rules
221
+
222
+ - **Skills & docs alignment**: Whenever engine code changes (models, configuration, pipeline, jobs, migrations, scrapers, events, health rules, or dashboard), the corresponding `sm-*` skill and its `reference/` files MUST be updated in the same PR to ensure skills always reflect current engine behavior.
data/CONTRIBUTING.md CHANGED
@@ -4,7 +4,7 @@ This project ships each roadmap slice behind a fast, reliable test loop. The not
4
4
 
5
5
  ## Test Suite Expectations
6
6
 
7
- - **Fast feedback:** run `bundle exec rake app:test:smoke` for unit, helper, and job coverage before pushing. Use `SOURCE_MONITOR_TEST_WORKERS=1` locally when profiling failures for determinism.
7
+ - **Fast feedback:** run `bundle exec rake app:test:smoke` for unit, helper, and job coverage before pushing. Use `PARALLEL_WORKERS=1` locally when profiling failures for determinism.
8
8
  - **Full validation:** continue to run `bundle exec rails test` (or `bin/test-coverage` in CI) before marking a slice ready for review.
9
9
  - **Background jobs:** the default adapter is `:test`. Switch to inline execution only for the precise block that needs it via `with_inline_jobs { ... }`; never flip the global adapter.
10
10
  - **Database usage:** prefer transactional fixtures over manual `delete_all`. Reach for `setup_once` (TestProf’s `before_all`) when immutable data can be shared safely across examples.
@@ -13,16 +13,16 @@ This project ships each roadmap slice behind a fast, reliable test loop. The not
13
13
  ## Performance Profiling
14
14
 
15
15
  - **Local commands:**
16
- - `TAG_PROF=type SOURCE_MONITOR_TEST_WORKERS=1 bundle exec rails test`
17
- - `EVENT_PROF=sql.active_record SOURCE_MONITOR_TEST_WORKERS=1 bundle exec rails test`
18
- - `TEST_STACK_PROF=1 SOURCE_MONITOR_TEST_WORKERS=1 bundle exec rails test test/integration`
16
+ - `TAG_PROF=type PARALLEL_WORKERS=1 bundle exec rails test`
17
+ - `EVENT_PROF=sql.active_record PARALLEL_WORKERS=1 bundle exec rails test`
18
+ - `TEST_STACK_PROF=1 PARALLEL_WORKERS=1 bundle exec rails test test/integration`
19
19
  - **CI automation:** a scheduled `profiling` workflow runs the commands above nightly, archives `tmp/test_prof`, and applies guardrails via `bin/check-test-prof-metrics` (suite ≤ 80s, integration ≤ 35s, DB time ≤ 5s). Failures block the job so regressions surface quickly.
20
20
 
21
21
  ## Code Review Checklist
22
22
 
23
23
  Before approval, verify that the changes:
24
24
 
25
- 1. Avoid unnecessary database persistence (`build_stubbed`/test doubles over `.create` when assertions allow).
25
+ 1. Avoid unnecessary database persistence (test doubles over `.create` when assertions allow).
26
26
  2. Share heavy setup with `setup_once` or helper memoization instead of per-test rebuilds.
27
27
  3. Scope inline job execution to `with_inline_jobs { ... }` blocks—no suite-wide adapter swaps.
28
28
  4. Keep new or modified system specs lean, relying on lower-level coverage when UI is not essential.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- source_monitor (0.3.0)
4
+ source_monitor (0.3.2)
5
5
  cssbundling-rails (~> 1.4)
6
6
  faraday (~> 2.9)
7
7
  faraday-follow_redirects (~> 0.4)
@@ -99,7 +99,7 @@ GEM
99
99
  ast (2.4.3)
100
100
  base64 (0.3.0)
101
101
  bigdecimal (4.0.1)
102
- brakeman (7.1.1)
102
+ brakeman (8.0.2)
103
103
  racc
104
104
  builder (3.3.0)
105
105
  capybara (3.40.0)
@@ -128,17 +128,17 @@ GEM
128
128
  erubi (1.13.1)
129
129
  et-orbi (1.4.0)
130
130
  tzinfo
131
- faraday (2.14.0)
131
+ faraday (2.14.1)
132
132
  faraday-net_http (>= 2.0, < 3.5)
133
133
  json
134
134
  logger
135
135
  faraday-follow_redirects (0.5.0)
136
136
  faraday (>= 1, < 3)
137
- faraday-gzip (3.0.4)
137
+ faraday-gzip (3.1.0)
138
138
  faraday (>= 2.0, < 3)
139
139
  zlib (~> 3.0)
140
- faraday-net_http (3.4.1)
141
- net-http (>= 0.5.0)
140
+ faraday-net_http (3.4.2)
141
+ net-http (~> 0.5)
142
142
  faraday-retry (2.4.0)
143
143
  faraday (~> 2.0)
144
144
  feedjira (4.0.1)
@@ -182,8 +182,8 @@ GEM
182
182
  minitest (6.0.1)
183
183
  prism (~> 1.5)
184
184
  minitest-mock (5.27.0)
185
- net-http (0.6.0)
186
- uri
185
+ net-http (0.9.1)
186
+ uri (>= 0.11.1)
187
187
  net-imap (0.6.2)
188
188
  date
189
189
  net-protocol
@@ -222,13 +222,13 @@ GEM
222
222
  parser (3.3.10.1)
223
223
  ast (~> 2.4.1)
224
224
  racc
225
- pg (1.6.2)
226
- pg (1.6.2-aarch64-linux)
227
- pg (1.6.2-aarch64-linux-musl)
228
- pg (1.6.2-arm64-darwin)
229
- pg (1.6.2-x86_64-darwin)
230
- pg (1.6.2-x86_64-linux)
231
- pg (1.6.2-x86_64-linux-musl)
225
+ pg (1.6.3)
226
+ pg (1.6.3-aarch64-linux)
227
+ pg (1.6.3-aarch64-linux-musl)
228
+ pg (1.6.3-arm64-darwin)
229
+ pg (1.6.3-x86_64-darwin)
230
+ pg (1.6.3-x86_64-linux)
231
+ pg (1.6.3-x86_64-linux-musl)
232
232
  pp (0.6.3)
233
233
  prettyprint
234
234
  prettyprint (0.2.0)
@@ -326,13 +326,13 @@ GEM
326
326
  rubocop-performance (>= 1.24)
327
327
  rubocop-rails (>= 2.30)
328
328
  ruby-progressbar (1.13.0)
329
- ruby-readability (0.7.2)
329
+ ruby-readability (0.7.3)
330
330
  guess_html_encoding (>= 0.0.4)
331
331
  nokogiri (>= 1.6.0)
332
332
  rubyzip (3.2.2)
333
333
  sax-machine (1.3.2)
334
334
  securerandom (0.4.1)
335
- selenium-webdriver (4.38.0)
335
+ selenium-webdriver (4.40.0)
336
336
  base64 (~> 0.2)
337
337
  logger (~> 1.4)
338
338
  rexml (~> 3.2, >= 3.2.5)
@@ -358,7 +358,7 @@ GEM
358
358
  thor (>= 1.3.1)
359
359
  stackprof (0.2.27)
360
360
  stringio (3.2.0)
361
- test-prof (1.4.4)
361
+ test-prof (1.5.2)
362
362
  thor (1.5.0)
363
363
  timeout (0.6.0)
364
364
  tsort (0.2.0)
@@ -372,8 +372,7 @@ GEM
372
372
  unicode-emoji (4.2.0)
373
373
  uri (1.1.1)
374
374
  useragent (0.16.11)
375
- vcr (6.3.1)
376
- base64
375
+ vcr (6.4.0)
377
376
  webmock (3.26.1)
378
377
  addressable (>= 2.8.0)
379
378
  crack (>= 0.3.2)
@@ -386,7 +385,7 @@ GEM
386
385
  xpath (3.2.0)
387
386
  nokogiri (~> 1.8)
388
387
  zeitwerk (2.7.4)
389
- zlib (3.2.1)
388
+ zlib (3.2.2)
390
389
 
391
390
  PLATFORMS
392
391
  aarch64-linux-gnu
data/README.md CHANGED
@@ -9,8 +9,8 @@ SourceMonitor is a production-ready Rails 8 mountable engine for ingesting, norm
9
9
  In your host Rails app:
10
10
 
11
11
  ```bash
12
- bundle add source_monitor --version "~> 0.1.2"
13
- # or add `gem "source_monitor", "~> 0.1.2"` manually, then run:
12
+ bundle add source_monitor --version "~> 0.3.1"
13
+ # or add `gem "source_monitor", "~> 0.3.1"` manually, then run:
14
14
  bundle install
15
15
  ```
16
16
 
@@ -25,7 +25,7 @@ This exposes `bin/source_monitor` (via Bundler binstubs) so you can run the guid
25
25
  - First-class observability through ActiveSupport notifications and `SourceMonitor::Metrics` counters/gauges
26
26
 
27
27
  ## Requirements
28
- - Ruby 3.4.4 (we recommend [rbenv](https://github.com/rbenv/rbenv) for local development: `rbenv install 3.4.4 && rbenv local 3.4.4`, but use whatever Ruby version manager suits your environment—asdf, chruby, rvm, or container-based workflows all work fine)
28
+ - Ruby 4.0+ (we recommend [rbenv](https://github.com/rbenv/rbenv) for local development, but use whatever Ruby version manager suits your environment—asdf, chruby, rvm, or container-based workflows all work fine)
29
29
  - Rails ≥ 8.0.2.1 in the host application
30
30
  - PostgreSQL 13+ (engine migrations use JSONB, SKIP LOCKED, advisory locks, and Solid Cable tables)
31
31
  - Node.js 18+ (npm or Yarn) for asset linting and the Tailwind/esbuild bundling pipeline
@@ -41,7 +41,7 @@ This exposes `bin/source_monitor` (via Bundler binstubs) so you can run the guid
41
41
  Before running any SourceMonitor commands inside your host app, add the gem and install dependencies:
42
42
 
43
43
  ```bash
44
- bundle add source_monitor --version "~> 0.1.2"
44
+ bundle add source_monitor --version "~> 0.3.1"
45
45
  # or edit your Gemfile, then run
46
46
  bundle install
47
47
  ```
@@ -111,6 +111,19 @@ The generated initializer documents every setting. Key areas:
111
111
 
112
112
  See [docs/configuration.md](docs/configuration.md) for exhaustive coverage and examples.
113
113
 
114
+ ## Claude Code Skills
115
+
116
+ SourceMonitor ships 14 engine-specific Claude Code skills (`sm-*` prefix) that give AI agents deep context about the engine's domain model, configuration DSL, pipeline stages, and testing conventions. Skills are bundled with the gem and installed into your host app's `.claude/skills/` directory.
117
+
118
+ ```bash
119
+ bin/rails source_monitor:skills:install # Consumer skills (host app integration)
120
+ bin/rails source_monitor:skills:contributor # Contributor skills (engine development)
121
+ bin/rails source_monitor:skills:all # All skills
122
+ bin/rails source_monitor:skills:remove # Remove all sm-* skills
123
+ ```
124
+
125
+ The guided installer (`bin/source_monitor install`) also offers to install consumer skills as part of the setup workflow.
126
+
114
127
  ## Deployment Considerations
115
128
  - Copy engine migrations before every deploy and run `bin/rails db:migrate`.
116
129
  - Precompile assets so SourceMonitor's bundled CSS/JS outputs are available at runtime.
@@ -130,7 +143,7 @@ Common installation and runtime issues (missing migrations, realtime not streami
130
143
  - Quality checks: `bin/rubocop`, `bin/brakeman --no-pager`, `bin/lint-assets`.
131
144
  - Record HTTP fixtures with VCR under `test/vcr_cassettes/` and keep coverage ≥ 90% for new code.
132
145
 
133
- Contributions follow the clean architecture and TDD guidelines in `.ai/project_overview.md`. Review `.ai/tasks.md` to align with the active roadmap slice before opening a pull request.
146
+ Contributions follow the clean architecture and TDD guidelines in `CLAUDE.md` and `AGENTS.md`.
134
147
 
135
148
  ## License
136
149
  SourceMonitor is released under the [MIT License](MIT-LICENSE).
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.2
data/docs/deployment.md CHANGED
@@ -60,7 +60,7 @@ Keep this guide alongside your platform runbooks so teams can confidently deploy
60
60
 
61
61
  ## Container Reference Stack
62
62
 
63
- The repository ships a reusable Docker stack under `examples/docker` that mirrors the recommended process model. It builds a Ruby 3.3 image with Node, mounts your generated example via `APP_PATH`, and launches three services (`web`, `worker`, `scheduler`) alongside Postgres and Redis. Use it to trial production settings locally or as a baseline for ECS/Kubernetes manifests.
63
+ The repository ships a reusable Docker stack under `examples/docker` that mirrors the recommended process model. It builds a Ruby 4.0 image with Node, mounts your generated example via `APP_PATH`, and launches three services (`web`, `worker`, `scheduler`) alongside Postgres and Redis. Use it to trial production settings locally or as a baseline for ECS/Kubernetes manifests.
64
64
 
65
65
  ## Setup Workflow Rollout Checklist
66
66
 
data/docs/setup.md CHANGED
@@ -6,8 +6,8 @@ This guide consolidates the new guided installer, verification commands, and rol
6
6
 
7
7
  | Requirement | Minimum | Notes |
8
8
  | --- | --- | --- |
9
- | Ruby | 3.4.4 | Use rbenv and match the engine's `.ruby-version`. |
10
- | Rails | 8.0.2.1 | Run `bin/rails about` inside the host to confirm. |
9
+ | Ruby | 4.0.1 | Use rbenv and match the engine's `.ruby-version`. |
10
+ | Rails | 8.1.2 | Run `bin/rails about` inside the host to confirm. |
11
11
  | PostgreSQL | 14+ | Required for Solid Queue tables and item storage. |
12
12
  | Node.js | 18+ | Needed for Tailwind/esbuild assets when the host owns node tooling. |
13
13
  | Background jobs | Solid Queue (>= 0.3, < 3.0) | Add `solid_queue` to the host Gemfile if not present. |
@@ -18,8 +18,8 @@ This guide consolidates the new guided installer, verification commands, and rol
18
18
  Run these commands inside your host Rails application before invoking the guided workflow:
19
19
 
20
20
  ```bash
21
- bundle add source_monitor --version "~> 0.1.2"
22
- # or add gem "source_monitor", "~> 0.1.2" to Gemfile manually
21
+ bundle add source_monitor --version "~> 0.3.1"
22
+ # or add gem "source_monitor", "~> 0.3.1" to Gemfile manually
23
23
  bundle install
24
24
  ```
25
25
 
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "pathname"
5
+
6
+ module SourceMonitor
7
+ module Setup
8
+ class SkillsInstaller
9
+ SM_SKILL_PATTERN = "sm-*"
10
+
11
+ CONSUMER_SKILLS = %w[
12
+ sm-host-setup sm-configure sm-scraper-adapter
13
+ sm-event-handler sm-model-extension sm-dashboard-widget
14
+ ].freeze
15
+
16
+ CONTRIBUTOR_SKILLS = %w[
17
+ sm-domain-model sm-architecture sm-engine-test
18
+ sm-configuration-setting sm-pipeline-stage sm-engine-migration
19
+ sm-job sm-health-rule
20
+ ].freeze
21
+
22
+ def initialize(gem_root: nil, output: $stdout)
23
+ @gem_root = Pathname.new(gem_root || resolve_gem_root)
24
+ @output = output
25
+ end
26
+
27
+ def install(target_dir:, group: :consumer)
28
+ target = Pathname.new(target_dir)
29
+ result = { installed: [], skipped: [] }
30
+
31
+ source_skills_dir = gem_root.join(".claude", "skills")
32
+ return result unless source_skills_dir.directory?
33
+
34
+ skill_dirs = Dir[source_skills_dir.join(SM_SKILL_PATTERN).to_s].sort
35
+ return result if skill_dirs.empty?
36
+
37
+ allowed = skills_for_group(group)
38
+ skill_dirs = skill_dirs.select { |path| allowed.include?(File.basename(path)) }
39
+ return result if skill_dirs.empty?
40
+
41
+ FileUtils.mkdir_p(target.to_s)
42
+
43
+ skill_dirs.each do |source_path|
44
+ skill_name = File.basename(source_path)
45
+ dest_path = target.join(skill_name)
46
+
47
+ if dest_path.directory?
48
+ result[:skipped] << skill_name
49
+ else
50
+ FileUtils.cp_r(source_path, dest_path.to_s)
51
+ result[:installed] << skill_name
52
+ end
53
+ end
54
+
55
+ result
56
+ end
57
+
58
+ def remove(target_dir:)
59
+ target = Pathname.new(target_dir)
60
+ result = { removed: [] }
61
+
62
+ return result unless target.directory?
63
+
64
+ Dir[target.join(SM_SKILL_PATTERN).to_s].sort.each do |path|
65
+ skill_name = File.basename(path)
66
+ FileUtils.rm_rf(path)
67
+ result[:removed] << skill_name
68
+ end
69
+
70
+ result
71
+ end
72
+
73
+ private
74
+
75
+ attr_reader :gem_root, :output
76
+
77
+ def skills_for_group(group)
78
+ case group
79
+ when :consumer then CONSUMER_SKILLS
80
+ when :contributor then CONTRIBUTOR_SKILLS
81
+ when :all then CONSUMER_SKILLS + CONTRIBUTOR_SKILLS
82
+ else raise ArgumentError, "Unknown skill group: #{group.inspect}. Use :consumer, :contributor, or :all"
83
+ end
84
+ end
85
+
86
+ def resolve_gem_root
87
+ spec = Gem.loaded_specs["source_monitor"]
88
+ return spec.gem_dir if spec
89
+
90
+ File.expand_path("../../..", __dir__)
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "pathname"
4
+ require_relative "skills_installer"
4
5
 
5
6
  module SourceMonitor
6
7
  module Setup
@@ -35,7 +36,8 @@ module SourceMonitor
35
36
  migration_installer: MigrationInstaller.new,
36
37
  initializer_patcher: InitializerPatcher.new,
37
38
  devise_detector: method(:default_devise_detector),
38
- verifier: Verification::Runner.new
39
+ verifier: Verification::Runner.new,
40
+ skills_installer: SkillsInstaller.new
39
41
  )
40
42
  @dependency_checker = dependency_checker
41
43
  @prompter = prompter
@@ -47,6 +49,7 @@ module SourceMonitor
47
49
  @initializer_patcher = initializer_patcher
48
50
  @devise_detector = devise_detector
49
51
  @verifier = verifier
52
+ @skills_installer = skills_installer
50
53
  end
51
54
 
52
55
  def run
@@ -67,6 +70,13 @@ module SourceMonitor
67
70
  end
68
71
 
69
72
  verifier.call
73
+
74
+ if prompter.yes?("Install Claude Code skills for using SourceMonitor?", default: true)
75
+ skills_installer.install(target_dir: skills_target_dir, group: :consumer)
76
+ if prompter.yes?("Also install contributor skills for engine development?", default: false)
77
+ skills_installer.install(target_dir: skills_target_dir, group: :contributor)
78
+ end
79
+ end
70
80
  end
71
81
 
72
82
  private
@@ -80,7 +90,12 @@ module SourceMonitor
80
90
  :migration_installer,
81
91
  :initializer_patcher,
82
92
  :devise_detector,
83
- :verifier
93
+ :verifier,
94
+ :skills_installer
95
+
96
+ def skills_target_dir
97
+ File.join(Dir.pwd, ".claude", "skills")
98
+ end
84
99
 
85
100
  def devise_available?
86
101
  !!devise_detector.call
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SourceMonitor
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.2"
5
5
  end
@@ -38,4 +38,62 @@ namespace :source_monitor do
38
38
  end
39
39
  end
40
40
  end
41
+
42
+ namespace :skills do
43
+ desc "Install consumer Claude Code skills for using SourceMonitor"
44
+ task :install do
45
+ require "source_monitor/setup/skills_installer"
46
+
47
+ install_skills(group: :consumer)
48
+ end
49
+
50
+ desc "Install contributor Claude Code skills for engine development"
51
+ task :contributor do
52
+ require "source_monitor/setup/skills_installer"
53
+
54
+ install_skills(group: :contributor)
55
+ end
56
+
57
+ desc "Install all Claude Code skills (consumer + contributor)"
58
+ task :all do
59
+ require "source_monitor/setup/skills_installer"
60
+
61
+ install_skills(group: :all)
62
+ end
63
+
64
+ desc "Remove Source Monitor Claude Code skills from host project"
65
+ task :remove do
66
+ require "source_monitor/setup/skills_installer"
67
+
68
+ target_dir = File.join(Dir.pwd, ".claude", "skills")
69
+ installer = SourceMonitor::Setup::SkillsInstaller.new
70
+
71
+ result = installer.remove(target_dir:)
72
+
73
+ if result[:removed].any?
74
+ puts "Removed skills: #{result[:removed].join(', ')}" # rubocop:disable Rails/Output
75
+ else
76
+ puts "No sm-* skills found to remove." # rubocop:disable Rails/Output
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def install_skills(group:)
83
+ target_dir = File.join(Dir.pwd, ".claude", "skills")
84
+ installer = SourceMonitor::Setup::SkillsInstaller.new
85
+
86
+ result = installer.install(target_dir:, group:)
87
+
88
+ if result[:installed].any?
89
+ puts "Installed skills: #{result[:installed].join(', ')}" # rubocop:disable Rails/Output
90
+ end
91
+
92
+ if result[:skipped].any?
93
+ puts "Skipped (already installed): #{result[:skipped].join(', ')}" # rubocop:disable Rails/Output
94
+ end
95
+
96
+ if result[:installed].empty? && result[:skipped].empty?
97
+ puts "No sm-* skills found in the source_monitor gem." # rubocop:disable Rails/Output
98
+ end
41
99
  end
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  end
28
28
  end
29
29
  spec.files += [ "CHANGELOG.md" ].select { |path| File.exist?(File.join(__dir__, path)) }
30
+ spec.files += Dir[".claude/skills/sm-*/**/*"]
30
31
  spec.files.uniq!
31
32
 
32
33
  spec.require_paths = [ "lib" ]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: source_monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - dchuk
@@ -294,6 +294,42 @@ files:
294
294
  - ".claude/skills/rails-presenter/SKILL.md"
295
295
  - ".claude/skills/rails-query-object/SKILL.md"
296
296
  - ".claude/skills/rails-service-object/SKILL.md"
297
+ - ".claude/skills/sm-architecture/SKILL.md"
298
+ - ".claude/skills/sm-architecture/reference/extraction-patterns.md"
299
+ - ".claude/skills/sm-architecture/reference/module-map.md"
300
+ - ".claude/skills/sm-configuration-setting/SKILL.md"
301
+ - ".claude/skills/sm-configuration-setting/reference/settings-catalog.md"
302
+ - ".claude/skills/sm-configuration-setting/reference/settings-pattern.md"
303
+ - ".claude/skills/sm-configure/SKILL.md"
304
+ - ".claude/skills/sm-configure/reference/configuration-reference.md"
305
+ - ".claude/skills/sm-dashboard-widget/SKILL.md"
306
+ - ".claude/skills/sm-dashboard-widget/reference/dashboard-patterns.md"
307
+ - ".claude/skills/sm-domain-model/SKILL.md"
308
+ - ".claude/skills/sm-domain-model/reference/model-graph.md"
309
+ - ".claude/skills/sm-domain-model/reference/table-structure.md"
310
+ - ".claude/skills/sm-engine-migration/SKILL.md"
311
+ - ".claude/skills/sm-engine-migration/reference/migration-conventions.md"
312
+ - ".claude/skills/sm-engine-test/SKILL.md"
313
+ - ".claude/skills/sm-engine-test/reference/test-helpers.md"
314
+ - ".claude/skills/sm-engine-test/reference/test-patterns.md"
315
+ - ".claude/skills/sm-event-handler/SKILL.md"
316
+ - ".claude/skills/sm-event-handler/reference/events-api.md"
317
+ - ".claude/skills/sm-health-rule/SKILL.md"
318
+ - ".claude/skills/sm-health-rule/reference/health-system.md"
319
+ - ".claude/skills/sm-host-setup/SKILL.md"
320
+ - ".claude/skills/sm-host-setup/reference/initializer-template.md"
321
+ - ".claude/skills/sm-host-setup/reference/setup-checklist.md"
322
+ - ".claude/skills/sm-job/SKILL.md"
323
+ - ".claude/skills/sm-job/reference/job-conventions.md"
324
+ - ".claude/skills/sm-model-extension/SKILL.md"
325
+ - ".claude/skills/sm-model-extension/reference/extension-api.md"
326
+ - ".claude/skills/sm-pipeline-stage/SKILL.md"
327
+ - ".claude/skills/sm-pipeline-stage/reference/completion-handlers.md"
328
+ - ".claude/skills/sm-pipeline-stage/reference/entry-processing.md"
329
+ - ".claude/skills/sm-pipeline-stage/reference/feed-fetcher-architecture.md"
330
+ - ".claude/skills/sm-scraper-adapter/SKILL.md"
331
+ - ".claude/skills/sm-scraper-adapter/reference/adapter-contract.md"
332
+ - ".claude/skills/sm-scraper-adapter/reference/example-adapter.md"
297
333
  - ".claude/skills/solid-queue-setup/SKILL.md"
298
334
  - ".claude/skills/tdd-cycle/SKILL.md"
299
335
  - ".claude/skills/viewcomponent-patterns/SKILL.md"
@@ -359,6 +395,7 @@ files:
359
395
  - MIT-LICENSE
360
396
  - README.md
361
397
  - Rakefile
398
+ - VERSION
362
399
  - app/assets/builds/.keep
363
400
  - app/assets/builds/source_monitor/application.css
364
401
  - app/assets/builds/source_monitor/application.js
@@ -606,6 +643,7 @@ files:
606
643
  - lib/source_monitor/setup/prompter.rb
607
644
  - lib/source_monitor/setup/requirements.rb
608
645
  - lib/source_monitor/setup/shell_runner.rb
646
+ - lib/source_monitor/setup/skills_installer.rb
609
647
  - lib/source_monitor/setup/verification/action_cable_verifier.rb
610
648
  - lib/source_monitor/setup/verification/printer.rb
611
649
  - lib/source_monitor/setup/verification/result.rb