command_deck 0.1.2 → 0.2.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: 2f79a2f12ff19b218e7b02e3269ebaff3a283bc3772cdedeaffe829a7e3c9adc
4
- data.tar.gz: 0b76ee1ba7f39d8b3a8a781ec33aefe32efdd9e5b66edcfced9e9fc77ea8dcfb
3
+ metadata.gz: 2d7607e2931f95aa4dfd89508fce37ab2d9b769c4e5463692d9a6d1a8e420861
4
+ data.tar.gz: 8efb1447f274e41cb071524d92e2e718349fe0b90dd32124db4e6daa60fcfb8f
5
5
  SHA512:
6
- metadata.gz: 64a99c105eb4dbce276c748aca3781dbe8f74e5bec7b7ab6073e141a7e7fceac5680bfc4e8f67f1aaac25e2642914ef4d6d7df7e0d0e597614836326f652ec25
7
- data.tar.gz: d9ce128531b79674de1d8125995969bf8d4e12df619e7b03aa52a569760f204d7a38fcc28e5cdce5604d9ae8b43fe82e2867a3e972724ddebfe9f5d71b2750b4
6
+ metadata.gz: ded56cf9f23174bdc5406d70ec1bf66788706708aae8edc84c8af9f87882f6ec6bd728b62c5f511eb9139776822a6a8645d9548b71145920bd6f073c9d3079e6
7
+ data.tar.gz: 20bcfcca9de31c7da07fb6b36630bd6dd7b1151cc1eda6c89d45332b55c5ff2a1169a8a774fa57e7128fe034719983d6c1c0f6c86e831fb504682012b5aa9ef9
data/.rubocop.yml CHANGED
@@ -1,3 +1,7 @@
1
+ plugins:
2
+ - rubocop-minitest
3
+ - rubocop-rake
4
+
1
5
  AllCops:
2
6
  TargetRubyVersion: 3.0
3
7
  NewCops: enable
data/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## [0.2.0] - 2025-10-09
4
+
5
+ ### Breaking Changes
6
+
7
+ - Panels must now be defined as classes inheriting from `CommandDeck::BasePanel`
8
+ - Panel files define `Panels::*` constants (not `CommandDeck::Panels::*`)
9
+ - Middleware is no longer automatically injected (must be added manually in `config/application.rb`)
10
+
11
+ ### Added
12
+
13
+ - Full Rails autoloading and Zeitwerk compatibility
14
+ - Proper class-based panel architecture
15
+ - Automatic panel registration via `BasePanel.inherited` hook
16
+
17
+ ### Changed
18
+
19
+ - Consolidated Railtie into Engine for simpler initialization
20
+ - Panels namespace changed: `app/command_deck/panels/global.rb` → `Panels::Global`
21
+ - Cleaner, self-documenting code architecture
22
+
23
+ ### Fixed
24
+
25
+ - Middleware stack freezing conflicts with other gems (Bullet, etc.)
26
+ - CI/test environment compatibility
27
+ - Zeitwerk constant resolution errors
28
+
29
+ ## [0.1.3] - 2025-09-23
30
+
31
+ - Unchilenizes the README file
32
+
3
33
  ## [0.1.2] - 2025-09-11
4
34
 
5
35
  ### Added
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,63 @@
1
+ # Contributing to Command Deck
2
+
3
+ Thank you for considering contributing to Command Deck!
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/crow-rojas/command_deck.git
9
+ cd command_deck
10
+ bundle install
11
+ ```
12
+
13
+ ## Running Tests
14
+
15
+ ```bash
16
+ bundle exec rake test
17
+ ```
18
+
19
+ ## Code Style
20
+
21
+ We use RuboCop for code style enforcement:
22
+
23
+ ```bash
24
+ bundle exec rubocop
25
+ ```
26
+
27
+ Fix auto-correctable issues:
28
+
29
+ ```bash
30
+ bundle exec rubocop -A
31
+ ```
32
+
33
+ ## Making Changes
34
+
35
+ 1. Fork the repository
36
+ 2. Create a feature branch (`git checkout -b my-feature`)
37
+ 3. Make your changes
38
+ 4. Add tests for new functionality
39
+ 5. Ensure all tests pass
40
+ 6. Run RuboCop and fix any offenses
41
+ 7. Commit your changes (`git commit -am 'Add feature'`)
42
+ 8. Push to your branch (`git push origin my-feature`)
43
+ 9. Create a Pull Request
44
+
45
+ ## Pull Request Guidelines
46
+
47
+ - Keep changes focused and atomic
48
+ - Update CHANGELOG.md with your changes
49
+ - Update README.md if adding new features
50
+ - Ensure backward compatibility when possible
51
+ - Add tests for bug fixes and new features
52
+ - Follow existing code style
53
+
54
+ ## Reporting Issues
55
+
56
+ - Use the GitHub issue tracker
57
+ - Include Ruby and Rails versions
58
+ - Provide steps to reproduce
59
+ - Include relevant code samples
60
+
61
+ ## Questions?
62
+
63
+ Feel free to open an issue for questions or discussions.
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Command Deck
2
2
 
3
- Command Deck is a tiny, dev-only Rails engine that gives you a floating panel to run custom actions and quick admin tasks without opening Rails console.
3
+ Convenient, unobtrusive, dev-oriented Rails engine that allows you to run custom actions and quick admin tasks through a floating panel without opening the Rails console.
4
4
 
5
- You define panels/tabs/actions in a minimal DSL. Each action can declare a few params (text, boolean, number, selector), run Ruby code, and return a JSON-ish result shown in the UI.
5
+ Define panels/tabs/actions with a minimal class-based DSL. Each action can declare parameters (text, boolean, number, selector), run Ruby code, and return a JSON result shown in the UI.
6
+
7
+ ![Demo](public/img/demo.gif)
6
8
 
7
9
  ## Installation
8
10
 
@@ -11,79 +13,88 @@ Add the gem to your application:
11
13
  ```ruby
