aia 0.9.13 → 0.9.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5d9ca1e0f36d50857345bcad1268359e8435c16ba2c159d68482c070de59207
4
- data.tar.gz: 20e10d41131b850e7320613f0959d8c94589e48422bc5ba948954c614c094c12
3
+ metadata.gz: acca553714c1fe19ed2a152a5ca500691d0435817369e60a1d773b9996d02802
4
+ data.tar.gz: f97fd1bc43cf1d8d1a8d2364313ad59a89462c31b71648c28828faa3ddc36ab9
5
5
  SHA512:
6
- metadata.gz: bb7913215b44a686db90c9e9e4a69a00024611c0a28f7f06da4290ad7781ef9685288845ea17f3c4180f74badf4d0829a462596a0280aed91354b6d54a36f975
7
- data.tar.gz: 1701b67da9e0aa8afa4cd1815422989544c191e50a38f58205984b1d96033d4a6dea27fe1b9efceb9307b231848fd9cc6440bd83203a9b03dfa7c5dbee700fd2
6
+ metadata.gz: 3b54ffdbcc2268e9a509f4c144182249c2d02cc520b0f1f37d7ebe8a4e79400cd2e23a96f77660019c5fb205a0bdf5df8eff14c3809f24c58886aee1fbde306f
7
+ data.tar.gz: 57a0a68ddedd0bdd69a5f25802cb9a09f8c300829d2e48c2f6025147eae3b29c861d47004614dc33108cf3a403605ee98ad9c0c239aae47e05afb8def40fb738
data/.version CHANGED
@@ -1 +1 @@
1
- 0.9.13
1
+ 0.9.15
data/CHANGELOG.md CHANGED
@@ -1,7 +1,59 @@
1
1
  # Changelog
2
2
  ## [Unreleased]
3
-
4
3
  ## Released
4
+ ### [0.9.15] 2025-09-21
5
+
6
+ #### New Features
7
+ - **NEW FEATURE**: Added `//paste` directive to insert clipboard contents into prompts
8
+ - **NEW FEATURE**: Added `//clipboard` alias for the paste directive
9
+
10
+ #### Technical Changes
11
+ - Enhanced DirectiveProcessor with clipboard integration using the clipboard gem
12
+ - Added comprehensive test coverage for paste directive functionality
13
+
14
+ ### [0.9.14] 2025-09-19
15
+
16
+ #### New Features
17
+ - **NEW FEATURE**: Added `//checkpoint` directive to create named snapshots of conversation context
18
+ - **NEW FEATURE**: Added `//restore` directive to restore context to a previous checkpoint
19
+ - **NEW FEATURE**: Enhanced `//context` (and `//review`) directive to display checkpoint markers in conversation history
20
+ - **NEW FEATURE**: Added `//cp` alias for checkpoint directive
21
+
22
+ #### Improvements
23
+ - **ENHANCEMENT**: Context manager now tracks checkpoint positions for better context visualization
24
+ - **ENHANCEMENT**: Checkpoint system uses auto-incrementing integer names when no name is provided
25
+ - **ENHANCEMENT**: Restore directive defaults to last checkpoint when no name specified
26
+ - **ENHANCEMENT**: Clear context now also clears all checkpoints
27
+
28
+ #### Bug Fixes
29
+ - **BUG FIX**: Fixed `//help` directive that was showing empty list of directives
30
+ - **BUG FIX**: Help directive now displays all directives from all registered modules
31
+ - **BUG FIX**: Help directive now shows proper descriptions and aliases for all directives
32
+ - **BUG FIX**: Help directive organizes directives by category for better readability
33
+
34
+ #### Technical Changes
35
+ - Enhanced ContextManager with checkpoint storage and restoration capabilities
36
+ - Added checkpoint_positions method to track checkpoint locations in context
37
+ - Refactored help directive to collect directives from all registered modules
38
+ - Added comprehensive test coverage for checkpoint and restore functionality
39
+
40
+ ### [0.9.13] 2025-09-02
41
+ #### New Features
42
+ - **NEW FEATURE**: Added `--metrics` flag to show token counts for each model
43
+ - **NEW FEATURE**: Added `--cost` flag to enable cost estimation for each model
44
+
45
+ #### Improvements
46
+ - **DEPENDENCY**: Removed versionaire dependency, simplifying version management
47
+ - **ENHANCEMENT**: Improved test suite reliability and coverage
48
+ - **ENHANCEMENT**: Updated Gemfile.lock with latest dependency versions
49
+
50
+ #### Bug Fixes
51
+ - **BUG FIX**: Fixed version handling issues by removing external versioning dependency
52
+
53
+ #### Technical Changes
54
+ - Simplified version management by removing versionaire gem
55
+ - Enhanced test suite with improved assertions and coverage
56
+ - Updated various gem dependencies to latest stable versions
5
57
 
