prompt_manager 1.0.2 → 1.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +138 -27
  3. data/README.md +127 -271
  4. data/lib/pm/configuration.rb +34 -4
  5. data/lib/pm/core_directives.rb +21 -20
  6. data/lib/pm/directive.rb +26 -34
  7. data/lib/pm/directives.rb +55 -16
  8. data/lib/pm/errors.rb +71 -0
  9. data/lib/pm/metadata.rb +110 -9
  10. data/lib/pm/parsed.rb +51 -46
  11. data/lib/pm/render_scope.rb +74 -0
  12. data/lib/pm/renderer.rb +59 -0
  13. data/lib/pm/shell.rb +95 -40
  14. data/lib/pm/version.rb +1 -1
  15. data/lib/pm.rb +116 -57
  16. data/lib/prompt_manager.rb +6 -0
  17. metadata +13 -113
  18. data/.envrc +0 -3
  19. data/.irbrc +0 -14
  20. data/COMMITS.md +0 -196
  21. data/Rakefile +0 -12
  22. data/docs/api/configuration.md +0 -59
  23. data/docs/api/constants.md +0 -60
  24. data/docs/api/index.md +0 -14
  25. data/docs/api/metadata.md +0 -99
  26. data/docs/api/parsed.md +0 -98
  27. data/docs/api/pm-module.md +0 -169
  28. data/docs/api/render-context.md +0 -51
  29. data/docs/architecture/design-decisions.md +0 -70
  30. data/docs/architecture/index.md +0 -6
  31. data/docs/architecture/processing-pipeline.md +0 -112
  32. data/docs/assets/css/custom.css +0 -1
  33. data/docs/assets/images/prompt_manager.gif +0 -0
  34. data/docs/assets/images/prompt_manager.mp4 +0 -0
  35. data/docs/examples/ai-agent-prompts.md +0 -173
  36. data/docs/examples/code-review-prompt.md +0 -107
  37. data/docs/examples/index.md +0 -7
  38. data/docs/examples/multi-file-composition.md +0 -123
  39. data/docs/getting-started/configuration.md +0 -106
  40. data/docs/getting-started/index.md +0 -7
  41. data/docs/getting-started/installation.md +0 -34
  42. data/docs/getting-started/quick-start.md +0 -94
  43. data/docs/guides/comment-stripping.md +0 -64
  44. data/docs/guides/custom-directives.md +0 -180
  45. data/docs/guides/erb-rendering.md +0 -102
  46. data/docs/guides/includes.md +0 -184
  47. data/docs/guides/index.md +0 -11
  48. data/docs/guides/parameters.md +0 -96
  49. data/docs/guides/parsing.md +0 -151
  50. data/docs/guides/shell-expansion.md +0 -108
  51. data/docs/index.md +0 -70
  52. data/mkdocs.yml +0 -181
data/lib/pm/shell.rb CHANGED
@@ -1,57 +1,112 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'open3'
4
+ require 'strscan'
4
5
 
5
6
  module PM
6
- # Expands shell references in a string.
7
- # $ENVAR and ${ENVAR} are replaced with the environment variable value.
8
- # $(command) is executed and replaced with its stdout.
9
- def self.expand_shell(string)
10
- result = expand_commands(string)
11
- expand_env_vars(result)
7
+ # Expands shell references in a string in a single left-to-right pass:
8
+ #
9
+ # $(command) -- replaced with the command's stdout (trailing newline removed)
10
+ # $VAR, ${VAR} -- replaced with the environment variable (UPPERCASE names only; "" if unset)
11
+ # \$ -- a literal dollar sign; the backslash is removed
12
+ #
13
+ # Command output is spliced in verbatim and never re-scanned, so a `$VAR` or
14
+ # `$(...)` that a command prints stays literal. With `erb_safe: true` any
15
+ # `<%` in command output is written as `<%%`, which ERB renders as a literal
16
+ # `<%`, so output cannot inject Ruby into a later ERB pass.
17
+ #
18
+ # Fenced code blocks (lines starting with ``` or ~~~) are copied through
19
+ # untouched: a prompt can show shell syntax to the model without running it.
20
+ #
21
+ # Raises PM::ShellExpansionError for an unmatched `$(` and
22
+ # PM::ShellCommandError when a command exits non-zero.
23
+ def self.expand_shell(string, erb_safe: false)
24
+ ShellExpander.new(string, erb_safe: erb_safe).expand
12
25
  end
