ask-rails 0.7.0 → 0.9.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: 805ea4f5713b8cfacc7f25c54b6229b788199ddba9ab1dc5a50c4719a834f256
4
- data.tar.gz: da2648a6027373d0c65f37786c347e6fda211d6f43a38378042acb8dae1a7ca8
3
+ metadata.gz: 8c73b254e032db5c313a0eeca47499a4b30152fcf725ed410e575b0ea0a9460f
4
+ data.tar.gz: bfe5f9b1769e4ea4b864b7dee0c6ca3d1a6587186ccac7820a71f65999f8e0f5
5
5
  SHA512:
6
- metadata.gz: 02e6b7d1dca1617b4070e9068cb6be162040756119ef1dbdab793ec27b1cb1aaa33a46eb88d7dcc9c9734e3b3c570172f816290f2629be0a09c8cdef041a88e9
7
- data.tar.gz: bedabfd712c7397baf254aecaf8c2c2316dfb47964303d4b91437e9ef53dcf187a31fccdc406e8b5434de5029d657179845d31044de8e2ee148abff0baef8063
6
+ metadata.gz: 9c02cc27c98ea141900339703160ecfad56ed70979292a654b8b1f6c7e6562f02307abc7c02a88e319cc3f8e78b66677cfa37bee8a9fc84430f07ef3b3188ba4
7
+ data.tar.gz: d8f235e67a77dba643184f1f81d71f40c70be04725d24e26f6a4778b41bb6cf658f7e1a73067b9ebd88bb1552e25862dce57fe21b52653cfceb7d1db066fc32a
data/CHANGELOG.md CHANGED
@@ -1,26 +1,42 @@
1
- ## [0.7.0] — 2026-07-31
1
+ ## [0.9.0] — 2026-07-30
2
2
 
3
- ### Added
3
+ ### Fixed
4
+
5
+ - **Agent generator + templates now follow the ask-agent directory convention.**
6
+ `rails generate ask:agent support_bot` creates `app/agents/support_bot/agent.rb`
7
+ + `instructions.md` + `tools/` (the discovery layout), not a flat
8
+ `app/agents/support_bot.rb`. Templates no longer reference the removed
9
+ `system_prompt`/`tool` Definition DSL — they use `model`, `provider`,
10
+ `max_turns`, and `tools` (plural), with instructions auto-loaded from
11
+ the sibling `instructions.md`.
4
12
 
5
- - **`ask:workflow NAME` generator** — scaffolds a workflow module under `app/workflows/<name>/` with `workflow.rb` and `steps/` directory. Requires ask-graph; aborts with a helpful message if it's not installed.
13
+ ## [0.8.0] 2026-07-31
6
14
 
7
- - **`ask:agent NAME` generator** — scaffolds an individual agent under `app/agents/`.
15
+ ### Added
8
16
 
9
- - **ask-graph support in install generator** — `ask:install` now creates `app/workflows/application_workflow.rb` and the workflows directory when ask-graph is installed. Pass `--skip-graph` to skip. The initializer's graph configuration block is only generated when ask-graph is present:
17
+ - **`Ask::Actions` action convention** — user-facing operations callable from any channel (web, Slack, voice) by name:
10
18
 
11
19
  ```ruby
12
- if defined?(Ask::Graph)
13
- Ask::Graph.storage = ASK_STATE
14
- end
20
+ Ask::Actions.dispatch(action: "chats.create", context: context, params: {})
15
21
  ```
16
22
 
17
- ### Changed
23
+ - `Ask::Actions::Result` — uniform response shape (`ok`/`error`, `message`, `data`, `code`)
24
+ - `Ask::Actions::Context` — per-request context bag; attributes become accessors
25
+ - `Ask::Actions::Backend` — dispatcher with explicit registration (`Ask::Actions.register`) and convention resolution (`"chats.create"` → `Chats::Create` via Zeitwerk). Unknown actions raise `Ask::Actions::Backend::UnknownAction` with guidance.
26
+
27
+ - **`ask:action NAME [NAMESPACE]` generator** — scaffolds actions:
28
+
29
+ ```bash
30
+ rails generate ask:action create_workspace # app/actions/create_workspace.rb
31
+ rails generate ask:action chats create # app/actions/chats/create.rb → "chats.create"
32
+ ```
18
33
 
