simple-agent-extension 0.2.1 → 0.2.2
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/CHANGELOG.md +6 -0
- data/README.md +6 -10
- data/lib/simple_agent_extension/agent_directory_loader.rb +8 -3
- data/lib/simple_agent_extension/cli.rb +31 -7
- data/lib/simple_agent_extension/extensions/base.rb +9 -0
- data/lib/simple_agent_extension/frontmatter.rb +2 -0
- data/lib/simple_agent_extension/metadata_loader.rb +8 -0
- data/lib/simple_agent_extension/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ab373fc18955bd0baacc40937dcb56758ef1868b628761e9f718c0f92b85f8f
|
|
4
|
+
data.tar.gz: e059df069d89a8097aa6f08acc9f2dff02c32ebd2adce5b083e34fe0fcd722a3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a88591dbccfda4b2e5abf84fcb2861cd35151dea90574e93b081d0c568a3eb11e6357df7726c3dd857fd4de6bf49f0eaf5651ad1c24bee910120ac32794647a3
|
|
7
|
+
data.tar.gz: 4df63619203ce861896717301521835f0261a38b97b466ed4f4ee1a3a4cb2c0ffc3a3993b6b8d75d8e5482e4f9c376ed973f1045252dd9c8a9cacc3f327dd516
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
Requires Ruby 3.3 or later.
|
|
7
|
+
Requires Ruby 3.3 or later (not needed beforehand when running with `rvx`, which provides Ruby itself).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Add the gem to your Gemfile:
|
|
10
10
|
|
|
11
11
|
```ruby
|
|
12
12
|
# Gemfile
|
|
13
13
|
group :development do
|
|
14
|
-
gem "simple-agent-extension"
|
|
14
|
+
gem "simple-agent-extension"
|
|
15
15
|
end
|
|
16
16
|
```
|
|
17
17
|
|
|
@@ -25,16 +25,12 @@ Then run the CLI through Bundler:
|
|
|
25
25
|
bundle exec simple-agent-extension packages
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Or run it without a Gemfile with [rv](https://github.com/spinel-coop/rv)'s `rvx`, which installs the gem on first use:
|
|
29
29
|
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
github: "colorfulcompany/simple-agent-extension",
|
|
33
|
-
tag: "v0.1.0"
|
|
30
|
+
```sh
|
|
31
|
+
rvx simple-agent-extension packages
|
|
34
32
|
```
|
|
35
33
|
|
|
36
|
-
`branch:` and `ref:` are also available; note that `branch:` follows new commits rather than pinning.
|
|
37
|
-
|
|
38
34
|
## Usage
|
|
39
35
|
|
|
40
36
|
### Defining a package
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module SimpleAgentExtension
|
|
4
|
-
class
|
|
4
|
+
class AgentDirectoryNotFound < Error; end
|
|
5
|
+
class AgentDirectoryNotDirectory < Error; end
|
|
6
|
+
class AgentDirectoryNotReadable < Error; end
|
|
5
7
|
class MissingAgentRegistration < Error; end
|
|
6
8
|
class UnloadableAgentRegistration < Error; end
|
|
7
9
|
|
|
@@ -28,12 +30,15 @@ module SimpleAgentExtension
|
|
|
28
30
|
@directories.map { |directory| canonical_directory(directory) }.uniq
|
|
29
31
|
end
|
|
30
32
|
|
|
33
|
+
# The error class names the condition, so the message carries the path
|
|
34
|
+
# alone.
|
|
31
35
|
def canonical_directory(directory)
|
|
32
36
|
path = File.expand_path(directory)
|
|
33
|
-
raise
|
|
37
|
+
raise AgentDirectoryNotFound, path unless File.exist?(path)
|
|
38
|
+
raise AgentDirectoryNotDirectory, path unless File.directory?(path)
|
|
34
39
|
|
|
35
40
|
path = File.realpath(path)
|
|
36
|
-
raise
|
|
41
|
+
raise AgentDirectoryNotReadable, path unless File.readable?(path)
|
|
37
42
|
|
|
38
43
|
path
|
|
39
44
|
end
|
|
@@ -6,6 +6,13 @@ require "simple_agent_extension"
|
|
|
6
6
|
module SimpleAgentExtension
|
|
7
7
|
# Command-line adapter for public package compilation and deployment.
|
|
8
8
|
class CLI
|
|
9
|
+
# The command line itself was written wrong. The message describes the
|
|
10
|
+
# mistake in full, so where it was raised tells the caller nothing.
|
|
11
|
+
class UsageError < Error; end
|
|
12
|
+
|
|
13
|
+
# No command was resolved, so the caller still needs the vocabulary.
|
|
14
|
+
class CommandError < UsageError; end
|
|
15
|
+
|
|
9
16
|
COMMANDS = {
|
|
10
17
|
"packages" => "List package names under the source root",
|
|
11
18
|
"build" => "Compile artifacts into the build root",
|
|
@@ -22,6 +29,12 @@ module SimpleAgentExtension
|
|
|
22
29
|
@error = error
|
|
23
30
|
end
|
|
24
31
|
|
|
32
|
+
# Only errors this CLI defines, and the one OptionParser raises for a
|
|
33
|
+
# misspelled option, are reduced to a message. Everything else passes
|
|
34
|
+
# through with its class, origin, and backtrace intact.
|
|
35
|
+
#
|
|
36
|
+
# CommandError has to be listed first: it is a UsageError, so the wider
|
|
37
|
+
# clause would take it otherwise.
|
|
25
38
|
def run(arguments)
|
|
26
39
|
arguments = arguments.dup
|
|
27
40
|
options = default_options
|
|
@@ -35,9 +48,10 @@ module SimpleAgentExtension
|
|
|
35
48
|
AgentDirectoryLoader.new(options[:agent_directories]).load
|
|
36
49
|
run_command(command, options)
|
|
37
50
|
0
|
|
38
|
-
rescue
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
rescue CommandError => error
|
|
52
|
+
report_failure(error, usage: parser)
|
|
53
|
+
rescue OptionParser::ParseError, UsageError => error
|
|
54
|
+
report_failure(error)
|
|
41
55
|
end
|
|
42
56
|
|
|
43
57
|
# Aligns the name column alone. Columns an Agent does not declare are
|
|
@@ -55,6 +69,16 @@ module SimpleAgentExtension
|
|
|
55
69
|
|
|
56
70
|
private
|
|
57
71
|
|
|
72
|
+
# @param [Exception] error
|
|
73
|
+
# @param [OptionParser, nil] usage printed when the caller still needs the
|
|
74
|
+
# command vocabulary
|
|
75
|
+
# @return [Integer] exit status the run reports as a failure
|
|
76
|
+
def report_failure(error, usage: nil)
|
|
77
|
+
@error.puts error.message
|
|
78
|
+
@error.puts usage if usage
|
|
79
|
+
1
|
|
80
|
+
end
|
|
81
|
+
|
|
58
82
|
def default_options
|
|
59
83
|
{
|
|
60
84
|
source_root: File.expand_path("packages"),
|
|
@@ -105,9 +129,9 @@ module SimpleAgentExtension
|
|
|
105
129
|
|
|
106
130
|
def command(arguments)
|
|
107
131
|
command = arguments.shift
|
|
108
|
-
raise
|
|
109
|
-
raise
|
|
110
|
-
raise
|
|
132
|
+
raise CommandError, "missing command" unless command
|
|
133
|
+
raise CommandError, "unknown command: #{command}" unless COMMANDS.key?(command)
|
|
134
|
+
raise CommandError, "unexpected arguments: #{arguments.join(" ")}" unless arguments.empty?
|
|
111
135
|
|
|
112
136
|
command
|
|
113
137
|
end
|
|
@@ -115,7 +139,7 @@ module SimpleAgentExtension
|
|
|
115
139
|
def validate_options(command, options)
|
|
116
140
|
return unless options[:force] && command != "deploy"
|
|
117
141
|
|
|
118
|
-
raise
|
|
142
|
+
raise UsageError, "--force is only valid for deploy"
|
|
119
143
|
end
|
|
120
144
|
|
|
121
145
|
def run_command(command, options)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
module SimpleAgentExtension
|
|
2
2
|
module Extensions
|
|
3
|
+
class EntrypointDocumentNotFound < Error; end
|
|
4
|
+
class InvalidEntrypointFrontmatter < Error; end
|
|
5
|
+
|
|
3
6
|
EntrypointDocument = Data.define(:metadata, :body)
|
|
4
7
|
|
|
5
8
|
# An extension that owns loading metadata from its directory.
|
|
@@ -48,6 +51,12 @@ module SimpleAgentExtension
|
|
|
48
51
|
metadata, body = Frontmatter.parse(File.read(entrypoint_path))
|
|
49
52
|
|
|
50
53
|
EntrypointDocument.new(metadata, body)
|
|
54
|
+
rescue Errno::ENOENT => e
|
|
55
|
+
not_found = EntrypointDocumentNotFound.new("entrypoint of package `#{@package}' / type `#{type}', #{entrypoint_path} not found.")
|
|
56
|
+
not_found.set_backtrace(e.backtrace)
|
|
57
|
+
raise not_found, cause: nil
|
|
58
|
+
rescue Psych::SyntaxError => e
|
|
59
|
+
raise InvalidEntrypointFrontmatter, "#{entrypoint_path}: #{[e.problem, e.context].compact.join(" ")} at line #{e.line + Frontmatter::METADATA_START_LINE_OFFSET} column #{e.column}", cause: nil
|
|
51
60
|
end
|
|
52
61
|
|
|
53
62
|
# @return [MetadataLoader] source YAML reader
|
|
@@ -13,6 +13,8 @@ module SimpleAgentExtension
|
|
|
13
13
|
module Frontmatter
|
|
14
14
|
DELIMITER = "---".freeze
|
|
15
15
|
PATTERN = /\A---\r?\n(.*?)^---[ \t]*\r?\n?/m
|
|
16
|
+
# Metadata starts after the opening delimiter line.
|
|
17
|
+
METADATA_START_LINE_OFFSET = 1
|
|
16
18
|
|
|
17
19
|
class InvalidFrontmatter < Error; end
|
|
18
20
|
|
|
@@ -8,15 +8,23 @@ module SimpleAgentExtension
|
|
|
8
8
|
# reader exposes adaptive, common static, and Agent-specific static fragment
|
|
9
9
|
# collections without defining their field vocabulary.
|
|
10
10
|
class MetadataLoader
|
|
11
|
+
class InvalidMetadata < Error; end
|
|
12
|
+
|
|
11
13
|
FILENAME = "metadata.yaml".freeze
|
|
12
14
|
|
|
15
|
+
# Psych does not know which file it parsed, so the path is attached here.
|
|
16
|
+
# Its backtrace points into Psych itself, so it is dropped.
|
|
17
|
+
#
|
|
13
18
|
# @param [String] dir
|
|
14
19
|
# @return [MetadataLoader] empty when +metadata.yaml+ is absent, never nil
|
|
20
|
+
# @raise [InvalidMetadata] when +metadata.yaml+ has a YAML syntax error
|
|
15
21
|
def self.load(dir)
|
|
16
22
|
path = File.join(dir, FILENAME)
|
|
17
23
|
return new(Metadata.new) unless File.exist?(path)
|
|
18
24
|
|
|
19
25
|
new(Metadata.from(YAML.safe_load(File.read(path)) || {})) # rubocop:disable Style/YAMLFileRead
|
|
26
|
+
rescue Psych::SyntaxError => e
|
|
27
|
+
raise InvalidMetadata, "#{path}: #{[e.problem, e.context].compact.join(" ")} at line #{e.line} column #{e.column}", cause: nil
|
|
20
28
|
end
|
|
21
29
|
|
|
22
30
|
# @param [Metadata] metadata source YAML mapping
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: simple-agent-extension
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ''
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: 'Coding Agent Extension Utility with Simple DSL and Rule Translating
|
|
14
14
|
and Deploying '
|