context_spook 1.2.0 → 1.3.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/bin/context_spook +5 -11
- data/context_spook.gemspec +6 -6
- data/lib/context_spook/generator.rb +17 -43
- data/lib/context_spook/output_context.rb +36 -0
- data/lib/context_spook/toon.rb +8 -0
- data/lib/context_spook/utils.rb +2 -0
- data/lib/context_spook/verbose_puts.rb +25 -0
- data/lib/context_spook/version.rb +1 -1
- data/spec/context_spook/generator_spec.rb +78 -42
- data/spec/context_spook/toon_spec.rb +56 -0
- metadata +9 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a00a3e36535b351b630e539a1dfae938bb2325c2f639e3d0b318f1cac0e8c14f
|
|
4
|
+
data.tar.gz: 3c7976d1672dd67d6b0b07d64350e3baf211d6e8752b83631de9f5a17ae642f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82bf0afffa28eab0b379ec94c9a7a7cd34406ca82ccf4a7e78d26103082b8610ce3461a06a26772381fe59d6cfa401516eed532d33c6742cff980d08dea5508d
|
|
7
|
+
data.tar.gz: f969059b0b7ca9490ceb6560c5735da343c4ee5ee5ff856bae919da5ab66f02886e55a7096ad33b91241a147d78f5b5a82ec652ce25800658d46e4dc6a87bbc2
|
data/bin/context_spook
CHANGED
|
@@ -61,7 +61,7 @@ context = nil
|
|
|
61
61
|
output = nil
|
|
62
62
|
|
|
63
63
|
if opts[?i]
|
|
64
|
-
context = ContextSpook.generate_context(verbose: opts[?v]) do
|
|
64
|
+
context = ContextSpook.generate_context(verbose: opts[?v], format: opts[?F]) do
|
|
65
65
|
context do
|
|
66
66
|
opts[?i].to_a.each do |glob|
|
|
67
67
|
glob = File.expand_path(glob)
|
|
@@ -74,9 +74,10 @@ if opts[?i]
|
|
|
74
74
|
end
|
|
75
75
|
else
|
|
76
76
|
filename = ARGV.shift or fail 'require context definition file as an argument'
|
|
77
|
-
context = ContextSpook.generate_context(filename, verbose: opts[?v])
|
|
77
|
+
context = ContextSpook.generate_context(filename, verbose: opts[?v], format: opts[?F])
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
+
output = STDOUT
|
|
80
81
|
if opts[?S]
|
|
81
82
|
output = NULL
|
|
82
83
|
else
|
|
@@ -85,18 +86,11 @@ else
|
|
|
85
86
|
fail "Filename #{output_filename.inspect} already exists!"
|
|
86
87
|
end
|
|
87
88
|
output = File.new output_filename, ?w
|
|
88
|
-
else
|
|
89
|
-
output = STDOUT
|
|
90
89
|
end
|
|
91
90
|
end
|
|
92
91
|
case opts[?F]
|
|
93
|
-
when /\
|
|
94
|
-
|
|
95
|
-
STDERR.puts "Built #{ContextSpook::Utils.format_size(context.toon_size)} of TOON context in total."
|
|
96
|
-
end
|
|
97
|
-
output.puts context.to_toon
|
|
98
|
-
when /\AJSON\z/i, nil
|
|
99
|
-
JSON.dump(context.as_json, output)
|
|
92
|
+
when /\A(JSON|TOON)\z/i, nil
|
|
93
|
+
context.generator.output_context(output:)
|
|
100
94
|
else
|
|
101
95
|
STDERR.puts "Invalid output format #{opts[?F].inspect}"
|
|
102
96
|
end
|
data/context_spook.gemspec
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: context_spook 1.
|
|
2
|
+
# stub: context_spook 1.3.0 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "context_spook".freeze
|
|
6
|
-
s.version = "1.
|
|
6
|
+
s.version = "1.3.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]
|
|
@@ -12,19 +12,19 @@ Gem::Specification.new do |s|
|
|
|
12
12
|
s.description = "context_spook is a library that collects and organizes project\ninformation to help AI assistants understand codebases better.\n".freeze
|
|
13
13
|
s.email = "flori@ping.de".freeze
|
|
14
14
|
s.executables = ["context_spook".freeze]
|
|
15
|
-
s.extra_rdoc_files = ["README.md".freeze, "lib/context_spook.rb".freeze, "lib/context_spook/generator.rb".freeze, "lib/context_spook/toon.rb".freeze, "lib/context_spook/utils.rb".freeze, "lib/context_spook/version.rb".freeze]
|
|
16
|
-
s.files = [".contexts/project.rb".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/context_spook".freeze, "context_spook.gemspec".freeze, "hello_world.json".freeze, "hey_world.yaml".freeze, "lib/context_spook.rb".freeze, "lib/context_spook/generator.rb".freeze, "lib/context_spook/toon.rb".freeze, "lib/context_spook/utils.rb".freeze, "lib/context_spook/version.rb".freeze, "spec/context_spook/generator_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
15
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/context_spook.rb".freeze, "lib/context_spook/generator.rb".freeze, "lib/context_spook/output_context.rb".freeze, "lib/context_spook/toon.rb".freeze, "lib/context_spook/utils.rb".freeze, "lib/context_spook/verbose_puts.rb".freeze, "lib/context_spook/version.rb".freeze]
|
|
16
|
+
s.files = [".contexts/project.rb".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/context_spook".freeze, "context_spook.gemspec".freeze, "hello_world.json".freeze, "hey_world.yaml".freeze, "lib/context_spook.rb".freeze, "lib/context_spook/generator.rb".freeze, "lib/context_spook/output_context.rb".freeze, "lib/context_spook/toon.rb".freeze, "lib/context_spook/utils.rb".freeze, "lib/context_spook/verbose_puts.rb".freeze, "lib/context_spook/version.rb".freeze, "spec/context_spook/generator_spec.rb".freeze, "spec/context_spook/toon_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
17
17
|
s.homepage = "https://github.com/flori/context_spook".freeze
|
|
18
18
|
s.licenses = ["MIT".freeze]
|
|
19
19
|
s.rdoc_options = ["--title".freeze, "ContextSpook - context_spook collects project context for AI".freeze, "--main".freeze, "README.md".freeze]
|
|
20
20
|
s.required_ruby_version = Gem::Requirement.new(">= 3.1".freeze)
|
|
21
21
|
s.rubygems_version = "4.0.3".freeze
|
|
22
22
|
s.summary = "context_spook collects project context for AI".freeze
|
|
23
|
-
s.test_files = ["spec/context_spook/generator_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
23
|
+
s.test_files = ["spec/context_spook/generator_spec.rb".freeze, "spec/context_spook/toon_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
24
24
|
|
|
25
25
|
s.specification_version = 4
|
|
26
26
|
|
|
27
|
-
s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.
|
|
27
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.17.0".freeze])
|
|
28
28
|
s.add_development_dependency(%q<all_images>.freeze, ["~> 0.6".freeze])
|
|
29
29
|
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2".freeze])
|
|
30
30
|
s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
|
|
@@ -5,36 +5,14 @@ require 'mize'
|
|
|
5
5
|
require 'mime-types'
|
|
6
6
|
require 'yaml'
|
|
7
7
|
require 'context_spook/toon'
|
|
8
|
+
require 'context_spook/verbose_puts'
|
|
9
|
+
require 'context_spook/output_context'
|
|
8
10
|
|
|
9
11
|
# The ContextSpook module serves as a namespace container for collecting and
|
|
10
12
|
# organizing project information for AI assistance.
|
|
11
13
|
module ContextSpook
|
|
12
14
|
include DSLKit::Interpreter
|
|
13
15
|
|
|
14
|
-
# The VerbosePuts module provides a conditional output mechanism for
|
|
15
|
-
# displaying status or debug messages.
|
|
16
|
-
#
|
|
17
|
-
# This module includes a method that outputs messages to standard error only
|
|
18
|
-
# when a verbose flag is enabled. It is designed to be included in classes
|
|
19
|
-
# that need to conditionally emit verbose logging information during
|
|
20
|
-
# processing.
|
|
21
|
-
module VerbosePuts
|
|
22
|
-
# The verbose_puts method outputs the given arguments to standard error
|
|
23
|
-
# only if verbose mode is enabled.
|
|
24
|
-
#
|
|
25
|
-
# This method serves as a conditional output mechanism, allowing debug or
|
|
26
|
-
# status messages to be displayed based on the verbosity setting of the
|
|
27
|
-
# object.
|
|
28
|
-
#
|
|
29
|
-
# @param a [ Array ] the arguments to be printed to standard error
|
|
30
|
-
#
|
|
31
|
-
# @return [ nil ] always returns nil after attempting to output
|
|
32
|
-
def verbose_puts(*a)
|
|
33
|
-
@verbose or return
|
|
34
|
-
STDERR.puts(a)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
16
|
# The generate_context method processes a context definition file or block
|
|
39
17
|
# and returns the resulting context object.
|
|
40
18
|
#
|
|
@@ -57,14 +35,14 @@ module ContextSpook
|
|
|
57
35
|
#
|
|
58
36
|
# @raise [ ArgumentError ] if neither a filename nor a block is provided
|
|
59
37
|
# @raise [ ArgumentError ] if both a filename and a block are provided
|
|
60
|
-
def self.generate_context(filename = nil, verbose: false, &block)
|
|
38
|
+
def self.generate_context(filename = nil, verbose: false, format: nil, &block)
|
|
61
39
|
verbose = !!verbose
|
|
62
40
|
filename.present? ^ block or
|
|
63
41
|
raise ArgumentError, 'need either a filename or a &block argument'
|
|
64
42
|
generator = if filename
|
|
65
|
-
Generator.send(:new, verbose:).send(:parse, File.read(filename))
|
|
43
|
+
Generator.send(:new, verbose:, format:).send(:parse, File.read(filename))
|
|
66
44
|
else
|
|
67
|
-
Generator.send(:new, verbose:, &block)
|
|
45
|
+
Generator.send(:new, verbose:, format:, &block)
|
|
68
46
|
end
|
|
69
47
|
generator.output_context_size
|
|
70
48
|
generator.context
|
|
@@ -76,6 +54,9 @@ module ContextSpook
|
|
|
76
54
|
# assistance.
|
|
77
55
|
class Generator
|
|
78
56
|
include VerbosePuts
|
|
57
|
+
include OutputContext
|
|
58
|
+
|
|
59
|
+
attr_reader :verbose
|
|
79
60
|
|
|
80
61
|
private_class_method :new
|
|
81
62
|
|
|
@@ -86,8 +67,9 @@ module ContextSpook
|
|
|
86
67
|
# output during processing, defaults to lfalse.
|
|
87
68
|
# @param block [ Proc ] a block of code to be evaluated within the object's context
|
|
88
69
|
# If no block is given, the method does nothing.
|
|
89
|
-
def initialize(verbose: false, &block)
|
|
70
|
+
def initialize(verbose: false, format: nil, &block)
|
|
90
71
|
@verbose = !!verbose
|
|
72
|
+
@format = (format || 'JSON').upcase
|
|
91
73
|
block and instance_eval(&block)
|
|
92
74
|
end
|
|
93
75
|
|
|
@@ -99,24 +81,12 @@ module ContextSpook
|
|
|
99
81
|
def context(&block)
|
|
100
82
|
if block
|
|
101
83
|
@context and raise ArgumentError, "only one context allowed"
|
|
102
|
-
@context = Context.new(
|
|
84
|
+
@context = Context.new(generator: self, &block)
|
|
103
85
|
else
|
|
104
86
|
@context
|
|
105
87
|
end
|
|
106
88
|
end
|
|
107
89
|
|
|
108
|
-
# The output_context_size method prints the total size of the generated
|
|
109
|
-
# context JSON representation.
|
|
110
|
-
#
|
|
111
|
-
# This method calculates the size of the context object when serialized to
|
|
112
|
-
# JSON, formats it using binary units (KiB, MiB, etc.), and outputs the
|
|
113
|
-
# result to standard error.
|
|
114
|
-
def output_context_size
|
|
115
|
-
context_size = @context&.size.to_i
|
|
116
|
-
json_context_size = ContextSpook::Utils.format_size(context_size)
|
|
117
|
-
verbose_puts "Built #{json_context_size} of JSON context in total."
|
|
118
|
-
end
|
|
119
|
-
|
|
120
90
|
# The Context class represents and manages project context data, providing
|
|
121
91
|
# structured storage for file contents, command outputs, variables, and
|
|
122
92
|
# metadata that can be serialized to JSON for AI assistance.
|
|
@@ -134,11 +104,15 @@ module ContextSpook
|
|
|
134
104
|
# during processing, defaults to false.
|
|
135
105
|
# @param block [ Proc ] a block of code to be evaluated within the object's context
|
|
136
106
|
# If no block is given, the method does nothing.
|
|
137
|
-
def initialize(
|
|
138
|
-
@
|
|
107
|
+
def initialize(generator:, &block)
|
|
108
|
+
@generator = generator
|
|
139
109
|
block and instance_eval(&block)
|
|
140
110
|
end
|
|
141
111
|
|
|
112
|
+
attr_reader :generator
|
|
113
|
+
|
|
114
|
+
delegate :verbose, to: :generator
|
|
115
|
+
|
|
142
116
|
# The namespace method creates a scoped block with a given name.
|
|
143
117
|
#
|
|
144
118
|
# @param name [ Object ] the name to scope the block with
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# The ContextSpook::OutputContext module provides methods for outputting
|
|
2
|
+
# context data in various formats.
|
|
3
|
+
#
|
|
4
|
+
# This module is included in the ContextSpook::Generator class to enable output
|
|
5
|
+
# functionality for generated context objects.
|
|
6
|
+
module ContextSpook::OutputContext
|
|
7
|
+
# The output_context_size method prints the total size of the generated
|
|
8
|
+
# context JSON representation.
|
|
9
|
+
#
|
|
10
|
+
# This method calculates the size of the context object when serialized to
|
|
11
|
+
# JSON, formats it using binary units (KiB, MiB, etc.), and outputs the
|
|
12
|
+
# result to standard error.
|
|
13
|
+
def output_context_size
|
|
14
|
+
context_size =
|
|
15
|
+
(@format == 'TOON' ? @context&.toon_size : @context&.size).to_i
|
|
16
|
+
context_size = ContextSpook::Utils.format_size(context_size)
|
|
17
|
+
verbose_puts "Built #{context_size} of #@format context in total."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The output_context method writes the generated context to the specified
|
|
21
|
+
# output stream in either TOON or JSON format.
|
|
22
|
+
#
|
|
23
|
+
# This method serializes the context object into either TOON format or JSON
|
|
24
|
+
# format depending on the configured format, and writes the result to the
|
|
25
|
+
# provided output stream, which defaults to STDOUT.
|
|
26
|
+
#
|
|
27
|
+
# @param output [ IO ] the output stream to write the context data to,
|
|
28
|
+
# defaults to STDOUT
|
|
29
|
+
def output_context(output: STDOUT)
|
|
30
|
+
if @format == 'TOON'
|
|
31
|
+
output.puts(@context.to_toon)
|
|
32
|
+
else
|
|
33
|
+
JSON.dump(@context.as_json, output)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/context_spook/toon.rb
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
require 'ruby_json_toon'
|
|
2
2
|
|
|
3
|
+
# The ContextSpook::TOON module provides TOON (Token-Oriented Object Notation)
|
|
4
|
+
# serialization functionality for context objects.
|
|
3
5
|
module ContextSpook::TOON
|
|
6
|
+
# Converts the context object to TOON format.
|
|
7
|
+
#
|
|
8
|
+
# @return [String] the TOON-encoded representation of the context
|
|
4
9
|
def to_toon
|
|
5
10
|
RubyJsonToon.encode(as_json)
|
|
6
11
|
end
|
|
7
12
|
memoize method: :to_toon
|
|
8
13
|
|
|
14
|
+
# Calculates the size of the TOON representation.
|
|
15
|
+
#
|
|
16
|
+
# @return [Integer] the size in bytes of the TOON representation
|
|
9
17
|
def toon_size
|
|
10
18
|
to_toon.size
|
|
11
19
|
end
|
data/lib/context_spook/utils.rb
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module ContextSpook
|
|
2
|
+
# The VerbosePuts module provides a conditional output mechanism for
|
|
3
|
+
# displaying status or debug messages.
|
|
4
|
+
#
|
|
5
|
+
# This module includes a method that outputs messages to standard error only
|
|
6
|
+
# when a verbose flag is enabled. It is designed to be included in classes
|
|
7
|
+
# that need to conditionally emit verbose logging information during
|
|
8
|
+
# processing.
|
|
9
|
+
module VerbosePuts
|
|
10
|
+
# The verbose_puts method outputs the given arguments to standard error
|
|
11
|
+
# only if verbose mode is enabled.
|
|
12
|
+
#
|
|
13
|
+
# This method serves as a conditional output mechanism, allowing debug or
|
|
14
|
+
# status messages to be displayed based on the verbosity setting of the
|
|
15
|
+
# object.
|
|
16
|
+
#
|
|
17
|
+
# @param a [ Array ] the arguments to be printed to standard error
|
|
18
|
+
#
|
|
19
|
+
# @return [ nil ] always returns nil after attempting to output
|
|
20
|
+
def verbose_puts(*a)
|
|
21
|
+
verbose or return
|
|
22
|
+
STDERR.puts(a)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -1,56 +1,92 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe ContextSpook::Generator do
|
|
4
|
-
let :
|
|
5
|
-
ContextSpook.generate_context('.contexts/project.rb', verbose:
|
|
4
|
+
let :my_context do
|
|
5
|
+
ContextSpook.generate_context('.contexts/project.rb', verbose: false)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
describe 'generating w/o verbose' do
|
|
9
|
+
it 'context can be generated from block' do
|
|
10
|
+
expect_any_instance_of(described_class).to\
|
|
11
|
+
receive(:output_context_size).and_call_original
|
|
12
|
+
my_context = ContextSpook.generate_context do
|
|
13
|
+
context do
|
|
14
|
+
variable foo: 'bar'
|
|
15
|
+
metadata version: '1.0'
|
|
16
|
+
end
|
|
15
17
|
end
|
|
18
|
+
expect(my_context).to be_a described_class::Context
|
|
19
|
+
expect(my_context.variables[:foo]).to eq 'bar'
|
|
20
|
+
expect(my_context.metadata[:version]).to eq '1.0'
|
|
16
21
|
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
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
it 'context can be generated from filename' do
|
|
24
|
+
expect_any_instance_of(described_class).to\
|
|
25
|
+
receive(:output_context_size).and_call_original
|
|
26
|
+
expect(my_context).to be_a described_class::Context
|
|
27
|
+
expect(my_context.metadata[:ruby]).to eq RUBY_DESCRIPTION
|
|
28
|
+
end
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
it 'could handle premature output_context_size calls' do
|
|
31
|
+
expect_any_instance_of(described_class).to\
|
|
32
|
+
receive(:output_context_size).and_call_original
|
|
33
|
+
described_class.send(:new).output_context_size
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'cannot do from block and filename' do
|
|
37
|
+
expect {
|
|
38
|
+
ContextSpook.generate_context('.contexts/project.rb') { }
|
|
39
|
+
}.to raise_error(ArgumentError, /need either a filename or a &block/)
|
|
40
|
+
end
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
it 'context be transformed to JSON if loaded' do
|
|
43
|
+
context_as_json = my_context.to_json
|
|
44
|
+
expect(my_context.size).to be > 1024
|
|
45
|
+
expect(JSON(context_as_json)).to be_a Hash
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'can output context in JSON' do
|
|
49
|
+
output = StringIO.new
|
|
50
|
+
expect_any_instance_of(described_class).to receive(:output_context).
|
|
51
|
+
with(output:).and_call_original
|
|
52
|
+
my_context.generator.output_context(output:)
|
|
53
|
+
expect(output.string).to include '"ruby":%s' % RUBY_DESCRIPTION.dump
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'can output context in TOON' do
|
|
57
|
+
my_context = ContextSpook.generate_context(
|
|
58
|
+
'.contexts/project.rb', verbose: false, format: 'TOON'
|
|
59
|
+
)
|
|
60
|
+
output = StringIO.new
|
|
61
|
+
expect_any_instance_of(described_class).to receive(:output_context).
|
|
62
|
+
with(output:).and_call_original
|
|
63
|
+
my_context.generator.output_context(output:)
|
|
64
|
+
expect(output.string).to include 'ruby: %s' % RUBY_DESCRIPTION.dump
|
|
65
|
+
end
|
|
39
66
|
end
|
|
40
67
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
68
|
+
describe 'generating with verbose' do
|
|
69
|
+
let :my_context do
|
|
70
|
+
ContextSpook.generate_context('.contexts/project.rb', verbose: true)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'can output context size' do
|
|
74
|
+
expect_any_instance_of(described_class).to receive(:output_context_size).
|
|
75
|
+
and_call_original
|
|
76
|
+
expect_any_instance_of(described_class).to receive(:verbose_puts).
|
|
77
|
+
with(/Built.*of JSON context in total/)
|
|
78
|
+
allow_any_instance_of(described_class::Context).to receive(:verbose_puts)
|
|
79
|
+
my_context
|
|
80
|
+
end
|
|
45
81
|
end
|
|
46
82
|
|
|
47
83
|
describe 'Context' do
|
|
48
84
|
it 'can have variables' do
|
|
49
|
-
expect(
|
|
85
|
+
expect(my_context.variables[:branch]).to be_present
|
|
50
86
|
end
|
|
51
87
|
|
|
52
88
|
it 'can have files' do
|
|
53
|
-
file =
|
|
89
|
+
file = my_context.files['lib/context_spook.rb']
|
|
54
90
|
expect(file).to be_present
|
|
55
91
|
expect(file[:content]).to be_present
|
|
56
92
|
expect(file[:content_types]).to be_present
|
|
@@ -61,7 +97,7 @@ describe ContextSpook::Generator do
|
|
|
61
97
|
end
|
|
62
98
|
|
|
63
99
|
it 'can have commands' do
|
|
64
|
-
command =
|
|
100
|
+
command = my_context.commands['tree']
|
|
65
101
|
expect(command).to be_present
|
|
66
102
|
expect(command[:working_directory]).to eq Dir.pwd
|
|
67
103
|
expect(command[:exit_code]).not_to be_nil
|
|
@@ -74,38 +110,38 @@ describe ContextSpook::Generator do
|
|
|
74
110
|
end
|
|
75
111
|
|
|
76
112
|
it 'can have metada' do
|
|
77
|
-
expect(
|
|
113
|
+
expect(my_context.metadata[:ruby]).to eq RUBY_DESCRIPTION
|
|
78
114
|
end
|
|
79
115
|
|
|
80
116
|
it 'can have json metadata' do
|
|
81
|
-
expect(
|
|
117
|
+
expect(my_context.metadata[:hello_world]).to eq("hello" => "world")
|
|
82
118
|
end
|
|
83
119
|
|
|
84
120
|
it 'can have yaml metadata' do
|
|
85
|
-
expect(
|
|
121
|
+
expect(my_context.metadata[:hey_world]).to eq("hey" => "world")
|
|
86
122
|
end
|
|
87
123
|
|
|
88
124
|
it 'handles missing json files gracefully' do
|
|
89
|
-
expect(
|
|
125
|
+
expect(my_context.json('nixda.json')).to be_nil
|
|
90
126
|
end
|
|
91
127
|
|
|
92
128
|
it 'handles invalid json content gracefully' do
|
|
93
129
|
Tempfile.create('invalid.json') do |f|
|
|
94
130
|
f.write('{ invalid json }')
|
|
95
131
|
f.close
|
|
96
|
-
expect(
|
|
132
|
+
expect(my_context.json(f.path)).to be_nil
|
|
97
133
|
end
|
|
98
134
|
end
|
|
99
135
|
|
|
100
136
|
it 'handles missing yaml files gracefully' do
|
|
101
|
-
expect(
|
|
137
|
+
expect(my_context.yaml('nixda.yaml')).to be_nil
|
|
102
138
|
end
|
|
103
139
|
|
|
104
140
|
it 'handles invalid yaml content gracefully' do
|
|
105
141
|
Tempfile.create('invalid.yaml') do |f|
|
|
106
142
|
f.write('invalid: [yaml')
|
|
107
143
|
f.close
|
|
108
|
-
expect(
|
|
144
|
+
expect(my_context.yaml(f.path)).to be_nil
|
|
109
145
|
end
|
|
110
146
|
end
|
|
111
147
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ContextSpook::TOON do
|
|
4
|
+
let(:context) do
|
|
5
|
+
ContextSpook.generate_context do
|
|
6
|
+
context do
|
|
7
|
+
variable foo: 'bar'
|
|
8
|
+
metadata version: '1.0'
|
|
9
|
+
file 'lib/context_spook.rb'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe '#to_toon' do
|
|
15
|
+
it 'converts context to TOON format' do
|
|
16
|
+
toon_output = context.to_toon
|
|
17
|
+
expect(toon_output).to be_a(String)
|
|
18
|
+
expect(toon_output).to_not be_empty
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'produces valid TOON output' do
|
|
22
|
+
toon_output = context.to_toon
|
|
23
|
+
# TOON should be a valid string representation
|
|
24
|
+
expect { RubyJsonToon.decode(toon_output) }.not_to raise_error
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#toon_size' do
|
|
29
|
+
it 'returns the size of TOON representation in bytes' do
|
|
30
|
+
size = context.toon_size
|
|
31
|
+
expect(size).to be_a(Integer)
|
|
32
|
+
expect(size).to be > 0
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'matches the size of the TOON output' do
|
|
36
|
+
size = context.toon_size
|
|
37
|
+
toon_output = context.to_toon
|
|
38
|
+
expect(size).to eq(toon_output.size)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe 'integration with ContextSpook::Generator::Context' do
|
|
43
|
+
it 'is included in Context class' do
|
|
44
|
+
expect(context).to respond_to(:to_toon)
|
|
45
|
+
expect(context).to respond_to(:toon_size)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'works with context data' do
|
|
49
|
+
toon_output = context.to_toon
|
|
50
|
+
expect(toon_output).to include('variables:')
|
|
51
|
+
expect(toon_output).to include('metadata:')
|
|
52
|
+
expect(toon_output).to include('files:')
|
|
53
|
+
expect(toon_output).to include('commands:')
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
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: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 2.
|
|
18
|
+
version: 2.17.0
|
|
19
19
|
type: :development
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 2.
|
|
25
|
+
version: 2.17.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: all_images
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -202,8 +202,10 @@ extra_rdoc_files:
|
|
|
202
202
|
- README.md
|
|
203
203
|
- lib/context_spook.rb
|
|
204
204
|
- lib/context_spook/generator.rb
|
|
205
|
+
- lib/context_spook/output_context.rb
|
|
205
206
|
- lib/context_spook/toon.rb
|
|
206
207
|
- lib/context_spook/utils.rb
|
|
208
|
+
- lib/context_spook/verbose_puts.rb
|
|
207
209
|
- lib/context_spook/version.rb
|
|
208
210
|
files:
|
|
209
211
|
- ".contexts/project.rb"
|
|
@@ -217,10 +219,13 @@ files:
|
|
|
217
219
|
- hey_world.yaml
|
|
218
220
|
- lib/context_spook.rb
|
|
219
221
|
- lib/context_spook/generator.rb
|
|
222
|
+
- lib/context_spook/output_context.rb
|
|
220
223
|
- lib/context_spook/toon.rb
|
|
221
224
|
- lib/context_spook/utils.rb
|
|
225
|
+
- lib/context_spook/verbose_puts.rb
|
|
222
226
|
- lib/context_spook/version.rb
|
|
223
227
|
- spec/context_spook/generator_spec.rb
|
|
228
|
+
- spec/context_spook/toon_spec.rb
|
|
224
229
|
- spec/spec_helper.rb
|
|
225
230
|
homepage: https://github.com/flori/context_spook
|
|
226
231
|
licenses:
|
|
@@ -249,4 +254,5 @@ specification_version: 4
|
|
|
249
254
|
summary: context_spook collects project context for AI
|
|
250
255
|
test_files:
|
|
251
256
|
- spec/context_spook/generator_spec.rb
|
|
257
|
+
- spec/context_spook/toon_spec.rb
|
|
252
258
|
- spec/spec_helper.rb
|