19
- - Shared `ask_state` table is explicitly documented as serving both agent sessions and workflow checkpoints.
34
+ - **Actions in install generator** — `ask:install` now creates `app/actions/` and `app/actions/application_action.rb` (base class with `call(context:, params:)` `#call`). The initializer documents the actions block with a registration example.
20
35
 
21
36
  ### Tested
22
37
 
23
- - 11 generator tests, 51 assertions, 0 failures.
38
+ - 25 new tests (Result, Context, Backend, generators) — 48 runs, 141 assertions, 0 failures.
39
+ - End-to-end smoke test in a fresh Rails 8.1 app: `ask:install` + `ask:action` (namespaced and top-level) run; `Ask::Actions.dispatch` resolves both via convention; unknown actions raise with a helpful message.
24
40
 
25
41
  ## [0.7.0] — 2026-07-31
26
42
 
data/README.md CHANGED
@@ -24,6 +24,7 @@ This creates:
24
24
  |---|---|
25
25
  | `config/initializers/ask.rb` | Agent + workflow configuration (graph block only generated when ask-graph is installed) |
26
26
  | `app/agents/application_agent.rb` | Base class for your agents |
27
+ | `app/actions/application_action.rb` | Base class for your actions |
27
28
  | `app/workflows/application_workflow.rb` | Base class for your workflows (only with ask-graph) |
28
29
  | `db/migrate/*_create_ask_state.rb` | Shared key-value state table — workflow checkpoints and agent session indexes |
29
30
  | `db/migrate/*_create_ask_audit_logs.rb` | Agent session audit log |
@@ -40,16 +41,28 @@ Scaffolds a new agent:
40
41
  rails generate ask:agent support_bot
41
42
  ```
42
43
 
43
- Creates `app/agents/support_bot.rb`:
44
+ Creates the agent directory convention used by ask-agent discovery:
45
+
46
+ ```
47
+ app/agents/support_bot/
48
+ ├── agent.rb # class Agents::SupportBot < ApplicationAgent
49
+ ├── instructions.md # auto-loaded as the system prompt
50
+ └── tools/ # per-agent tools (referenced with `tools :tool_name`)
51
+ ```
44
52
 
45
53
  ```ruby
54
+ # app/agents/support_bot/agent.rb
46
55
  module Agents
47
56
  class SupportBot < ApplicationAgent
48
- system_prompt "You are a helpful assistant."
57
+ model "gpt-4o"
58
+ # tools :search_knowledge_base
49
59
  end
50
60
  end
51
61
  ```
52
62
 
63
+ Run it with `Ask::Agent.new("support_bot")`. The directory name is the
64
+ agent name — keep the file named `agent.rb`.
65
+
53
66
  ### `ask:workflow NAME`
54
67
 
55
68
  Scaffolds a new workflow (requires ask-graph):
@@ -68,6 +81,27 @@ module NotifyCustomer
68
81
  end
69
82
  ```
70
83
 
84
+ ### `ask:action NAME [NAMESPACE]`
85
+
86
+ Scaffolds a new action — a user-facing operation callable from any channel (web, Slack, voice) by name:
87
+
88
+ ```bash
89
+ rails generate ask:action create_workspace # app/actions/create_workspace.rb
90
+ rails generate ask:action chats create # app/actions/chats/create.rb
91
+ ```
92
+
93
+ Creates `app/actions/chats/create.rb`:
94
+
95
+ ```ruby
96
+ module Chats
97
+ class Create < ApplicationAction
98
+ def call
99
+ Ask::Actions::Result.ok(message: "Chat created", data: { id: record.id })
100
+ end
101
+ end
102
+ end
103
+ ```
104
+
71
105
  ### Skipping workflow scaffolding
72
106
 
73
107
  If you don't use ask-graph, install with:
@@ -132,6 +166,40 @@ result.payment
132
166
 
