prompt_manager 1.0.1 → 1.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +130 -25
  3. data/README.md +127 -263
  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 +60 -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 -131
  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 -81
  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 -127
  50. data/docs/guides/shell-expansion.md +0 -108
  51. data/docs/index.md +0 -70
  52. data/mkdocs.yml +0 -181
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f6339dd195179a1d9d9f996d1dfc4d0c689a3ed4bb9415fe2d5d68eaaa761ba
4
- data.tar.gz: 2b443af6d4ea259fd124c6ff9d225129d0e233fbffc0d9e86a42ce2189595f29
3
+ metadata.gz: 054d44665ba78d1751047ba4ebc0eb34a37cc312fe36e7cf238c7412c505f3bc
4
+ data.tar.gz: 0b4fb1dd12313e82bd489defaed84eadf9e1919726503e9235ce3a2ed582d820
5
5
  SHA512:
6
- metadata.gz: 26ec66ace02ff31ced22d3bd331884c0c74d5ee7356e138897759ed70be2be7d52dca239d3f1ac30c6599c8133446d199db7833de18fda7053e6fc977a1bde3b
7
- data.tar.gz: a60049ad709699ec112b43c6f281dd50ae6b80d3774c5c9a58e56d6daebcb5ccfc647544461f62f3f6e4a23367421d1401b34988ae22657764b72bf387c03ff8
6
+ metadata.gz: 4f30c3a11c0e2931740670a8bc4030a1714630f4eda0d511e4a49a69de276f1793825e1a7de6b01d510309e09225d51f64bdb24d83755a037809342d39366ba1
7
+ data.tar.gz: 8be879b0911d23e5c3db84bf0e686b6a29ef77c9adecb3be8058b4094d231ed0c79876fe638c5aeb21b9184fbb95dc63e2dab151f231d918f661a11e4a78f22f
data/CHANGELOG.md CHANGED
@@ -1,23 +1,128 @@
1
- ### [1.0.1] - 2026-02-04
2
-
3
- #### Added
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [1.1.0] - 2026-11-01
8
+
9
+ A hardening release. Shell expansion can no longer be hijacked by its own
10
+ output, the include chain works as documented, every failure PM raises has a
11
+ class of its own, and the gem ships with zero runtime dependencies at 23 KB
12
+ instead of 9.6 MB. No template syntax changed; see **Upgrading** for the
13
+ behaviour that did.
14
+
15
+ ### Upgrading from 1.0.x
16
+
17
+ - **Ruby 4.0.9 or later is required** (was 3.2).
18
+ - **Errors are typed.** Failures that raised `RuntimeError` now raise a
19
+ `PM::Error` subclass (`PM::CircularIncludeError`, `PM::ShellCommandError`,
20
+ `PM::FileNotFoundError`, ...). `rescue RuntimeError` no longer catches them;
21
+ `rescue PM::Error` does. Missing-parameter errors are still `ArgumentError`s
22
+ with the same message, via `PM::MissingParameterError`.
23
+ - **Two silent cases now raise:** an unmatched `$(` (`PM::ShellExpansionError`)
24
+ and a `shell:` / `erb:` value that is not a boolean or true/false/yes/no/on/off
25
+ (`PM::MetadataError`).
26
+ - **`PM::Metadata` is no longer an `OpenStruct`.** Dot access, predicates, `[]`,
27
+ `respond_to?`, and `to_h` are unchanged; only `is_a?(OpenStruct)` checks break.
28
+ - **`PM::Parsed` and `PM::RenderContext` are immutable `Data` objects.** Readers
29
+ are unchanged; writers such as `parsed.content = ...` are gone.
30
+ - **`PM.directives` returns a frozen snapshot.** Use `PM.register` and
31
+ `PM.reset_directives!` to change the registry.
32
+ - **The gem no longer contains `docs/`, examples, or media.** Documentation is
33
+ at <https://madbomber.github.io/prompt_manager>.
34
+
35
+ ### Added
36
+
37
+ - **Error hierarchy** rooted at `PM::Error`: `MetadataError`,
38
+ `ShellExpansionError` > `ShellCommandError` (`#command`, `#status`, `#stderr`),
39
+ `IncludeError` > `CircularIncludeError` / `IncludeDepthError` /
40
+ `IncludeContextError`, `FileNotFoundError`, `DirectiveAlreadyRegisteredError`;
41
+ plus `ParameterError` > `MissingParameterError` / `UnknownParameterError`
42
+ under `ArgumentError`.
43
+ - **Configuration:** `lock!` / `unlock!` / `locked?` make the global `shell` and
44
+ `erb` final so a file cannot re-enable a stage; `max_include_depth` (default 10,
45
+ `nil` = unlimited); `strict_parameters` turns an unknown template name into
46
+ `PM::UnknownParameterError` instead of `""`. `PM.configure` returns the config.
47
+ - **Shell expansion:** `\$` writes a literal `$`; fenced code blocks (``` / ~~~)
48
+ are skipped; `PM.expand_shell(str, erb_safe: true)` escapes `<%` in command output.
49
+ - **`PM::Parsed`:** `#to_h`, `#to_markdown` (round-trippable front matter +
50
+ content, derived keys omitted), `#parameters`, `#key?`.
51
+ - **`PM::Metadata`:** `Enumerable`, plus `dig`, `fetch`, `keys`, `values`,
52
+ `size`, `empty?`, `delete`, `each_pair`, `==`.
53
+ - **`PM.directive?(name)`.**
54
+ - **CI:** GitHub Actions on Ubuntu and macOS with a 100% line-coverage gate
55
+ (SimpleCov); `.ruby-version` pins development to 4.0.9.
56
+ - **Docs:** new Security guide and Errors reference.
57
+
58
+ ### Changed
59
+
60
+ - **Shell expansion is one left-to-right pass.** Command output is spliced in
61
+ verbatim and never re-scanned, so `$VAR`, `$(...)`, or `<%` printed by a
62
+ command stays text. Command stderr goes to `$stderr` on success and into
63
+ `ShellCommandError` on failure.
64
+ - **`include` tracks ancestors, not every rendered file,** so the same fragment
65
+ can be included twice in one prompt. Included files may have any extension.
66
+ - **Front matter is validated:** must be a mapping (or empty); `parameters:`
67
+ must be a mapping; flags are coerced as described under Upgrading.
68
+ - **Directive registry policy:** `PM.register` is atomic (nothing is registered
69
+ if any name is taken). `PM::Directive.register_all` is idempotent, lets a later
70
+ subclass override an earlier one, and raises if a name was claimed with
71
+ `PM.register`.
72
+ - **Template name resolution is defined:** parameter (called without arguments)
73
+ > directive > `nil` (or error in strict mode).
74
+ - **Internals:** rendering moved from `Parsed` into `PM::Renderer` and
75
+ `PM::RenderScope`; `Parsed#render_with` remains for `include`.
76
+ - **Packaging:** gemspec allow-lists `lib/**/*.rb`, `README.md`, `CHANGELOG.md`,
77
+ `LICENSE`; adds `changelog_uri`, `documentation_uri`, `bug_tracker_uri`;
78
+ development dependencies move to the Gemfile.
79
+
80
+ ### Fixed
81
+
82
+ - Including the same file twice raised "Circular include detected".
83
+ - Empty (`---\n---`) or scalar front matter raised `NoMethodError`.
84
+ - `include` of a path without `.md` parsed the path string as the prompt.
85
+ - `created_at` raised `NotImplementedError` on filesystems without birthtime;
86
+ it now falls back to `ctime`.
87
+ - `erb: 'true'` (a string) silently disabled ERB.
88
+ - A metadata key named like an `Object` method (`hash`, `method`, `display`)
89
+ returned the method instead of the value.
90
+ - Two tests asserted nothing and produced `ruby -w` warnings; `.irbrc` used the
91
+ removed 0.x API.
92
+ - Documentation corrections throughout: built-in directive lists, error messages,
93
+ `content` newline examples, `Struct` signatures, hard-coded version, an opening
94
+ example that registered the built-in `:read`, and fences nested inside fences.
95
+
96
+ ### Removed
97
+
98
+ - The `ostruct` runtime dependency. PM now has none.
99
+ - `test/pm_test.rb` (redundant with the Rakefile glob).
100
+ - Documentation, examples, and media from the packaged gem.
101
+
102
+ ## [1.0.2] - 2026-02-09
103
+
104
+ ### Changed
105
+ - Made `PM.parse_string` a public class method so it can be called directly for parsing strings without file-based metadata enrichment.
106
+
107
+ ## [1.0.1] - 2026-02-04
108
+
109
+ ### Added
4
110
  - **`PM::Directive` base class** — class-based DSL for defining directive categories. Use `desc` before method definitions to mark them as directives, and `alias_method` for aliases. Subclass tracking, `register_all`, `category_name`, and `build_dispatch_block` are all built-in.
