activeadmin-command_palette 0.1.6

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 (33) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +51 -0
  3. data/CODE_OF_CONDUCT.md +26 -0
  4. data/CONTRIBUTING.md +23 -0
  5. data/GOVERNANCE.md +25 -0
  6. data/LICENSE.md +21 -0
  7. data/README.md +152 -0
  8. data/SECURITY.md +25 -0
  9. data/activeadmin-command_palette.gemspec +68 -0
  10. data/app/assets/controllers/activeadmin_command_palette/command_palette_controller.js +817 -0
  11. data/app/controllers/active_admin/command_palette/options_controller.rb +61 -0
  12. data/app/views/active_admin/command_palette/_palette.html.erb +45 -0
  13. data/config/locales/activeadmin_command_palette.en.yml +21 -0
  14. data/config/locales/activeadmin_command_palette.fi.yml +21 -0
  15. data/config/locales/activeadmin_command_palette.sv.yml +21 -0
  16. data/config/polyrun_coverage.yml +8 -0
  17. data/config/routes.rb +7 -0
  18. data/lib/activeadmin/command_palette/catalog.rb +184 -0
  19. data/lib/activeadmin/command_palette/compiler.rb +159 -0
  20. data/lib/activeadmin/command_palette/configuration.rb +148 -0
  21. data/lib/activeadmin/command_palette/dsl.rb +13 -0
  22. data/lib/activeadmin/command_palette/engine.rb +67 -0
  23. data/lib/activeadmin/command_palette/finder.rb +103 -0
  24. data/lib/activeadmin/command_palette/helper.rb +136 -0
  25. data/lib/activeadmin/command_palette/integration.rb +17 -0
  26. data/lib/activeadmin/command_palette/resource_config.rb +52 -0
  27. data/lib/activeadmin/command_palette/resource_dsl.rb +47 -0
  28. data/lib/activeadmin/command_palette/resource_methods.rb +11 -0
  29. data/lib/activeadmin/command_palette/url_helpers.rb +22 -0
  30. data/lib/activeadmin/command_palette/version.rb +7 -0
  31. data/lib/activeadmin/command_palette.rb +38 -0
  32. data/sig/activeadmin/command_palette.rbs +5 -0
  33. metadata +392 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 509b73ad390b1fe9b43d2cb712f41afbccdd52af79a47ab7ab65121bd93d82ef
