diogenes 0.1.8 → 0.1.9
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/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +7 -0
- data/lib/diogenes/cli/validate.rb +57 -0
- data/lib/diogenes/cli.rb +3 -1
- data/lib/diogenes/validate/issue.rb +20 -0
- data/lib/diogenes/validate/runner.rb +102 -0
- data/lib/diogenes/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6afa2ba374311b5556d89936cb4939e408f607fc94c422d79e32198701ed66ca
|
|
4
|
+
data.tar.gz: e96686ce7eae01d70e95b9a7a816e5d68421358be2636f71c0beaa943996205d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1dc1a3434a2799bdce07985ba7b1084acfa5c11069ed149c65c1d7c7cbe7156a2caed421c9abd923a57951c6878fe602767281233541fc7e2cc8400bafec8167
|
|
7
|
+
data.tar.gz: b39b504cffdf7788596eecbd62da2b479d9e8f5cb849a1097106415663e490ad3427d3dcfe7e97ddccb925aa583ee466b4e609f2b6508bb427e57295dcad6c3d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.1.9](https://github.com/meaganewaller/diogenes/compare/diogenes/v0.1.8...diogenes/v0.1.9) (2026-06-27)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **validate:** add diogenes validate command :mag: ([#17](https://github.com/meaganewaller/diogenes/issues/17)) ([0bbdb93](https://github.com/meaganewaller/diogenes/commit/0bbdb9359c9c6ba3444623dba2d569f294b82988))
|
|
9
|
+
|
|
3
10
|
## [0.1.8](https://github.com/meaganewaller/diogenes/compare/diogenes/v0.1.7...diogenes/v0.1.8) (2026-06-27)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
module Diogenes
|
|
5
|
+
class Cli
|
|
6
|
+
class Validate
|
|
7
|
+
DIOGENES_DIR = ".diogenes" #: String
|
|
8
|
+
|
|
9
|
+
#: (argv: Array[String], cwd: String, out: IO, err: IO, **untyped) -> Integer
|
|
10
|
+
def self.run(argv:, cwd:, out:, err:, **_opts)
|
|
11
|
+
new(argv:, cwd:, out:, err:).run
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#: (argv: Array[String], cwd: String, out: IO, err: IO) -> void
|
|
15
|
+
def initialize(argv:, cwd:, out:, err:)
|
|
16
|
+
@argv = argv #: Array[String]
|
|
17
|
+
@cwd = cwd #: String
|
|
18
|
+
@out = out #: IO
|
|
19
|
+
@err = err #: IO
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#: () -> Integer
|
|
23
|
+
def run
|
|
24
|
+
diogenes_dir = File.join(@cwd, DIOGENES_DIR)
|
|
25
|
+
unless Dir.exist?(diogenes_dir)
|
|
26
|
+
@err.puts "No #{DIOGENES_DIR}/ found. Run `diogenes init` first."
|
|
27
|
+
return 1
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
@out.puts "Validating #{DIOGENES_DIR}/ sources..."
|
|
31
|
+
@out.puts
|
|
32
|
+
|
|
33
|
+
issues = Diogenes::Validate::Runner.new(diogenes_dir).run
|
|
34
|
+
errors = issues.select(&:error?)
|
|
35
|
+
warnings = issues.select(&:warning?)
|
|
36
|
+
|
|
37
|
+
if errors.empty? && warnings.empty?
|
|
38
|
+
@out.puts "✓ All sources valid. Ready to build."
|
|
39
|
+
return 0
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
issues.each { |issue| @out.puts issue.to_s }
|
|
43
|
+
@out.puts
|
|
44
|
+
|
|
45
|
+
if errors.empty?
|
|
46
|
+
@out.puts "#{warnings.size} warning#{"s" unless warnings.size == 1} found."
|
|
47
|
+
0
|
|
48
|
+
else
|
|
49
|
+
parts = ["#{errors.size} error#{"s" unless errors.size == 1}"]
|
|
50
|
+
parts << "#{warnings.size} warning#{"s" unless warnings.size == 1}" if warnings.any?
|
|
51
|
+
@out.puts "#{parts.join(", ")} found."
|
|
52
|
+
1
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/diogenes/cli.rb
CHANGED
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
require_relative "cli/init"
|
|
5
5
|
require_relative "cli/build"
|
|
6
6
|
require_relative "cli/evaluate"
|
|
7
|
+
require_relative "cli/validate"
|
|
7
8
|
|
|
8
9
|
module Diogenes
|
|
9
10
|
class Cli
|
|
10
11
|
COMMANDS = {
|
|
11
12
|
"init" => Init,
|
|
12
13
|
"build" => Build,
|
|
13
|
-
"evaluate" => Evaluate
|
|
14
|
+
"evaluate" => Evaluate,
|
|
15
|
+
"validate" => Validate
|
|
14
16
|
}.freeze #: Hash[String, Class]
|
|
15
17
|
|
|
16
18
|
#: (?Array[String] argv, ?out: IO, ?err: IO, **untyped) -> Integer
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
module Diogenes
|
|
5
|
+
module Validate
|
|
6
|
+
Issue = Struct.new(:severity, :file, :message, keyword_init: true) do
|
|
7
|
+
#: () -> bool
|
|
8
|
+
def error? = severity == :error
|
|
9
|
+
|
|
10
|
+
#: () -> bool
|
|
11
|
+
def warning? = severity == :warning
|
|
12
|
+
|
|
13
|
+
#: () -> String
|
|
14
|
+
def to_s
|
|
15
|
+
tag = error? ? "ERROR" : " WARN"
|
|
16
|
+
file ? " #{tag} #{file} — #{message}" : " #{tag} #{message}"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
module Diogenes
|
|
5
|
+
module Validate
|
|
6
|
+
class Runner
|
|
7
|
+
SOURCE_SUBDIRS = %w[skills rules hooks].freeze #: Array[String]
|
|
8
|
+
ARTIFACTS_SUBDIR = "artifacts" #: String
|
|
9
|
+
TOKENS_PER_CHAR = 4.0 #: Float
|
|
10
|
+
PROMPT_TOKEN_LIMIT = 2000 #: Integer
|
|
11
|
+
|
|
12
|
+
#: (String) -> void
|
|
13
|
+
def initialize(diogenes_dir)
|
|
14
|
+
@diogenes_dir = diogenes_dir #: String
|
|
15
|
+
@issues = [] #: Array[Validate::Issue]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#: () -> Array[Validate::Issue]
|
|
19
|
+
def run
|
|
20
|
+
Diogenes.reset!
|
|
21
|
+
load_config
|
|
22
|
+
load_sources
|
|
23
|
+
check_artifact_templates
|
|
24
|
+
check_prompt_lengths
|
|
25
|
+
@issues
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
#: () -> void
|
|
31
|
+
def load_config
|
|
32
|
+
config = File.join(@diogenes_dir, "diogenes.rb")
|
|
33
|
+
return unless File.exist?(config)
|
|
34
|
+
|
|
35
|
+
load_file(config)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#: () -> void
|
|
39
|
+
def load_sources
|
|
40
|
+
SOURCE_SUBDIRS.each do |subdir|
|
|
41
|
+
Dir.glob(File.join(@diogenes_dir, subdir, "**/*.rb")).sort.each do |file|
|
|
42
|
+
load_file(file)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#: (String) -> void
|
|
48
|
+
def load_file(path)
|
|
49
|
+
load path
|
|
50
|
+
rescue StandardError, SyntaxError => e
|
|
51
|
+
@issues << Issue.new(severity: :error, file: relative(path), message: e.message)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#: () -> void
|
|
55
|
+
def check_artifact_templates
|
|
56
|
+
Diogenes.artifacts.each do |artifact|
|
|
57
|
+
next unless artifact.template
|
|
58
|
+
|
|
59
|
+
template_path = File.join(@diogenes_dir, ARTIFACTS_SUBDIR, artifact.template)
|
|
60
|
+
next if File.exist?(template_path)
|
|
61
|
+
|
|
62
|
+
@issues << Issue.new(
|
|
63
|
+
severity: :error,
|
|
64
|
+
file: nil,
|
|
65
|
+
message: "Artifact #{artifact.name.inspect} references template " \
|
|
66
|
+
"#{artifact.template.inspect} which does not exist in " \
|
|
67
|
+
".diogenes/#{ARTIFACTS_SUBDIR}/"
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
#: () -> void
|
|
73
|
+
def check_prompt_lengths
|
|
74
|
+
promptable_items.each do |type, name, prompt|
|
|
75
|
+
next unless prompt
|
|
76
|
+
|
|
77
|
+
estimated = (prompt.length / TOKENS_PER_CHAR).round
|
|
78
|
+
next unless estimated > PROMPT_TOKEN_LIMIT
|
|
79
|
+
|
|
80
|
+
@issues << Issue.new(
|
|
81
|
+
severity: :warning,
|
|
82
|
+
file: nil,
|
|
83
|
+
message: "#{type} #{name.inspect} prompt is ~#{estimated} tokens " \
|
|
84
|
+
"(exceeds #{PROMPT_TOKEN_LIMIT} token guideline)"
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
#: () -> Array[[String, String, String?]]
|
|
90
|
+
def promptable_items
|
|
91
|
+
skills = Diogenes.skills.map { |s| ["Skill", s.name, s.prompt] }
|
|
92
|
+
hooks = Diogenes.hooks.map { |h| ["Hook", h.name, h.prompt] }
|
|
93
|
+
skills + hooks
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
#: (String) -> String
|
|
97
|
+
def relative(path)
|
|
98
|
+
path.delete_prefix("#{@diogenes_dir}/")
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
data/lib/diogenes/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: diogenes
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Meagan Waller
|
|
@@ -67,6 +67,7 @@ files:
|
|
|
67
67
|
- lib/diogenes/cli/build.rb
|
|
68
68
|
- lib/diogenes/cli/evaluate.rb
|
|
69
69
|
- lib/diogenes/cli/init.rb
|
|
70
|
+
- lib/diogenes/cli/validate.rb
|
|
70
71
|
- lib/diogenes/configuration.rb
|
|
71
72
|
- lib/diogenes/dsl/artifact.rb
|
|
72
73
|
- lib/diogenes/dsl/hook.rb
|
|
@@ -89,6 +90,8 @@ files:
|
|
|
89
90
|
- lib/diogenes/templates/init/hooks/README.md
|
|
90
91
|
- lib/diogenes/templates/init/rules/five_gates.rb
|
|
91
92
|
- lib/diogenes/templates/init/skills/example_skill.rb
|
|
93
|
+
- lib/diogenes/validate/issue.rb
|
|
94
|
+
- lib/diogenes/validate/runner.rb
|
|
92
95
|
- lib/diogenes/version.rb
|
|
93
96
|
- sig/diogenes.rbs
|
|
94
97
|
- sig/generated/diogenes.rbs
|