13
26
 
14
- # Replaces $(command) with the command's stdout.
15
- # Handles nested parentheses in commands.
16
- def self.expand_commands(string)
17
- result = string.dup
18
- pos = 0
27
+ class ShellExpander
28
+ FENCE_OPEN_REGEXP = /[ ]{0,3}(`{3,}|~{3,})[^\n]*(?:\n|\z)/
29
+ LINE_REGEXP = /[^\n]*(?:\n|\z)/
30
+ ESCAPED_DOLLAR = /\\\$/
31
+ COMMAND_OPEN = /\$\(/
19
32
 
20
- while (start = result.index(COMMAND_START, pos))
21
- depth = 0
22
- i = start + 1
33
+ def initialize(string, erb_safe: false)
34
+ @scanner = StringScanner.new(string)
35
+ @erb_safe = erb_safe
36
+ end
23
37
 
24
- while i < result.length
25
- if result[i] == '('
26
- depth += 1
27
- elsif result[i] == ')'
28
- depth -= 1
29
- if depth == 0
30
- command = result[(start + 2)...i]
31
- output, status = Open3.capture2(command)
32
- output = output.chomp
33
- unless status.success?
34
- raise "Shell command failed (exit #{status.exitstatus}): #{command}"
35
- end
36
- result[start..i] = output
37
- pos = start + output.length
38
- break
39
- end
38
+ def expand
39
+ out = +''
40
+ at_line_start = true
41
+
42
+ until @scanner.eos?
43
+ if at_line_start && (fence = @scanner.scan(FENCE_OPEN_REGEXP))
44
+ out << fence << copy_fenced_block(fence)
45
+ elsif @scanner.scan(ESCAPED_DOLLAR)
46
+ out << '$'
47
+ elsif @scanner.scan(COMMAND_OPEN)
48
+ out << run_command
49
+ elsif @scanner.scan(ENV_VAR_REGEXP)
50
+ out << ENV.fetch(@scanner[1] || @scanner[2], '')
51
+ else
52
+ out << @scanner.getch
40
53
  end
41
- i += 1
54
+
55
+ at_line_start = out.end_with?("\n")
42
56
  end
43
57
 
44
- break if depth != 0
58
+ out
45
59
  end
46
60
 
47
- result
48
- end
49
- private_class_method :expand_commands
61
+ private
62
+
63
+ # Copies lines verbatim up to and including the closing fence (or end of input).
64
+ def copy_fenced_block(open_line)
65
+ marker = open_line[/`{3,}|~{3,}/]
66
+ close = /\A[ ]{0,3}#{Regexp.escape(marker[0])}{#{marker.length},}[ \t]*(?:\n|\z)\z/
67
+ out = +''
68
+
69
+ until @scanner.eos?
70
+ line = @scanner.scan(LINE_REGEXP)
71
+ out << line
72
+ break if line.match?(close)
73
+ end
74
+
75
+ out
76
+ end
77
+
78
+ # Called with the scanner positioned just after "$(". Finds the matching
79
+ # ")" (honouring nested parentheses), runs the command, and returns its stdout.
80
+ def run_command
81
+ command = read_command
82
+ output, stderr, status = Open3.capture3(command)
50
83
 
51
- # Replaces $ENVAR and ${ENVAR} with environment variable values.
52
- # Missing variables are replaced with an empty string.
53
- def self.expand_env_vars(string)
54
- string.gsub(ENV_VAR_REGEXP) { ENV.fetch($1 || $2, '') }
84
+ raise ShellCommandError.new(command, status, stderr) unless status.success?
85
+
86
+ $stderr.write(stderr) unless stderr.empty? # keep warnings visible, as with 1.0.x
87
+ output = output.chomp
88
+ output = output.gsub('<%', '<%%') if @erb_safe
89
+ output
90
+ end
91
+
92
+ def read_command
93
+ depth = 1
94
+ command = +''
95
+
96
+ until @scanner.eos?
97
+ char = @scanner.getch
98
+ if char == '('
99
+ depth += 1
100
+ elsif char == ')'
101
+ depth -= 1
102
+ break if depth.zero?
103
+ end
104
+ command << char
105
+ end
106
+
107
+ raise ShellExpansionError, "Unmatched $( in shell expansion: $(#{command}" unless depth.zero?
108
+
109
+ command
110
+ end
55
111
  end