6
58
  ### [0.9.12] 2025-08-28
7
59
 
data/README.md CHANGED
@@ -334,8 +334,11 @@ Directives are special commands in prompt files that begin with `//` and provide
334
334
  | Directive | Description | Example |
335
335
  |-----------|-------------|---------|
336
336
  | `//config` | Set configuration values | `//config model = gpt-4` |
337
- | `//context` | Show context for this conversation | `//context` |
337
+ | `//context` | Show context for this conversation with checkpoint markers | `//context` |
338
+ | `//checkpoint` | Create a named checkpoint of current context | `//checkpoint save_point` |
339
+ | `//restore` | Restore context to a previous checkpoint | `//restore save_point` |
338
340
  | `//include` | Insert file contents | `//include path/to/file.txt` |
341
+ | `//paste` | Insert clipboard contents | `//paste` |
339
342
  | `//shell` | Execute shell commands | `//shell ls -la` |
340
343
  | `//robot` | Show the pet robot ASCII art w/versions | `//robot` |
341
344
  | `//ruby` | Execute Ruby code | `//ruby puts "Hello World"` |
@@ -346,7 +349,7 @@ Directives are special commands in prompt files that begin with `//` and provide
346
349
  | `//model` | Show current model configuration | `//model` |
347
350
  | `//available_models` | List available models | `//available_models` |
348
351
  | `//tools` | Show a list of available tools and their description | `//tools` |
349
- | `//review` | Review current context | `//review` |
352
+ | `//review` | Review current context with checkpoint markers | `//review` |
350
353
 
351
354
  Directives can also be used in the interactive chat sessions.
352
355
 
@@ -370,6 +373,9 @@ Your prompt content here...
370
373
  # Include file contents
371
374
  //include ~/project/README.md
372
375
 
376
+ # Paste clipboard contents
377
+ //paste
378
+
373
379
  # Execute shell commands
374
380
  //shell git log --oneline -10
375
381
 
@@ -379,6 +385,64 @@ Your prompt content here...
379
385
  Analyze the above information and provide insights.
380
386
  ```
381
387
 
388
+ #### Context Management with Checkpoints
389
+
390
+ AIA provides powerful context management capabilities in chat mode through checkpoint and restore directives:
391
+
392
+ ```bash
393
+ # Create a checkpoint with automatic naming (1, 2, 3...)
394
+ //checkpoint
395
+
396
+ # Create a named checkpoint
397
+ //checkpoint important_decision
398
+
399
+ # Restore to the last checkpoint
400
+ //restore
401
+
402
+ # Restore to a specific checkpoint
403
+ //restore important_decision
404
+
405
+ # View context with checkpoint markers
406
+ //context
407
+ ```
408
+
409
+ **Example Chat Session:**
410
+ ```
411
+ You: Tell me about Ruby programming
412
+ AI: Ruby is a dynamic programming language...
413
+
414
+ You: //checkpoint ruby_basics
415
+
416
+ You: Now explain object-oriented programming
417
+ AI: Object-oriented programming (OOP) is...
418
+
419
+ You: //checkpoint oop_concepts
420
+
421
+ You: Actually, let's go back to Ruby basics
422
+ You: //restore ruby_basics
423
+
424
+ You: //context
425
+ === Chat Context ===
426
+ Total messages: 4
427
+ Checkpoints: ruby_basics, oop_concepts
428
+
429
+ 1. [System]: You are a helpful assistant
430
+ 2. [User]: Tell me about Ruby programming
431
+ 3. [Assistant]: Ruby is a dynamic programming language...
432
+
433
+ 📍 [Checkpoint: ruby_basics]
434
+ ----------------------------------------
435
+ 4. [User]: Now explain object-oriented programming
436
+ === End of Context ===
437
+ ```
438
+
439
+ **Key Features:**
440
+ - **Auto-naming**: Checkpoints without names use incrementing integers (1, 2, 3...)
441
+ - **Named checkpoints**: Use meaningful names like `//checkpoint before_refactor`
442
+ - **Default restore**: `//restore` without a name restores to the last checkpoint
443
+ - **Context visualization**: `//context` shows checkpoint markers in conversation history
444
+ - **Clean slate**: `//clear` removes all context and checkpoints
445
+
382
446
  #### Custom Directive Examples
383
447
 
384
448
  You can extend AIA with custom directives by creating Ruby files that define new directive methods:
@@ -160,6 +160,30 @@ if File.exist?(history_file)
160
160
  Now analyze <%= task %> using all available context layers.
161
161
  ```
162
162
 
163
+ ### Clipboard Integration
164
+ Quick data insertion from clipboard:
165
+
166
+ ```markdown
167
+ # Code Review with Clipboard Content
168
+
169
+ ## Code to Review
170
+ //paste
171
+
172
+ ## Review Guidelines
173
+ - Check for best practices
174
+ - Identify security vulnerabilities
175
+ - Suggest performance improvements
176
+ - Validate error handling
177
+
178
+ Please provide detailed feedback on the code above.
179
+ ```
180
+
181
+ This is particularly useful for:
182
+ - Quick code reviews when you've copied code from an IDE
183
+ - Analyzing error messages or logs copied from terminals
184
+ - Including data from spreadsheets or other applications
185
+ - Rapid prototyping with copied examples
186
+
163
187
  ### Context Filtering and Summarization
164
188
  Manage large contexts intelligently:
165
189
 
@@ -237,6 +261,11 @@ Generate an academic document with:
237
261
  <% end %>
238
262
  <% end %>
239
263
 
264
+ ## Clipboard Content (if applicable)
265
+ <% if include_clipboard %>
266
+ //paste
267
+ <% end %>
268
+
240
269
  Target audience: <%= audience || "general professional" %>
241
270
  Document length: <%= length || "2000-3000 words" %>
242
271
  ```
@@ -111,6 +111,24 @@ Include content from files or websites.
111
111
 
112
112
  **Aliases**: `//import`
113
113
 
114
+ ### `//paste`
115
+ Insert content from the system clipboard.
116
+
117
+ **Syntax**: `//paste`
118
+
119
+ **Examples**:
120
+ ```markdown
121
+ //paste
122
+ ```
123
+
124
+ **Features**:
125
+ - Inserts the current clipboard contents directly into the prompt
126
+ - Useful for quickly including copied text, code, or data
127
+ - Works across different platforms (macOS, Linux, Windows)
128
+ - Handles multi-line clipboard content
129
+
130
+ **Aliases**: `//clipboard`
131
+
114
132
  ### `//webpage`
115
133
  Include content from web pages (requires PUREMD_API_KEY).
116
134
 
@@ -271,21 +289,93 @@ Inserts a fun ASCII robot character for visual breaks in prompts.
271
289
 
272
290
  ## Context Management Directives
273
291
 
292
+ ### `//checkpoint`
293
+ Create a named checkpoint of the current conversation context.
294
+
295
+ **Syntax**: `//checkpoint [name]`
296
+
297
+ **Examples**:
298
+ ```markdown
299
+ //checkpoint # Auto-named checkpoint (1, 2, 3...)
300
+ //checkpoint important_decision # Named checkpoint
301
+ //checkpoint before_refactor # Descriptive name
302
+ ```
303
+
304
+ **Features**:
305
+ - **Auto-naming**: If no name provided, uses incrementing integers (1, 2, 3...)
306
+ - **Named checkpoints**: Use meaningful names for easy identification
307
+ - **Deep copying**: Safely stores complete conversation state
308
+ - **Chat mode only**: Only available during interactive chat sessions
309
+
310
+ **Usage**:
311
+ - `//checkpoint` - Create an auto-named checkpoint
312
+ - `//checkpoint name` - Create a checkpoint with specific name
313
+
314
+ **Aliases**: `//cp`
315
+
316
+ ### `//restore`
317
+ Restore conversation context to a previously saved checkpoint.
318
+
319
+ **Syntax**: `//restore [name]`
320
+
321
+ **Examples**:
322
+ ```markdown
323
+ //restore # Restore to last checkpoint
324
+ //restore important_decision # Restore to named checkpoint
325
+ //restore 1 # Restore to auto-named checkpoint
326
+ ```
327
+
328
+ **Features**:
329
+ - **Default behavior**: Without a name, restores to the most recent checkpoint
330
+ - **Named restoration**: Restore to any previously saved checkpoint
331
+ - **Context truncation**: Removes all messages added after the checkpoint
332
+ - **Client refresh**: Automatically refreshes AI client context
333
+
334
+ **Usage**:
335
+ - `//restore` - Restore to the last checkpoint created
336
+ - `//restore name` - Restore to a specific named checkpoint
337
+ - Returns error message if checkpoint doesn't exist
338
+
274
339
  ### `//clear`
275
340
  Clear conversation context in chat mode.
276
341
 
277
342
  **Syntax**: `//clear`
278
343
 