133
167
  Checkpoints are saved to the shared `ask_state` table, so workflows resume after crashes.
134
168
 
169
+ ### Actions
170
+
171
+ Actions are the operations your users trigger — booking an appointment, creating a chat, upgrading a plan. They live in `app/actions/` and are dispatched **by name**, so any channel (web controller, Slack handler, voice agent) calls the same operation:
172
+
173
+ ```ruby
174
+ # app/actions/chats/create.rb
175
+ module Chats
176
+ class Create < ApplicationAction
177
+ def call
178
+ chat = context.channel.start_new_chat!
179
+ Ask::Actions::Result.ok(message: "Chat created", data: { chat: chat })
180
+ end
181
+ end
182
+ end
183
+ ```
184
+
185
+ ```ruby
186
+ # From any channel:
187
+ context = Ask::Actions::Context.new(user: current_user, session: session)
188
+ result = Ask::Actions.dispatch(action: "chats.create", context: context, params: { name: "general" })
189
+ result.ok? # => true
190
+ result.message # => "Chat created"
191
+ result.data # => { chat: ... }
192
+ ```
193
+
194
+ By convention, `"chats.create"` resolves to `Chats::Create` — no registration needed (Zeitwerk autoloads `app/actions/`). Register explicitly to override the convention or to list actions in `Ask::Actions.available`:
195
+
196
+ ```ruby
197
+ # config/initializers/ask.rb
198
+ Ask::Actions.register "chats.create", Chats::Create
199
+ ```
200
+
201
+ Unknown action names raise `Ask::Actions::Backend::UnknownAction` with a helpful message.
202
+
135
203
  ## Configuration
136
204
 
