prompt_manager 0.5.7 → 0.5.8

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 +4 -0
  3. data/COMMITS.md +196 -0
  4. data/README.md +485 -203
  5. data/docs/.keep +0 -0
  6. data/docs/advanced/custom-keywords.md +421 -0
  7. data/docs/advanced/dynamic-directives.md +535 -0
  8. data/docs/advanced/performance.md +612 -0
  9. data/docs/advanced/search-integration.md +635 -0
  10. data/docs/api/configuration.md +355 -0
  11. data/docs/api/directive-processor.md +431 -0
  12. data/docs/api/prompt-class.md +354 -0
  13. data/docs/api/storage-adapters.md +462 -0
  14. data/docs/assets/favicon.ico +1 -0
  15. data/docs/assets/logo.svg +24 -0
  16. data/docs/core-features/comments.md +48 -0
  17. data/docs/core-features/directive-processing.md +38 -0
  18. data/docs/core-features/erb-integration.md +68 -0
  19. data/docs/core-features/error-handling.md +197 -0
  20. data/docs/core-features/parameter-history.md +76 -0
  21. data/docs/core-features/parameterized-prompts.md +500 -0
  22. data/docs/core-features/shell-integration.md +79 -0
  23. data/docs/development/architecture.md +544 -0
  24. data/docs/development/contributing.md +425 -0
  25. data/docs/development/roadmap.md +234 -0
  26. data/docs/development/testing.md +822 -0
  27. data/docs/examples/advanced.md +523 -0
  28. data/docs/examples/basic.md +688 -0
  29. data/docs/examples/real-world.md +776 -0
  30. data/docs/examples.md +337 -0
  31. data/docs/getting-started/basic-concepts.md +318 -0
  32. data/docs/getting-started/installation.md +97 -0
  33. data/docs/getting-started/quick-start.md +256 -0
  34. data/docs/index.md +230 -0
  35. data/docs/migration/v0.9.0.md +459 -0
  36. data/docs/migration/v1.0.0.md +591 -0
  37. data/docs/storage/activerecord-adapter.md +348 -0
  38. data/docs/storage/custom-adapters.md +176 -0
  39. data/docs/storage/filesystem-adapter.md +236 -0
  40. data/docs/storage/overview.md +427 -0
  41. data/examples/advanced_integrations.rb +52 -0
  42. data/examples/prompts_dir/advanced_demo.txt +79 -0
  43. data/examples/prompts_dir/directive_example.json +1 -0
  44. data/examples/prompts_dir/directive_example.txt +8 -0
  45. data/examples/prompts_dir/todo.json +1 -1
  46. data/improvement_plan.md +996 -0
  47. data/lib/prompt_manager/storage/file_system_adapter.rb +8 -2
  48. data/lib/prompt_manager/version.rb +1 -1
  49. data/mkdocs.yml +146 -0
  50. data/prompt_manager_logo.png +0 -0
  51. metadata +46 -3
  52. data/LICENSE.txt +0 -21