5
111
  - **Built-in `insert` directive** (alias: `read`) — insert any file's raw content into a prompt. Unlike `include`, the inserted content is not parsed, shell-expanded, or ERB-rendered.
6
112
  - New test file `directive_base_test.rb` with tests for the `PM::Directive` DSL, subclass tracking, category naming, and dispatch block building.
7
113
  - New test fixtures for `insert`/`read` directive coverage.
8
114
 
9
- #### Changed
115
+ ### Changed
10
116
  - **`PM::CoreDirectives`** — built-in `include`, `insert`/`read` directives refactored as a `PM::Directive` subclass using the `desc` DSL.
11
117
  - `PM.register` directive aliases now support registration via `alias_method` in `PM::Directive` subclasses, with automatic detection via `UnboundMethod#original_name`.
12
118
  - Directive registry simplified; `PM.reset_directives!` now delegates to `PM::Directive.register_all`.
13
119
  - Updated README and documentation guides for custom directives and includes.
14
120
 
15
- ## Released
16
- ### [1.0.0] = 2026-02-03
121
+ ## [1.0.0] - 2026-02-03
17
122
 
18
123
  **Complete rewrite** — repositioned from a prompt management system with storage adapters to a focused prompt parsing and rendering engine.
19
124
 
20
- #### Breaking Changes
125
+ ### Breaking Changes
21
126
  - **New `PM` module replaces `PromptManager`** — the entire codebase has been restructured under the `PM` namespace. A backward-compatibility alias (`PromptManager = PM`) is provided via `require 'prompt_manager'`.