279
- **Usage**: Only available during chat sessions. Clears the conversation history while keeping the session active.
344
+ **Usage**: Only available during chat sessions. Clears the conversation history and all checkpoints while keeping the session active.
280
345
 
281
346
  ### `//review`
282
- Display current conversation context.
347
+ Display current conversation context with checkpoint markers.
283
348
 
284
349
  **Syntax**: `//review`
285
350
 
286
351
  **Aliases**: `//context`
287
352
 
288
- Shows the current context manager state, including conversation history and metadata.
353
+ **Example Output**:
354
+ ```
355
+ === Chat Context ===
356
+ Total messages: 5
357
+ Checkpoints: ruby_basics, oop_concepts
358
+
359
+ 1. [System]: You are a helpful assistant
360
+ 2. [User]: Tell me about Ruby programming
361
+ 3. [Assistant]: Ruby is a dynamic programming language...
362
+
363
+ 📍 [Checkpoint: ruby_basics]
364
+ ----------------------------------------
365
+ 4. [User]: Now explain object-oriented programming
366
+ 5. [Assistant]: Object-oriented programming (OOP) is...
367
+
368
+ 📍 [Checkpoint: oop_concepts]
369
+ ----------------------------------------
370
+ === End of Context ===
371
+ ```
372
+
373
+ **Features**:
374
+ - Shows complete conversation history with message numbers
375
+ - Displays checkpoint markers (📍) at their exact positions
376
+ - Lists all available checkpoints
377
+ - Truncates long messages for readability (200 characters)
378
+ - Shows total message count and checkpoint summary
289
379
 
290
380
  ## Model and Information Directives
291
381
 
data/docs/guides/chat.md CHANGED
@@ -112,19 +112,71 @@ You: How do I handle user authentication?
112
112
  AI: For your Flask application, here are several authentication options...
113
113
  ```
114
114
 
115
+ #### Context Checkpoints
116
+ Create savepoints in your conversation to easily return to specific moments:
117
+
118
+ ```
119
+ You: Let's explore different authentication approaches for Flask.
120
+ AI: I can help you explore various authentication methods...
121
+
122
+ You: //checkpoint auth_start
123
+
124
+ You: Tell me about JWT authentication.
125
+ AI: JWT (JSON Web Tokens) authentication is a stateless approach...
126
+
127
+ You: //checkpoint jwt_discussion
128
+
129
+ You: What about OAuth integration?
130
+ AI: OAuth provides a robust framework for authentication...
131
+
132
+ You: Actually, let's go back to the JWT discussion
133
+ You: //restore jwt_discussion
134
+
135
+ You: //context
136
+ === Chat Context ===
137
+ Total messages: 6
138
+ Checkpoints: auth_start, jwt_discussion
139
+
140
+ 1. [System]: You are a helpful assistant
141
+ 2. [User]: Let's explore different authentication approaches for Flask.
142
+ 3. [Assistant]: I can help you explore various authentication methods...
143
+
144
+ 📍 [Checkpoint: auth_start]
145
+ ----------------------------------------
146
+ 4. [User]: Tell me about JWT authentication.
147
+ 5. [Assistant]: JWT (JSON Web Tokens) authentication is a stateless approach...
148
+
149
+ 📍 [Checkpoint: jwt_discussion]
150
+ ----------------------------------------
151
+ === End of Context ===
152
+ ```
153
+
154
+ **Checkpoint Commands**:
155
+ - `//checkpoint` - Create auto-numbered checkpoint (1, 2, 3...)
156
+ - `//checkpoint name` - Create named checkpoint
157
+ - `//restore` - Restore to last checkpoint
158
+ - `//restore name` - Restore to specific checkpoint
159
+ - `//cp name` - Short alias for checkpoint
160
+
161
+ **Use Cases for Checkpoints**:
162
+ - **Exploring alternatives**: Save before trying different approaches
163
+ - **Debugging conversations**: Return to working state after errors
164
+ - **Session branching**: Explore multiple conversation paths
165
+ - **Learning sessions**: Bookmark important explanations
166
+
115
167
  #### Context Inspection
116
168
  ```
117
- You: /context
118
- # Shows current conversation history and metadata
169
+ You: //context
170
+ # Shows current conversation history with checkpoint markers
171
+
172
+ You: //review
173
+ # Alternative command for context inspection
119
174
  ```
120
175
 
121
176
  #### Context Clearing
122
177
  ```
123
- You: /clear
124
- # Clears conversation history while keeping session active
125
-
126
- You: /new
127
- # Starts a completely fresh session
178
+ You: //clear
179
+ # Clears conversation history and all checkpoints while keeping session active
128
180
  ```