137
205
  API keys are resolved automatically by `Ask::Auth`:
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Actions
5
+ # Dispatches named actions to their classes.
6
+ #
7
+ # Resolution order:
8
+ # 1. Explicitly registered actions (Ask::Actions.register)
9
+ # 2. Convention: "chats.create" resolves to Chats::Create
10
+ #
11
+ # Convention resolution works with Zeitwerk — app/actions/chats/create.rb
12
+ # is autoloaded as Chats::Create with no configuration.
13
+ class Backend
14
+ class UnknownAction < StandardError
15
+ def initialize(action)
16
+ super(<<~MSG.strip)
17
+ Unknown action #{action.inspect}. Define it at app/actions/ \
18
+ (e.g. app/actions/chats/create.rb for "chats.create") or register \
19
+ it with Ask::Actions.register.
20
+ MSG
21
+ end
22
+ end
23
+
24
+ CONVENTION = /\A[a-z0-9_.]+\z/
25
+
26
+ class << self
27
+ def register(action, klass)
28
+ registered[action.to_s] = klass
29
+ end
30
+
31
+ def registered
32
+ @registered ||= {}
33
+ end
34
+
35
+ def reset!
36
+ @registered = {}
37
+ end
38
+
39
+ def available
40
+ registered.keys
41
+ end
42
+
43
+ def dispatch(action:, context:, params: {})
44
+ resolve(action).call(context: context, params: params)
45
+ end
46
+
47
+ def resolve(action)
48
+ name = action.to_s
49
+ registered[name] || resolve_by_convention(name) || unknown_action!(name)
50
+ end
51
+
52
+ private
53
+
54
+ def resolve_by_convention(name)
55
+ return nil unless name.match?(CONVENTION)
56
+
57
+ name.split(".").map { |part| part.split("_").map(&:capitalize).join }.join("::").safe_constantize
58
+ end
59
+
60
+ def unknown_action!(name)
61
+ raise UnknownAction, name
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Actions
5
+ # A per-request bag of context. Channel adapters construct it with
6
+ # whatever the app needs — user, session, workspace, channel, voice call —
7
+ # and actions read from it. Attributes become accessors on the instance.
8
+ #
9
+ # @example
10
+ # context = Ask::Actions::Context.new(user: user, session: session, workspace: workspace)
11
+ # context.user # => user
12
+ # context.workspace # => workspace
13
+ class Context
14
+ def initialize(**attributes)
15
+ attributes.each { |name, value| define_attribute(name, value) }
16
+ end
17
+
18
+ private
19
+
20
+ def define_attribute(name, value)
21
+ singleton_class.attr_accessor(name)
22
+ public_send("#{name}=", value)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ask
4
+ module Actions
5
+ # The uniform response shape every action returns. Channel adapters
6
+ # (web controllers, Slack handlers, voice agents) consume the same
7
+ # contract regardless of which surface a request came from.
8
+ #
9
+ # @example
10
+ # Ask::Actions::Result.ok(message: "Booking confirmed", data: { booking: booking })
11
+ # Ask::Actions::Result.error(message: "Slot unavailable", code: :slot_taken)
12
+ class Result
13
+ attr_reader :ok, :message, :data, :code
14
+
15
+ def initialize(ok:, message:, data: {}, code: nil)
16
+ @ok = ok
17
+ @message = message
18
+ @data = data
19
+ @code = code
20
+ end
21
+
22
+ def ok?
23
+ ok
24
+ end
25
+
26
+ def error?
27
+ !ok
28
+ end
29
+
30
+ def to_h
31
+ { ok: ok, message: message, data: data, code: code }
32
+ end
33
+
34
+ def self.ok(message: "", data: {}, code: nil)
35
+ new(ok: true, message: message, data: data, code: code)
36
+ end
37
+
38
+ def self.error(message: "", data: {}, code: nil)
39
+ new(ok: false, message: message, data: data, code: code)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "actions/result"
4
+ require_relative "actions/context"
5
+ require_relative "actions/backend"
6
+
7
+ module Ask
8
+ # Actions — a convention for user-facing operations callable from any channel.
9
+ #
10
+ # Every action lives in app/actions/, responds to .call(context:, params:),
11
+ # and returns an Ask::Actions::Result. Dispatch them by name so any channel —
12
+ # web, Slack, voice — can invoke the same operation:
13
+ #
14
+ # Ask::Actions.dispatch(action: "chats.create", context: context, params: {})
15
+ #
16
+ # By convention, "chats.create" resolves to Chats::Create (app/actions/chats/create.rb).
17
+ # Register explicitly to override the convention or to list actions in
18
+ # Ask::Actions.available:
19
+ #
20
+ # Ask::Actions.register "chats.create", Chats::Create
21
+ module Actions
22
+ class << self
23
+ def register(action, klass)
24
+ Backend.register(action, klass)
25
+ end
26
+
27
+ def dispatch(action:, context:, params: {})
28
+ Backend.dispatch(action: action, context: context, params: params)
29
+ end
30
+
31
+ def resolve(action)
32
+ Backend.resolve(action)
33
+ end
34
+
35
+ def available
36
+ Backend.available
37
+ end
38
+
39
+ def reset!
40
+ Backend.reset!
41
+ end
42
+ end
43
+ end
44
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  module Rails
5
- VERSION = "0.7.0"
5
+ VERSION = "0.9.0"
6
6
  end
7
7
  end
data/lib/ask/rails.rb CHANGED
@@ -9,4 +9,5 @@ end
9
9
 
10
10
  require_relative "rails/version"
11
11
  require_relative "rails/state"