22
127
  - **Storage adapters removed** — `FileSystemAdapter`, `ActiveRecordAdapter`, and all database-backed persistence have been removed. The library now operates on strings, files, and Pathnames directly.
23
128
  - **`Prompt` class removed** — replaced by the lightweight `PM::Parsed` struct.
@@ -25,7 +130,7 @@
25
130
  - **Parameter history removed** — the library no longer tracks historical parameter values per keyword.
26
131
  - **Configuration simplified** — only three settings remain: `prompts_dir`, `shell`, and `erb`. Options like `parameter_regex` and `search_proc` have been removed.
27
132
 
28
- #### New Features
133
+ ### New Features
29
134
  - **Symbol and single-word parsing** — `PM.parse(:code_review)` and `PM.parse('code_review')` automatically resolve to `code_review.md` in the configured `prompts_dir`.
30
135
  - **Directive aliases** — `PM.register(:webpage, :website, :web) { |ctx, url| ... }` registers multiple names for a single directive with rollback on duplicate detection.
31
136
  - **`PM::Metadata`** — OpenStruct-based metadata with automatic predicate methods for boolean fields (e.g., `metadata.shell?`).
@@ -33,7 +138,7 @@
33
138
  - **Built-in `include` directive** — compose prompts from multiple files with loop protection.
34
139
  - **Streamlined parsing pipeline** — strip HTML comments, extract YAML front matter, optional shell expansion (`$VAR`, `${VAR}`, `$(command)`), optional ERB rendering.
35
140
 
36
- #### Removed
141
+ ### Removed
37
142
  - `PromptManager::Prompt` class
38
143
  - `PromptManager::DirectiveProcessor` class
39
144
  - `PromptManager::Storage::FileSystemAdapter`
@@ -41,35 +146,35 @@
41
146
  - Custom error classes (`PromptManager::Error` hierarchy)
42
147
  - Development dependencies on `activerecord`, `sqlite3`, and `tocer`
43
148
 
44
- #### Added
149
+ ### Added
45
150
  - Runtime dependency on `ostruct`
46
151
  - Comprehensive test suite (8 test files, 19 fixtures)