129
181
 
130
182
  ### Tool Integration in Chat
@@ -3,11 +3,13 @@
3
3
  module AIA
4
4
  # Manages the conversation context for chat sessions.
5
5
  class ContextManager
6
- attr_reader :context
6
+ attr_reader :context, :checkpoints
7
7
 
8
8
  # Initializes the ContextManager with an optional system prompt.
9
9
  def initialize(system_prompt: nil)
10
10
  @context = []
11
+ @checkpoints = {}
12
+ @checkpoint_counter = 0
11
13
  add_system_prompt(system_prompt) if system_prompt && !system_prompt.strip.empty?
12
14
  end
13
15
 
@@ -43,6 +45,10 @@ module AIA
43
45
  @context = []
44
46
  end
45
47
 
48
+ # Clear all checkpoints when clearing context
49
+ @checkpoints.clear
50
+ @checkpoint_counter = 0
51
+
46
52
  # Attempt to clear the LLM client's context as well
47
53
  begin
48
54
  if AIA.config.client && AIA.config.client.respond_to?(:clear_context)
@@ -61,6 +67,60 @@ module AIA
61
67
  end
62
68
  end
63
69
 
70
+ # Creates a checkpoint of the current context with an optional name.
71
+ #
72
+ # @param name [String, nil] The name of the checkpoint. If nil, uses an incrementing integer.
73
+ # @return [String] The name of the created checkpoint.
74
+ def create_checkpoint(name: nil)
75
+ if name.nil?
76
+ @checkpoint_counter += 1
77
+ name = @checkpoint_counter.to_s
78
+ end
79
+
80
+ # Store a deep copy of the current context and its position
81
+ @checkpoints[name] = {
82
+ context: @context.map(&:dup),
83
+ position: @context.size
84
+ }
85
+ @last_checkpoint_name = name
86
+ name
87
+ end
88
+
89
+ # Restores the context to a previously saved checkpoint.
90
+ #
91
+ # @param name [String, nil] The name of the checkpoint to restore. If nil, uses the last checkpoint.
92
+ # @return [Boolean] True if restore was successful, false otherwise.
93
+ def restore_checkpoint(name: nil)
94
+ name = @last_checkpoint_name if name.nil?
95
+
96
+ return false if name.nil? || !@checkpoints.key?(name)
97
+
98
+ # Restore the context from the checkpoint
99
+ checkpoint_data = @checkpoints[name]
100
+ @context = checkpoint_data[:context].map(&:dup)
101
+ true
102
+ end
103
+
104
+ # Returns the list of available checkpoint names.
105
+ #
106
+ # @return [Array<String>] The names of all checkpoints.
107
+ def checkpoint_names
108
+ @checkpoints.keys
109
+ end
110
+
111
+ # Returns checkpoint information mapped to context positions.
112
+ #
113
+ # @return [Hash<Integer, Array<String>>] Position to checkpoint names mapping.
114
+ def checkpoint_positions
115
+ positions = {}
116
+ @checkpoints.each do |name, data|
117
+ position = data[:position]
118
+ positions[position] ||= []
119
+ positions[position] << name
120
+ end
121
+ positions
122
+ end
123
+
64
124
  private
65
125
 
66
126
  # Adds or replaces the system prompt at the beginning of the context.
@@ -34,7 +34,7 @@ module AIA
34
34
  # Display details for all configured models
35
35
  puts
36
36
  models = Array(AIA.config.model)
37
-
37
+
38
38
  if models.size == 1
39
39
  puts "Current Model:"
40
40
  puts "=============="
@@ -48,10 +48,10 @@ module AIA
48
48
  puts
49
49
  puts "Model Details:"
50
50
  puts "-" * 50
51
-
51
+
52
52
  models.each_with_index do |model_name, index|
53
53
  puts "#{index + 1}. #{model_name}#{index == 0 ? ' (primary)' : ''}"
54
-
54
+
55
55
  # Try to get model details if available
56
56
  begin
57
57
  # Access the model details from RubyLLM's model registry
@@ -98,16 +98,89 @@ module AIA
98
98
  end
99
99
 
100
100
  def self.review(args, context_manager = nil)