12
14
  # Gemfile (development only recommended)
13
15
  group :development do
14
- gem "command_deck"
16
+ gem 'command_deck'
15
17
  end
16
18
  ```
17
19
 
18
- Mount the engine (dev only):
20
+ Mount the engine:
19
21
 
20
22
  ```ruby
21
23
  # config/routes.rb
22
- if Rails.env.development?
23
- mount CommandDeck::Engine => "/command_deck"
24
- end
24
+ mount CommandDeck::Engine => '/command_deck' if Rails.env.development?
25
25
  ```
26
26
 
27
- Start your app and the floating panel should appear.
27
+ Add middleware to inject the floating panel:
28
28
 
29
- ## Define actions (DSL)
29
+ ```ruby
30
+ # config/application.rb
30
31
 
31
- Create Ruby files in `app/command_deck/**/*.rb`. Example:
32
+ module YourApp
33
+ class Application < Rails::Application
34
+ # ... other config ...
35
+
36
+ config.middleware.insert_after ActionDispatch::DebugExceptions, CommandDeck::Middleware if Rails.env.development?
37
+ end
38
+ end
39
+ ```
32
40
 
33
- ```ruby
34
- CommandDeck.panel "Utilities" do
35
- tab "Demo" do
36
- action "Greet", key: "utils.greet" do
37
- param :name, :string, label: "Your name", required: true
41
+ ## Define actions
38
42
 
39
- perform do |p, _ctx|
40
- { message: "Hello, #{p[:name]}!" }
41
- end
42
- end
43
+ Create panel classes in `app/command_deck/panels/*.rb`:
43
44
 
44
- action "Pick a Color", key: "utils.color" do
45
- # You can pass simple arrays, pairs, or hashes as choices
46
- param :color, :selector,
47
- options: [
48
- ["Red", "red"],
49
- ["Green", "green"],
50
- ["Blue", "blue"]
51
- ],
52
- include_blank: true
53
-
54
- perform do |p, _ctx|
55
- { chosen: p[:color] }
45
+ ```ruby
46
+ # app/command_deck/panels/utilities.rb
47
+ module Panels
48
+ class Utilities < CommandDeck::BasePanel
49
+ panel 'Utilities' do
50
+ tab 'Demo' do
51
+ action 'Greet', key: 'utils.greet' do
52
+ param :name, :string, label: 'Your name', required: true
53
+
54
+ perform do |p, _ctx|
55
+ { message: "Hello, #{p[:name]}!" }
56
+ end
57
+ end
58
+
59
+ action 'Pick a Color', key: 'utils.color' do
60
+ # You can pass simple arrays, pairs, or hashes as choices
61
+ param :color, :selector,
62
+ options: [
63
+ ['Red', 'red'],
64
+ ['Green', 'green'],
65
+ ['Blue', 'blue']
66
+ ],
67
+ include_blank: true
68
+
69
+ perform do |p, _ctx|
70
+ { chosen: p[:color] }
71
+ end
72
+ end
56
73
  end
57
74
  end
58
75
  end
59
76
  end
60
77
  ```
61
78
 
62
- This will create a panel called "Utilities" with a tab called "Demo" and two actions: "Greet" and "Pick a Color".
79
+ This creates a panel with a tab and two actions. File path matches constant: `app/command_deck/panels/utilities.rb` → `Panels::Utilities`
63
80
 
64
81
  ![Demo](public/img/demo.png)
65
82
 
66
83
  ## DSL API
67
84
 