47
152
  - Full documentation site under `docs/` with guides for parsing, shell expansion, ERB rendering, custom directives, and prompt composition
48
153
 
49
- ### [0.5.8] = 2025-09-01
154
+ ## [0.5.8] - 2025-09-01
50
155
  - fixed issue where removed keywords from prompt text were still being included in parameters if they existed in the JSON file (addresses AIA issue #105)
51
156
  - parameters now only include keywords currently present in the prompt text, while preserving historical values for existing keywords
52
157
 
53
- ### [0.5.7] = 2025-06-25
158
+ ## [0.5.7] - 2025-06-25
54
159
  - fixed a problem when the value of a parameter is an empty array
55
160
  - fixed a failing test
56
161
 
57
- ### [0.5.6] = 2025-06-04
162
+ ## [0.5.6] - 2025-06-04
58
163
  - fixed a problem where shell integration was not working correctly for $(shell command)
59
164
 
60
- ### [0.5.5] = 2025-05-21
165
+ ## [0.5.5] - 2025-05-21
61
166
  - fixed bug in parameter substitution when value is an Array now uses last entry
62
167
 
63
- ### [0.5.4] = 2025-05-18
168
+ ## [0.5.4] - 2025-05-18
64
169
  - fixed typo in the Prompt class envvar should have been envar which prevented shell integration from taking place.
65
170
 
66
- ### [0.5.3] = 2025-05-14
171
+ ## [0.5.3] - 2025-05-14
67
172
  - fixed issue were directives were not getting their content added to the prompt text
68
173
  - Updated documentation and versioning.
69
174
  - Added new error classes for better error handling.
70
175
  - Improved parameter handling and directive processing.
71
176
 
72
- ### [0.5.0] = 2025-03-29
177
+ ## [0.5.0] - 2025-03-29
73
178
  - Major refactoring of to improve processing of parameters and directives.
74
179
  - Added PromptManager::DirectiveProcessor as an example of how to implement custom directives.
75
180
  - Added support for //include directive that protects against loops.
@@ -77,33 +182,33 @@
77
182
  - Added support for ERB processing within a prompt.
78
183
  - Improved test coverage.
79
184
 
80
- ### [0.4.2] = 2024-10-26
185
+ ## [0.4.2] - 2024-10-26
81
186
  - Added configurable parameter_regex to customize keyword pattern
82
187
 
83
- ### [0.4.1] = 2023-12-29
188
+ ## [0.4.1] - 2023-12-29
84
189
  - Changed @directives from Hash to an Array
85
190
  - Fixed keywords not being substituted in directives
86
191
 
87
- ### [0.4.0] = 2023-12-19
192
+ ## [0.4.0] - 2023-12-19
88
193
  - Add "//directives param(s)" with keywords just like the prompt text.
89
194
 
90
- ### [0.3.3] = 2023-12-01
195
+ ## [0.3.3] - 2023-12-01
91
196
  - Added example of using the `search_proc` config parameter with the FileSystemAdapter.
92
197
 
93
- ### [0.3.2] = 2023-12-01
198
+ ## [0.3.2] - 2023-12-01
94
199
 
95
200
  - The ActiveRecordAdapter is passing its unit tests
96
201
  - Dropped the concept of an sqlite3 adapter since active record can be used to access sqlite3 databases as well as the big boys.
97
202
 
98
- ### [0.3.0] = 2023-11-28
203
+ ## [0.3.0] - 2023-11-28
99
204
 
100
205
  - **Breaking change** The value of the parameters Hash for a keyword is now an Array instead of a single value. The last value in the Array is always the most recent value used for the given keyword. This was done to support the use of a Readline::History object editing in the [aia](https://github.com/MadBomber/aia) CLI tool
101
206
 
102
- ### [0.2.0] - 2023-11-21
207
+ ## [0.2.0] - 2023-11-21
103
208
 
104
209
  - **Breaking change to FileSystemAdapter config process**
105
210
  - added list and path as extra methods in FileSystemAdapter
106
211
 
107
- ### [0.1.0] - 2023-11-16
212
+ ## [0.1.0] - 2023-11-16
108
213
 
109
214
  - Initial release using the FileSystemAdapter