101
- ap context_manager.get_context
101
+ return "Error: Context manager not available for //review directive." if context_manager.nil?
102
+
103
+ context = context_manager.get_context
104
+ checkpoint_positions = context_manager.checkpoint_positions
105
+
106
+ # Display context with checkpoint markers
107
+ puts "\n=== Chat Context ==="
108
+ puts "Total messages: #{context.size}"
109
+
110
+ if checkpoint_positions.any?
111
+ puts "Checkpoints: #{context_manager.checkpoint_names.join(', ')}"
112
+ end
113
+
114
+ puts "\n"
115
+
116
+ context.each_with_index do |message, index|
117
+ # Check if there's a checkpoint at this position
118
+ if checkpoint_positions[index]
119
+ checkpoint_names = checkpoint_positions[index].join(', ')
120
+ puts "📍 [Checkpoint: #{checkpoint_names}]"
121
+ puts "-" * 40
122
+ end
123
+
124
+ # Display the message
125
+ role_display = message[:role].capitalize
126
+ content_preview = message[:content].to_s
127
+
128
+ # Truncate long content for display
129
+ if content_preview.length > 200
130
+ content_preview = content_preview[0..197] + "..."
131
+ end
132
+
133
+ puts "#{index + 1}. [#{role_display}]: #{content_preview}"
134
+ puts ""
135
+ end
136
+
137
+ # Check if there's a checkpoint at the end (after all messages)
138
+ if checkpoint_positions[context.size]
139
+ checkpoint_names = checkpoint_positions[context.size].join(', ')
140
+ puts "📍 [Checkpoint: #{checkpoint_names}]"
141
+ puts "-" * 40
142
+ end
143
+
144
+ puts "=== End of Context ==="
102
145
  ''
103
146
  end
104
147
 
148
+ def self.checkpoint(args, context_manager = nil)
149
+ if context_manager.nil?
150
+ return "Error: Context manager not available for //checkpoint directive."
151
+ end
152
+
153
+ name = args.empty? ? nil : args.join(' ').strip
154
+ checkpoint_name = context_manager.create_checkpoint(name: name)
155
+ "Checkpoint '#{checkpoint_name}' created."
156
+ end
157
+
158
+ def self.restore(args, context_manager = nil)
159
+ if context_manager.nil?
160
+ return "Error: Context manager not available for //restore directive."
161
+ end
162
+
163
+ name = args.empty? ? nil : args.join(' ').strip
164
+
165
+ if context_manager.restore_checkpoint(name: name)
166
+ restored_name = name || context_manager.checkpoint_names.last
167
+ "Context restored to checkpoint '#{restored_name}'."
168
+ else
169
+ if name
170
+ "Error: Checkpoint '#{name}' not found. Available checkpoints: #{context_manager.checkpoint_names.join(', ')}"
171
+ else
172
+ "Error: No checkpoints available to restore."
173
+ end
174
+ end
175
+ end
176
+
105
177
  # Set up aliases - these work on the module's singleton class
106
178
  class << self
107
179
  alias_method :cfg, :config
108
180
  alias_method :temp, :temperature
109
181
  alias_method :topp, :top_p
110
182
  alias_method :context, :review
183
+ alias_method :ckp, :checkpoint
111
184
  end
112
185
  end
113
186
  end
@@ -85,30 +85,163 @@ module AIA
85
85
  puts "===================="
86
86
  puts
87
87
 