12
+ require_relative "actions"
12
13
  require_relative "rails/railtie" if defined?(::Rails::Railtie)
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # <%= dispatch_name %> action.
4
+ #
5
+ # Dispatch it from any channel — web, Slack, voice:
6
+ # Ask::Actions.dispatch(action: "<%= dispatch_name %>", context: context, params: {})
7
+ #
8
+ # Return an Ask::Actions::Result:
9
+ # Ask::Actions::Result.ok(message: "Done", data: { id: record.id })
10
+ <% if namespaced? -%>
11
+ module <%= namespace_class_name %>
12
+ class <%= action_class_name %> < ApplicationAction
13
+ # def call
14
+ # Ask::Actions::Result.ok(message: "Done")
15
+ # end
16
+ end
17
+ end
18
+ <% else -%>
19
+ class <%= action_class_name %> < ApplicationAction
20
+ # def call
21
+ # Ask::Actions::Result.ok(message: "Done")
22
+ # end
23
+ end
24
+ <% end -%>
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module Ask
6
+ module Generators
7
+ # Creates an action under app/actions. Actions are operations callable
8
+ # from any channel by name — dispatch them with Ask::Actions.dispatch.
9
+ #
10
+ # rails generate ask:action create_workspace
11
+ # # => app/actions/create_workspace.rb (dispatch name: "create_workspace")
12
+ #
13
+ # rails generate ask:action chats create
14
+ # # => app/actions/chats/create.rb (dispatch name: "chats.create")
15
+ class ActionGenerator < ::Rails::Generators::NamedBase
16
+ source_root File.expand_path("action/templates", __dir__)
17
+
18
+ desc "Creates an action under app/actions — a user-facing operation callable from any channel"
19
+
20
+ def create_action
21
+ template "action.rb", action_path
22
+ end
23
+
24
+ private
25
+
26
+ def action_path
27
+ if namespaced?
28
+ "app/actions/#{namespace_name}/#{action_name}.rb"
29
+ else
30
+ "app/actions/#{action_name}.rb"
31
+ end
32
+ end
33
+
34
+ def namespaced?
35
+ args.any?
36
+ end
37
+
38
+ def namespace_name
39
+ file_name
40
+ end
41
+
42
+ def action_name
43
+ namespaced? ? args.first.underscore : file_name
44
+ end
45
+
46
+ def namespace_class_name
47
+ namespace_name.camelize
48
+ end
49
+
50
+ def action_class_name
51
+ action_name.camelize
52
+ end
53
+
54
+ def dispatch_name
55
+ namespaced? ? "#{namespace_name}.#{action_name}" : action_name
56
+ end
57
+ end
58
+ end
59
+ end
@@ -6,13 +6,17 @@
6
6
  # agent = Ask::Agent.new("<%= file_name %>")
7
7
  # response = agent.run("Hello")
8
8
  #
9
+ # Instructions load automatically from instructions.md next to this file.
10
+ # Per-agent tools live in tools/ — reference them with `tools :tool_name`.
11
+ #
9
12
  module Agents
10
13
  class <%= class_name %> < ApplicationAgent
11
14
  # model "gpt-4o"
12
- system_prompt "You are a helpful assistant."
15
+ # provider :openai
16
+ # max_turns 25
13
17
 
14
- # tool :bash
15
- # tool :read
16
- # tool :grep
18
+ # tools :bash
19
+ # tools :read
20
+ # tools :grep
17
21
  end
18
22
  end
@@ -0,0 +1,9 @@
1
+ # <%= class_name %>
2
+
3
+ You are a helpful assistant. Describe what this agent does and how it
4
+ should behave. This file is auto-loaded as the system prompt.
5
+
6
+ ## Guidelines
7
+
8
+ - Be concise and direct.
9
+ - Use the tools available to you when you need information.
@@ -7,10 +7,12 @@ module Ask
7
7
  class AgentGenerator < ::Rails::Generators::NamedBase
8
8
  source_root File.expand_path("agent/templates", __dir__)
9
9
 
10
- desc "Creates an agent under app/agents — subclass ApplicationAgent with a model and system prompt"
10
+ desc "Creates an agent under app/agents/<name>/the ask-agent directory convention with agent.rb, instructions.md, and tools/"
11
11
 
12
12
  def create_agent
13
- template "agent.rb", "app/agents/#{file_name}.rb"
13
+ template "agent.rb", "app/agents/#{file_name}/agent.rb"
14
+ template "instructions.md", "app/agents/#{file_name}/instructions.md"
15
+ empty_directory "app/agents/#{file_name}/tools"
14
16
  end
15
17
  end
