flowengine-rails 0.1.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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/branch-name.sh +49 -0
  3. data/.claude/commands/create-pr.md +93 -0
  4. data/.claude/commands/stash-unstaged.md +21 -0
  5. data/.claude/commands/unstash-unstaged.md +15 -0
  6. data/.claude/settings.json +72 -0
  7. data/.rubocop_todo.yml +17 -0
  8. data/.ruby-version +1 -0
  9. data/CHANGELOG.md +5 -0
  10. data/CLAUDE.md +153 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +294 -0
  13. data/Rakefile +43 -0
  14. data/app/assets/javascripts/flow_engine/embed.js +44 -0
  15. data/app/assets/javascripts/flow_engine/progress_controller.js +17 -0
  16. data/app/assets/javascripts/flow_engine/step_controller.js +22 -0
  17. data/app/assets/stylesheets/flow_engine/application.css +569 -0
  18. data/app/controllers/flow_engine/admin/definitions_controller.rb +95 -0
  19. data/app/controllers/flow_engine/application_controller.rb +41 -0
  20. data/app/controllers/flow_engine/sessions_controller.rb +91 -0
  21. data/app/helpers/flow_engine/sessions_helper.rb +20 -0
  22. data/app/models/flow_engine/application_record.rb +8 -0
  23. data/app/models/flow_engine/flow_definition.rb +75 -0
  24. data/app/models/flow_engine/flow_session.rb +98 -0
  25. data/app/views/flow_engine/admin/definitions/_form.html.erb +27 -0
  26. data/app/views/flow_engine/admin/definitions/edit.html.erb +5 -0
  27. data/app/views/flow_engine/admin/definitions/index.html.erb +41 -0
  28. data/app/views/flow_engine/admin/definitions/mermaid.html.erb +9 -0
  29. data/app/views/flow_engine/admin/definitions/new.html.erb +5 -0
  30. data/app/views/flow_engine/admin/definitions/show.html.erb +25 -0
  31. data/app/views/flow_engine/sessions/completed.html.erb +34 -0
  32. data/app/views/flow_engine/sessions/new.html.erb +17 -0
  33. data/app/views/flow_engine/sessions/show.html.erb +26 -0
  34. data/app/views/flow_engine/sessions/steps/_boolean.html.erb +10 -0
  35. data/app/views/flow_engine/sessions/steps/_display.html.erb +4 -0
  36. data/app/views/flow_engine/sessions/steps/_multi_select.html.erb +8 -0
  37. data/app/views/flow_engine/sessions/steps/_number.html.erb +3 -0
  38. data/app/views/flow_engine/sessions/steps/_number_matrix.html.erb +13 -0
  39. data/app/views/flow_engine/sessions/steps/_single_select.html.erb +8 -0
  40. data/app/views/flow_engine/sessions/steps/_text.html.erb +11 -0
  41. data/app/views/flow_engine/sessions/steps/_unknown.html.erb +4 -0
  42. data/app/views/layouts/flow_engine/application.html.erb +26 -0
  43. data/app/views/layouts/flow_engine/embed.html.erb +30 -0
  44. data/config/routes.rb +22 -0
  45. data/db/migrate/01_create_flow_engine_definitions.rb +18 -0
  46. data/db/migrate/02_create_flow_engine_sessions.rb +18 -0
  47. data/exe/flowengine-rails +4 -0
  48. data/justfile +49 -0
  49. data/lefthook.yml +16 -0
  50. data/lib/flowengine/rails/configuration.rb +23 -0
  51. data/lib/flowengine/rails/dsl_loader.rb +35 -0
  52. data/lib/flowengine/rails/engine.rb +26 -0
  53. data/lib/flowengine/rails/version.rb +7 -0
  54. data/lib/flowengine/rails.rb +27 -0
  55. data/lib/generators/flow_engine/flow/flow_generator.rb +29 -0
  56. data/lib/generators/flow_engine/flow/templates/flow_definition.rb.tt +27 -0
  57. data/lib/generators/flow_engine/flow/templates/seed_task.rake.tt +22 -0
  58. data/lib/generators/flow_engine/install/install_generator.rb +34 -0
  59. data/lib/generators/flow_engine/install/templates/initializer.rb +25 -0
  60. data/log/.gitkeep +0 -0
  61. data/sig/flowengine/rails.rbs +6 -0
  62. metadata +164 -0
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateFlowEngineDefinitions < ActiveRecord::Migration[8.0]
4
+ def change
5
+ create_table :flow_engine_definitions do |t|
6
+ t.string :name, null: false
7
+ t.integer :version, null: false, default: 1
8
+ t.text :dsl, null: false
9
+ t.boolean :active, null: false, default: false
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :flow_engine_definitions, %i[name version], unique: true
15
+ add_index :flow_engine_definitions, :name, unique: true, where: "active = 1",
16
+ name: "index_flow_engine_definitions_on_name_active"
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateFlowEngineSessions < ActiveRecord::Migration[8.0]
4
+ def change
5
+ create_table :flow_engine_sessions do |t|
6
+ t.references :definition, null: false, foreign_key: { to_table: :flow_engine_definitions }
7
+ t.string :current_step_id
8
+ t.json :answers, default: {}
9
+ t.json :history, default: []
10
+ t.string :status, null: false, default: "in_progress"
11
+ t.json :metadata, default: {}
12
+
13
+ t.timestamps
14
+ end
15
+
16
+ add_index :flow_engine_sessions, :status
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "flowengine/rails"
data/justfile ADDED
@@ -0,0 +1,49 @@
1
+ set shell := ["bash", "-c"]
2
+
3
+ set dotenv-load
4
+
5
+ [no-exit-message]
6
+ recipes:
7
+ @just --choose
8
+
9
+ test:
10
+ @bundle exec rspec
11
+ @bundle exec rubocop
12
+
13
+ # Setup Ruby dependencies
14
+ setup-ruby:
15
+ #!/usr/bin/env bash
16
+ [[ -d ~/.rbenv ]] || git clone https://github.com/rbenv/rbenv.git ~/.rbenv
17
+ [[ -d ~/.rbenv/plugins/ruby-build ]] || git clone https://github.com/rbenv/rbenv.git ~/.rbenv
18
+ cd ~/.rbenv/plugins/ruby-build && git pull && cd - >/dev/null
19
+ echo -n "Checking if Ruby $(cat .ruby-version | tr -d '\n') is already installed..."
20
+ rbenv install -s "$(cat .ruby-version | tr -d '\n')" >/dev/null 2>&1 && echo "yes" || echo "it wasn't, but now it is"
21
+ bundle check || bundle install -j 12
22
+
23
+ setup: setup-ruby
24
+
25
+ cli DATA SCHEMA *ARGS:
26
+ #!/usr/bin/env bash
27
+ cd .. && ./cli validate-json -f {{DATA}} -s {{SCHEMA}}
28
+
29
+ format:
30
+ @bundle exec rubocop -a
31
+ @bundle exec rubocop --auto-gen-config
32
+
33
+ lint:
34
+ @bundle exec rubocop
35
+
36
+ # Generates library documentation into ./doc folder and opens the browser
37
+ doc:
38
+ @bundle exec rake doc
39
+ @open ./doc/index.html
40
+
41
+ clean:
42
+ @rm -rf pkg
43
+ @rm -rf coverage
44
+
45
+ release:
46
+ @bundle exec rake release
47
+
48
+ check-all: lint test
49
+
data/lefthook.yml ADDED
@@ -0,0 +1,16 @@
1
+ pre-commit:
2
+ parallel: true
3
+ jobs:
4
+ - name: format
5
+ glob: "*.{js,ts,tsx}"
6
+ run: npx biome format --write {staged_files}
7
+ stage_fixed: true
8
+
9
+ - name: rubocop
10
+ glob: "*.{rb,rake}"
11
+ run: bundle exec rubocop -a --format progress {staged_files}
12
+ staged_fixed: true
13
+
14
+ - name: rspecs
15
+ glob: "spec/**/*_spec.rb"
16
+ run: bundle exec rspec --format progress
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowEngine
4
+ module Rails
5
+ class Configuration
6
+ attr_accessor :embed_allowed_origins,
7
+ :default_layout,
8
+ :embed_layout,
9
+ :cache_definitions,
10
+ :on_session_complete,
11
+ :admin_authentication_method
12
+
13
+ def initialize
14
+ @embed_allowed_origins = []
15
+ @default_layout = "flow_engine/application"
16
+ @embed_layout = "flow_engine/embed"
17
+ @cache_definitions = true
18
+ @on_session_complete = nil
19
+ @admin_authentication_method = nil
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowEngine
4
+ module Rails
5
+ class DslLoader
6
+ class << self
7
+ def load(dsl_text, cache_key: nil)
8
+ return FlowEngine.load_dsl(dsl_text) unless cache_key && FlowEngine::Rails.configuration.cache_definitions
9
+
10
+ cache_fetch(cache_key) { FlowEngine.load_dsl(dsl_text) }
11
+ end
12
+
13
+ def clear_cache!
14
+ mutex.synchronize { cache.clear }
15
+ end
16
+
17
+ private
18
+
19
+ def cache_fetch(key)
20
+ mutex.synchronize do
21
+ cache[key] ||= yield
22
+ end
23
+ end
24
+
25
+ def cache
26
+ @cache ||= {}
27
+ end
28
+
29
+ def mutex
30
+ @mutex ||= Mutex.new
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowEngine
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ isolate_namespace FlowEngine
7
+
8
+ initializer "flow_engine.assets" do |app|
9
+ app.config.assets.paths << root.join("app", "assets", "stylesheets") if app.config.respond_to?(:assets)
10
+ app.config.assets.paths << root.join("app", "assets", "javascripts") if app.config.respond_to?(:assets)
11
+ end
12
+
13
+ initializer "flow_engine.importmap", before: "importmap" do |app|
14
+ if app.config.respond_to?(:importmap) && root.join("config",
15
+ "importmap.rb").exist?
16
+ app.config.importmap.paths << root.join("config", "importmap.rb")
17
+ end
18
+ end
19
+
20
+ config.generators do |g|
21
+ g.test_framework :rspec
22
+ g.fixture_replacement :factory_bot, dir: "spec/factories"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowEngine
4
+ module Rails
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "flowengine"
4
+ require_relative "rails/version"
5
+ require_relative "rails/configuration"
6
+ require_relative "rails/dsl_loader"
7
+ require_relative "rails/engine"
8
+
9
+ module FlowEngine
10
+ module Rails
11
+ class Error < StandardError; end
12
+
13
+ class << self
14
+ def configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ def configure
19
+ yield(configuration)
20
+ end
21
+
22
+ def reset_configuration!
23
+ @configuration = Configuration.new
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowEngine
4
+ module Generators
5
+ class FlowGenerator < ::Rails::Generators::NamedBase
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ desc "Generate a flow definition file and seed task"
9
+
10
+ def create_flow_definition
11
+ template "flow_definition.rb.tt", "db/flow_definitions/#{file_name}.rb"
12
+ end
13
+
14
+ def create_seed_task
15
+ template "seed_task.rake.tt", "lib/tasks/flow_engine_#{file_name}.rake"
16
+ end
17
+
18
+ def show_next_steps
19
+ say ""
20
+ say "Flow definition created!", :green
21
+ say ""
22
+ say "Next steps:"
23
+ say " 1. Edit db/flow_definitions/#{file_name}.rb"
24
+ say " 2. Seed it: rails flow_engine:seed:#{file_name}"
25
+ say ""
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Flow definition: <%= class_name %>
4
+ # Edit this file then seed it with: rails flow_engine:seed:<%= file_name %>
5
+
6
+ <%= class_name.upcase %>_DSL = <<~RUBY
7
+ FlowEngine.define do
8
+ start :welcome
9
+
10
+ step :welcome do
11
+ type :display
12
+ question "Welcome to the <%= class_name.titleize %> flow!"
13
+ transition to: :first_question
14
+ end
15
+
16
+ step :first_question do
17
+ type :text
18
+ question "What is your name?"
19
+ transition to: :done
20
+ end
21
+
22
+ step :done do
23
+ type :display
24
+ question "Thank you for completing the flow!"
25
+ end
26
+ end
27
+ RUBY
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :flow_engine do
4
+ namespace :seed do
5
+ desc "Seed the <%= class_name %> flow definition"
6
+ task <%= file_name %>: :environment do
7
+ require Rails.root.join("db/flow_definitions/<%= file_name %>")
8
+
9
+ dsl_text = <%= class_name.upcase %>_DSL
10
+
11
+ definition = FlowEngine::Definition.find_or_initialize_by(
12
+ name: "<%= file_name %>",
13
+ version: 1
14
+ )
15
+ definition.dsl = dsl_text
16
+ definition.save!
17
+ definition.activate!
18
+
19
+ puts "Seeded and activated: #{definition.name} v#{definition.version}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowEngine
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ desc "Install FlowEngine: copy migrations, create initializer, add mount route"
9
+
10
+ def copy_migrations
11
+ rake "flow_engine:install:migrations"
12
+ end
13
+
14
+ def create_initializer
15
+ template "initializer.rb", "config/initializers/flow_engine.rb"
16
+ end
17
+
18
+ def add_route
19
+ route 'mount FlowEngine::Rails::Engine => "/flow_engine"'
20
+ end
21
+
22
+ def show_post_install
23
+ say ""
24
+ say "FlowEngine installed successfully!", :green
25
+ say ""
26
+ say "Next steps:"
27
+ say " 1. Run migrations: rails db:migrate"
28
+ say " 2. Edit config/initializers/flow_engine.rb"
29
+ say " 3. Create a flow: rails generate flow_engine:flow my_intake"
30
+ say ""
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ FlowEngine::Rails.configure do |config|
4
+ # Origins allowed to embed the flow widget via iframe.
5
+ # Use ["*"] to allow all origins, or specify domains:
6
+ # config.embed_allowed_origins = ["https://example.com"]
7
+ config.embed_allowed_origins = []
8
+
9
+ # Layout used for regular (non-embedded) flow sessions
10
+ # config.default_layout = "flow_engine/application"
11
+
12
+ # Layout used for embedded (iframe) flow sessions
13
+ # config.embed_layout = "flow_engine/embed"
14
+
15
+ # Cache parsed DSL definitions in memory (recommended for production)
16
+ config.cache_definitions = Rails.env.production?
17
+
18
+ # Callback fired when a session is completed.
19
+ # Receives the completed FlowEngine::Session instance.
20
+ # config.on_session_complete = ->(session) { MyNotifier.flow_completed(session) }
21
+
22
+ # Method name to call on ApplicationController for admin authentication.
23
+ # Set to nil to disable (open admin). Example: :authenticate_admin!
24
+ # config.admin_authentication_method = :authenticate_admin!
25
+ end
data/log/.gitkeep ADDED
File without changes
@@ -0,0 +1,6 @@
1
+ module Flowengine
2
+ module Rails
3
+ VERSION: String
4
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flowengine-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Konstantin Gredeskoul
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: flowengine
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rails
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 8.1.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 8.1.2
40
+ - !ruby/object:Gem::Dependency
41
+ name: stimulus-rails
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: turbo-rails
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.0'
68
+ description: FlowEngine::Rails provides ActiveRecord persistence, Hotwire-based web
69
+ wizard UI, admin CRUD for flow definitions, and an iframe-embeddable widget. Built
70
+ on the flowengine core gem.
71
+ email:
72
+ - kigster@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".claude/branch-name.sh"
78
+ - ".claude/commands/create-pr.md"
79
+ - ".claude/commands/stash-unstaged.md"
80
+ - ".claude/commands/unstash-unstaged.md"
81
+ - ".claude/settings.json"
82
+ - ".rubocop_todo.yml"
83
+ - ".ruby-version"
84
+ - CHANGELOG.md
85
+ - CLAUDE.md
86
+ - LICENSE.txt
87
+ - README.md
88
+ - Rakefile
89
+ - app/assets/javascripts/flow_engine/embed.js
90
+ - app/assets/javascripts/flow_engine/progress_controller.js
91
+ - app/assets/javascripts/flow_engine/step_controller.js
92
+ - app/assets/stylesheets/flow_engine/application.css
93
+ - app/controllers/flow_engine/admin/definitions_controller.rb
94
+ - app/controllers/flow_engine/application_controller.rb
95
+ - app/controllers/flow_engine/sessions_controller.rb
96
+ - app/helpers/flow_engine/sessions_helper.rb
97
+ - app/models/flow_engine/application_record.rb
98
+ - app/models/flow_engine/flow_definition.rb
99
+ - app/models/flow_engine/flow_session.rb
100
+ - app/views/flow_engine/admin/definitions/_form.html.erb
101
+ - app/views/flow_engine/admin/definitions/edit.html.erb
102
+ - app/views/flow_engine/admin/definitions/index.html.erb
103
+ - app/views/flow_engine/admin/definitions/mermaid.html.erb
104
+ - app/views/flow_engine/admin/definitions/new.html.erb
105
+ - app/views/flow_engine/admin/definitions/show.html.erb
106
+ - app/views/flow_engine/sessions/completed.html.erb
107
+ - app/views/flow_engine/sessions/new.html.erb
108
+ - app/views/flow_engine/sessions/show.html.erb
109
+ - app/views/flow_engine/sessions/steps/_boolean.html.erb
110
+ - app/views/flow_engine/sessions/steps/_display.html.erb
111
+ - app/views/flow_engine/sessions/steps/_multi_select.html.erb
112
+ - app/views/flow_engine/sessions/steps/_number.html.erb
113
+ - app/views/flow_engine/sessions/steps/_number_matrix.html.erb
114
+ - app/views/flow_engine/sessions/steps/_single_select.html.erb
115
+ - app/views/flow_engine/sessions/steps/_text.html.erb
116
+ - app/views/flow_engine/sessions/steps/_unknown.html.erb
117
+ - app/views/layouts/flow_engine/application.html.erb
118
+ - app/views/layouts/flow_engine/embed.html.erb
119
+ - config/routes.rb
120
+ - db/migrate/01_create_flow_engine_definitions.rb
121
+ - db/migrate/02_create_flow_engine_sessions.rb
122
+ - exe/flowengine-rails
123
+ - justfile
124
+ - lefthook.yml
125
+ - lib/flowengine/rails.rb
126
+ - lib/flowengine/rails/configuration.rb
127
+ - lib/flowengine/rails/dsl_loader.rb
128
+ - lib/flowengine/rails/engine.rb
129
+ - lib/flowengine/rails/version.rb
130
+ - lib/generators/flow_engine/flow/flow_generator.rb
131
+ - lib/generators/flow_engine/flow/templates/flow_definition.rb.tt
132
+ - lib/generators/flow_engine/flow/templates/seed_task.rake.tt
133
+ - lib/generators/flow_engine/install/install_generator.rb
134
+ - lib/generators/flow_engine/install/templates/initializer.rb
135
+ - log/.gitkeep
136
+ - sig/flowengine/rails.rbs
137
+ homepage: https://github.com/kigster/flowengine-rails
138
+ licenses:
139
+ - MIT
140
+ metadata:
141
+ allowed_push_host: https://rubygems.org
142
+ homepage_uri: https://github.com/kigster/flowengine-rails
143
+ source_code_uri: https://github.com/kigster/flowengine-rails
144
+ changelog_uri: https://github.com/kigster/flowengine-rails/blob/main/CHANGELOG.md
145
+ rubygems_mfa_required: 'true'
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: 4.0.1
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubygems_version: 4.0.3
161
+ specification_version: 4
162
+ summary: Rails Engine adapter for FlowEngine — persistence, web wizard UI, and admin
163
+ CRUD
164
+ test_files: []