88
- directives = self.methods(false).map(&:to_s).reject do |m|
89
- ['run', 'initialize', 'private?', 'descriptions', 'aliases', 'build_aliases'].include?(m)
90
- end.sort
91
-
92
- build_aliases(directives)
88
+ # Manual descriptions for all directives
89
+ directive_descriptions = {
90
+ # Configuration directives
91
+ 'config' => 'View or set configuration values',
92
+ 'model' => 'View or change the AI model',
93
+ 'temperature' => 'Set the temperature parameter for AI responses',
94
+ 'top_p' => 'Set the top_p parameter for AI responses',
95
+ 'clear' => 'Clear the conversation context',
96
+ 'review' => 'Display the current conversation context with checkpoint markers',
97
+ 'checkpoint' => 'Create a named checkpoint of the current context',
98
+ 'restore' => 'Restore context to a previous checkpoint',
99
+
100
+ # Utility directives
101
+ 'tools' => 'List available tools',
102
+ 'next' => 'Set the next prompt in the sequence',
103
+ 'pipeline' => 'Set or view the prompt workflow sequence',
104
+ 'terse' => 'Add instruction for concise responses',
105
+ 'robot' => 'Display ASCII robot art',
106
+
107
+ # Execution directives
108
+ 'ruby' => 'Execute Ruby code',
109
+ 'shell' => 'Execute shell commands',
110
+ 'say' => 'Use text-to-speech to speak the text',
111
+
112
+ # Web and File directives
113
+ 'webpage' => 'Fetch and include content from a webpage',
114
+ 'include' => 'Include content from a file',
115
+ 'include_file' => 'Include file content (internal use)',
116
+ 'included_files' => 'List files that have been included',
117
+ 'included_files=' => 'Set the list of included files',
118
+
119
+ # Model directives
120
+ 'available_models' => 'List all available AI models',
121
+ 'compare' => 'Compare responses from multiple models',
122
+ 'help' => 'Show this help message',
123
+
124
+ # Aliases (these get their descriptions from main directive)
125
+ 'cfg' => nil, # alias for config
126
+ 'temp' => nil, # alias for temperature
127
+ 'topp' => nil, # alias for top_p
128
+ 'context' => nil, # alias for review
129
+ 'cp' => nil, # alias for checkpoint
130
+ 'workflow' => nil, # alias for pipeline
131
+ 'rb' => nil, # alias for ruby
132
+ 'sh' => nil, # alias for shell
133
+ 'web' => nil, # alias for webpage
134
+ 'website' => nil, # alias for webpage
135
+ 'import' => nil, # alias for include
136
+ 'models' => nil, # alias for available_models
137
+ 'all_models' => nil, # alias for available_models
138
+ 'am' => nil, # alias for available_models
139
+ 'llms' => nil, # alias for available_models
140
+ 'available' => nil, # alias for available_models
141
+ 'cmp' => nil, # alias for compare
142
+ }
143
+
144
+ # Get all registered directive modules from the Registry
145
+ all_modules = [
146
+ AIA::Directives::WebAndFile,
147
+ AIA::Directives::Utility,
148
+ AIA::Directives::Configuration,
149
+ AIA::Directives::Execution,
150
+ AIA::Directives::Models
151
+ ]
152
+
153
+ all_directives = {}
154
+ excluded_methods = ['run', 'initialize', 'private?', 'descriptions', 'aliases', 'build_aliases',
155
+ 'desc', 'method_added', 'register_directive_module', 'process',
156
+ 'directive?', 'prefix_size']
157
+
158
+ # Collect directives from all modules
159
+ all_modules.each do |mod|
160
+ methods = mod.methods(false).map(&:to_s).reject { |m| excluded_methods.include?(m) }
161
+
162
+ methods.each do |method|
163
+ # Skip if this is an alias (has nil description)
164
+ next if directive_descriptions.key?(method) && directive_descriptions[method].nil?
165
+
166
+ description = directive_descriptions[method] || method.gsub('_', ' ').capitalize
167
+
168
+ all_directives[method] = {
169
+ module: mod.name.split('::').last,
170
+ description: description,
171
+ aliases: []
172
+ }
173
+ end
174
+ end
93
175
 
94
- directives.each do |directive|
95
- next unless descriptions[directive]
176
+ # Manually map known aliases
177
+ alias_mappings = {
178
+ 'config' => ['cfg'],
179
+ 'temperature' => ['temp'],
180
+ 'top_p' => ['topp'],
181
+ 'review' => ['context'],
182
+ 'checkpoint' => ['cp'],
183
+ 'pipeline' => ['workflow'],
184
+ 'ruby' => ['rb'],
185
+ 'shell' => ['sh'],
186
+ 'webpage' => ['web', 'website'],
187
+ 'include' => ['import'],
188
+ 'available_models' => ['models', 'all_models', 'am', 'llms', 'available'],
189
+ 'compare' => ['cmp']
190
+ }
191
+
192
+ # Apply alias mappings
193
+ alias_mappings.each do |directive, aliases|
194
+ if all_directives[directive]
195
+ all_directives[directive][:aliases] = aliases
196
+ end
197
+ end
96
198
 
97
- others = aliases[directive]
199
+ # Sort and display directives by category
200
+ categories = {
201
+ 'Configuration' => ['config', 'model', 'temperature', 'top_p', 'clear', 'review', 'checkpoint', 'restore'],
202
+ 'Utility' => ['tools', 'next', 'pipeline', 'terse', 'robot', 'help'],
203
+ 'Execution' => ['ruby', 'shell', 'say'],
204
+ 'Web & Files' => ['webpage', 'include'],
205
+ 'Models' => ['available_models', 'compare']
206
+ }
207
+
208
+ categories.each do |category, directives|
209
+ puts "#{category}:"
210
+ puts "-" * category.length
211
+
212
+ directives.each do |directive|
213
+ info = all_directives[directive]
214
+ next unless info
215
+
216
+ if info[:aliases] && !info[:aliases].empty?
217
+ with_prefix = info[:aliases].map { |m| PromptManager::Prompt::DIRECTIVE_SIGNAL + m }
218
+ alias_text = " (aliases: #{with_prefix.join(', ')})"
219
+ else
220
+ alias_text = ""
221
+ end
98
222
 