16
18
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Base class for your application's actions.
4
+ #
5
+ # Subclass this to define actions — operations callable from any channel
6
+ # (web, Slack, voice) by name:
7
+ #
8
+ # module Chats
9
+ # class Create < ApplicationAction
10
+ # def call
11
+ # chat = context.channel.start_new_chat!
12
+ # Ask::Actions::Result.ok(message: "Chat created", data: { chat: chat })
13
+ # end
14
+ # end
15
+ # end
16
+ #
17
+ # Then dispatch from anywhere:
18
+ # Ask::Actions.dispatch(action: "chats.create", context: context, params: {})
19
+ #
20
+ class ApplicationAction
21
+ def self.call(context:, params: {})
22
+ new(context: context, params: params).call
23
+ end
24
+
25
+ def initialize(context:, params: {})
26
+ @context = context
27
+ @params = params
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :context, :params
33
+ end
@@ -4,23 +4,20 @@
4
4
  #
5
5
  # Subclass this to define agents:
6
6
  #
7
- # class Agents::SupportBot < ApplicationAgent
7
+ # # app/agents/support_bot/agent.rb
8
+ # class SupportBotAgent < ApplicationAgent
8
9
  # model "gpt-4o"
9
- # system_prompt "You help users with support questions."
10
- #
11
- # tool :search_knowledge_base
10
+ # tools :search_knowledge_base
12
11
  # end
13
12
  #
13
+ # # app/agents/support_bot/instructions.md — auto-loaded as the system prompt
14
+ # # app/agents/support_bot/tools/search_knowledge_base.rb — per-agent tools
15
+ #
14
16
  # Then run:
15
17
  # agent = Ask::Agent.new("support_bot")
16
18
  # agent.run("How do I reset my password?")
17
19
  #
18
20
  class ApplicationAgent < Ask::Agent::Definition
19
- # Default instructions — override in subclasses
20
- system_prompt "You are a helpful assistant."
21
-
22
- # Uncomment to add built-in tools:
23
- # tool :bash
24
- # tool :read
25
- # tool :grep
21
+ # Default instructions — override by adding an instructions.md file
22
+ # in the agent directory, or with option :system_prompt, "..."
26
23
  end
@@ -31,3 +31,13 @@ if defined?(Ask::Graph)
31
31
  # Ask::Graph.default_step_timeout 30
32
32
  # Ask::Graph.default_workflow_timeout 60
33
33
  end
34
+
35
+ # Actions
36
+ #
37
+ # Actions live in app/actions/ and are dispatched by name from any channel:
38
+ # Ask::Actions.dispatch(action: "chats.create", context: context, params: {})
39
+ #
40
+ # By convention, "chats.create" resolves to Chats::Create
41
+ # (app/actions/chats/create.rb). Register explicitly to override the
42
+ # convention or to list the action in Ask::Actions.available:
43
+ # Ask::Actions.register "chats.create", Chats::Create
@@ -27,6 +27,14 @@ module Ask
27
27
  template "application_agent.rb", "app/agents/application_agent.rb"
28
28
  end
29
29
 
30
+ def create_actions_directory
31
+ empty_directory "app/actions"
32
+ end
33
+
34
+ def create_application_action
35
+ template "application_action.rb", "app/actions/application_action.rb"
36
+ end
37
+
30
38
  def create_workflows_directory
31
39
  return if skip_graph?
32
40
  empty_directory "app/workflows"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -105,12 +105,20 @@ files:
105
105
  - LICENSE
106
106
  - README.md
107
107
  - lib/ask-rails.rb
108
+ - lib/ask/actions.rb
109
+ - lib/ask/actions/backend.rb
110
+ - lib/ask/actions/context.rb
111
+ - lib/ask/actions/result.rb
108
112
  - lib/ask/rails.rb
109
113
  - lib/ask/rails/railtie.rb
110
114
  - lib/ask/rails/state.rb
111
115
  - lib/ask/rails/version.rb
116
+ - lib/generators/ask/action/templates/action.rb
117
+ - lib/generators/ask/action_generator.rb
112
118
  - lib/generators/ask/agent/templates/agent.rb
119
+ - lib/generators/ask/agent/templates/instructions.md
113
120
  - lib/generators/ask/agent_generator.rb
121
+ - lib/generators/ask/install/templates/application_action.rb
114
122
  - lib/generators/ask/install/templates/application_agent.rb
115
123
  - lib/generators/ask/install/templates/application_workflow.rb
116
124
  - lib/generators/ask/install/templates/audit_log_migration.rb