56
- private_class_method :expand_env_vars
57
112
  end
data/lib/pm/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PM
4
- VERSION = '1.0.2'
4
+ VERSION = '1.2.0'
5
5
  end
data/lib/pm.rb CHANGED
@@ -4,8 +4,11 @@ require 'date'
4
4
  require 'pathname'
5
5
  require 'yaml'
6
6
 
7
- # PM (PromptManager) parses YAML metadata from markdown strings or files.
8
- # Processing pipeline: strip HTML comments → extract metadata → shell expansion → ERB on demand.
7
+ # PM (PromptManager) parses YAML front matter from markdown strings or files.
8
+ # Pipeline: strip HTML comments → extract metadata → shell expansion → ERB on demand (#to_s).
9
+ #
10
+ # Not thread-safe: PM.config and the directive registry are process-wide state.
11
+ # Configure and register directives at boot, then parse and render from any thread.
9
12
  module PM
10
13
  METADATA_REGEXP = /
11
14
  \A
@@ -19,8 +22,13 @@ module PM
19
22
  /mx
20
23
 
21
24
  HTML_COMMENT_REGEXP = /<!--.*?-->/m
22
- ENV_VAR_REGEXP = /\$\{([A-Z_][A-Z0-9_]*)\}|\$([A-Z_][A-Z0-9_]*)/
23
- COMMAND_START = '$('
25
+ ENV_VAR_REGEXP = /\$\{([A-Z_][A-Z0-9_]*)\}|\$([A-Z_][A-Z0-9_]*)/
26
+ COMMAND_START = '$('
27
+
28
+ # Front-matter keys that control the pipeline and must be true/false.
29
+ FLAG_KEYS = %w[shell erb].freeze
30
+ TRUE_WORDS = %w[true yes on].freeze
31
+ FALSE_WORDS = %w[false no off].freeze
24
32
 
25
33
  def self.config
26
34
  @config ||= Configuration.new
@@ -28,99 +36,150 @@ module PM
28
36
 
29
37
  def self.configure
30
38
  yield config
39
+ config
31
40
  end
32
41
 
33
42
  # --- Parsing ---
34
43
 
35
- # Parses a source through the full pipeline:
36
- # strip HTML comments → extract YAML metadata → shell expansion (when shell: true).
44
+ # Parses a source through the full pipeline.
45
+ #
46
+ # When source is a Pathname, responds to :to_path, is a String ending in
47
+ # ".md", a Symbol, or a single word (e.g. "greeting"), it is treated as a
48
+ # file path. Symbols and single-word strings become "name.md" basenames.
49
+ # Relative paths are resolved against PM.config.prompts_dir. The file is
50
+ # read and `directory`, `name`, `created_at`, `modified_at` are added to
51
+ # the metadata.
37
52
  #
38
- # When source is a Pathname, responds to :to_path, is a String ending
39
- # in ".md", a Symbol, or a single word (e.g. "greeting"), it is treated
40
- # as a file path. Symbols and single-word strings are converted to
41
- # "name.md" basenames. The file is read and parsed, and `directory`,
42
- # `name`, `created_at`, `modified_at` are added to metadata.
53
+ # Otherwise source is parsed directly as a string (see .parse_string).
43
54
  #
44
- # Otherwise source is parsed directly as a string.
55
+ # Raises Errno::ENOENT when the file does not exist.
45
56
  def self.parse(source)
46
57
  source = "#{source}.md" if source.is_a?(Symbol) || single_word?(source)
