prompt_manager 0.5.8 → 1.0.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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +206 -516
  4. data/Rakefile +0 -8
  5. data/docs/api/configuration.md +31 -327
  6. data/docs/api/constants.md +60 -0
  7. data/docs/api/index.md +14 -0
  8. data/docs/api/metadata.md +99 -0
  9. data/docs/api/parsed.md +98 -0
  10. data/docs/api/pm-module.md +131 -0
  11. data/docs/api/render-context.md +51 -0
  12. data/docs/architecture/design-decisions.md +70 -0
  13. data/docs/architecture/index.md +6 -0
  14. data/docs/architecture/processing-pipeline.md +112 -0
  15. data/docs/assets/css/custom.css +1 -0
  16. data/docs/assets/images/prompt_manager.gif +0 -0
  17. data/docs/assets/images/prompt_manager.mp4 +0 -0
  18. data/docs/examples/ai-agent-prompts.md +173 -0
  19. data/docs/examples/code-review-prompt.md +107 -0
  20. data/docs/examples/index.md +7 -0
  21. data/docs/examples/multi-file-composition.md +123 -0
  22. data/docs/getting-started/configuration.md +106 -0
  23. data/docs/getting-started/index.md +7 -0
  24. data/docs/getting-started/installation.md +10 -73
  25. data/docs/getting-started/quick-start.md +50 -225
  26. data/docs/guides/comment-stripping.md +64 -0
  27. data/docs/guides/custom-directives.md +115 -0
  28. data/docs/guides/erb-rendering.md +102 -0
  29. data/docs/guides/includes.md +146 -0
  30. data/docs/guides/index.md +11 -0
  31. data/docs/guides/parameters.md +96 -0
  32. data/docs/guides/parsing.md +127 -0
  33. data/docs/guides/shell-expansion.md +108 -0
  34. data/docs/index.md +54 -214
  35. data/lib/pm/configuration.rb +17 -0
  36. data/lib/pm/directives.rb +61 -0
  37. data/lib/pm/metadata.rb +17 -0
  38. data/lib/pm/parsed.rb +59 -0
  39. data/lib/pm/shell.rb +57 -0
  40. data/lib/pm/version.rb +5 -0
  41. data/lib/pm.rb +121 -0
  42. data/lib/prompt_manager.rb +2 -27
  43. data/mkdocs.yml +101 -66
  44. metadata +42 -101
  45. data/docs/.keep +0 -0
  46. data/docs/advanced/custom-keywords.md +0 -421
  47. data/docs/advanced/dynamic-directives.md +0 -535
  48. data/docs/advanced/performance.md +0 -612
  49. data/docs/advanced/search-integration.md +0 -635
  50. data/docs/api/directive-processor.md +0 -431
  51. data/docs/api/prompt-class.md +0 -354
  52. data/docs/api/storage-adapters.md +0 -462
  53. data/docs/assets/favicon.ico +0 -1
  54. data/docs/assets/logo.svg +0 -24
  55. data/docs/core-features/comments.md +0 -48
  56. data/docs/core-features/directive-processing.md +0 -38
  57. data/docs/core-features/erb-integration.md +0 -68
  58. data/docs/core-features/error-handling.md +0 -197
  59. data/docs/core-features/parameter-history.md +0 -76
  60. data/docs/core-features/parameterized-prompts.md +0 -500
  61. data/docs/core-features/shell-integration.md +0 -79
  62. data/docs/development/architecture.md +0 -544
  63. data/docs/development/contributing.md +0 -425
  64. data/docs/development/roadmap.md +0 -234
  65. data/docs/development/testing.md +0 -822
  66. data/docs/examples/advanced.md +0 -523
  67. data/docs/examples/basic.md +0 -688
  68. data/docs/examples/real-world.md +0 -776
  69. data/docs/examples.md +0 -337
  70. data/docs/getting-started/basic-concepts.md +0 -318
  71. data/docs/migration/v0.9.0.md +0 -459
  72. data/docs/migration/v1.0.0.md +0 -591
  73. data/docs/storage/activerecord-adapter.md +0 -348
  74. data/docs/storage/custom-adapters.md +0 -176
  75. data/docs/storage/filesystem-adapter.md +0 -236
  76. data/docs/storage/overview.md +0 -427
  77. data/examples/advanced_integrations.rb +0 -52
  78. data/examples/directives.rb +0 -102
  79. data/examples/prompts_dir/advanced_demo.txt +0 -79
  80. data/examples/prompts_dir/directive_example.json +0 -1
  81. data/examples/prompts_dir/directive_example.txt +0 -8
  82. data/examples/prompts_dir/todo.json +0 -1
  83. data/examples/prompts_dir/todo.txt +0 -7
  84. data/examples/prompts_dir/toy/8-ball.txt +0 -4
  85. data/examples/rgfzf +0 -44
  86. data/examples/simple.rb +0 -160
  87. data/examples/using_search_proc.rb +0 -68
  88. data/improvement_plan.md +0 -996
  89. data/lib/prompt_manager/directive_processor.rb +0 -47
  90. data/lib/prompt_manager/prompt.rb +0 -195
  91. data/lib/prompt_manager/storage/active_record_adapter.rb +0 -157
  92. data/lib/prompt_manager/storage/file_system_adapter.rb +0 -339
  93. data/lib/prompt_manager/storage.rb +0 -34
  94. data/lib/prompt_manager/version.rb +0 -5
  95. data/prompt_manager_logo.png +0 -0
