context_spook 1.3.0 → 1.5.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/Rakefile +1 -1
- data/context_spook.gemspec +4 -4
- data/lib/context_spook/generator.rb +40 -16
- data/lib/context_spook/toon/example.md +69 -0
- data/lib/context_spook/toon.rb +15 -2
- data/lib/context_spook/version.rb +1 -1
- data/spec/context_spook/generator_spec.rb +15 -0
- data/spec/context_spook/toon_spec.rb +16 -2
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5cca218e18443bf3698be556f93b822253a9f0dd4c93322d1ee9c826d1a26dc3
|
|
4
|
+
data.tar.gz: d8c48e20203cbc5c1c0741e93805480aa7fbe9987821fe2b9839447902879149
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a7f1fb4f2b26f9c59dc6a48be8db0a2ffc4381250334a401c6ad2944fe398cb18bcc0154df6111d26ceac1a9bcad7ac4386626aeb681bbe20f1286310fbe58f0
|
|
7
|
+
data.tar.gz: 990b7df25449551007c8e986ec479bdf5656195e47ef6d7243603849179a5fac6edaa6e245bbfaa99768115b3b46eeffc5baf6f37e542c8a4b729dc443ba8b13
|
data/Rakefile
CHANGED
|
@@ -38,7 +38,7 @@ GemHadar do
|
|
|
38
38
|
dependency 'mime-types', '~> 3.0'
|
|
39
39
|
dependency 'yaml', '~> 0.4'
|
|
40
40
|
dependency 'pathname', '~> 0.4'
|
|
41
|
-
dependency 'ruby
|
|
41
|
+
dependency 'toon-ruby', '>= 0.1'
|
|
42
42
|
development_dependency 'all_images', '~> 0.6'
|
|
43
43
|
development_dependency 'rspec', '~> 3.2'
|
|
44
44
|
development_dependency 'debug'
|
data/context_spook.gemspec
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: context_spook 1.
|
|
2
|
+
# stub: context_spook 1.5.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.5.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]
|
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
|
13
13
|
s.email = "flori@ping.de".freeze
|
|
14
14
|
s.executables = ["context_spook".freeze]
|
|
15
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]
|
|
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/toon/example.md".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]
|
|
@@ -36,5 +36,5 @@ Gem::Specification.new do |s|
|
|
|
36
36
|
s.add_runtime_dependency(%q<mime-types>.freeze, ["~> 3.0".freeze])
|
|
37
37
|
s.add_runtime_dependency(%q<yaml>.freeze, ["~> 0.4".freeze])
|
|
38
38
|
s.add_runtime_dependency(%q<pathname>.freeze, ["~> 0.4".freeze])
|
|
39
|
-
s.add_runtime_dependency(%q<ruby
|
|
39
|
+
s.add_runtime_dependency(%q<toon-ruby>.freeze, [">= 0.1".freeze])
|
|
40
40
|
end
|
|
@@ -13,28 +13,30 @@ require 'context_spook/output_context'
|
|
|
13
13
|
module ContextSpook
|
|
14
14
|
include DSLKit::Interpreter
|
|
15
15
|
|
|
16
|
-
# The generate_context method
|
|
17
|
-
#
|
|
16
|
+
# The generate_context method creates a context object by either evaluating a
|
|
17
|
+
# block or parsing a file
|
|
18
18
|
#
|
|
19
|
-
# This method serves as the primary entry point for generating
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
# The method ensures that only one context definition mechanism is used.
|
|
19
|
+
# This method serves as the primary entry point for generating context data.
|
|
20
|
+
# It accepts either a filename pointing to a context definition file or a
|
|
21
|
+
# block containing the context definition. The method handles the creation of
|
|
22
|
+
# a generator instance, processes the context definition, and returns the
|
|
23
|
+
# resulting context object.
|
|
25
24
|
#
|
|
26
|
-
# @param filename [ String, nil ] the path to
|
|
27
|
-
#
|
|
25
|
+
# @param filename [ String, nil ] the path to a context definition file, or
|
|
26
|
+
# nil if using a block
|
|
28
27
|
# @param verbose [ TrueClass, FalseClass ] flag to enable verbose output
|
|
29
|
-
# during processing
|
|
30
|
-
# @param
|
|
31
|
-
#
|
|
28
|
+
# during processing
|
|
29
|
+
# @param format [ String, nil ] the output format for the context, either
|
|
30
|
+
# 'JSON' or 'TOON'
|
|
31
|
+
# @param block [ Proc ] a block containing the context definition, used if
|
|
32
|
+
# filename is nil
|
|
32
33
|
#
|
|
33
|
-
# @return [ ContextSpook::Generator::Context ] the context object
|
|
34
|
-
#
|
|
34
|
+
# @return [ ContextSpook::Generator::Context ] the generated context object containing
|
|
35
|
+
# project metadata, file contents, command outputs, and variables
|
|
35
36
|
#
|
|
36
37
|
# @raise [ ArgumentError ] if neither a filename nor a block is provided
|
|
37
|
-
# @raise [ ArgumentError ] if
|
|
38
|
+
# @raise [ ArgumentError ] if an invalid format is specified
|
|
39
|
+
# @raise [ ArgumentError ] if the context definition file cannot be read or parsed
|
|
38
40
|
def self.generate_context(filename = nil, verbose: false, format: nil, &block)
|
|
39
41
|
verbose = !!verbose
|
|
40
42
|
filename.present? ^ block or
|
|
@@ -56,8 +58,18 @@ module ContextSpook
|
|
|
56
58
|
include VerbosePuts
|
|
57
59
|
include OutputContext
|
|
58
60
|
|
|
61
|
+
# The verbose method returns the verbose flag indicating whether verbose
|
|
62
|
+
# output is enabled.
|
|
63
|
+
#
|
|
64
|
+
# @return [ TrueClass, FalseClass ] true if verbose output is enabled,
|
|
65
|
+
# false otherwise
|
|
59
66
|
attr_reader :verbose
|
|
60
67
|
|
|
68
|
+
# The format method returns the format identifier for the context output.
|
|
69
|
+
#
|
|
70
|
+
# @return [ String ] the format identifier, either 'JSON' or 'TOON'
|
|
71
|
+
attr_reader :format
|
|
72
|
+
|
|
61
73
|
private_class_method :new
|
|
62
74
|
|
|
63
75
|
# The initialize method sets up the object by evaluating the provided block
|
|
@@ -70,6 +82,9 @@ module ContextSpook
|
|
|
70
82
|
def initialize(verbose: false, format: nil, &block)
|
|
71
83
|
@verbose = !!verbose
|
|
72
84
|
@format = (format || 'JSON').upcase
|
|
85
|
+
%w[ TOON JSON ].include?(@format) or
|
|
86
|
+
raise ArgumentError,
|
|
87
|
+
"format needs to be either JSON or TOON, was #{@format.inspect}"
|
|
73
88
|
block and instance_eval(&block)
|
|
74
89
|
end
|
|
75
90
|
|
|
@@ -107,8 +122,17 @@ module ContextSpook
|
|
|
107
122
|
def initialize(generator:, &block)
|
|
108
123
|
@generator = generator
|
|
109
124
|
block and instance_eval(&block)
|
|
125
|
+
meta(format: generator.format)
|
|
126
|
+
if generator.format == 'TOON'
|
|
127
|
+
meta(toon_example: toon_example)
|
|
128
|
+
end
|
|
110
129
|
end
|
|
111
130
|
|
|
131
|
+
# The generator method returns the generator object associated with this
|
|
132
|
+
# context.
|
|
133
|
+
#
|
|
134
|
+
# @return [ ContextSpook::Generator ] the generator instance that created
|
|
135
|
+
# this context
|
|
112
136
|
attr_reader :generator
|
|
113
137
|
|
|
114
138
|
delegate :verbose, to: :generator
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# TOON (Token-Oriented Object Notation)
|
|
2
|
+
|
|
3
|
+
It is a compact, human-readable serialization format that reduces JSON token
|
|
4
|
+
count by 30-40% while maintaining lossless data fidelity. It uses CSV-style
|
|
5
|
+
tabular arrays for uniform data structures and YAML-like indentation for nested
|
|
6
|
+
objects, making it ideal for LLM input where token efficiency and parsing
|
|
7
|
+
reliability matter.
|
|
8
|
+
|
|
9
|
+
Key benefit: Same data, fewer tokens, better LLM understanding.
|
|
10
|
+
|
|
11
|
+
**Original JSON:**
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"database": {
|
|
15
|
+
"name": "user_management",
|
|
16
|
+
"tables": [
|
|
17
|
+
{
|
|
18
|
+
"name": "users",
|
|
19
|
+
"columns": [
|
|
20
|
+
{
|
|
21
|
+
"name": "id",
|
|
22
|
+
"type": "integer",
|
|
23
|
+
"primary_key": true
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "email",
|
|
27
|
+
"type": "string",
|
|
28
|
+
"unique": true
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"row_count": 1000
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "orders",
|
|
35
|
+
"columns": [
|
|
36
|
+
{
|
|
37
|
+
"name": "id",
|
|
38
|
+
"type": "integer",
|
|
39
|
+
"primary_key": true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "user_id",
|
|
43
|
+
"type": "integer"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"row_count": 5000
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**TOON equivalent:**
|
|
54
|
+
```
|
|
55
|
+
database:
|
|
56
|
+
name: user_management
|
|
57
|
+
tables[2]{name,row_count}:
|
|
58
|
+
users,1000
|
|
59
|
+
orders,5000
|
|
60
|
+
tables[2]{name,columns}:
|
|
61
|
+
users:
|
|
62
|
+
columns[2]{name,type,primary_key}:
|
|
63
|
+
id,integer,true
|
|
64
|
+
email,string,true
|
|
65
|
+
orders:
|
|
66
|
+
columns[2]{name,type}:
|
|
67
|
+
id,integer,true
|
|
68
|
+
user_id,integer,false
|
|
69
|
+
```
|
data/lib/context_spook/toon.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'toon'
|
|
2
2
|
|
|
3
3
|
# The ContextSpook::TOON module provides TOON (Token-Oriented Object Notation)
|
|
4
4
|
# serialization functionality for context objects.
|
|
@@ -7,7 +7,7 @@ module ContextSpook::TOON
|
|
|
7
7
|
#
|
|
8
8
|
# @return [String] the TOON-encoded representation of the context
|
|
9
9
|
def to_toon
|
|
10
|
-
|
|
10
|
+
::Toon.encode(as_json)
|
|
11
11
|
end
|
|
12
12
|
memoize method: :to_toon
|
|
13
13
|
|
|
@@ -17,4 +17,17 @@ module ContextSpook::TOON
|
|
|
17
17
|
def toon_size
|
|
18
18
|
to_toon.size
|
|
19
19
|
end
|
|
20
|
+
|
|
21
|
+
# The toon_example method reads and returns the content of an example
|
|
22
|
+
# Markdown file that demonstrates the TOON (Token-Oriented Object Notation)
|
|
23
|
+
# format.
|
|
24
|
+
#
|
|
25
|
+
# This method is used to provide a sample representation of how context data
|
|
26
|
+
# can be formatted in TOON, which is an alternative serialization format
|
|
27
|
+
# supported by the ContextSpook library.
|
|
28
|
+
#
|
|
29
|
+
# @return [ String ] the content of the TOON example Markdown file
|
|
30
|
+
def toon_example
|
|
31
|
+
File.read(Pathname.new(__dir__) + 'toon/example.md')
|
|
32
|
+
end
|
|
20
33
|
end
|
|
@@ -33,6 +33,21 @@ describe ContextSpook::Generator do
|
|
|
33
33
|
described_class.send(:new).output_context_size
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
context 'can handle formats' do
|
|
37
|
+
it 'raises exceptions for invalid formats' do
|
|
38
|
+
generator = described_class.send(:new, format: 'TOON')
|
|
39
|
+
expect(generator.format).to eq 'TOON'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'raises exceptions for invalid formats' do
|
|
43
|
+
expect {
|
|
44
|
+
described_class.send(:new, format: 'YAML')
|
|
45
|
+
}.to raise_error(
|
|
46
|
+
ArgumentError, /format needs to be either JSON or TOON, was "YAML"/
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
36
51
|
it 'cannot do from block and filename' do
|
|
37
52
|
expect {
|
|
38
53
|
ContextSpook.generate_context('.contexts/project.rb') { }
|
|
@@ -20,8 +20,22 @@ describe ContextSpook::TOON do
|
|
|
20
20
|
|
|
21
21
|
it 'produces valid TOON output' do
|
|
22
22
|
toon_output = context.to_toon
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
expect(toon_output).to match(
|
|
24
|
+
%r{
|
|
25
|
+
\Afiles:\n
|
|
26
|
+
^[ ]{2}"lib/context_spook\.rb":\n
|
|
27
|
+
^[ ]{4}content:[ ]"[^"]+"\n
|
|
28
|
+
^[ ]{4}size:[ ]120\n
|
|
29
|
+
^[ ]{4}lines:[ ]5\n
|
|
30
|
+
^[ ]{4}content_types\[2\]:[ ]application/x-ruby,text/x-ruby\n
|
|
31
|
+
^commands:\n
|
|
32
|
+
^metadata:\n
|
|
33
|
+
^[ ]{2}version:[ ]"1\.0"\n
|
|
34
|
+
^[ ]{2}format:[ ]JSON\n
|
|
35
|
+
^variables:\n
|
|
36
|
+
^[ ]{2}foo:[ ]bar\z
|
|
37
|
+
}x
|
|
38
|
+
)
|
|
25
39
|
end
|
|
26
40
|
end
|
|
27
41
|
|
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.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -178,19 +178,19 @@ dependencies:
|
|
|
178
178
|
- !ruby/object:Gem::Version
|
|
179
179
|
version: '0.4'
|
|
180
180
|
- !ruby/object:Gem::Dependency
|
|
181
|
-
name: ruby
|
|
181
|
+
name: toon-ruby
|
|
182
182
|
requirement: !ruby/object:Gem::Requirement
|
|
183
183
|
requirements:
|
|
184
|
-
- - "
|
|
184
|
+
- - ">="
|
|
185
185
|
- !ruby/object:Gem::Version
|
|
186
|
-
version: '1
|
|
186
|
+
version: '0.1'
|
|
187
187
|
type: :runtime
|
|
188
188
|
prerelease: false
|
|
189
189
|
version_requirements: !ruby/object:Gem::Requirement
|
|
190
190
|
requirements:
|
|
191
|
-
- - "
|
|
191
|
+
- - ">="
|
|
192
192
|
- !ruby/object:Gem::Version
|
|
193
|
-
version: '1
|
|
193
|
+
version: '0.1'
|
|
194
194
|
description: |
|
|
195
195
|
context_spook is a library that collects and organizes project
|
|
196
196
|
information to help AI assistants understand codebases better.
|
|
@@ -221,6 +221,7 @@ files:
|
|
|
221
221
|
- lib/context_spook/generator.rb
|
|
222
222
|
- lib/context_spook/output_context.rb
|
|
223
223
|
- lib/context_spook/toon.rb
|
|
224
|
+
- lib/context_spook/toon/example.md
|
|
224
225
|
- lib/context_spook/utils.rb
|
|
225
226
|
- lib/context_spook/verbose_puts.rb
|
|
226
227
|
- lib/context_spook/version.rb
|