68
- Define panels under `app/command_deck/**/*.rb`.
69
-
70
- ```ruby
71
- CommandDeck.panel(title, owner: nil, group: nil, key: nil) { ... }
72
- ```
73
-
74
- Inside a panel, define tabs:
85
+ Panels inherit from `CommandDeck::BasePanel`. Define tabs within a panel:
75
86
 
76
87
  ```ruby
77
88
  tab(title) { ... }
78
89
  ```
79
90
 
80
- Inside a tab, define actions:
91
+ Define actions within a tab:
81
92
 
82
93
  ```ruby
83
94
  action(title, key:) { ... }
84
95
  ```
85
96
 
86
- Inside an action, declare params and the code to run:
97
+ Declare params and execution logic within an action:
87
98
 
88
99
  ```ruby
89
100
  param(name, type, **opts)
@@ -110,17 +121,14 @@ Selector-specific options:
110
121
  - `return:` `:value` (default), `:label`, or `:both` (`{ label:, value: }`).
111
122
  - Choice shapes accepted:
112
123
  - Values: `%w[a b c]`
113
- - Pairs: `[["Label A", "a"], ["Label B", "b"]]`
124
+ - Pairs: `[['Label A', 'a'], ['Label B', 'b']]`
114
125
  - Objects: `{ label:, value:, meta?: { ... } }`
115
126
 
116
- Action execution:
117
-
118
- - The block `perform { |params, ctx| ... }` receives your coerced params and a context hash (reserved for future use).
119
- - Return any object serializable to JSON (Hash recommended) to show it in the UI.
127
+ The `perform` block receives coerced params and a context hash. Return any JSON-serializable object (Hash recommended).
120
128
 
121
129
  ## Security
122
130
 
123
- Command Deck is intended for development only. The engine mounts only in dev and skips CSRF by default. **DO NOT ENABLE IT IN PRODUCTION**.
131
+ Intended for development only. **DO NOT ENABLE IN PRODUCTION**.
124
132
 
125
133
  ## Development
126
134
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CommandDeck
4
+ # Base class for panel definitions.
5
+ #
6
+ # Example:
7
+ # module Panels
8
+ # class Global < CommandDeck::BasePanel
9
+ # panel "Global Tools" do
10
+ # tab "Update" do
11
+ # action "Do Something", key: "global.do_something" do
12
+ # perform { |params, ctx| { ok: true } }
13
+ # end
14
+ # end
15
+ # end
16
+ # end
17
+ # end
18
+ class BasePanel
19
+ class << self
20
+ def panel(title, **opts, &block)
21
+ @panel_definition = { title: title, opts: opts, block: block }
22
+ end
23
+
24
+ def register!
25
+ return unless @panel_definition
26
+
27
+ Registry.panel(
28
+ @panel_definition[:title],
29
+ **@panel_definition[:opts],
30
+ &@panel_definition[:block]
31
+ )
32
+ end
33
+
34
+ def inherited(subclass)
35
+ super
36
+ CommandDeck.register_panel_class(subclass)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -8,8 +8,12 @@ module CommandDeck
8
8
  class Engine < ::Rails::Engine
9
9
  isolate_namespace CommandDeck
10
10
 
11
+ initializer "command_deck.add_autoload_paths", before: :set_autoload_paths do |app|
12
+ panels_path = Rails.root.join("app/command_deck")
13
+ app.config.autoload_paths << panels_path.to_s if panels_path.exist?
14
+ end
15
+
11
16
  initializer "command_deck.mount_point" do
12
- # Default mount point. If the host app has a relative_url_root, respect it.
13
17
  mp = "/command_deck"
14
18
  if defined?(Rails) && Rails.application.config.respond_to?(:relative_url_root)
15
19
  root = Rails.application.config.relative_url_root
@@ -18,11 +22,20 @@ module CommandDeck
18
22
  CommandDeck::Middleware.mount_point = mp
19
23
  end
20
24
 
21
- initializer "command_deck.middleware" do |app|
22
- # Dev-only injection. Safe no-op in other environments.
23
- if defined?(Rails) && Rails.env.development?
24
- app.middleware.insert_after ActionDispatch::DebugExceptions, CommandDeck::Middleware
25
+ config.to_prepare do
26
+ next unless Rails.env.development?
27
+
28
+ CommandDeck::Registry.clear!
29
+
30
+ if defined?(Panels)
31
+ Panels.constants.each do |const_name|
32
+ Panels.const_get(const_name)
33
+ rescue NameError => e
34
+ Rails.logger.warn "[CommandDeck] Could not load panel: #{e.message}"
35
+ end
25
36
  end
37
+
38
+ CommandDeck.register_all_panels!
26
39
  end
27
40
  end
28
41
  end
@@ -96,8 +96,4 @@ module CommandDeck
96
96
  end
97
97
  end
98
98
  end
99
-
100
- def self.panel(title, ...)
101
- Registry.panel(title, ...)
102
- end
103
99
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CommandDeck
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/command_deck.rb CHANGED
@@ -3,12 +3,25 @@
3
3
  require_relative "command_deck/version"
4
4
  require "command_deck/registry"
5
5
  require "command_deck/executor"
6
+ require "command_deck/base_panel"
6
7
 
8
+ # Main module of the Command Deck gem
7
9
  module CommandDeck
8
10
  class Error < StandardError; end
9
- end
10
11
 
11
- if defined?(Rails)
12
- require "command_deck/railtie"
13
- require "command_deck/engine"
12
+ class << self
13
+ def panel_classes
14
+ @panel_classes ||= []
15
+ end
16
+
17
+ def register_panel_class(klass)
18
+ panel_classes << klass unless panel_classes.include?(klass)
19
+ end
20
+
21
+ def register_all_panels!
22
+ panel_classes.each(&:register!)
23
+ end
24
+ end
14
25
  end
26
+
27
+ require "command_deck/engine" if defined?(Rails)
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_deck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - crowrojas
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-09-11 00:00:00.000000000 Z
11
+ date: 2025-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '7.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '9.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,9 @@ dependencies:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '7.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '9.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: railties
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -31,6 +37,9 @@ dependencies:
31
37
  - - ">="
32
38
  - !ruby/object:Gem::Version
33
39
  version: '7.0'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '9.0'
34
43
  type: :runtime
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,8 +47,13 @@ dependencies:
38
47
  - - ">="
39
48
  - !ruby/object:Gem::Version
40
49
  version: '7.0'
41
- description: Command Deck is a tiny floating UI that allows you to run commands in
42
- your Rails app.
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '9.0'
53
+ description: |
54
+ Command Deck is a Rails engine that provides a floating panel UI for running custom admin
55
+ actions and tasks without opening the Rails console. Define panels/tabs/actions with a
56
+ class-based DSL.
43
57
  email:
44
58
  - cristobal.rojasbrito@gmail.com
45
59
  executables: []
@@ -49,6 +63,7 @@ files:
49
63
  - ".rubocop.yml"
50
64
  - CHANGELOG.md
51
65
  - CODE_OF_CONDUCT.md
66
+ - CONTRIBUTING.md
52
67
  - LICENSE.txt
53
68
  - README.md
54
69
  - Rakefile
@@ -74,13 +89,14 @@ files:
74
89
  - lib/command_deck/assets/js/ui/overlay/theme_manager.js
75
90
  - lib/command_deck/assets/js/ui/panel_selector.js
76
91
  - lib/command_deck/assets/js/ui/settings_dropdown.js
92
+ - lib/command_deck/base_panel.rb
77
93
  - lib/command_deck/engine.rb
78
94
  - lib/command_deck/executor.rb
79
95
  - lib/command_deck/injector.rb
80
96
  - lib/command_deck/middleware.rb
81
- - lib/command_deck/railtie.rb
82
97
  - lib/command_deck/registry.rb
83
98
  - lib/command_deck/version.rb
99
+ - public/img/demo.gif
84
100
  - public/img/demo.png
85
101
  - sig/command_deck.rbs
86
102
  homepage: https://github.com/crow-rojas/command_deck
@@ -89,7 +105,7 @@ licenses:
89
105
  metadata:
90
106
  allowed_push_host: https://rubygems.org
91
107
  homepage_uri: https://github.com/crow-rojas/command_deck
92
- source_code_uri: https://github.com/crow-rojas/command_deck
108
+ source_code_uri: https://github.com/crow-rojas/command_deck/tree/master
93
109
  changelog_uri: https://github.com/crow-rojas/command_deck/blob/master/CHANGELOG.md
94
110
  rubygems_mfa_required: 'true'
95
111
  post_install_message:
@@ -110,6 +126,5 @@ requirements: []
110
126
  rubygems_version: 3.5.22
111
127
  signing_key:
112
128
  specification_version: 4
113
- summary: Command Deck is a tiny floating UI that allows you to run commands in your
114
- Rails app.
129
+ summary: Dev-oriented floating panel for running custom actions in Rails apps
115
130
  test_files: []
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rails/railtie"
4
-
5
- module CommandDeck
6
- # Rails engine for Command Deck
7
- class Railtie < ::Rails::Railtie
8
- initializer "command_deck.load_panels", after: :load_config_initializers do
9
- path = Rails.root.join("app/command_deck")
10
- Dir[path.join("**/*.rb")].each { |f| load f } if Dir.exist?(path)
11
- end
12
- end
13
- end