@@ -0,0 +1,996 @@
1
+ # PromptManager Gem Improvement Plan
2
+
3
+ ## Overview
4
+ This document outlines potential improvements for the PromptManager gem based on a comprehensive code review conducted on 2025-09-01. The gem is currently at version 0.5.8 and is a key component of the AIA (AI Assistant) toolchain.
5
+
6
+ ## Current State Assessment
7
+ - **Version**: 0.5.8
8
+ - **Overall Rating**: 8.5/10
9
+ - **Status**: Production-ready, actively maintained
10
+ - **Core Strengths**: Clean architecture, flexible storage adapters, thoughtful parameter management
11
+
12
+ ## Improvement Categories
13
+
14
+ ### 1. Parameter Format Flexibility
15
+ **Priority: HIGH**
16
+ **Effort: Low-Medium**
17
+
18
+ #### Support Multiple Parameter Formats
19
+ - Add support for `{{keyword}}` format (Liquid/Handlebars style)
20
+ - Maintain backward compatibility with `[KEYWORD]` format
21
+ - Allow users to configure their preferred format
22
+ - Auto-detect format from prompt content
23
+
24
+ #### Implementation Approach
25
+ ```ruby
26
+ # Configuration options
27
+ PromptManager::Prompt.parameter_regex = :liquid # Use {{param}} style
28
+ PromptManager::Prompt.parameter_regex = :square # Use [PARAM] style (current)
29
+ PromptManager::Prompt.parameter_regex = :auto # Auto-detect from content
30
+
31
+ # Or custom regex
32
+ PromptManager::Prompt.parameter_regex = /\{\{([^}]+)\}\}/
33
+
34
+ # Pre-defined format constants
35
+ PARAM_FORMATS = {
36
+ square: /(\[[A-Z _|]+\])/, # Current: [KEYWORD]
37
+ liquid: /\{\{([^}]+)\}\}/, # Liquid: {{keyword}}
38
+ handlebars: /\{\{([^}]+)\}\}/, # Same as liquid
39
+ erb: /<%=\s*([^%>]+)\s*%>/, # ERB style: <%= keyword %>
40
+ dollar: /\$\{([^}]+)\}/ # Shell style: ${keyword}
41
+ }
42
+ ```
43
+
44
+ #### Auto-detection Logic
45
+ - Scan prompt for different formats
46
+ - Use the most prevalent format found
47
+ - Warn if multiple formats detected
48
+
49
+ ### 2. Markdown as First-Class Format
50
+ **Priority: HIGH**
51
+ **Effort: Medium**
52
+
53
+ #### Native Markdown Support
54
+ - Treat Markdown as the default prompt format
55
+ - Parse and preserve Markdown structure
56
+ - Special handling for:
57
+ - Code blocks (preserve without parameter substitution)
58
+ - Headers for prompt metadata
59
+ - Lists for structured content
60
+ - Front matter (YAML) for prompt configuration
61
+
62
+ #### Markdown-Aware Features with YAML Front Matter
63
+ ```markdown
64
+ ---
65
+ # Prompt Metadata (always preserved, never sent to LLM)
66
+ title: Customer Support Response
67
+ description: Template for responding to customer service inquiries with empathy and professionalism
68
+ version: 2.1
69
+ keywords: [customer-service, support, response-template]
70
+
71
+ # LLM Configuration (can be used by the calling application)
72
+ model: gpt-4
73
+ temperature: 0.7
74
+ max_tokens: 500
75
+ top_p: 0.9
76
+ frequency_penalty: 0.0
77
+ presence_penalty: 0.0
78
+
79
+ # Parameter Descriptions (for documentation and validation)
80
+ parameters:
81
+ company_name:
82
+ description: The name of the company providing support
83
+ type: string
84
+ required: true
85
+ product:
86
+ description: The product the customer is asking about
87
+ type: string
88
+ required: true
89
+ customer_tier:
90
+ description: Customer tier level (bronze, silver, gold, platinum)
91
+ type: string
92
+ default: silver
93
+ enum: [bronze, silver, gold, platinum]
94
+ customer_message:
95
+ description: The customer's inquiry or complaint
96
+ type: string
97
+ required: true
98
+ max_length: 1000
99
+ max_words:
100
+ description: Maximum words for the response
101
+ type: integer
102
+ default: 200
103
+ min: 50
104
+ max: 500
105
+ ---
106
+
107
+ # System Prompt
108
+ You are a helpful customer support agent for {{company_name}}.
109
+
110
+ ## Context
111
+ - Product: {{product}}
112
+ - Customer tier: {{customer_tier}}
113
+
114
+ ## Task
115
+ Respond to the following customer inquiry:
116
+
117
+ ```
118
+ {{customer_message}}
119
+ ```
120
+
121
+ Keep your response under {{max_words}} words.
122
+ ```
123
+
124
+ #### YAML Front Matter Standard Fields
125
+
126
+ ##### Core Metadata
127
+ ```yaml
128
+ ---
129
+ # Required fields
130
+ title: Short descriptive title
131
+ description: One-line description of what this prompt does
132
+
133
+ # Optional but recommended
134
+ version: Semantic version (e.g., 1.2.3)
135
+ keywords: [tag1, tag2, tag3] # For search and categorization
136
+ author: Developer name or team
137
+ created: 2024-01-15
138
+ updated: 2024-12-20
139
+ ---
140
+ ```
141
+
142
+ ##### LLM Configuration
143
+ ```yaml
144
+ ---
145
+ # Common LLM parameters that apps can use
146
+ model: gpt-4 # or claude-3, llama-2, etc.
147
+ temperature: 0.7
148
+ max_tokens: 1000
149
+ top_p: 0.9
150
+ frequency_penalty: 0.0
151
+ presence_penalty: 0.0
152
+ stream: false
153
+ system_prompt: "You are a helpful assistant" # If separate from main prompt
154
+ ---
155
+ ```
156
+
157
+ ##### Parameter Documentation
158
+ ```yaml
159
+ ---
160
+ parameters:
161
+ parameter_name:
162
+ description: What this parameter is for
163
+ type: string|integer|number|boolean|array
164
+ required: true|false
165
+ default: Default value if not provided
166
+ enum: [option1, option2, option3] # If limited choices
167
+ min: 0 # For numbers
168
+ max: 100 # For numbers
169
+ max_length: 500 # For strings
170
+ pattern: "^[A-Z]+$" # Regex validation
171
+ example: "Example value"
172
+ ---
173
+ ```
174
+
175
+ #### Benefits of YAML Front Matter
176
+ - **Self-documenting**: Parameters are documented where they're used
177
+ - **Validation-ready**: Type information enables runtime validation
178
+ - **Tool-friendly**: IDEs can provide better autocomplete with parameter descriptions
179
+ - **Searchable**: Keywords make prompts discoverable
180
+ - **Configuration**: LLM settings travel with the prompt
181
+
182
+ #### Implementation
183
+ ```ruby
184
+ class PromptManager::Prompt
185
+ attr_reader :metadata, :llm_config, :parameter_specs
186
+
187
+ def initialize(id:, storage_adapter: nil)
188
+ @storage_adapter = storage_adapter || self.class.storage_adapter
189
+ load_prompt(id)
190
+ end
191
+
192
+ private
193
+
194
+ def load_prompt(id)
195
+ content = @storage_adapter.get(id: id)
196
+ parse_markdown_prompt(content[:text])
197
+ end
198
+
199
+ def parse_markdown_prompt(text)
200
+ # Extract front matter
201
+ if text =~ /\A---\n(.*?)\n---\n(.*)/m
202
+ front_matter = YAML.safe_load($1)
203
+ prompt_body = $2
204
+
205
+ # Separate metadata categories
206
+ @metadata = extract_metadata(front_matter)
207
+ @llm_config = extract_llm_config(front_matter)
208
+ @parameter_specs = front_matter['parameters'] || {}
209
+
210
+ # Process the prompt body
211
+ @text = process_prompt_body(prompt_body)
212
+ else
213
+ @text = process_prompt_body(text)
214
+ end
215
+ end
216
+
217
+ def extract_metadata(fm)
218
+ {
219
+ title: fm['title'],
220
+ description: fm['description'],
221
+ version: fm['version'],
222
+ keywords: fm['keywords'] || [],
223
+ author: fm['author'],
224
+ created: fm['created'],
225
+ updated: fm['updated']
226
+ }.compact
227
+ end
228
+
229
+ def extract_llm_config(fm)
230
+ {
231
+ model: fm['model'],
232
+ temperature: fm['temperature'],
233
+ max_tokens: fm['max_tokens'],
234
+ top_p: fm['top_p'],
235
+ frequency_penalty: fm['frequency_penalty'],
236
+ presence_penalty: fm['presence_penalty']
237
+ }.compact
238
+ end
239
+
240
+ def validate_parameters(params)
241
+ @parameter_specs.each do |name, spec|
242
+ value = params[name] || params["{{#{name}}}"]
243
+
244
+ # Check required
245
+ if spec['required'] && value.nil?
246
+ raise ParameterError, "Required parameter '#{name}' is missing"
247
+ end
248
+
249
+ # Apply default if needed
250
+ if value.nil? && spec['default']
251
+ params[name] = spec['default']
252
+ next
253
+ end
254
+
255
+ # Type validation
256
+ validate_type(name, value, spec['type']) if value && spec['type']
257
+
258
+ # Enum validation
259
+ if spec['enum'] && value && !spec['enum'].include?(value)
260
+ raise ParameterError, "Parameter '#{name}' must be one of: #{spec['enum'].join(', ')}"
261
+ end
262
+
263
+ # Range validation for numbers
264
+ if spec['type'] == 'integer' || spec['type'] == 'number'
265
+ validate_range(name, value, spec['min'], spec['max'])
266
+ end
267
+
268
+ # Length validation for strings
269
+ if spec['type'] == 'string' && spec['max_length'] && value.length > spec['max_length']
270
+ raise ParameterError, "Parameter '#{name}' exceeds maximum length of #{spec['max_length']}"
271
+ end
272
+ end
273
+ end
274
+ end
275
+ ```
276
+
277
+ #### Usage Example
278
+ ```ruby
279
+ prompt = PromptManager::Prompt.new(id: 'customer_support')
280
+
281
+ # Access metadata
282
+ puts prompt.metadata[:title] # "Customer Support Response"
283
+ puts prompt.metadata[:description] # "Template for responding to..."
284
+
285
+ # Access LLM configuration
286
+ puts prompt.llm_config[:temperature] # 0.7
287
+ puts prompt.llm_config[:model] # "gpt-4"
288
+
289
+ # Get parameter documentation
290
+ prompt.parameter_specs.each do |name, spec|
291
+ puts "#{name}: #{spec['description']}"
292
+ puts " Type: #{spec['type']}, Required: #{spec['required']}"
293
+ end
294
+
295
+ # Parameters are validated before substitution
296
+ prompt.parameters = {
297
+ 'company_name' => 'Acme Corp',
298
+ 'product' => 'Widget Pro',
299
+ 'customer_tier' => 'gold',
300
+ 'customer_message' => 'My widget is broken!'
301
+ } # Validates against parameter_specs
302
+ ```
303
+
304
+ #### Benefits
305
+ - Prompts are more readable and maintainable
306
+ - Can leverage Markdown editors and preview tools
307
+ - Better documentation within prompts
308
+ - Supports rich formatting for complex prompts
309
+ - Self-contained prompt packages with all configuration
310
+
311
+ ### 2a. Comment Handling in Markdown Prompts
312
+ **Priority: HIGH**
313
+ **Effort: Low-Medium**
314
+
315
+ #### The Challenge
316
+ Markdown files (`.md`) don't have a standard inline comment syntax that's hidden from rendering. We need a way to include developer notes that won't be sent to the LLM.
317
+
318
+ #### Proposed Solutions
319
+
320
+ ##### Option 1: HTML Comments (Recommended)
321
+ ```markdown
322
+ <!-- DEVELOPER NOTE: This prompt requires customer_name to be validated -->
323
+ # Customer Service Response
324
+
325
+ <!-- TODO: Add tone parameter to control formality -->
326
+ Hello {{customer_name}},
327
+
328
+ <!-- The following section is critical for compliance -->
329
+ We understand your concern about {{issue}}.
330
+ ```
331
+ **Pros:**
332
+ - Standard HTML/Markdown convention
333
+ - Invisible in rendered Markdown
334
+ - Supported by all Markdown editors
335
+ - GitHub/GitLab render them as hidden
336
+
337
+ **Cons:**
338
+ - More verbose than `#` comments
339
+ - Can be accidentally included if not stripped properly
340
+
341
+ ##### Option 2: Custom Markers
342
+ ```markdown
343
+ %% DEVELOPER: This is a comment that won't be sent to LLM %%
344
+ # System Prompt
345
+
346
+ %% TODO: Add parameter validation %%
347
+ You are {{role}}.
348
+
349
+ ### OR using different markers ###
350
+
351
+ [//]: # (This is a comment using Markdown's link reference syntax)
352
+ [//]: # (It's completely hidden in rendered output)
353
+ ```
354
+ **Pros:**
355
+ - `%%` is used by Obsidian for comments
356
+ - `[//]: #` is valid Markdown that renders as nothing
357
+ - Can choose syntax that suits the team
358
+
359
+ **Cons:**
360
+ - Not universally recognized
361
+ - May confuse developers unfamiliar with the convention
362
+
363
+ ##### Option 3: Front Matter Comments
364
+ ```yaml
365
+ ---
366
+ title: Customer Support
367
+ # Comments in YAML front matter
368
+ # These are for developers only
369
+ _dev_notes: |
370
+ This prompt requires the following parameters:
371
+ - customer_name: validated email
372
+ - issue: max 500 chars
373
+ _todo:
374
+ - Add sentiment analysis
375
+ - Test with GPT-4
376
+ ---
377
+ ```
378
+ **Pros:**
379
+ - Keeps all metadata in one place
380
+ - YAML supports comments natively
381
+ - Can have structured developer notes
382
+
383
+ **Cons:**
384
+ - Only works for header comments, not inline
385
+ - Might clutter front matter
386
+
387
+ ##### Option 4: Special Code Blocks
388
+ ````markdown
389
+ ```comment
390
+ This is a developer comment block.
391
+ It will be stripped before sending to LLM.
392
+ Can contain multiple lines and formatting.
393
+ ```
394
+
395
+ # Actual Prompt
396
+ Hello {{name}}
397
+
398
+ ```dev-note
399
+ Remember to validate the name parameter
400
+ ```
401
+ ````
402
+ **Pros:**
403
+ - Clear visual distinction
404
+ - Can contain formatted content
405
+ - Easy to parse and remove
406
+
407
+ **Cons:**
408
+ - Takes more vertical space
409
+ - Not standard Markdown
410
+
411
+ #### Implementation Strategy
412
+ ```ruby
413
+ class MarkdownPromptProcessor
414
+ COMMENT_PATTERNS = {
415
+ html: /<!--.*?-->/m,
416
+ obsidian: /%%.*?%%/m,
417
+ link_ref: /\[\/\/\]: # \(.*?\)/,
418
+ code_block: /```(?:comment|dev-note|note).*?```/m
419
+ }
420
+
421
+ def strip_comments(content, style: :html)
422
+ content.gsub(COMMENT_PATTERNS[style], '')
423
+ end
424
+
425
+ # Support multiple comment styles simultaneously
426
+ def strip_all_comments(content)
427
+ COMMENT_PATTERNS.values.reduce(content) do |text, pattern|
428
+ text.gsub(pattern, '')
429
+ end
430
+ end
431
+ end
432
+ ```
433
+
434
+ #### Configuration Options
435
+ ```ruby
436
+ PromptManager.configure do |config|
437
+ config.prompt_extension = '.md'
438
+ config.comment_style = :html # or :obsidian, :all
439
+ config.preserve_comments_in_storage = true # Keep comments in .md file
440
+ config.strip_comments_for_llm = true # Remove before sending to LLM
441
+ end
442
+ ```
443
+
444
+ ### 2b. The __END__ Marker in Markdown
445
+ **Priority: HIGH**
446
+ **Effort: Low**
447
+
448
+ #### Preserving the __END__ Convention
449
+ The `__END__` marker is a valuable convention from Ruby (and Perl) that provides a clear demarcation for "everything after this is not part of the main content." This is especially useful for:
450
+ - Extensive developer notes
451
+ - Test data and examples
452
+ - Changelog for the prompt
453
+ - Scratchpad for prompt iterations
454
+ - Reference materials
455
+
456
+ #### Implementation in Markdown Context
457
+ ```markdown
458
+ ---
459
+ title: Customer Support Agent
460
+ version: 3.2
461
+ ---
462
+
463
+ # System Prompt
464
+ You are a helpful customer support agent for {{company_name}}.
465
+
466
+ <!-- inline comment about the tone parameter -->
467
+ Maintain a {{tone}} tone throughout your response.
468
+
469
+ ## Your Task
470
+ Respond to: {{customer_message}}
471
+
472
+ __END__
473
+
474
+ # Developer Notes
475
+ This prompt has gone through several iterations:
476
+ - v3.2: Added tone parameter
477
+ - v3.1: Simplified the system prompt
478
+ - v3.0: Complete rewrite for GPT-4
479
+
480
+ # Test Cases
481
+ - customer_message: "I'm angry about my broken product!"
482
+ tone: "empathetic"
483
+ expected: Should acknowledge frustration
484
+
485
+ # Random thoughts
486
+ Maybe we should add a parameter for response length?
487
+ The client mentioned they want more formal responses for enterprise customers.
488
+
489
+ # Old version we might want to reference
490
+ You are a customer support representative who always...
491
+ (this was too verbose)
492
+ ```
493
+
494
+ #### Benefits of Keeping __END__
495
+ 1. **Unstructured Space**: Everything after `__END__` can be free-form without worrying about syntax
496
+ 2. **Backward Compatible**: Existing prompts using this convention still work
497
+ 3. **Clear Separation**: Visually obvious where the prompt ends
498
+ 4. **No Escaping Needed**: After `__END__`, no need to worry about HTML comment syntax
499
+ 5. **Markdown Friendly**: Can still use Markdown formatting in the notes section for readability
500
+
501
+ #### Processing Logic
502
+ ```ruby
503
+ class MarkdownPromptProcessor
504
+ def process(content)
505
+ # Split at __END__ marker
506
+ parts = content.split(/^__END__$/m, 2)
507
+
508
+ prompt_content = parts[0]
509
+ developer_notes = parts[1] # Everything after __END__ (if present)
510
+
511
+ # Process only the prompt content
512
+ prompt_content = strip_html_comments(prompt_content)
513
+ prompt_content = substitute_parameters(prompt_content)
514
+
515
+ # Return processed prompt (developer_notes are never sent to LLM)
516
+ prompt_content
517
+ end
518
+
519
+ def save_to_storage(content)
520
+ # When saving, preserve everything including __END__ section
521
+ content
522
+ end
523
+ end
524
+ ```
525
+
526
+ #### Combined Comment Strategy
527
+ ```markdown
528
+ <!-- Quick inline comment -->
529
+ # Main Prompt
530
+
531
+ Here's the prompt with {{parameters}}.
532
+
533
+ <!-- Another inline note about the section below -->
534
+ ## Special Instructions
535
+
536
+ Follow these guidelines:
537
+ <!-- TODO: Add more guidelines -->
538
+ - Be concise
539
+ - Be helpful
540
+
541
+ __END__
542
+
543
+ Everything down here is free-form developer notes.
544
+ No need for <!-- --> syntax.
545
+ Can paste examples, old versions, test cases, etc.
546
+
547
+ This section is NEVER sent to the LLM but is preserved in the .md file.
548
+ ```
549
+
550
+ #### Configuration
551
+ ```ruby
552
+ PromptManager.configure do |config|
553
+ config.prompt_extension = '.md'
554
+ config.comment_style = :html # For inline comments
555
+ config.honor_end_marker = true # Respect __END__ marker
556
+ config.end_marker = '__END__' # Customizable if needed
557
+ config.strip_comments_for_llm = true # Remove both HTML comments and __END__ section
558
+ end
559
+ ```
560
+
561
+ ### 3. Performance Optimizations
562
+ **Priority: Medium**
563
+ **Effort: Medium**
564
+
565
+ #### Optimize Parameter Parsing
566
+ - Current: Regex scanning on every parameter extraction
567
+ - Proposed: Cache parsed parameters with dirty tracking
568
+ - Implement lazy evaluation for large prompts
569
+
570
+ #### Benchmark-Driven Improvements
571
+ - Add performance benchmarks to test suite
572
+ - Profile regex operations for large prompts (>10KB)
573
+ - Consider using StringScanner for improved parsing performance
574
+
575
+ ### 3. Storage Adapter Enhancements
576
+ **Priority: High**
577
+ **Effort: Low-Medium**
578
+
579
+ #### Formalize Storage Adapter Interface
580
+ ```ruby
581
+ # lib/prompt_manager/storage/base_adapter.rb
582
+ module PromptManager
583
+ module Storage
584
+ class BaseAdapter
585
+ def get(id:)
586
+ raise NotImplementedError
587
+ end
588
+
589
+ def save(id:, text:, parameters:)
590
+ raise NotImplementedError
591
+ end
592
+
593
+ def delete(id:)
594
+ raise NotImplementedError
595
+ end
596
+
597
+ def list
598
+ raise NotImplementedError
599
+ end
600
+
601
+ def search(term:)
602
+ raise NotImplementedError
603
+ end
604
+ end
605
+ end
606
+ end
607
+ ```
608
+
609
+ #### Add New Storage Adapters
610
+ - **RedisAdapter**: For high-performance caching
611
+ - **S3Adapter**: For cloud storage
612
+ - **PostgreSQLAdapter**: With JSONB support for parameters
613
+ - **MemoryAdapter**: For testing and temporary storage
614
+
615
+ ### 4. Serialization Flexibility
616
+ **Priority: Medium**
617
+ **Effort: Low**
618
+
619
+ #### Make Serialization Pluggable
620
+ - Extract serialization into strategy pattern
621
+ - Support multiple formats:
622
+ - JSON (current)
623
+ - YAML
624
+ - MessagePack (for performance)
625
+ - Custom serializers
626
+
627
+ ```ruby
628
+ class FileSystemAdapter
629
+ def initialize(serializer: JSONSerializer.new)
630
+ @serializer = serializer
631
+ end
632
+ end
633
+ ```
634
+
635
+ ### 5. Enhanced Directive System
636
+ **Priority: Medium-High**
637
+ **Effort: High**
638
+
639
+ #### Directive Registry
640
+ - Allow registration of custom directives
641
+ - Plugin architecture for directive processors
642
+ - Built-in directives:
643
+ - `//include` (existing)
644
+ - `//template` - ERB template processing
645
+ - `//exec` - Execute shell commands
646
+ - `//fetch` - Fetch content from URLs
647
+ - `//cache` - Cache directive results
648
+
649
+ #### Directive Middleware Chain
650
+ ```ruby
651
+ class DirectiveProcessor
652
+ def register(name, handler)
653
+ @handlers[name] = handler
654
+ end
655
+
656
+ def process(directive_line)
657
+ middleware_chain.call(directive_line)
658
+ end
659
+ end
660
+ ```
661
+
662
+ ### 6. Parameter Management Improvements
663
+ **Priority: High**
664
+ **Effort: Medium**
665
+
666
+ #### Parameter Validation
667
+ - Add parameter type hints: `[NAME:string]`, `[AGE:number]`, `[ACTIVE:boolean]`
668
+ - Validation rules: required, optional, default values
669
+ - Pattern matching: `[EMAIL:email]`, `[URL:url]`
670
+
671
+ #### Parameter Inheritance
672
+ - Support prompt templates with parameter inheritance
673
+ - Base prompts that other prompts can extend
674
+
675
+ ### 7. Testing and Quality Improvements
676
+ **Priority: Medium**
677
+ **Effort: Low**
678
+
679
+ #### Enhanced Test Coverage
680
+ - Add integration tests for storage adapters
681
+ - Property-based testing for parameter substitution
682
+ - Mutation testing to ensure test quality
683
+
684
+ #### CI/CD Improvements
685
+ - Add GitHub Actions for automated testing
686
+ - Code coverage badges
687
+ - Automated gem releases
688
+
689
+ ### 8. Documentation and Examples
690
+ **Priority: Low-Medium**
691
+ **Effort: Low**
692
+
693
+ #### Improve Documentation
694
+ - Add YARD documentation to all public methods
695
+ - Create a documentation site (GitHub Pages)
696
+ - Video tutorials for common use cases
697
+ - Migration guides for version upgrades
698
+
699
+ #### Extended Examples
700
+ - Real-world use cases
701
+ - Integration examples with popular AI libraries
702
+ - Best practices guide
703
+
704
+ ### 9. Backwards Compatibility Strategy
705
+ **Priority: High**
706
+ **Effort: Ongoing**
707
+
708
+ #### Versioning Strategy
709
+ - Follow Semantic Versioning strictly
710
+ - Deprecation warnings for breaking changes
711
+ - Migration tools for major version upgrades
712
+
713
+ ### 10. New Features
714
+ **Priority: Low-Medium**
715
+ **Effort: Variable**
716
+
717
+ #### Prompt Versioning
718
+ - Track prompt history
719
+ - Rollback capabilities
720
+ - Diff viewing between versions
721
+
722
+ #### Prompt Marketplace/Sharing
723
+ - Export/import prompt packages
724
+ - Prompt templates repository
725
+ - Community sharing features
726
+
727
+ ## Breaking Changes for v0.9.0
728
+
729
+ Since we're making format changes, let's bundle all breaking changes into v0.9.0:
730
+
731
+ ### 1. File Format Changes (BREAKING)
732
+ - **Default extension**: `.txt` → `.md`
733
+ - **Parameter format**: `[KEYWORD]` → `{{keyword}}` (auto-detect for migration)
734
+ - **Front matter**: Add YAML front matter support
735
+ - **Serialization**: Keep JSON as default, add pluggable support (YAML, MessagePack optional)
736
+
737
+ ### 2. API Changes (BREAKING)
738
+ ```ruby
739
+ # Current v0.5.x API
740
+ prompt = PromptManager::Prompt.new(id: 'test')
741
+ prompt.parameters['[NAME]'] = 'value'
742
+
743
+ # New v0.9.0 API
744
+ prompt = PromptManager::Prompt.new(id: 'test')
745
+ prompt.set_parameter('name', 'value') # Cleaner API, but keeps '[NAME]' internally
746
+ prompt.metadata[:title] # Access to front matter
747
+ prompt.llm_config[:temperature] # LLM configuration
748
+ ```
749
+
750
+ ### 3. Storage Adapter Interface (BREAKING)
751
+ ```ruby
752
+ # v0.5.x - informal interface
753
+ class MyAdapter
754
+ def get(id:); end
755
+ def save(id:, text:, parameters:); end
756
+ end
757
+
758
+ # v0.9.0 - formal interface with base class
759
+ class MyAdapter < PromptManager::Storage::BaseAdapter
760
+ def get(id:); end
761
+ def save(id:, text:, parameters:, metadata: {}, llm_config: {}); end
762
+ def delete(id:); end
763
+ def list(filter: {}); end
764
+ def search(query:, filters: {}); end
765
+ end
766
+ ```
767
+
768
+ ### 4. Parameter Handling (BREAKING)
769
+ ```ruby
770
+ # v0.5.x - manual parameter management
771
+ prompt.parameters['[NAME]'] = ['value1', 'value2']
772
+
773
+ # v0.9.0 - simplified with validation
774
+ prompt.set_parameter('name', 'value2') # Automatically manages history, stores as '[NAME]'
775
+ prompt.validate_parameters! # Based on front matter specs
776
+ ```
777
+
778
+ ### 5. Configuration Changes (BREAKING)
779
+ ```ruby
780
+ # v0.5.x
781
+ PromptManager::Storage::FileSystemAdapter.config do |config|
782
+ config.prompts_dir = 'path'
783
+ config.prompt_extension = '.txt'
784
+ config.params_extension = '.json'
785
+ end
786
+
787
+ # v0.9.0
788
+ PromptManager.configure do |config|
789
+ config.storage_adapter = :file_system
790
+ config.prompts_dir = 'path'
791
+ config.prompt_extension = '.md'
792
+ config.parameter_format = :liquid # {{}} style
793
+ config.serializer = :json # Keep JSON as default
794
+ config.validate_parameters = true
795
+ end
796
+ ```
797
+
798
+ ### 6. What We're NOT Changing (Staying Backward Compatible)
799
+
800
+ #### Keep JCL-Style Directives (NO CHANGE)
801
+ ```ruby
802
+ # Keeping current JCL-style directives
803
+ //include path/to/file.txt
804
+ //import another/file.md
805
+
806
+ # These remain unchanged - familiar and working well
807
+ ```
808
+
809
+ #### Keep Parameter Key Format (NO CHANGE)
810
+ ```ruby
811
+ # Internal storage keeps current format
812
+ {
813
+ '[NAME]' => ['Alice', 'Bob'],
814
+ '[AGE]' => ['25', '30']
815
+ }
816
+
817
+ # New API abstracts this away:
818
+ prompt.set_parameter('name', 'Bob') # Becomes '[NAME]' internally
819
+ prompt.get_parameter('name') # Returns value for '[NAME]'
820
+ ```
821
+
822
+ #### Keep JSON as Default Serializer (NO CHANGE)
823
+ ```ruby
824
+ # JSON remains the default for .json parameter files
825
+ # YAML support added as optional feature for those who want it
826
+ ```
827
+
828
+ #### Option C: Error Handling Overhaul
829
+ ```ruby
830
+ # v0.5.x - basic errors
831
+ begin
832
+ prompt.to_s
833
+ rescue PromptManager::Error => e
834
+ # Generic error
835
+ end
836
+
837
+ # v1.0 - specific error types
838
+ begin
839
+ prompt.to_s
840
+ rescue PromptManager::ParameterValidationError => e
841
+ puts "Invalid parameter: #{e.parameter_name}"
842
+ rescue PromptManager::TemplateParsingError => e
843
+ puts "Template error at line #{e.line_number}"
844
+ rescue PromptManager::DirectiveError => e
845
+ puts "Directive '#{e.directive}' failed: #{e.message}"
846
+ end
847
+ ```
848
+
849
+ #### Option D: Prompt Class Restructure
850
+ ```ruby
851
+ # v0.5.x - monolithic Prompt class
852
+ class Prompt
853
+ # Everything mixed together
854
+ end
855
+
856
+ # v1.0 - separation of concerns
857
+ class Prompt
858
+ include Parameterizable
859
+ include Validatable
860
+ include Serializable
861
+
862
+ attr_reader :metadata, :llm_config, :content
863
+ end
864
+ ```
865
+
866
+ ## Implementation Roadmap (Revised)
867
+
868
+ ### v0.9.0 - Breaking Changes Release (The Big Jump)
869
+ - [ ] Default to new formats (.md, {{}} parameters)
870
+ - [ ] YAML front matter support with metadata and LLM config
871
+ - [ ] New cleaner API (`set_parameter`, `get_parameter`)
872
+ - [ ] Formal storage adapter interface with base class
873
+ - [ ] Parameter validation system based on front matter
874
+ - [ ] Migration tools for automatic format conversion
875
+ - [ ] Backward compatibility for existing parameter access
876
+ - [ ] Keep JCL directives, bracket storage, JSON serialization
877
+
878
+ ### v1.0.0 - Stability Release
879
+ - [ ] Performance optimizations and bug fixes
880
+ - [ ] Complete documentation with migration guide
881
+ - [ ] Production hardening based on v0.9 feedback
882
+
883
+ ### v1.1.0 - Enhanced Features
884
+ - [ ] New storage adapters (Redis, S3)
885
+ - [ ] Performance optimizations
886
+ - [ ] Directive registry system
887
+ - [ ] Template inheritance
888
+
889
+ ## Migration Strategy
890
+
891
+ ### Automated Migration Tool
892
+ ```bash
893
+ # Convert existing prompts to v0.9.0 format
894
+ prompt_manager migrate --from=0.5.x --to=0.9 --path=~/.prompts
895
+
896
+ # Preview changes without applying
897
+ prompt_manager migrate --dry-run --path=~/.prompts
898
+
899
+ # Convert specific aspects
900
+ prompt_manager migrate --parameters-only --path=~/.prompts
901
+ prompt_manager migrate --add-frontmatter --path=~/.prompts
902
+ ```
903
+
904
+ ### Migration Process
905
+ 1. **Backup**: Always backup existing prompt directory
906
+ 2. **Convert files**: `.txt` → `.md` with front matter injection
907
+ 3. **Update parameters**: `[KEYWORD]` → `{{keyword}}`
908
+ 4. **Generate specs**: Create parameter documentation in front matter
909
+ 5. **Update JSON**: Convert parameter files to YAML (optional)
910
+
911
+ ### Migration Example
912
+ ```ruby
913
+ # Before migration: joke.txt
914
+ Tell me a [KIND] joke about [SUBJECT]
915
+
916
+ # joke.json
917
+ {
918
+ "[KIND]": ["pun", "family friendly"],
919
+ "[SUBJECT]": ["parrot", "garbage man"]
920
+ }
921
+ ```
922
+
923
+ ```markdown
924
+ # After migration: joke.md
925
+ ---
926
+ title: Joke Generator
927
+ description: Generates jokes of specified type about a subject
928
+ version: 0.9.0
929
+ parameters:
930
+ kind:
931
+ description: Type of joke to generate
932
+ type: string
933
+ required: true
934
+ example: "pun"
935
+ subject:
936
+ description: Subject of the joke
937
+ type: string
938
+ required: true
939
+ example: "parrot"
940
+ ---
941
+
942
+ Tell me a {{kind}} joke about {{subject}}
943
+ ```
944
+
945
+ ### Backward Compatibility Layer (v0.9.x)
946
+ ```ruby
947
+ # Support both old and new syntax during transition
948
+ class Prompt
949
+ def parameters=(params)
950
+ if params.keys.first&.include?('[')
951
+ # Old format: convert automatically
952
+ deprecation_warning "Bracket format deprecated. Use set_parameter() instead."
953
+ params.each do |key, value|
954
+ clean_key = key.gsub(/[\[\]]/, '').downcase
955
+ set_parameter(clean_key, value)
956
+ end
957
+ else
958
+ # New format
959
+ params.each { |key, value| set_parameter(key, value) }
960
+ end
961
+ end
962
+ end
963
+ ```
964
+
965
+ ## Discussion Points
966
+
967
+ ### Questions to Consider
968
+ 1. Should {{keyword}} format become the default in v1.0?
969
+ 2. How should we handle mixed parameter formats in a single prompt?
970
+ 3. Should Markdown front matter replace the current comment-based metadata?
971
+ 4. Is there value in supporting Liquid filters like {{name | upcase}}?
972
+ 5. Should code blocks in Markdown always be parameter-substitution-free zones?
973
+ 6. What other Markdown features need special handling (tables, links, images)?
974
+
975
+ ### Trade-offs
976
+ - **Format Flexibility vs Complexity**: Supporting multiple formats adds parsing complexity
977
+ - **Markdown Features vs Performance**: Full Markdown parsing may impact performance
978
+ - **Backward Compatibility vs Modern Standards**: Moving to {{}} format may break existing prompts
979
+ - **Features vs Maintenance**: More formats mean more edge cases to handle
980
+
981
+ ## Next Steps
982
+ 1. Prioritize improvements based on user feedback
983
+ 2. Create GitHub issues for each improvement
984
+ 3. Set up a project board for tracking progress
985
+ 4. Establish contribution guidelines for community involvement
986
+ 5. Consider creating a beta release channel for testing new features
987
+
988
+ ## Notes
989
+ - This plan is a living document and should be updated as development progresses
990
+ - Community feedback should be actively sought and incorporated
991
+ - Breaking changes should be minimized and well-documented when necessary
992
+
993
+ ---
994
+
995
+ *Last Updated: 2025-09-01*
996
+ *Version: 1.0*