4
+ data.tar.gz: d897245191a9056ff09d22cba322831a7ec2f8808ad2a44a2dea305dc205ba75
5
+ SHA512:
6
+ metadata.gz: a74e1279e40fe8a1030fb2473b0d0b9af28f868a36147c946c0fb116cd6599fdaddecd5f3db0e869ff1b167c251c909980ad5f15ddc70b0ea206c28bdbe4ba47
7
+ data.tar.gz: 0d49f774e833e14eab01da3f44fae9cfc6644149a2179a1e45cbcfafa4e4b49051e5c32baf9c993a4e6d7985f2929a4444ae1b179f0a3b7f77ed25b2840b3406
data/CHANGELOG.md ADDED
@@ -0,0 +1,51 @@
1
+ # CHANGELOG
2
+
3
+ ## Unreleased
4
+
5
+ ## 0.1.6
6
+
7
+ - Publish as `activeadmin-command_palette` so Bundler requires `activeadmin/command_palette` by default; yank mistaken `activeadmin-command-palette` 0.1.6.
8
+ - Require ActiveAdmin 4.0.0.beta23 or newer.
9
+ - Keep kind labels on result rows as plain text instead of filled chips inside the panel.
10
+ - Send finder queries in CSRF-protected request bodies and combine multi-kind search into one bounded request.
11
+ - Refuse executable navigation URLs and cross-origin mutating actions.
12
+ - Announce asynchronous search states to assistive technology and preserve fragments in prefilled create links.
13
+ - Run JavaScript behavior tests in CI and release checks; reject releases from a dirty Git worktree.
14
+ - Finder options may include `detail` and `keywords`; `subtitle` maps to `detail`.
15
+ - Navigate crumbs become keywords; local filter matches label, detail, kind, and keywords with substring or fuzzy subsequence.
16
+ - Longer query prefixes win; results show a detail line and kind section headers; Enter activates the only remaining item when nothing is highlighted.
17
+
18
+ ## 0.1.5
19
+
20
+ - Rename the gem to `activeadmin-command_palette` so Bundler loads `activeadmin/command_palette` by default.
21
+
22
+ ## 0.1.4
23
+
24
+ - Resource DSL: `command_palette` in `ActiveAdmin.register` with `find_by`, `actions`, `create`, and `member`.
25
+ - `reload!` compiles resource registrations into actions and finders via optional `default_finder`.
26
+ - Run `reload!` from ActiveAdmin `after_load` (not bare `to_prepare`) so compile sees loaded resources.
27
+ - Action `if:` (boolean or view-context callable) omits the action from the request payload when false.
28
+
29
+ ## 0.1.3
30
+
31
+ - Allow `put` with confirm; interpolate `%{record_param}` / `%{resource}` in `url` and `query`.
32
+ - Support explicit empty `path_args` for member actions that open collection routes with query.
33
+
34
+ ## 0.1.2
35
+
36
+ - Contextual actions: `scope`, `when`, `resource`, `verb`, `params`, `help`, `finder_kind`.
37
+ - Allow `delete` with confirm; submit via POST `_method=delete`.
38
+ - Emit page `context` for member/collection gating; include view actions without a URL.
39
+ - Client: filter by context, view enters kind find, create merges optional query params and shows help.
40
+
41
+ ## 0.1.1
42
+
43
+ - Clear selection during debounce, abort stale fetches, and show loading, error, and sign-in states instead of empty matches.
44
+ - Require non-empty `confirm` for POST actions; allow only `get` and `post`.
45
+ - Keep recent items in `sessionStorage` for navigate/action destinations only.
46
+ - Expose combobox/`aria-activedescendant` state on the palette input.
47
+
48
+ ## 0.1.0
49
+
50
+ - Initial local package: Cmd+K palette shell, menu catalog, allow-listed actions, host finder protocol, and JSON options endpoint.
51
+ - Locale files for English, Finnish, and Swedish.
@@ -0,0 +1,26 @@
1
+ # Code of Conduct
2
+
3
+ ## Pledge
4
+
5
+ Participation is a harassment-free experience. Treat each other with respect. Keep private context private.
6
+
7
+ ## Expected behavior
8
+
9
+ - Engage with genuine curiosity. Admit uncertainty.
10
+ - Own every line you submit, including generated code.
11
+ - Correct errors politely.
12
+ - Use language that welcomes people and respects identity and privacy.
13
+
14
+ ## Unacceptable behavior
15
+
16
+ - Harassment, trolling, or insulting comments, public or private.
17
+ - Using jargon or volume, including automated spam, to silence others.
18
+ - Sharing others' data or personal context without permission.
19
+
20
+ ## Automation
21
+
22
+ You remain responsible for bugs, security holes, and bias in generated artifacts you submit.
23
+
24
+ ## Enforcement
25
+
26
+ Report abusive or harassing behavior to contact@kiskolabs.com. Reports are reviewed and investigated.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,23 @@
1
+ # Contributing Guidelines
2
+
3
+ ## Automation authorship
4
+
5
+ You may use AI and automation tools. You remain the author of every line you submit: review, debug, and understand the change.
6
+
7
+ Keep pull requests small enough to review. Annotate non-obvious logic.
8
+
9
+ Never send project secrets or private context to public models.
10
+
11
+ ## How to contribute
12
+
13
+ ### Reporting issues
14
+
15
+ Verify the facts before filing. Use issue templates for goals, constraints, and reproduction steps.
16
+
17
+ ### Pull requests
18
+
19
+ Keep one pull request to one goal. Explain why the change is needed. Run smoke tests and regression checks locally before opening the request.
20
+
21
+ ### Review
22
+
23
+ Reviewers will ask about approach and trade-offs. Treat suggested changes as part of the work.
data/GOVERNANCE.md ADDED
@@ -0,0 +1,25 @@
1
+ # Project Governance
2
+
3
+ ## Roles
4
+
5
+ ### Contributors
6
+
7
+ Anyone who submits code, documentation, or participates in discussions. Contributors take ownership of problems they identify and follow the project's quality standards.
8
+
9
+ ### Maintainers
10
+
11
+ Maintainers:
12
+
13
+ 1. Set scope and architectural direction.
14
+ 2. Review contributions (human or automated) against security and logic standards.
15
+ 3. Decide when the community is divided.
16
+
17
+ ## Decision making
18
+
19
+ ### Lazy consensus
20
+
21
+ For routine changes, a proposal that draws no objection within two weeks is approved.
22
+
23
+ ### Maintainer approval
24
+
25
+ Major architectural changes, high-risk automation integrations, or changes that affect business logic need explicit maintainer approval. A change must solve a real problem.
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 amkisko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # activeadmin-command_palette
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/activeadmin-command_palette.svg)](https://badge.fury.io/rb/activeadmin-command_palette) [![Test Status](https://github.com/amkisko/activeadmin-command_palette.rb/actions/workflows/test.yml/badge.svg)](https://github.com/amkisko/activeadmin-command_palette.rb/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/amkisko/activeadmin-command_palette.rb/graph/badge.svg)](https://app.codecov.io/github/amkisko/activeadmin-command_palette.rb)
4
+
5
+ Cmd+K / Ctrl+K command palette for ActiveAdmin 4.
6
+
7
+ Provides menu navigation, an allow-listed action catalog, and host-registered record finders. The gem does not know your domain models.
8
+
9
+ ## Requirements
10
+
11
+ - Ruby 3.4+ (CI matrix: Ruby 3.4 and 4.0)
12
+ - Rails 7.2+ (Rails 7.2 and 8.1 tested in CI)
13
+ - ActiveAdmin 4.0.0.beta23+ (Tailwind CSS v4 host build)
14
+ - importmap-rails
15
+
16
+ ## Install
17
+
18
+ Add the gem to your Gemfile:
19
+
20
+ ```ruby
21
+ gem "activeadmin-command_palette"
22
+ ```
23
+
24
+ Mount the engine inside your authenticated admin area:
25
+
26
+ ```ruby
27
+ authenticate :user do
28
+ mount ActiveAdmin::CommandPalette::Engine => "/admin/command_palette", as: "active_admin_command_palette"
29
+ end
30
+ ```
31
+
32
+ Wire the layout body controller and data attributes, render the palette partial, and add a header button that calls `show`.
33
+
34
+ Register finders and actions in an initializer or with the resource DSL.
35
+
36
+ Built-in UI locales: English (`en`), Finnish (`fi`), Swedish (`sv`).
37
+
38
+ ## Configuration
39
+
40
+ Prefer resource-level registration in `ActiveAdmin.register`:
41
+
42
+ ```ruby
43
+ ActiveAdmin.register User do
44
+ command_palette do
45
+ kind "user"
46
+ noun "user"
47
+ label_method :name_or_email
48
+ find_by :email, :nickname, :name
49
+ order :name
50
+ actions :view, :create, :edit, :destroy
51
+ create help: "Create user — optional email=", params: [
52
+ {name: "email", required: false, query_key: "user[email]"}
53
+ ]
54
+ member "Open in chat",
55
+ path: :admin_chat_path,
56
+ path_args: [],
57
+ query: {context_selector: "user:%{record_param}"},
58
+ if: -> { feature_enabled? }
59
+ end
60
+ end
61
+ ```
62
+
63
+ Host initializer keeps auth, prefixes, global shortcuts, and a `default_finder` that receives each resource registration:
64
+
65
+ ```ruby
66
+ ActiveAdmin::CommandPalette.configure do |config|
67
+ config.register_prefix "@", kind: "user"
68
+ config.search_kind_limit = 20
69
+ config.default_finder = lambda { |registration:, query:, helpers:, user:, limit:|
70
+ # return Array of { id:, kind:, label:, url:, detail?, keywords? }
71
+ }
72
+ config.actions = [
73
+ {id: "open-jobs", label: "Open jobs", url: "/admin/good_job"}
74
+ ]
75
+ config.authorize_with = ->(controller) { controller.current_user.present? }
76
+ end
77
+ ```
78
+
79
+ `reload!` (run from ActiveAdmin `after_load`) merges resource DSL actions/finders with the global `actions` list.
80
+
81
+ Action fields: `scope` (`global` / `collection` / `member`), `when` (`any` / `index` / `show` / `new` / `edit`), `resource`, `verb` (`view` / `create` / `edit` / `destroy` / …), `params`, `help`, `finder_kind`, `query`, `if` (boolean or callable evaluated in the view on each request), optional `detail` / `keywords`. The layout emits a page `context` value used to gate member and collection actions.
82
+
83
+ Finder rows may include optional `detail` (second line under the label; `subtitle` is accepted as an alias) and `keywords` (extra client match strings). Longer registered prefixes win when several share a start (for example `@team` before `@`).
84
+
85
+ ### Host finder recipe
86
+
87
+ Apply host authorization before returning rows. Prefer this match order when building SQL: exact primary key, then exact unique columns from `find_by`, then prefix match, then `ILIKE` / `LIKE`, then `limit`. Put a stable person-facing name in `label` and email, identifier, or id in `detail` when that helps operators disambiguate.
88
+
89
+ Mount the engine inside your authenticated admin boundary and set `authorize_with` so the JSON options endpoint stays closed to unsigned or unauthorized callers.
90
+
91
+ ### Related surfaces
92
+
93
+ Palette finders are a separate contract from admin GraphQL endpoints, ActiveAdmin controller finders, and form autocomplete. A host `default_finder` may use any backend; the palette still speaks the finder protocol above.
94
+
95
+ ## Limits
96
+
97
+ - Minimum query length: 2 (configurable)
98
+ - Maximum options per kind: 20 (configurable)
99
+ - Maximum finder kinds in a combined search: 20 (configurable)
100
+ - Client debounce: 200ms
101
+ - The client sends finder queries as CSRF-protected JSON `POST` requests; `GET` remains available for existing integrations
102
+ - Finder responses use `Cache-Control: no-store`, and the engine filters `q` from Rails parameter logs
103
+ - Action methods are allow-listed to `get`, `post`, `put`, and `delete`
104
+ - `POST`, `PUT`, and `DELETE` registrations require non-empty `confirm` text; the client also refuses those methods without confirmation
105
+ - Member actions may set `path_args: []` and a `query` hash with `%{record_param}` placeholders
106
+ - Recent items use `sessionStorage` and store only static navigate/action GET destinations (not member actions)
107
+ - Local navigate and action filter matches label, detail, kind, and keywords (substring or character subsequence)
108
+
109
+ ## Development
110
+
111
+ ```bash
112
+ bundle install
113
+ bundle exec appraisal install
114
+ make lint
115
+ make test
116
+ ```
117
+
118
+ `make lint` runs Biome (`npx @biomejs/biome@2.3.8`, same version as Trunk) on JavaScript under `app/assets`, plus RuboCop and RBS. `make test` also runs the JavaScript behavior suite. See `spec/README.md` for focused runs and coverage notes.
119
+
120
+ Release:
121
+
122
+ ```bash
123
+ make release
124
+ ```
125
+
126
+ ## Design RFCs
127
+
128
+ Numbered design documents for the public contract live in [`rfcs/`](rfcs/README.md). Shipped features are specified in RFC 0003 through RFC 0006. Finder detail and bounded POST search are proposed in RFC 0007 and RFC 0008. Process rules are RFC 0001.
129
+
130
+ ## Links
131
+
132
+ - [GitHub](https://github.com/amkisko/activeadmin-command_palette.rb)
133
+ - [GitLab](https://gitlab.com/amkisko/activeadmin-command_palette.rb)
134
+ - [RubyGems](https://rubygems.org/gems/activeadmin-command_palette)
135
+ - [libraries.io](https://libraries.io/rubygems/activeadmin-command_palette)
136
+ - [Deps.dev](https://deps.dev/rubygems/activeadmin-command_palette)
137
+ - [SonarCloud](https://sonarcloud.io/project/overview?id=amkisko_activeadmin-command_palette.rb)
138
+ - [Snyk](https://snyk.io/test/github/amkisko/activeadmin-command_palette.rb)
139
+ - [Codecov](https://app.codecov.io/github/amkisko/activeadmin-command_palette.rb)
140
+ - [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/amkisko/activeadmin-command_palette.rb)
141
+
142
+ ## License
143
+
144
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
145
+
146
+ ## Sponsors
147
+
148
+ Sponsored by [Kisko Labs](https://www.kiskolabs.com).
149
+
150
+ <a href="https://www.kiskolabs.com">
151
+ <img src="kisko.svg" width="200" alt="Sponsored by Kisko Labs" />
152
+ </a>
data/SECURITY.md ADDED
@@ -0,0 +1,25 @@
1
+ # SECURITY
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ Email security details to: security@kiskolabs.com
6
+
7
+ Send the report only to that address. Include description, steps to reproduce, potential impact, and a suggested fix when you have one.
8
+
9
+ ### Response Timeline
10
+
11
+ - We will acknowledge receipt of your report.
12
+ - We will provide an initial assessment.
13
+ - We will keep you informed of our progress and resolution timeline.
14
+
15
+ ### Disclosure Policy
16
+
17
+ - We will work with you to understand and resolve the issue.
18
+ - We will credit you for the discovery unless you prefer to remain anonymous.
19
+ - We will publish a security advisory after the vulnerability is patched.
20
+ - We will coordinate public disclosure with you.
21
+
22
+ ## Automation Security
23
+
24
+ - Keep production credentials, API keys, and personal data out of prompts sent to third-party models or automation services.
25
+ - Verify automated dependencies.
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/activeadmin/command_palette/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "activeadmin-command_palette"
7
+ spec.version = ActiveAdmin::CommandPalette::VERSION
8
+ spec.authors = ["Andrei Makarov"]
9
+ spec.email = ["contact@kiskolabs.com"]
10
+
11
+ spec.summary = "Cmd+K command palette for ActiveAdmin 4"
12
+ spec.description = "Keyboard command palette for ActiveAdmin 4: menu navigation, registered actions, and host-defined record finders."
13
+ spec.license = "MIT"
14
+ spec.platform = Gem::Platform::RUBY
15
+ spec.required_ruby_version = ">= 3.4"
16
+
17
+ repository_url = "https://github.com/amkisko/activeadmin-command_palette.rb"
18
+
19
+ spec.homepage = repository_url
20
+ spec.metadata = {
21
+ "homepage_uri" => repository_url,
22
+ "source_code_uri" => "#{repository_url}/tree/main",
23
+ "changelog_uri" => "#{repository_url}/blob/main/CHANGELOG.md",
24
+ "bug_tracker_uri" => "#{repository_url}/issues",
25
+ "documentation_uri" => "#{repository_url}#readme",
26
+ "rubygems_mfa_required" => "true"
27
+ }
28
+
29
+ spec.files = Dir.chdir(__dir__) do
30
+ %w[
31
+ CHANGELOG.md
32
+ CODE_OF_CONDUCT.md
33
+ CONTRIBUTING.md
34
+ GOVERNANCE.md
35
+ LICENSE.md
36
+ README.md
37
+ SECURITY.md
38
+ activeadmin-command_palette.gemspec
39
+ ].select { |path| File.file?(path) } +
40
+ Dir["{app,config,lib,sig}/**/*"]
41
+ end
42
+
43
+ spec.require_paths = ["lib"]
44
+
45
+ spec.add_dependency "activeadmin", ">= 4.0.0.beta23", "< 5"
46
+ spec.add_dependency "importmap-rails"
47
+ spec.add_dependency "rails", ">= 7.2"
48
+
49
+ spec.add_development_dependency "appraisal", "~> 2"
50
+ spec.add_development_dependency "bundler", ">= 2"
51
+ spec.add_development_dependency "bundler-audit", "~> 0.9"
52
+ spec.add_development_dependency "factory_bot", "~> 6"
53
+ spec.add_development_dependency "polyrun", ">= 2.2.0"
54
+ spec.add_development_dependency "prosopite", "~> 2.0"
55
+ spec.add_development_dependency "rake", "~> 13"
56
+ spec.add_development_dependency "rbs", "~> 4"
57
+ spec.add_development_dependency "rspec", "~> 3"
58
+ spec.add_development_dependency "rspec-rails", ">= 6"
59
+ spec.add_development_dependency "rubocop-rails", "~> 2.34"
60
+ spec.add_development_dependency "rubocop-rspec", "~> 3.8"
61
+ spec.add_development_dependency "rubocop-thread_safety", "~> 0.7"
62
+ spec.add_development_dependency "sqlite3", ">= 2.9.6"
63
+ spec.add_development_dependency "standard", "~> 1.52"
64
+ spec.add_development_dependency "standard-custom", "~> 1.0"
65
+ spec.add_development_dependency "standard-performance", "~> 1.8"
66
+ spec.add_development_dependency "standard-rails", "~> 1.5"
67
+ spec.add_development_dependency "standard-rspec", "~> 0.3"
68
+ end