@@ -1,102 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
- # frozen_string_literal: true
4
- # warn_indent: true
5
- ##########################################################
6
- ###
7
- ## File: directives.rb
8
- ## Desc: Demo of the PromptManager and FileStorageAdapter
9
- ## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
10
- ##
11
- #
12
-
13
- param1 = "param_one"
14
- param2 = "param_two"
15
-
16
-
17
- class MyDirectives
18
- def self.good_directive(*args)
19
- puts "inside #{__method__} with these parameters:"
20
- puts args.join(",\n")
21
- end
22
- end
23
-
24
- def concept_break = print "\n------------------------\n\n\n"
25
-
26
- require_relative '../lib/prompt_manager'
27
- require_relative '../lib/prompt_manager/storage/file_system_adapter'
28
-
29
- require 'amazing_print'
30
- require 'pathname'
31
-
32
- require 'debug_me'
33
- include DebugMe
34
-
35
- HERE = Pathname.new( __dir__ )
36
- PROMPTS_DIR = HERE + "prompts_dir"
37
-
38
-
39
- ######################################################
40
- # Main
41
-
42
- at_exit do
43
- puts
44
- puts "Done."
45
- puts
46
- end
47
-
48
- # Configure the Storage Adapter to use
49
- PromptManager::Storage::FileSystemAdapter.config do |config|
50
- config.prompts_dir = PROMPTS_DIR
51
- # config.search_proc = nil # default
52
- # config.prompt_extension = '.txt' # default
53
- # config.parms+_extension = '.json' # default
54
- end
55
-
56
- PromptManager::Prompt.storage_adapter = PromptManager::Storage::FileSystemAdapter.new
57
-
58
- # Use {parameter name} brackets to define a parameter
59
- # Note: must include capturing parentheses to make scan return arrays
60
- PromptManager::Prompt.parameter_regex = /(\{[A-Za-z _|]+\})/
61
-
62
- # Retrieve a prompt
63
- # Note: The 'get' method returns a Hash, not a Prompt object
64
- # Use 'find' instead to get a Prompt object with methods
65
- prompt = PromptManager::Prompt.find(id: 'directive_example')
66
-
67
- # Shows prompt without comments or directives
68
- # It still has its parameter placeholders
69
- puts prompt
70
- concept_break
71
-
72
- puts "Directives are processed automatically when you call to_s on a prompt"
73
- puts "The DirectiveProcessor class handles directives like //include"
74
- puts "You don't need to process them manually"
75
-
76
- puts "Custom directive processing can be done by creating a custom DirectiveProcessor"
77
- puts "and setting it when creating a Prompt instance:"
78
-
79
- concept_break
80
-
81
-
82
-
83
- puts "Parameters in the prompt:"
84
- ap prompt.parameters
85
- puts "-"*16
86
-
87
- # Extract parameters from the prompt text using the parameter_regex
88
- puts "Parameters identified in the prompt text:"
89
- # With a capturing group, scan returns an array of arrays, so we need to flatten
90
- prompt_params = prompt.text.scan(PromptManager::Prompt.parameter_regex).flatten
91
- ap prompt_params
92
- concept_break
93
-
94
- # Set a parameter value (should be a string, not appending to an array)
95
- prompt.parameters['{language}'] = 'French'
96
-
97
- puts "After Substitution"
98
- puts prompt
99
-
100
- # Save the updated parameters
101
- prompt.save
102
-
@@ -1,79 +0,0 @@
1
- # System Analysis and Historical Comparison Report
2
- # Generated with PromptManager - ERB + Shell Integration Demo
3
-
4
- ```markdown
5
- ## Current System Information
6
-
7
- **Timestamp**: <%= Time.now.strftime('%A, %B %d, %Y at %I:%M:%S %p %Z') %>
8
- **Analysis Duration**: <%= Time.now - Time.parse('2024-01-01') %> seconds since 2024 began
9
-
10
- ### Hardware Platform Details
11
- **Architecture**: $HOSTTYPE$MACHTYPE
12
- **Hostname**: $HOSTNAME
13
- **Operating System**: $OSTYPE
14
- **Shell**: $SHELL (version: $BASH_VERSION)
15
- **User**: $USER
16
- **Home Directory**: $HOME
17
- **Current Path**: $PWD
18
- **Terminal**: $TERM
19
-
20
- ### Detailed System Profile
21
- <% if RUBY_PLATFORM.include?('darwin') %>
22
- **Platform**: macOS/Darwin System
23
- **Ruby Platform**: <%= RUBY_PLATFORM %>
24
- **Ruby Version**: <%= RUBY_VERSION %>
25
- **Ruby Engine**: <%= RUBY_ENGINE %>
26
- <% elsif RUBY_PLATFORM.include?('linux') %>
27
- **Platform**: Linux System
28
- **Ruby Platform**: <%= RUBY_PLATFORM %>
29
- **Ruby Version**: <%= RUBY_VERSION %>
30
- **Ruby Engine**: <%= RUBY_ENGINE %>
31
- <% else %>
32
- **Platform**: Other Unix-like System
33
- **Ruby Platform**: <%= RUBY_PLATFORM %>
34
- **Ruby Version**: <%= RUBY_VERSION %>
35
- **Ruby Engine**: <%= RUBY_ENGINE %>
36
- <% end %>
37
-
38
- ### Environment Configuration
39
- **PATH**: $PATH
40
- **Language**: $LANG
41
- **Editor**: $EDITOR
42
- **Pager**: $PAGER
43
-
44
- ### Development Environment
45
- <% if ENV['RBENV_VERSION'] %>
46
- **Ruby Version Manager**: rbenv (version: <%= ENV['RBENV_VERSION'] %>)
47
- <% elsif ENV['RVM_VERSION'] %>
48
- **Ruby Version Manager**: RVM (version: <%= ENV['RVM_VERSION'] %>)
49
- <% else %>
50
- **Ruby Version Manager**: System Ruby or other
51
- <% end %>
52
-
53
- **Gem Home**: $GEM_HOME
54
- **Gem Path**: $GEM_PATH
55
-
56
- ### Performance Context
57
- **Load Average**: <%= `uptime`.strip rescue 'Unable to determine' %>
58
- **Memory Info**: <%= `vm_stat | head -5`.strip rescue 'Unable to determine' if RUBY_PLATFORM.include?('darwin') %>
59
- **Disk Usage**: <%= `df -h / | tail -1`.strip rescue 'Unable to determine' %>
60
-
61
- ## Analysis Request
62
-
63
- You are a technology historian and systems analyst. Please provide a comprehensive comparison between this current system and **the most powerful Apple computer created in the 20th century** (which would be from the 1990s).
64
-
65
- Consider these aspects in your analysis:
66
-
67
- 1. **Processing Power**: Compare the computational capabilities
68
- 2. **Memory and Storage**: Analyze RAM and storage differences
69
- 3. **Architecture Evolution**: Discuss the architectural changes
70
- 4. **Operating System**: Compare the OS sophistication
71
- 5. **Development Environment**: Contrast the programming environments
72
- 6. **Historical Context**: Put both systems in their historical perspective
73
- 7. **Price and Accessibility**: Consider cost and availability differences
74
- 8. **Legacy Impact**: How each system influenced computing
75
-
76
- Please be specific about which Apple computer from the 1990s you're comparing against, and provide concrete numbers where possible. Make the comparison engaging and educational, highlighting the dramatic evolution of computing power over the decades.
77
-
78
- **Format your response as a detailed technical report with clear sections and specific comparisons.**
79
- ```
@@ -1 +0,0 @@
1
- {"{language}":"French"}
@@ -1,8 +0,0 @@
1
- # This is a demonstration of directive processing
2
- # Comments like this are ignored when the prompt is processed
3
-
4
- // good_directive param_one param_two
5
-
6
- This is a demonstration of parameters using {language} syntax.
7
-
8
- You can substitute parameters like {language} with values.
@@ -1 +0,0 @@
1
- {"[LANGUAGE]":[],"[KEYWORD_AKA_TODO]":"TODO"}
@@ -1,7 +0,0 @@
1
- # prompts_dir/todo.txt
2
- # Desc: Let the robot fix the TODO items.
3
- #
4
-
5
- As an experienced [LANGUAGE] software engineer write some [LANGUAGE] source code. Consider the following [LANGUAGE] file. For each comment line that contains the word "[KEYWORD_AKA_TODO]" take the text that follows that word as a requirement to be implemented in [LANGUAGE]. Remove the "[KEYWORD_AKA_TODO]" word from the comment line. After the line insert the [LANGUAGE] code that implements the requirement.
6
-
7
- __END__
@@ -1,4 +0,0 @@
1
- # prompt_manager/examples/prompts_dir/toy/8-ball.txt
2
- # Desc: In the late 1940s the toy "Magic 8 Ball" came to market
3
-
4
- As a magic 8-ball, provide me with a terse answer to what you suspect that I am thinking about.
data/examples/rgfzf DELETED
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Refactored examples/rgfzf to take search term and directory path as parameters
3
-
4
- search_term="$1"
5
- directory_path="${2:-$(pwd)}" # Use given directory path, or current working directory if not provided
6
-
7
- # Verify that a search term is provided
8
- if [[ -z "$search_term" ]]; then
9
- echo "Usage: $0 search_term [directory_path]"
10
- exit 1
11
- fi
12
-
13
- # Ensure ripgrep (rg) and fzf are installed
14
- if ! command -v rg &> /dev/null || ! command -v fzf &> /dev/null; then
15
- echo "Please ensure ripgrep and fzf are installed before running this script."
16
- exit 1
17
- fi
18
-
19
- # Perform the file search using ripgrep and selection using fzf
20
- selected_file=$(
21
- rg --files-with-matches \
22
- --no-messages \
23
- --smart-case "$search_term" "$directory_path" |
24
- sed "s#^$directory_path/##" | # Strip out the directory path
25
- fzf --ansi \
26
- --color "hl:-1:underline,hl+:-1:underline:reverse" \
27
- --preview "cat $directory_path/{}" \
28
- --preview-window "up,60%,border-bottom" \
29
- --no-multi \
30
- --exit-0 \
31
- --query "$search_term"
32
- )
33
-
34
-
35
- # If no file was selected, exit the script
36
- if [[ -z "$selected_file" ]]; then
37
- # echo "No file selected."
38
- exit 0
39
- fi
40
-
41
- # Remove the file extension
42
- prompt_id=$(echo "$selected_file" | sed "s/\.[^.]*$//")
43
-
44
- echo "$prompt_id"
data/examples/simple.rb DELETED
@@ -1,160 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
- # frozen_string_literal: true
4
- # warn_indent: true
5
- ##########################################################
6
- ###
7
- ## File: simple.rb
8
- ## Desc: Simple demo of the PromptManager and FileStorageAdapter
9
- ## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
10
- ##
11
- #
12
-
13
- require 'prompt_manager'
14
- require 'prompt_manager/storage/file_system_adapter'
15
-
16
- require 'amazing_print'
17
- require 'pathname'
18
-
19
- HERE = Pathname.new( __dir__ )
20
- PROMPTS_DIR = HERE + "prompts_dir"
21
-
22
-
23
- ######################################################
24
- # Main
25
-
26
- at_exit do
27
- puts
28
- puts "Done."
29
- puts
30
- end
31
-
32
- # Configure the Storage Adapter to use
33
- PromptManager::Storage::FileSystemAdapter.config do |config|
34
- config.prompts_dir = PROMPTS_DIR
35
- # config.search_proc = nil # default
36
- # config.prompt_extension = '.txt' # default
37
- # config.parms+_extension = '.json' # default
38
- end
39
-
40
- PromptManager::Prompt.storage_adapter = PromptManager::Storage::FileSystemAdapter.new
41
-
42
- # Get a prompt
43
- # Note: The 'get' method returns a Hash, not a Prompt object
44
- # Use 'find' instead to get a Prompt object with methods
45
-
46
- todo = PromptManager::Prompt.find(id: 'todo')
47
-
48
- # This sequence simulates presenting each of the previously
49
- # used values for each keyword to the user to accept or
50
- # edit.
51
-
52
- # ap todo.keywords
53
-
54
- # This is a new keyword that was added after the current
55
- # todo.json file was created. Simulate the user setting
56
- # its value.
57
-
58
- todo.parameters["[KEYWORD_AKA_TODO]"] = "TODO"
59
-
60
- # When the parameter values change, the prompt must
61
- # be saved to persist the changes
62
- todo.save
63
-
64
-
65
- puts <<~EOS
66
-
67
- Raw Text from Prompt File
68
- includes all lines
69
- =========================
70
- EOS
71
-
72
- puts todo.text
73
-
74
-
75
- puts <<~EOS
76
-
77
- Last Set of Parameters Used
78
- Includes those recently added
79
- =============================
80
- EOS
81
-
82
- ap todo.parameters
83
-
84
-
85
- puts <<~EOS
86
-
87
- Prompt Ready to Send to gen-AI
88
- ==============================
89
- EOS
90
-
91
- puts todo.to_s
92
-
93
- puts <<~EOS
94
-
95
- When using the FileSystemAdapter for prompt storage you can have within
96
- the prompts_dir you can have many sub-directories. These sub-directories
97
- act like categories. The prompt ID is composed for the sub-directory name,
98
- a "/" character and then the normal prompt ID. For example "toy/8-ball"
99
-
100
- EOS
101
-
102
- magic = PromptManager::Prompt.find(id: 'toy/8-ball')
103
-
104
- puts "The magic PROMPT is:"
105
- puts magic
106
- puts
107
- puts "Remember if you want to see the full text of the prompt file:"
108
- puts magic.text
109
-
110
- puts "="*64
111
-
112
- puts <<~EOS
113
-
114
- The FileSystemAdapter also adds two new class methods to the Prompt class:
115
-
116
- list - provides an Array of prompt IDs
117
- path(prompt_id) - Returns a Pathname object to the prompt file
118
-
119
- EOS
120
-
121
- puts "List of prompts available"
122
- puts "========================="
123
-
124
- puts PromptManager::Prompt.list
125
-
126
- puts <<~EOS
127
-
128
- And the path to the "toy/8-ball" prompt file is:
129
-
130
- #{PromptManager::Prompt.path('toy/8-ball')}
131
-
132
- Use "your_prompt.path" for when you want to do something with the
133
- the prompt file like send it to a text editor.
134
-
135
- Your can also use the class method if you supply a prompt_id
136
- like this:
137
-
138
- EOS
139
-
140
- puts PromptManager::Prompt.path('toy/8-ball')
141
-
142
- puts
143
-
144
- puts "Default Search for Prompts"
145
- puts "=========================="
146
-
147
- print "Search Proc Class: "
148
- puts PromptManager::Prompt.storage_adapter.search_proc.class
149
-
150
- search_term = "txt" # some comment lines show the file name example: todo.txt
151
-
152
- puts "Search for '#{search_term}' ..."
153
-
154
- prompt_ids = PromptManager::Prompt.search search_term
155
-
156
- # NOTE: prompt+ids is an Array of prompt IDs even if there is only one entry.
157
- # or and empty array if there are no prompts have the search term.
158
-
159
- puts "Found: #{prompt_ids}"
160
-
@@ -1,68 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
- # frozen_string_literal: true
4
- # warn_indent: true
5
- ##########################################################
6
- ###
7
- ## File: using_search_proc.rb
8
- ## Desc: Simple demo of the PromptManager and FileStorageAdapter
9
- ## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
10
- ##
11
- #
12
-
13
- require 'prompt_manager'
14
- require 'prompt_manager/storage/file_system_adapter'
15
-
16
- require 'amazing_print'
17
- require 'pathname'
18
-
19
- HERE = Pathname.new( __dir__ )
20
- PROMPTS_DIR = HERE + "prompts_dir"
21
- SEARCH_SCRIPT = HERE + 'rgfzf' # a bash script using rg and fzf
22
-
23
- ######################################################
24
- # Main
25
-
26
- at_exit do
27
- puts
28
- puts "Done."
29
- puts
30
- end
31
-
32
- # Configure the Storage Adapter to use
33
- PromptManager::Storage::FileSystemAdapter.config do |config|
34
- config.prompts_dir = PROMPTS_DIR
35
- config.search_proc = ->(q) {`#{SEARCH_SCRIPT} #{q} #{PROMPTS_DIR}`} # default
36
- # config.prompt_extension = '.txt' # default
37
- # config.parms+_extension = '.json' # default
38
- end
39
-
40
- PromptManager::Prompt.storage_adapter = PromptManager::Storage::FileSystemAdapter.new
41
-
42
-
43
-
44
- puts "Using Custom Search Proc"
45
- puts "========================"
46
-
47
- print "Search Proc Class: "
48
- puts PromptManager::Prompt.storage_adapter.search_proc.class
49
-
50
- search_term = "txt" # some comment lines show the file name example: todo.txt
51
-
52
- puts "Search for '#{search_term}' ..."
53
-
54
- prompt_id = PromptManager::Prompt.search search_term
55
-
56
- # NOTE: the search proc uses fzf as a selection tool. In this
57
- # case only one selected prompt ID that matches the search
58
- # term will be returned.
59
-
60
- puts "Found: '#{prompt_id}' which is a #{prompt_id.class}. empty? #{prompt_id.empty?}"
61
-
62
- puts <<~EOS
63
-
64
- When the rgfzf bash script does not find a prompt ID or if the
65
- ESC key is pressed, the prompt ID that is returned will be an empty String.
66
-
67
- EOS
68
-