context_spook 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +48 -9
- data/Rakefile +1 -0
- data/bin/context_spook +0 -4
- data/context_spook.gemspec +3 -2
- data/contexts/project.rb +1 -1
- data/lib/context_spook/generator.rb +39 -3
- data/lib/context_spook/version.rb +1 -1
- data/spec/context_spook/generator_spec.rb +31 -4
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4088e8a4f8de00062dcea1b56b696dd1190731c0c30944a95c60a14cad995fa9
|
4
|
+
data.tar.gz: 996fb30d8a2542a387451416ece827dd1b8062344317ef798db803c216d39e17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df6ce1080b5b98a1e279f945cb0e5934592ea586c15abc24234b1c44aaa0d5aac55308227c2966a1e2e9912f620f4d13a5bda0940726028f589aa0ee522dc3fd
|
7
|
+
data.tar.gz: 2b787ae025a227d47f7d6ab53d850bc0c2084a6872e16bb2b60d122965d3dcdb17531fc4118371de82da0edcdd29b7a4ebe143b55019d3116bb424117edb85f4
|
data/README.md
CHANGED
@@ -32,8 +32,46 @@ $ gem install context_spook
|
|
32
32
|
|
33
33
|
## Usage
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
### Programmatic Usage
|
36
|
+
|
37
|
+
#### Directly in Ruby
|
38
|
+
|
39
|
+
Now you can generate context from a block directly in Ruby using the DSL:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
context = ContextSpook::generate_context do
|
43
|
+
context do
|
44
|
+
variable branch: `git rev-parse --abbrev-ref HEAD`.chomp
|
45
|
+
|
46
|
+
namespace "structure" do
|
47
|
+
command "tree", tags: %w[ project_structure ]
|
48
|
+
end
|
49
|
+
|
50
|
+
namespace "lib" do
|
51
|
+
Dir['lib/**/*.rb'].each do |filename|
|
52
|
+
file filename, tags: 'lib'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# ... rest of your context definition, see below for full example
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
This approach can be used to dynamically generate a context when it is not
|
62
|
+
configurable via a user context definition file, or as a fallback when users
|
63
|
+
have not yet created such files.
|
64
|
+
|
65
|
+
Afterwards you can store the context as JSON in Ruby or send it to another
|
66
|
+
application.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
File.write 'context.json', context.to_json
|
70
|
+
```
|
71
|
+
|
72
|
+
#### From a context definition file
|
73
|
+
|
74
|
+
Alternatively store the block's content above to a file `contexts/project.rb`:
|
37
75
|
|
38
76
|
```ruby
|
39
77
|
# contexts/project.rb
|
@@ -41,7 +79,7 @@ context do
|
|
41
79
|
variable branch: `git rev-parse --abbrev-ref HEAD`.chomp
|
42
80
|
|
43
81
|
namespace "structure" do
|
44
|
-
command "tree
|
82
|
+
command "tree", tags: %w[ project_structure ]
|
45
83
|
end
|
46
84
|
|
47
85
|
namespace "lib" do
|
@@ -72,9 +110,8 @@ context do
|
|
72
110
|
end
|
73
111
|
```
|
74
112
|
|
75
|
-
|
76
|
-
|
77
|
-
Now you can generate the context from the file, and store it as JSON in Ruby.
|
113
|
+
Now you can generate the context from the file, and store it as JSON in Ruby or
|
114
|
+
send it to another application.
|
78
115
|
|
79
116
|
```ruby
|
80
117
|
context = ContextSpook::generate_context('contexts/project.rb')
|
@@ -129,11 +166,13 @@ assistants understand:
|
|
129
166
|
"content": "...",
|
130
167
|
"size": 1234,
|
131
168
|
"lines": 56,
|
132
|
-
"tags": [
|
169
|
+
"tags": [
|
170
|
+
"lib"
|
171
|
+
]
|
133
172
|
}
|
134
173
|
},
|
135
174
|
"commands": {
|
136
|
-
"tree
|
175
|
+
"tree": {
|
137
176
|
"namespace": "structure",
|
138
177
|
"output": "lib\n├── context_spook\n│ └── generator.rb\n└── context_spook.rb\n\n2 directories, 3 files",
|
139
178
|
"exit_code": 0,
|
@@ -142,7 +181,7 @@ assistants understand:
|
|
142
181
|
},
|
143
182
|
"metadata": {
|
144
183
|
"ruby": "ruby 3.1.0 ...",
|
145
|
-
"code_coverage": {
|
184
|
+
"code_coverage": {}
|
146
185
|
},
|
147
186
|
"variables": {
|
148
187
|
"branch": "main"
|
data/Rakefile
CHANGED
@@ -29,6 +29,7 @@ GemHadar do
|
|
29
29
|
dependency 'tins', '~>1.39'
|
30
30
|
dependency 'json', '~>2.0'
|
31
31
|
dependency 'term-ansicolor', '~> 1.11'
|
32
|
+
dependency 'mize', '~> 0.6'
|
32
33
|
development_dependency 'all_images', '~> 0.6'
|
33
34
|
development_dependency 'rspec', '~> 3.2'
|
34
35
|
development_dependency 'debug'
|
data/bin/context_spook
CHANGED
@@ -4,8 +4,4 @@ require 'context_spook'
|
|
4
4
|
|
5
5
|
filename = ARGV.shift or fail 'require context definition file as first argument'
|
6
6
|
context_json = ContextSpook.generate_context(filename).to_json
|
7
|
-
context_json_size = Tins::Unit.format(
|
8
|
-
context_json.size, format: '%.2f %U', unit: ?b, prefix: 1024
|
9
|
-
)
|
10
|
-
STDERR.puts "Now outputting #{context_json_size} of JSON context in total."
|
11
7
|
puts context_json
|
data/context_spook.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: context_spook 0.
|
2
|
+
# stub: context_spook 0.2.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "context_spook".freeze
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.2.0".freeze
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
@@ -32,4 +32,5 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.39".freeze])
|
33
33
|
s.add_runtime_dependency(%q<json>.freeze, ["~> 2.0".freeze])
|
34
34
|
s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
|
35
|
+
s.add_runtime_dependency(%q<mize>.freeze, ["~> 0.6".freeze])
|
35
36
|
end
|
data/contexts/project.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'tins/xt'
|
2
2
|
require 'term/ansicolor'
|
3
3
|
require 'json'
|
4
|
-
|
4
|
+
require 'mize'
|
5
5
|
|
6
6
|
# The ContextSpook module serves as a namespace container for collecting and
|
7
7
|
# organizing project information for AI assistance.
|
@@ -19,8 +19,16 @@ module ContextSpook
|
|
19
19
|
#
|
20
20
|
# @return [ ContextSpook::Generator::Context ] the context object generated
|
21
21
|
# from the file contents
|
22
|
-
def self.generate_context(filename)
|
23
|
-
|
22
|
+
def self.generate_context(filename = nil, &block)
|
23
|
+
filename.present? ^ block or
|
24
|
+
raise ArgumentError, 'need either a filename or a &block argument'
|
25
|
+
generator = if filename
|
26
|
+
Generator.send(:new).send(:parse, File.read(filename))
|
27
|
+
else
|
28
|
+
Generator.send(:new, &block)
|
29
|
+
end
|
30
|
+
generator.output_context_size
|
31
|
+
generator.context
|
24
32
|
end
|
25
33
|
|
26
34
|
# The Generator class provides a DSL parser that interprets context
|
@@ -52,6 +60,20 @@ module ContextSpook
|
|
52
60
|
end
|
53
61
|
end
|
54
62
|
|
63
|
+
# The output_context_size method prints the total size of the generated
|
64
|
+
# context JSON representation.
|
65
|
+
#
|
66
|
+
# This method calculates the size of the context object when serialized to
|
67
|
+
# JSON, formats it using binary units (KiB, MiB, etc.), and outputs the
|
68
|
+
# result to standard error.
|
69
|
+
def output_context_size
|
70
|
+
context_size = @context&.size.to_i
|
71
|
+
json_content_size = Tins::Unit.format(
|
72
|
+
context_size, format: '%.2f %U', unit: ?b, prefix: 1024
|
73
|
+
)
|
74
|
+
STDERR.puts "Built #{json_content_size} of JSON context in total."
|
75
|
+
end
|
76
|
+
|
55
77
|
# The Context class represents and manages project context data, providing
|
56
78
|
# structured storage for file contents, command outputs, variables, and
|
57
79
|
# metadata that can be serialized to JSON for AI assistance.
|
@@ -214,6 +236,7 @@ module ContextSpook
|
|
214
236
|
# The to_json method converts the object to a JSON representation by
|
215
237
|
# first generating its hash form and then serializing that hash into JSON
|
216
238
|
# format.
|
239
|
+
memoize method:
|
217
240
|
def to_json(*)
|
218
241
|
as_json.to_json(*)
|
219
242
|
end
|
@@ -230,6 +253,19 @@ module ContextSpook
|
|
230
253
|
variables:
|
231
254
|
}
|
232
255
|
end
|
256
|
+
|
257
|
+
# The size method calculates and returns the byte size of the JSON
|
258
|
+
# representation of the context.
|
259
|
+
#
|
260
|
+
# This method determines the size in bytes of the JSON-serialized version
|
261
|
+
# of the context object, which is useful for understanding the total data
|
262
|
+
# payload being sent to an AI assistant.
|
263
|
+
#
|
264
|
+
# @return [ Integer ] the size in bytes of the JSON representation of the
|
265
|
+
# context
|
266
|
+
def size
|
267
|
+
to_json.size
|
268
|
+
end
|
233
269
|
end
|
234
270
|
|
235
271
|
private
|
@@ -5,19 +5,46 @@ describe ContextSpook::Generator do
|
|
5
5
|
ContextSpook.generate_context('contexts/project.rb')
|
6
6
|
end
|
7
7
|
|
8
|
-
it 'context can be generated' do
|
8
|
+
it 'context can be generated from block' do
|
9
|
+
expect_any_instance_of(described_class).to\
|
10
|
+
receive(:output_context_size).and_call_original
|
11
|
+
context = ContextSpook.generate_context do
|
12
|
+
context do
|
13
|
+
variable foo: 'bar'
|
14
|
+
metadata version: '1.0'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
expect(context).to be_a described_class::Context
|
18
|
+
expect(context.variables[:foo]).to eq 'bar'
|
19
|
+
expect(context.metadata[:version]).to eq '1.0'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'context can be generated from filename' do
|
23
|
+
expect_any_instance_of(described_class).to\
|
24
|
+
receive(:output_context_size).and_call_original
|
9
25
|
expect(context).to be_a described_class::Context
|
10
26
|
expect(context.metadata[:ruby]).to eq RUBY_DESCRIPTION
|
11
27
|
end
|
12
28
|
|
29
|
+
it 'could handle premature output_context_size calls' do
|
30
|
+
expect_any_instance_of(described_class).to\
|
31
|
+
receive(:output_context_size).and_call_original
|
32
|
+
described_class.send(:new).output_context_size
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'cannot do from block and filename' do
|
36
|
+
expect {
|
37
|
+
ContextSpook.generate_context('contexts/project.rb') { }
|
38
|
+
}.to raise_error(ArgumentError, /need either a filename or a &block/)
|
39
|
+
end
|
40
|
+
|
13
41
|
it 'context be transformed to JSON if loaded' do
|
14
42
|
context_as_json = context.to_json
|
15
|
-
expect(
|
43
|
+
expect(context.size).to be > 1024
|
16
44
|
expect(JSON(context_as_json)).to be_a Hash
|
17
45
|
end
|
18
46
|
|
19
47
|
describe 'Context' do
|
20
|
-
|
21
48
|
it 'can have variables' do
|
22
49
|
expect(context.variables[:branch]).to be_present
|
23
50
|
end
|
@@ -33,7 +60,7 @@ describe ContextSpook::Generator do
|
|
33
60
|
end
|
34
61
|
|
35
62
|
it 'can have commands' do
|
36
|
-
command = context.commands['tree
|
63
|
+
command = context.commands['tree']
|
37
64
|
expect(command).to be_present
|
38
65
|
expect(command[:working_directory]).to eq Dir.pwd
|
39
66
|
expect(command[:exit_code]).to be_present
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: context_spook
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
@@ -121,6 +121,20 @@ dependencies:
|
|
121
121
|
- - "~>"
|
122
122
|
- !ruby/object:Gem::Version
|
123
123
|
version: '1.11'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: mize
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0.6'
|
131
|
+
type: :runtime
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0.6'
|
124
138
|
description: |
|
125
139
|
context_spook is a library that collects and organizes project
|
126
140
|
information to help AI assistants understand codebases better.
|