rosett-ai 1.8.0 → 1.8.1
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 +24 -0
- data/lib/rosett_ai/mcp/enforcement/hook_generator.rb +6 -2
- data/lib/rosett_ai/mcp/tools/hook_install_tool.rb +14 -0
- data/lib/rosett_ai/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 95d279ef7cfbcfabd17980dcc444d353b1af0b31a1d19db87e5eaef99e59b4ab
|
|
4
|
+
data.tar.gz: a14e73c818b37af55a2eaefcb2ace6f9574a375faf24b8c30daa4aeabd8e5c57
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: edbf2bdf9f239fd288e55bf403b98dec1f5ae804a5437ff82e170c68a8f042b63426f19e4bade372e8425e3bda0b6d51d969cb47cf18c01d553f161feda0dc95
|
|
7
|
+
data.tar.gz: 9ac58d88a91de6ae5024c29acc51013ead935f63485adf128e07fdf9a2edd07d293e857023fc2c8bb8680114c62305e974709313ba2fa4bed1c77d54251a4a1b
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,30 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.8.1] - 2026-08-14
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **`HookGenerator#format_regex` regex-literal syntax error** — the generator
|
|
14
|
+
previously emitted patterns as `/regex/` literals, which produced a Ruby
|
|
15
|
+
`SyntaxError` when the pattern contained a forward slash inside a character
|
|
16
|
+
class (e.g. `[^\/\s]`) or as a path separator (e.g. `\/tmp\/`). Ruby parses
|
|
17
|
+
the first unescaped `/` as the closing regex delimiter, silently breaking the
|
|
18
|
+
hook. Both the `pattern` and `path_scope` fields now emit `Regexp.new("...")`
|
|
19
|
+
calls, which are immune to delimiter conflicts. The bug affected every
|
|
20
|
+
generated hook since the feature was introduced; no hook had ever parsed
|
|
21
|
+
cleanly on the real rule set.
|
|
22
|
+
|
|
23
|
+
- **`rai_hook_install` parse gate** — `HookInstallTool#write_hook` now runs
|
|
24
|
+
`ruby -c` on the generated script before writing it to disk. A `SyntaxError`
|
|
25
|
+
in the generated hook now raises immediately with a descriptive message rather
|
|
26
|
+
than silently installing a broken file.
|
|
27
|
+
|
|
28
|
+
- **Regression specs** — `hook_generator_spec.rb` now includes contexts for
|
|
29
|
+
patterns containing `/` inside character classes and path separators, with
|
|
30
|
+
assertions that `RubyVM::InstructionSequence.compile` succeeds and that the
|
|
31
|
+
emitted form is `Regexp.new(...)` rather than a `/regex/` literal.
|
|
32
|
+
|
|
9
33
|
## [1.8.0] - 2026-08-13
|
|
10
34
|
|
|
11
35
|
### Added
|
|
@@ -170,12 +170,16 @@ module RosettAi
|
|
|
170
170
|
].join("\n ")
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
-
# Formats a pattern string as a Regexp
|
|
173
|
+
# Formats a pattern string as a Regexp.new() call for the generated script.
|
|
174
|
+
#
|
|
175
|
+
# Uses Regexp.new("...") rather than /regex/ literals to avoid delimiter
|
|
176
|
+
# conflicts when patterns contain forward slashes (e.g. inside character
|
|
177
|
+
# classes like [^\/\s] or path patterns like \/tmp\/).
|
|
174
178
|
#
|
|
175
179
|
# @param pattern [String]
|
|
176
180
|
# @return [String]
|
|
177
181
|
def format_regex(pattern)
|
|
178
|
-
"
|
|
182
|
+
"Regexp.new(#{pattern.inspect})"
|
|
179
183
|
end
|
|
180
184
|
|
|
181
185
|
# Sanitizes a string for safe embedding in single-quoted Ruby strings.
|
|
@@ -142,12 +142,26 @@ module RosettAi
|
|
|
142
142
|
|
|
143
143
|
# @param hook_path [Pathname]
|
|
144
144
|
# @param content [String]
|
|
145
|
+
# @raise [RuntimeError] if the generated script fails Ruby syntax check
|
|
145
146
|
def write_hook(hook_path, content)
|
|
147
|
+
verify_ruby_syntax!(content)
|
|
146
148
|
FileUtils.mkdir_p(hook_path.dirname)
|
|
147
149
|
File.write(hook_path, content)
|
|
148
150
|
FileUtils.chmod(0o755, hook_path)
|
|
149
151
|
end
|
|
150
152
|
|
|
153
|
+
# Verifies generated hook content parses as valid Ruby before writing.
|
|
154
|
+
# Uses RubyVM::InstructionSequence.compile so no subprocess, Tempfile,
|
|
155
|
+
# or writable /tmp directory is required — the check works in CI containers.
|
|
156
|
+
#
|
|
157
|
+
# @param content [String] generated script content
|
|
158
|
+
# @raise [RuntimeError] if syntax check fails
|
|
159
|
+
def verify_ruby_syntax!(content)
|
|
160
|
+
RubyVM::InstructionSequence.compile(content)
|
|
161
|
+
rescue SyntaxError => e
|
|
162
|
+
raise "Generated hook failed Ruby syntax check: #{e.message}"
|
|
163
|
+
end
|
|
164
|
+
|
|
151
165
|
# Registers the hook in settings.json if not already present.
|
|
152
166
|
#
|
|
153
167
|
# @param hook_path [Pathname]
|
data/lib/rosett_ai/version.rb
CHANGED