completion-kit 0.1.0.rc1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +192 -0
- data/Rakefile +12 -0
- data/app/assets/config/completion_kit_manifest.js +1 -0
- data/app/assets/config/manifest.js +3 -0
- data/app/assets/images/completion_kit/logo.svg +6 -0
- data/app/assets/javascripts/completion_kit/evaluation_steps_controller.js +25 -0
- data/app/assets/stylesheets/completion_kit/application.css +2214 -0
- data/app/controllers/completion_kit/api/v1/base_controller.rb +29 -0
- data/app/controllers/completion_kit/api/v1/criteria_controller.rb +62 -0
- data/app/controllers/completion_kit/api/v1/datasets_controller.rb +51 -0
- data/app/controllers/completion_kit/api/v1/metrics_controller.rb +51 -0
- data/app/controllers/completion_kit/api/v1/prompts_controller.rb +64 -0
- data/app/controllers/completion_kit/api/v1/provider_credentials_controller.rb +51 -0
- data/app/controllers/completion_kit/api/v1/responses_controller.rb +32 -0
- data/app/controllers/completion_kit/api/v1/runs_controller.rb +71 -0
- data/app/controllers/completion_kit/api_reference_controller.rb +9 -0
- data/app/controllers/completion_kit/application_controller.rb +31 -0
- data/app/controllers/completion_kit/criteria_controller.rb +67 -0
- data/app/controllers/completion_kit/datasets_controller.rb +53 -0
- data/app/controllers/completion_kit/mcp_controller.rb +57 -0
- data/app/controllers/completion_kit/metrics_controller.rb +52 -0
- data/app/controllers/completion_kit/prompts_controller.rb +69 -0
- data/app/controllers/completion_kit/provider_credentials_controller.rb +63 -0
- data/app/controllers/completion_kit/responses_controller.rb +44 -0
- data/app/controllers/completion_kit/runs_controller.rb +131 -0
- data/app/helpers/completion_kit/application_helper.rb +193 -0
- data/app/jobs/completion_kit/application_job.rb +4 -0
- data/app/jobs/completion_kit/generate_job.rb +12 -0
- data/app/jobs/completion_kit/judge_job.rb +12 -0
- data/app/jobs/completion_kit/model_discovery_job.rb +29 -0
- data/app/mailers/completion_kit/application_mailer.rb +6 -0
- data/app/models/completion_kit/application_record.rb +5 -0
- data/app/models/completion_kit/criteria.rb +22 -0
- data/app/models/completion_kit/criteria_membership.rb +20 -0
- data/app/models/completion_kit/dataset.rb +24 -0
- data/app/models/completion_kit/metric.rb +97 -0
- data/app/models/completion_kit/model.rb +13 -0
- data/app/models/completion_kit/prompt.rb +99 -0
- data/app/models/completion_kit/provider_credential.rb +114 -0
- data/app/models/completion_kit/response.rb +30 -0
- data/app/models/completion_kit/review.rb +28 -0
- data/app/models/completion_kit/run.rb +253 -0
- data/app/models/completion_kit/run_metric.rb +6 -0
- data/app/models/completion_kit/suggestion.rb +8 -0
- data/app/services/completion_kit/anthropic_client.rb +86 -0
- data/app/services/completion_kit/api_config.rb +80 -0
- data/app/services/completion_kit/csv_processor.rb +65 -0
- data/app/services/completion_kit/judge_service.rb +87 -0
- data/app/services/completion_kit/llm_client.rb +45 -0
- data/app/services/completion_kit/mcp_dispatcher.rb +53 -0
- data/app/services/completion_kit/mcp_tools/criteria.rb +106 -0
- data/app/services/completion_kit/mcp_tools/datasets.rb +90 -0
- data/app/services/completion_kit/mcp_tools/metrics.rb +98 -0
- data/app/services/completion_kit/mcp_tools/prompts.rb +112 -0
- data/app/services/completion_kit/mcp_tools/provider_credentials.rb +97 -0
- data/app/services/completion_kit/mcp_tools/responses.rb +45 -0
- data/app/services/completion_kit/mcp_tools/runs.rb +130 -0
- data/app/services/completion_kit/model_discovery_service.rb +223 -0
- data/app/services/completion_kit/ollama_client.rb +80 -0
- data/app/services/completion_kit/open_ai_client.rb +71 -0
- data/app/services/completion_kit/open_router_client.rb +69 -0
- data/app/services/completion_kit/prompt_improvement_service.rb +81 -0
- data/app/views/completion_kit/api_reference/_example.html.erb +6 -0
- data/app/views/completion_kit/api_reference/index.html.erb +308 -0
- data/app/views/completion_kit/criteria/_form.html.erb +46 -0
- data/app/views/completion_kit/criteria/edit.html.erb +14 -0
- data/app/views/completion_kit/criteria/index.html.erb +37 -0
- data/app/views/completion_kit/criteria/new.html.erb +13 -0
- data/app/views/completion_kit/criteria/show.html.erb +37 -0
- data/app/views/completion_kit/datasets/_form.html.erb +29 -0
- data/app/views/completion_kit/datasets/edit.html.erb +13 -0
- data/app/views/completion_kit/datasets/index.html.erb +38 -0
- data/app/views/completion_kit/datasets/new.html.erb +12 -0
- data/app/views/completion_kit/datasets/show.html.erb +45 -0
- data/app/views/completion_kit/metrics/_form.html.erb +72 -0
- data/app/views/completion_kit/metrics/edit.html.erb +13 -0
- data/app/views/completion_kit/metrics/index.html.erb +34 -0
- data/app/views/completion_kit/metrics/new.html.erb +12 -0
- data/app/views/completion_kit/metrics/show.html.erb +49 -0
- data/app/views/completion_kit/prompts/_form.html.erb +52 -0
- data/app/views/completion_kit/prompts/edit.html.erb +13 -0
- data/app/views/completion_kit/prompts/index.html.erb +46 -0
- data/app/views/completion_kit/prompts/new.html.erb +12 -0
- data/app/views/completion_kit/prompts/show.html.erb +156 -0
- data/app/views/completion_kit/provider_credentials/_discovery_status.html.erb +30 -0
- data/app/views/completion_kit/provider_credentials/_form.html.erb +71 -0
- data/app/views/completion_kit/provider_credentials/edit.html.erb +12 -0
- data/app/views/completion_kit/provider_credentials/index.html.erb +41 -0
- data/app/views/completion_kit/provider_credentials/new.html.erb +12 -0
- data/app/views/completion_kit/responses/show.html.erb +87 -0
- data/app/views/completion_kit/runs/_actions.html.erb +14 -0
- data/app/views/completion_kit/runs/_form.html.erb +159 -0
- data/app/views/completion_kit/runs/_progress.html.erb +18 -0
- data/app/views/completion_kit/runs/_response_row.html.erb +13 -0
- data/app/views/completion_kit/runs/_sort_toolbar.html.erb +8 -0
- data/app/views/completion_kit/runs/_status_header.html.erb +15 -0
- data/app/views/completion_kit/runs/edit.html.erb +14 -0
- data/app/views/completion_kit/runs/index.html.erb +43 -0
- data/app/views/completion_kit/runs/new.html.erb +12 -0
- data/app/views/completion_kit/runs/show.html.erb +79 -0
- data/app/views/completion_kit/runs/suggestion.html.erb +47 -0
- data/app/views/layouts/completion_kit/application.html.erb +77 -0
- data/config/routes.rb +55 -0
- data/db/migrate/20260311000001_create_completion_kit_tables.rb +87 -0
- data/db/migrate/20260326000001_rename_criteria_to_instruction_on_metrics_and_reviews.rb +6 -0
- data/db/migrate/20260327000001_add_progress_to_runs.rb +6 -0
- data/db/migrate/20260327100001_replace_criteria_with_direct_metrics_on_runs.rb +12 -0
- data/db/migrate/20260328000001_add_error_message_to_runs.rb +5 -0
- data/db/migrate/20260329000001_create_completion_kit_models.rb +20 -0
- data/db/migrate/20260401170001_add_discovery_columns_to_completion_kit_provider_credentials.rb +7 -0
- data/db/migrate/20260403000001_add_temperature_to_completion_kit_runs.rb +5 -0
- data/db/migrate/20260403000002_create_completion_kit_suggestions.rb +13 -0
- data/db/migrate/20260403000003_add_applied_at_to_completion_kit_suggestions.rb +5 -0
- data/lib/completion-kit.rb +1 -0
- data/lib/completion_kit/engine.rb +35 -0
- data/lib/completion_kit/version.rb +3 -0
- data/lib/completion_kit.rb +55 -0
- data/lib/generators/completion_kit/install_generator.rb +21 -0
- data/lib/generators/completion_kit/templates/README +20 -0
- data/lib/generators/completion_kit/templates/initializer.rb +43 -0
- metadata +361 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: cdecf15deb685a524186a2bd4ba48268e10475da0d2cc2914969318893268f70
|
|
4
|
+
data.tar.gz: ce395abf147434f9a825f79902e47b171b074038d20c06bf7b86b80ba70eaa00
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9d13fd1d1863c87ca0f7ed78eb1853ac921ff39862b84c678e5b5c9977f1832edcfb50c52b2371f2dc88ad6360be22a78d39ef53385239939a1ac9297df444ff
|
|
7
|
+
data.tar.gz: bf95df5b178ccfe455350d216a894836a85cfeff5c117d0206b87211ef638c1d690790350168b5a9ad84e8e3895add8c89acdea98738a1c0d2025115679d939f
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/homemade-software-inc/completion-kit/main/docs/logo.png" alt="CompletionKit logo" width="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# CompletionKit
|
|
6
|
+
|
|
7
|
+
[](https://github.com/homemade-software-inc/completion-kit/actions/workflows/ci.yml)
|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
[](https://github.com/homemade-software-inc/completion-kit/network/updates)
|
|
11
|
+
|
|
12
|
+
You need to know whether your prompts produce the output you expect, consistently, across real data. CompletionKit gives you that, inside your Rails app.
|
|
13
|
+
|
|
14
|
+
Mount the engine, bring your prompts and datasets, and every input runs through a model you pick. Each output is scored against your own metrics and rubrics by an LLM-as-judge. When you change a prompt, re-run the same dataset and see exactly what got better and what broke — and when the scores tell you something's off, CompletionKit can suggest an improved version of the prompt based on the reviews, which you inspect as a diff and apply as a new version.
|
|
15
|
+
|
|
16
|
+
Drive it from the web UI, from the REST API, or from Claude Code and other MCP-aware agents via the built-in Model Context Protocol server. All three share the same state — your prompts, runs, datasets, and scores are one source of truth.
|
|
17
|
+
|
|
18
|
+
It's the difference between "this prompt seems to work" and "this prompt scores 4.3 out of 5 across 200 inputs, up from 3.8 last version."
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
gem "completion-kit"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bin/rails generate completion_kit:install
|
|
34
|
+
bin/rails db:migrate
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Set your provider keys via environment variables or the generated initializer:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
OPENAI_API_KEY=...
|
|
41
|
+
ANTHROPIC_API_KEY=...
|
|
42
|
+
LLAMA_API_KEY=...
|
|
43
|
+
LLAMA_API_ENDPOINT=...
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Available models are discovered dynamically from each provider's API.
|
|
47
|
+
|
|
48
|
+
### Encryption keys
|
|
49
|
+
|
|
50
|
+
Provider API keys are stored using [Rails Active Record encryption](https://guides.rubyonrails.org/active_record_encryption.html), so the host app must have encryption keys configured. If you haven't set them up already:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bin/rails db:encryption:init
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Copy the generated keys into `config/credentials.yml.enc` under `active_record_encryption`, or set the equivalent environment variables. CompletionKit won't boot without valid keys in production.
|
|
57
|
+
|
|
58
|
+
## Authentication
|
|
59
|
+
|
|
60
|
+
CompletionKit requires authentication in production. In development, routes are open by default (with a log warning).
|
|
61
|
+
|
|
62
|
+
### Basic Auth (recommended for simple setups)
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
# config/initializers/completion_kit.rb
|
|
66
|
+
CompletionKit.configure do |c|
|
|
67
|
+
c.username = "admin"
|
|
68
|
+
c.password = ENV["COMPLETION_KIT_PASSWORD"]
|
|
69
|
+
end
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Custom Auth (Devise, etc.)
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
# config/initializers/completion_kit.rb
|
|
76
|
+
CompletionKit.configure do |c|
|
|
77
|
+
c.auth_strategy = ->(controller) { controller.authenticate_user! }
|
|
78
|
+
end
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Only one mode can be active — setting both raises a `ConfigurationError`.
|
|
82
|
+
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
1. Create a prompt with `{{variable}}` placeholders
|
|
86
|
+
2. Create a test run and paste CSV data (headers match variable names)
|
|
87
|
+
3. Generate outputs, run AI review, inspect scored results
|
|
88
|
+
|
|
89
|
+
## Programmatic access
|
|
90
|
+
|
|
91
|
+
CompletionKit exposes every resource through both a REST JSON API and an MCP server. Both share the same bearer-token auth, so configure once and use either interface:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
# config/initializers/completion_kit.rb
|
|
95
|
+
CompletionKit.configure { |c| c.api_token = ENV["COMPLETION_KIT_API_TOKEN"] }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Concepts
|
|
99
|
+
|
|
100
|
+
These are the objects you'll work with, whether through the UI, the REST API, or the MCP server:
|
|
101
|
+
|
|
102
|
+
- **Prompt** — A named, versioned template with `{{variable}}` placeholders. Publishing a prompt freezes its template so runs always reference a known version; editing a published prompt creates a new version.
|
|
103
|
+
- **Dataset** — A CSV of real inputs. Column headers match the prompt's `{{variable}}` names, and each row becomes one test case.
|
|
104
|
+
- **Run** — A single execution of a prompt against a dataset. Tracks progress, stores outputs, and records which metrics were used for scoring.
|
|
105
|
+
- **Response** — The model's output for one row of the dataset, with any reviews attached.
|
|
106
|
+
- **Metric** — One evaluation dimension: a name, an instruction, evaluation steps, and 1–5-star rubric bands. The judge uses a metric to score a response.
|
|
107
|
+
- **Criteria** — A named, reusable bundle of metrics you can apply to a run in one step.
|
|
108
|
+
- **Provider Credential** — An API key for a model provider (OpenAI, Anthropic, Ollama, OpenRouter). Encrypted at rest using Rails' Active Record encryption, and never returned through the API.
|
|
109
|
+
|
|
110
|
+
### REST API
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
curl -H "Authorization: Bearer $TOKEN" \
|
|
114
|
+
http://localhost:3000/completion_kit/api/v1/prompts
|
|
115
|
+
|
|
116
|
+
curl -X POST http://localhost:3000/completion_kit/api/v1/prompts \
|
|
117
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
118
|
+
-H "Content-Type: application/json" \
|
|
119
|
+
-d '{"name":"summarizer","template":"Summarize: {{text}}","llm_model":"gpt-4.1"}'
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Mount the engine, then visit **`/completion_kit/api_reference`** in your running app for per-endpoint documentation with copy-to-clipboard curl examples pre-filled with your token.
|
|
123
|
+
|
|
124
|
+
### MCP server
|
|
125
|
+
|
|
126
|
+
CompletionKit also runs a [Model Context Protocol](https://modelcontextprotocol.io) server at the `/mcp` path within the engine mount, exposing the same resources as 36 tools (one per CRUD action plus process actions like `runs_generate` and `prompts_publish`). Point Claude Code, Cursor, or any other MCP client at it:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"mcpServers": {
|
|
131
|
+
"completion-kit": {
|
|
132
|
+
"url": "https://your-app.com/completion_kit/mcp",
|
|
133
|
+
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The in-app API reference page also ships install snippets you can copy straight into your MCP client config.
|
|
140
|
+
|
|
141
|
+
## Standalone App
|
|
142
|
+
|
|
143
|
+
CompletionKit ships with a standalone Rails app you can deploy as a hosted service.
|
|
144
|
+
|
|
145
|
+
### Quick Start
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cd standalone
|
|
149
|
+
bundle install
|
|
150
|
+
bin/rails completion_kit:install:migrations
|
|
151
|
+
bin/rails db:migrate
|
|
152
|
+
bin/rails server
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Visit `http://localhost:3000` for the home page, or `http://localhost:3000/completion_kit` for the engine UI.
|
|
156
|
+
|
|
157
|
+
### Configuration
|
|
158
|
+
|
|
159
|
+
Set environment variables:
|
|
160
|
+
|
|
161
|
+
| Variable | Purpose | Default |
|
|
162
|
+
|----------|---------|---------|
|
|
163
|
+
| `COMPLETION_KIT_API_TOKEN` | Bearer token for REST API and MCP access | (none — API disabled) |
|
|
164
|
+
| `COMPLETION_KIT_USERNAME` | Web UI login username | `admin` |
|
|
165
|
+
| `COMPLETION_KIT_PASSWORD` | Web UI login password | (none — open in dev) |
|
|
166
|
+
| `DATABASE_URL` | PostgreSQL connection string (production) | SQLite in dev |
|
|
167
|
+
|
|
168
|
+
### Deploying
|
|
169
|
+
|
|
170
|
+
Any Rails-friendly host works — Fly, Heroku, Render, self-managed Docker, etc. Point your host at a Postgres instance via `DATABASE_URL`, set the environment variables above, and run `cd standalone && bin/rails db:migrate` on each deploy.
|
|
171
|
+
|
|
172
|
+
When the gem ships a new engine migration, install it into your standalone app locally and commit the generated file before pushing:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
cd standalone
|
|
176
|
+
bin/rails completion_kit:install:migrations
|
|
177
|
+
bin/rails db:migrate
|
|
178
|
+
git add db/migrate/ && git commit -m "install new engine migration"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
That way your host's `db:migrate` picks up the new file on the next deploy. Don't run `completion_kit:install:migrations` on the host itself — migration files are source artifacts, they belong in git.
|
|
182
|
+
|
|
183
|
+
## Development
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
bundle install
|
|
187
|
+
bundle exec rspec
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
[MIT](https://opensource.org/licenses/MIT)
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//= link_directory ../stylesheets/completion_kit .css
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="2.4 2.3 88.74 89.1" width="512" height="512">
|
|
2
|
+
<path d="M57.7,56.4c1.2-1.2,1.8-3.1,1.4-5c-0.5-2-2.1-3.6-4.1-4c-3.5-0.7-6.6,1.9-6.6,5.3c0,1.5,0.6,2.8,1.5,3.8H37.4l0-12.6c-1.2,1.2-3.1,1.8-5,1.4c-2-0.5-3.6-2.1-4-4.1c-0.7-3.5,1.9-6.6,5.3-6.6c1.5,0,2.8,0.6,3.8,1.5V23.5H10.1c-3.1,0-5.7,2.5-5.7,5.7v54.5c0,3.1,2.5,5.7,5.7,5.7h27.2h27.2c3.1,0,5.7-2.5,5.7-5.7V56.4H57.7z" fill="#0891B2"/>
|
|
3
|
+
<path d="M54.7,37.5c-0.1-1.7,0.6-3.5,2.2-4.8c1.6-1.2,3.9-1.4,5.7-0.5c3.2,1.7,3.8,5.7,1.6,8.3c-0.9,1.1-2.3,1.8-3.6,1.9l9.6,8.1l17.5-20.9c2-2.4,1.7-6-0.7-8L66.2,4.3l-8.1,9.6c-0.2-1.7-1.2-3.4-3-4.3c-1.8-0.9-4.1-0.7-5.7,0.5c-2.8,2.2-2.8,6.3-0.2,8.4c1.1,0.9,2.5,1.4,3.9,1.2L45,29.5L54.7,37.5z" fill="#06B6D4"/>
|
|
4
|
+
<path d="M70.2,52.6c-0.5,0-0.9-0.2-1.3-0.5L59.3,44c-0.6-0.5-0.9-1.4-0.6-2.1c0.2-0.8,0.9-1.3,1.7-1.4c0.9-0.1,1.7-0.5,2.3-1.2c0.7-0.8,0.9-1.8,0.7-2.8c-0.2-1-0.8-1.9-1.8-2.4c-1.1-0.6-2.6-0.5-3.6,0.3c-1,0.7-1.5,1.8-1.4,3c0.1,0.8-0.4,1.6-1.1,1.9c-0.7,0.4-1.6,0.3-2.2-0.2L43.8,31c-0.4-0.3-0.7-0.8-0.7-1.4c0-0.5,0.1-1.1,0.5-1.5l5.9-7.1c-0.5-0.3-1-0.6-1.5-1c-1.7-1.4-2.7-3.6-2.6-5.8c0-2.2,1.1-4.3,2.9-5.7c2.2-1.8,5.3-2.1,7.9-0.7c1.1,0.6,2,1.3,2.6,2.3l6-7.1C65,2.6,65.5,2.3,66,2.3c0.5,0,1.1,0.1,1.5,0.5l20.9,17.5c1.6,1.3,2.5,3.2,2.7,5.2s-0.4,4-1.8,5.6L71.8,51.9c-0.3,0.4-0.8,0.7-1.4,0.7C70.4,52.6,70.3,52.6,70.2,52.6z M64.4,43.1l5.6,4.7l16.2-19.3c0.6-0.8,0.9-1.7,0.8-2.7s-0.5-1.9-1.3-2.5L66.4,7.1l-6.8,8.1c-0.5,0.6-1.4,0.9-2.1,0.6c-0.8-0.2-1.3-0.9-1.4-1.7c-0.1-1.2-0.8-2.2-1.9-2.7c-1.1-0.6-2.6-0.4-3.6,0.3c-0.9,0.7-1.3,1.6-1.4,2.7c0,1,0.4,2,1.2,2.7c0.7,0.6,1.5,0.9,2.4,0.8c0.8-0.1,1.6,0.4,1.9,1.1s0.3,1.6-0.2,2.2l-6.8,8.1l5.6,4.7c0.5-1,1.3-2,2.2-2.7c2.3-1.7,5.4-2,7.9-0.6c2,1.1,3.4,3,3.8,5.2s-0.2,4.5-1.6,6.2C65.4,42.4,64.9,42.8,64.4,43.1z" fill="#475569"/>
|
|
5
|
+
<path d="M70.3,54.4H61c0.3-1.1,0.3-2.3,0-3.5c-0.6-2.8-2.8-5-5.6-5.5c-2.2-0.5-4.5,0.1-6.3,1.5c-1.7,1.4-2.7,3.5-2.7,5.8c0,0.6,0.1,1.2,0.2,1.8h-7.3V43.8c0-0.8-0.5-1.5-1.2-1.8c-0.7-0.3-1.6-0.1-2.2,0.4c-0.8,0.8-2,1.2-3.2,0.9c-1.2-0.3-2.2-1.3-2.5-2.5c-0.2-1.1,0-2.1,0.7-2.9c0.7-0.8,1.6-1.3,2.6-1.3c0.9,0,1.7,0.3,2.4,1c0.6,0.6,1.4,0.7,2.2,0.4c0.7-0.3,1.2-1,1.2-1.8V23.5c0-1.1-0.9-2-2-2H10.1c-4.2,0-7.7,3.4-7.7,7.7v54.5c0,4.2,3.4,7.7,7.7,7.7h54.5c4.2,0,7.7-3.4,7.7-7.7V56.4C72.3,55.3,71.4,54.4,70.3,54.4z M10.1,25.5h25.2v7.3c-0.6-0.1-1.2-0.2-1.8-0.2c-2.2,0-4.3,1-5.8,2.7s-2,4-1.5,6.3c0.6,2.8,2.8,5,5.5,5.6c1.2,0.3,2.4,0.2,3.5,0v7.3H24.8c-0.8,0-1.5,0.5-1.8,1.2c-0.3,0.7-0.1,1.6,0.4,2.2c0.8,0.8,1.1,2,0.9,3.2c-0.3,1.2-1.3,2.2-2.6,2.5c-1.1,0.2-2.1,0-2.9-0.7c-0.8-0.7-1.3-1.6-1.3-2.6c0-0.9,0.3-1.7,1-2.4c0.6-0.6,0.7-1.4,0.4-2.2c-0.3-0.7-1-1.2-1.8-1.2H6.5V29.2C6.5,27.1,8.1,25.5,10.1,25.5z M36.6,74.9c-0.7,0.3-1.2,1-1.2,1.8v10.6H10.1c-2,0-3.7-1.6-3.7-3.7V58.4h7.3c-0.1,0.6-0.2,1.2-0.2,1.8c0,2.2,1,4.3,2.7,5.8c1.7,1.4,4,2,6.3,1.5c2.8-0.6,5-2.8,5.6-5.5c0.3-1.2,0.2-2.4,0-3.5h7.3V69c0,0.8,0.5,1.5,1.2,1.8c0.7,0.3,1.6,0.1,2.2-0.4c0.8-0.8,2-1.1,3.2-0.9c1.2,0.3,2.2,1.3,2.5,2.6c0.2,1.1,0,2.1-0.7,2.9c-0.7,0.8-1.6,1.3-2.6,1.3c-0.9,0-1.7-0.3-2.4-1C38.2,74.7,37.3,74.6,36.6,74.9z M68.3,83.6c0,2-1.6,3.7-3.7,3.7H39.4V80c0.6,0.1,1.2,0.2,1.8,0.2c2.2,0,4.3-1,5.8-2.7c1.4-1.7,2-4,1.5-6.3c-0.6-2.8-2.8-5-5.5-5.6c-1.2-0.3-2.4-0.2-3.5,0v-7.3H50c0.8,0,1.5-0.5,1.8-1.2c0.3-0.7,0.1-1.6-0.4-2.2c-0.6-0.6-1-1.5-1-2.4c0-1,0.5-2,1.3-2.6c0.8-0.7,1.8-0.9,2.9-0.7c1.2,0.3,2.3,1.3,2.6,2.5c0.3,1.2-0.1,2.4-0.9,3.2c-0.6,0.6-0.7,1.4-0.4,2.2c0.3,0.7,1,1.2,1.8,1.2h10.6V83.6z" fill="#475569"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
2
|
+
document.addEventListener("click", function (event) {
|
|
3
|
+
var addBtn = event.target.closest("[data-action='evaluation-steps#add']");
|
|
4
|
+
if (addBtn) {
|
|
5
|
+
var container = addBtn.closest("[data-controller='evaluation-steps']");
|
|
6
|
+
var list = container.querySelector("[data-evaluation-steps-target='list']");
|
|
7
|
+
var row = document.createElement("div");
|
|
8
|
+
row.className = "ck-step-row";
|
|
9
|
+
row.setAttribute("data-evaluation-steps-target", "row");
|
|
10
|
+
row.innerHTML =
|
|
11
|
+
'<input type="text" name="metric[evaluation_steps][]" value="" class="ck-input" placeholder="Describe this evaluation step..." />' +
|
|
12
|
+
'<button type="button" class="ck-icon-btn" data-action="evaluation-steps#remove" aria-label="Remove step">' +
|
|
13
|
+
'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.75"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>' +
|
|
14
|
+
"</button>";
|
|
15
|
+
list.appendChild(row);
|
|
16
|
+
row.querySelector("input").focus();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var removeBtn = event.target.closest("[data-action='evaluation-steps#remove']");
|
|
20
|
+
if (removeBtn) {
|
|
21
|
+
var stepRow = removeBtn.closest("[data-evaluation-steps-target='row']");
|
|
22
|
+
if (stepRow) stepRow.remove();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|