47
-
48
- if file_source?(source)
49
- raw = source.respond_to?(:to_path) ? source.to_path : source
50
- unless config.prompts_dir.empty?
51
- raw = (Pathname.new(config.prompts_dir) + raw).to_s
52
- end
53
- path = File.expand_path(raw)
54
- parsed = parse_string(File.read(path))
55
-
56
- stat = File.stat(path)
57
- metadata = build_metadata(
58
- parsed.metadata.to_h.merge(
59
- directory: File.dirname(path),
60
- name: File.basename(path),
61
- created_at: stat.birthtime,
62
- modified_at: stat.mtime
63
- )
58
+ return parse_string(source) unless file_source?(source)
59
+
60
+ path = resolve_path(source)
61
+ parsed = parse_string(File.read(path))
62
+ stat = File.stat(path)
63
+
64
+ metadata = build_metadata(
65
+ parsed.metadata.to_h.merge(
66
+ directory: File.dirname(path),
67
+ name: File.basename(path),
68
+ created_at: birthtime(stat),
69
+ modified_at: stat.mtime
64
70
  )
65
- Parsed.new(metadata: metadata, content: parsed.content)
71
+ )
72
+ Parsed.new(metadata: metadata, content: parsed.content)
73
+ end
74
+
75
+ # Parses a string, never treating it as a file name.
76
+ #
77
+ # Raises PM::MetadataError when the front matter is not a YAML mapping, or
78
+ # when `shell`, `erb`, or `parameters` have values of the wrong type.
79
+ # YAML syntax errors raise Psych::SyntaxError.
80
+ def self.parse_string(string)
81
+ stripped = strip_comments(string)
82
+ match = stripped.match(METADATA_REGEXP)
83
+
84
+ if match
85
+ metadata = build_metadata(load_front_matter(match[:metadata]))
86
+ content = match[:content]
66
87
  else
67
- parse_string(source)
88
+ metadata = build_metadata({})
89
+ content = stripped
68
90
  end
91
+
92
+ content = expand_shell(content, erb_safe: metadata.erb?) if metadata.shell?
93
+
94
+ Parsed.new(metadata: metadata, content: content)
69
95
  end
70
96
 
71
- # Returns true when source should be treated as a file path.
97
+ # Strips HTML comments from a string.
98
+ def self.strip_comments(string)
99
+ string.gsub(HTML_COMMENT_REGEXP, '')
100
+ end
101
+
102
+ # --- Internals ---
103
+
72
104
  def self.file_source?(source)
73
105
  source.respond_to?(:to_path) || (source.is_a?(String) && source.end_with?('.md'))
74
106
  end
75
107
  private_class_method :file_source?
76
108
 
77
- # Returns true when source is a single word with no spaces,
78
- # path separators, or file extension.
109
+ # True when source is a single word: no spaces, path separators, or extension.
79
110
  def self.single_word?(source)
80
111
  source.is_a?(String) && source.match?(/\A\w+\z/)
81
112
  end
82
113
  private_class_method :single_word?
83
114
 
84
- # Parses a string through the full pipeline.
85
- def self.parse_string(string)
86
- stripped = strip_comments(string)
87
- match = stripped.match(METADATA_REGEXP)
88
-
89
- if match
90
- metadata = build_metadata(YAML.safe_load(match[:metadata], permitted_classes: [Date, Time]))
91
- content = match[:content]
92
- else
93
- metadata = build_metadata({})
94
- content = stripped
95
- end
115
+ def self.resolve_path(source)
116
+ raw = source.respond_to?(:to_path) ? source.to_path : source
117
+ raw = (Pathname.new(config.prompts_dir) + raw).to_s unless config.prompts_dir.empty?
118
+ File.expand_path(raw)
119
+ end
120
+ private_class_method :resolve_path
121
+
122
+ # File creation time, falling back to ctime where the platform or
123
+ # filesystem has no birthtime (several Linux filesystems, containers).
124
+ def self.birthtime(stat)
125
+ stat.birthtime
126
+ rescue NotImplementedError, NoMethodError
127
+ stat.ctime
128
+ end
129
+ private_class_method :birthtime
96
130
 
97
- content = expand_shell(content) if metadata.shell?
131
+ def self.load_front_matter(yaml)
132
+ data = YAML.safe_load(yaml, permitted_classes: [Date, Time])
133
+ return {} if data.nil?
134
+ raise MetadataError, "Front matter must be a YAML mapping, got #{data.class}" unless data.is_a?(Hash)
98
135
 
99
- Parsed.new(metadata: metadata, content: content)
136
+ data
100
137
  end
138
+ private_class_method :load_front_matter
101
139
 
102
-
103
- # Builds a Metadata object with defaults for shell and erb.
140
+ # Builds Metadata with `shell` and `erb` resolved against the global config
141
+ # (the file wins unless the config is locked) and the `parameters` type checked.
104
142
  def self.build_metadata(hash)
105
- defaults = { 'shell' => config.shell, 'erb' => config.erb }
106
- Metadata.new(defaults.merge(hash.transform_keys(&:to_s)))
143
+ attrs = hash.transform_keys(&:to_s)
144
+
145
+ FLAG_KEYS.each do |key|
146
+ global = config.public_send(key)
147
+ value = attrs[key]
148
+ attrs[key] = config.locked? || value.nil? ? global : coerce_flag(key, value)
149
+ end
150
+
151
+ params = attrs['parameters']
152
+ unless params.nil? || params.is_a?(Hash)
153
+ raise MetadataError, "parameters must be a mapping, got #{params.class}"
154
+ end
155
+
156
+ Metadata.new(attrs)
107
157
  end
108
158
  private_class_method :build_metadata
109
159
 
110
- # Strips HTML comments from a string.
111
- def self.strip_comments(string)
112
- string.gsub(HTML_COMMENT_REGEXP, '')
160
+ def self.coerce_flag(key, value)
161
+ return value if value.equal?(true) || value.equal?(false)
162
+
163
+ word = value.to_s.strip.downcase
164
+ return true if TRUE_WORDS.include?(word)
165
+ return false if FALSE_WORDS.include?(word)
166
+
167
+ raise MetadataError, "#{key} must be true or false, got #{value.inspect}"
113
168
  end
169
+ private_class_method :coerce_flag
114
170
  end
115
171
 
116
- require_relative 'pm/configuration'
117
172
  require_relative 'pm/version'
173
+ require_relative 'pm/errors'
174
+ require_relative 'pm/configuration'
118
175
  require_relative 'pm/metadata'
176
+ require_relative 'pm/render_scope'
177
+ require_relative 'pm/renderer'
119
178
  require_relative 'pm/parsed'
179
+ require_relative 'pm/shell'
120
180
  require_relative 'pm/directives'
121
181
  require_relative 'pm/directive'
122
182
  require_relative 'pm/core_directives'
123
- require_relative 'pm/shell'
124
183
 
125
184
  # Register built-in directives from PM::CoreDirectives
126
185
  PM::Directive.register_all
@@ -1,3 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Entry point for `require 'prompt_manager'` (the gem name, which Bundler
4
+ # auto-requires). The library lives in the PM namespace; PromptManager is a
5
+ # namespace alias only. The 0.x PromptManager::Prompt / Storage API was
6
+ # removed in 1.0.0 and is not provided here.
1
7
  require_relative 'pm'
2
8
 
3
9
  PromptManager = PM
metadata CHANGED
@@ -1,142 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prompt_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: ostruct
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '0'
19
- type: :runtime
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - ">="
24
- - !ruby/object:Gem::Version
25
- version: '0'
26
- - !ruby/object:Gem::Dependency
27
- name: amazing_print
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '0'
40
- - !ruby/object:Gem::Dependency
41
- name: debug_me
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
- type: :development
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- - !ruby/object:Gem::Dependency
55
- name: minitest
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '0'
61
- type: :development
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: '0'
68
- - !ruby/object:Gem::Dependency
69
- name: simplecov
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: '0'
75
- type: :development
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: '0'
11
+ dependencies: []
82
12
  description: |
83
- PM (PromptManager) parses YAML metadata from markdown strings or files.
84
- It expands shell references, extracts metadata and content, and renders
85
- ERB templates on demand.
13
+ PM (PromptManager) parses YAML front matter from markdown strings or files.
14
+ It expands shell references, extracts metadata and content, composes prompts
15
+ from other files with include/insert directives, and renders ERB on demand.
86
16
  email:
87
17
  - dvanhoozer@gmail.com
88
18
  executables: []
89
19
  extensions: []
90
20
  extra_rdoc_files: []
91
21
  files:
92
- - ".envrc"
93
- - ".irbrc"
94
22
  - CHANGELOG.md
95
- - COMMITS.md
96
23
  - LICENSE
97
24
  - README.md
98
- - Rakefile
99
- - docs/api/configuration.md
100
- - docs/api/constants.md
101
- - docs/api/index.md
102
- - docs/api/metadata.md
103
- - docs/api/parsed.md
104
- - docs/api/pm-module.md
105
- - docs/api/render-context.md
106
- - docs/architecture/design-decisions.md
107
- - docs/architecture/index.md
108
- - docs/architecture/processing-pipeline.md
109
- - docs/assets/css/custom.css
110
- - docs/assets/images/prompt_manager.gif
111
- - docs/assets/images/prompt_manager.mp4
112
- - docs/examples/ai-agent-prompts.md
113
- - docs/examples/code-review-prompt.md
114
- - docs/examples/index.md
115
- - docs/examples/multi-file-composition.md
116
- - docs/getting-started/configuration.md
117
- - docs/getting-started/index.md
118
- - docs/getting-started/installation.md
119
- - docs/getting-started/quick-start.md
120
- - docs/guides/comment-stripping.md
121
- - docs/guides/custom-directives.md
122
- - docs/guides/erb-rendering.md
123
- - docs/guides/includes.md
124
- - docs/guides/index.md
125
- - docs/guides/parameters.md
126
- - docs/guides/parsing.md
127
- - docs/guides/shell-expansion.md
128
- - docs/index.md
129
25
  - lib/pm.rb
130
26
  - lib/pm/configuration.rb
131
27
  - lib/pm/core_directives.rb
132
28
  - lib/pm/directive.rb
133
29
  - lib/pm/directives.rb
30
+ - lib/pm/errors.rb
134
31
  - lib/pm/metadata.rb
135
32
  - lib/pm/parsed.rb
33
+ - lib/pm/render_scope.rb
34
+ - lib/pm/renderer.rb
136
35
  - lib/pm/shell.rb
137
36
  - lib/pm/version.rb
138
37
  - lib/prompt_manager.rb
139
- - mkdocs.yml
140
38
  homepage: https://github.com/MadBomber/prompt_manager
141
39
  licenses:
142
40
  - MIT
@@ -144,7 +42,9 @@ metadata:
144
42
  allowed_push_host: https://rubygems.org
145
43
  homepage_uri: https://github.com/MadBomber/prompt_manager
146
44
  source_code_uri: https://github.com/MadBomber/prompt_manager
147
- changelog_uri: https://github.com/MadBomber/prompt_manager
45
+ changelog_uri: https://github.com/MadBomber/prompt_manager/blob/main/CHANGELOG.md
46
+ documentation_uri: https://madbomber.github.io/prompt_manager
47
+ bug_tracker_uri: https://github.com/MadBomber/prompt_manager/issues
148
48
  rdoc_options: []
149
49
  require_paths:
150
50
  - lib
@@ -152,14 +52,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
52
  requirements:
153
53
  - - ">="
154
54
  - !ruby/object:Gem::Version
155
- version: 3.2.0
55
+ version: 4.0.9
156
56
  required_rubygems_version: !ruby/object:Gem::Requirement
157
57
  requirements:
158
58
  - - ">="
159
59
  - !ruby/object:Gem::Version
160
60
  version: '0'
161
61
  requirements: []
162
- rubygems_version: 4.0.6
62
+ rubygems_version: 4.0.23
163
63
  specification_version: 4
164
64
  summary: Parse YAML metadata from markdown prompts with shell expansion and ERB rendering
165
65
  test_files: []
data/.envrc DELETED
@@ -1,3 +0,0 @@
1
- # prompt_manager/.envrc
2
-
3
- export RR=`pwd`
data/.irbrc DELETED
@@ -1,14 +0,0 @@
1
- require_relative 'lib/prompt_manager'
2
- require_relative 'lib/prompt_manager/storage/file_system_adapter'
3
-
4
- HERE = Pathname.new __dir__
5
-
6
- PromptManager::Storage::FileSystemAdapter.config do |config|
7
- config.prompts_dir = HERE + 'examples/prompts_dir'
8
- # config.search_proc = nil # default
9
- # config.prompt_extension = '.txt' # default
10
- # config.parms+_extension = '.json' # default
11
- end
12
-
13
- PromptManager::Prompt.storage_adapter = PromptManager::Storage::FileSystemAdapter.new
14
-