99
- if others.empty?
100
- others_line = ""
101
- else
102
- with_prefix = others.map { |m| PromptManager::Prompt::DIRECTIVE_SIGNAL + m }
103
- others_line = "\tAliases:#{with_prefix.join(' ')}\n"
223
+ puts " //#{directive}#{alias_text}"
224
+ puts " #{info[:description]}"
225
+ puts
104
226
  end
227
+ end
105
228
 
106
- puts <<~TEXT
107
- //#{directive} #{descriptions[directive]}
108
- #{others_line}
109
- TEXT
229
+ # Show any uncategorized directives
230
+ categorized = categories.values.flatten
231
+ uncategorized = all_directives.keys - categorized - ['include_file', 'included_files', 'included_files=']
232
+
233
+ if uncategorized.any?
234
+ puts "Other:"
235
+ puts "------"
236
+ uncategorized.sort.each do |directive|
237
+ info = all_directives[directive]
238
+ puts " //#{directive}"
239
+ puts " #{info[:description]}"
240
+ puts
241
+ end
110
242
  end
111
243
 
244
+ puts "\nTotal: #{all_directives.size} directives available"
112
245
  ""
113
246
  end
114
247
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'faraday'
4
4
  require 'active_support/all'
5
+ require 'clipboard'
5
6
 
6
7
  module AIA
7
8
  module Directives
@@ -60,11 +61,21 @@ module AIA
60
61
  @included_files = files
61
62
  end
62
63
 
64
+ def self.paste(args = [], context_manager = nil)
65
+ begin
66
+ content = Clipboard.paste
67
+ content.to_s
68
+ rescue => e
69
+ "Error: Unable to paste from clipboard - #{e.message}"
70
+ end
71
+ end
72
+
63
73
  # Set up aliases - these work on the module's singleton class
64
74
  class << self
65
75
  alias_method :website, :webpage
66
- alias_method :web, :webpage
76
+ alias_method :web, :webpage
67
77
  alias_method :import, :include
78
+ alias_method :clipboard, :paste
68
79
  end
69
80
  end
70
81
  end
data/lib/aia/session.rb CHANGED
@@ -407,10 +407,12 @@ module AIA
407
407
 
408
408
  def process_chat_directive(follow_up_prompt)
409
409
  directive_output = @directive_processor.process(follow_up_prompt, @context_manager)
410
-
410
+
411
411
  return handle_clear_directive if follow_up_prompt.strip.start_with?("//clear")
412
+ return handle_checkpoint_directive(directive_output) if follow_up_prompt.strip.start_with?("//checkpoint")
413
+ return handle_restore_directive(directive_output) if follow_up_prompt.strip.start_with?("//restore")
412
414
  return handle_empty_directive_output if directive_output.nil? || directive_output.strip.empty?
413
-
415
+
414
416
  handle_successful_directive(follow_up_prompt, directive_output)
415
417
  end
416
418
 
@@ -438,6 +440,31 @@ module AIA
438
440
  nil
439
441
  end
440
442
 
443
+ def handle_checkpoint_directive(directive_output)
444
+ @ui_presenter.display_info(directive_output)
445
+ nil
446
+ end
447
+
448
+ def handle_restore_directive(directive_output)
449
+ # If the restore was successful, we also need to refresh the client's context
450
+ if directive_output.start_with?("Context restored")
451
+ # Try to clear and rebuild the client's context
452
+ if AIA.config.client && AIA.config.client.respond_to?(:clear_context)
453
+ AIA.config.client.clear_context
454
+ end
455
+
456
+ # Optionally reinitialize the client for a clean state
457
+ begin
458
+ AIA.config.client = AIA::RubyLLMAdapter.new
459
+ rescue => e
460
+ STDERR.puts "Error reinitializing client after restore: #{e.message}"
461
+ end
462
+ end
463
+
464
+ @ui_presenter.display_info(directive_output)
465
+ nil
466
+ end
467
+
441
468
  def handle_empty_directive_output
442
469
  nil
443
470
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aia
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.13
4
+ version: 0.9.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
@@ -51,6 +51,20 @@ dependencies:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: clipboard
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: faraday
56
70
  requirement: !ruby/object:Gem::Requirement
@@ -433,7 +447,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
433
447
  - !ruby/object:Gem::Version
434
448
  version: '0'
435
449
  requirements: []
436
- rubygems_version: 3.7.1
450
+ rubygems_version: 3.7.2
437
451
  specification_version: 4
438
452
  summary: Multi-model AI CLI with dynamic prompts, consensus responses, shell & Ruby
439
453
  integration, and seamless chat workflows.