immosquare-cleaner 1.0.2 → 1.1.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/LICENSE +21 -0
- data/bin/immosquare-cleaner +18 -1
- data/lib/immosquare-cleaner/directory_cleaner.rb +1 -0
- data/lib/immosquare-cleaner/hook.rb +37 -0
- data/lib/immosquare-cleaner/processors/go.rb +31 -0
- data/lib/immosquare-cleaner/version.rb +1 -1
- data/lib/immosquare-cleaner.rb +3 -0
- metadata +16 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 684fefa6f6061c2cfd2a30c10852463e2a8a0605dc8d4078fe9cb8f136bd3f97
|
|
4
|
+
data.tar.gz: 9437ae1b6de815f2b97d5dd10f61fb3ad412e6989969f73a10b481b9560efd8b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0962e5e3df0bf9493abeed5871e85fa8146787aec41b09ec37a322ccd88fd7d2454d1d08bb97aa03cf153f1e6ff75809b6d7f286fab0bf1f3ad5e4095f15291
|
|
7
|
+
data.tar.gz: 53315a827d4a2030c1ce6e05bd70c24ded051f9259056fd695261c99e3c3d4e969c89543fb46498e5dfd39ff3a8ec076300352c41860491e020255f8b9edd83f
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 immosquare
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/bin/immosquare-cleaner
CHANGED
|
@@ -31,16 +31,33 @@ OptionParser.new do |parser|
|
|
|
31
31
|
parser.on("-p", "--prevent-concurrent-write", "Prevent concurrent write") do
|
|
32
32
|
options[:prevent_concurrent_write] = true
|
|
33
33
|
end
|
|
34
|
+
parser.on("--hook", "Read the edited file from an AI agent hook payload on stdin") do
|
|
35
|
+
options[:hook] = true
|
|
36
|
+
end
|
|
34
37
|
parser.on("-h", "--help", "Prints this help") do
|
|
35
38
|
puts(parser)
|
|
36
39
|
exit
|
|
37
40
|
end
|
|
38
41
|
end.parse!
|
|
39
42
|
|
|
43
|
+
##============================================================##
|
|
44
|
+
## Hook mode : the edited file comes from the agent's JSON payload.
|
|
45
|
+
## Linters write their reports on stdout, which some agents
|
|
46
|
+
## (Gemini CLI) parse as the hook's JSON answer: everything goes
|
|
47
|
+
## to stderr instead. An unsupported or missing file ends the
|
|
48
|
+
## hook silently with exit 0, so the agent is never blocked.
|
|
49
|
+
##============================================================##
|
|
50
|
+
if options[:hook]
|
|
51
|
+
file_path = ImmosquareCleaner::Hook.file_path($stdin.read)
|
|
52
|
+
exit(0) if file_path.nil?
|
|
53
|
+
$stdout.reopen($stderr)
|
|
54
|
+
else
|
|
55
|
+
file_path = ARGV[0]
|
|
56
|
+
end
|
|
57
|
+
|
|
40
58
|
##============================================================##
|
|
41
59
|
## Check if the file path is provided
|
|
42
60
|
##============================================================##
|
|
43
|
-
file_path = ARGV[0]
|
|
44
61
|
if !file_path
|
|
45
62
|
puts("Error: Please provide a file or directory path.")
|
|
46
63
|
exit(1)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module ImmosquareCleaner
|
|
4
|
+
##============================================================##
|
|
5
|
+
## `immosquare-cleaner --hook` : the file to clean comes from the
|
|
6
|
+
## JSON an AI agent pipes on stdin after an edit, not from ARGV.
|
|
7
|
+
##
|
|
8
|
+
## Each agent nests the edited path differently:
|
|
9
|
+
## - Claude Code, Gemini CLI : tool_input.file_path
|
|
10
|
+
## - Kimi Code : tool_input.path
|
|
11
|
+
## - Grok : toolInput.file_path
|
|
12
|
+
## - Cursor (afterFileEdit) : file_path at the top level
|
|
13
|
+
## A relative path is resolved against the payload's `cwd`.
|
|
14
|
+
##
|
|
15
|
+
## A hook must never block the agent: anything that is not a
|
|
16
|
+
## supported file (no path, deleted file, directory, LICENSE,
|
|
17
|
+
## .env...) is skipped instead of reported.
|
|
18
|
+
##============================================================##
|
|
19
|
+
module Hook
|
|
20
|
+
PAYLOAD_KEYS = ["tool_input", "toolInput"].freeze
|
|
21
|
+
PATH_KEYS = ["file_path", "path", "target_file"].freeze
|
|
22
|
+
|
|
23
|
+
def self.file_path(raw_payload)
|
|
24
|
+
payload = JSON.parse(raw_payload.to_s)
|
|
25
|
+
return if !payload.is_a?(Hash)
|
|
26
|
+
|
|
27
|
+
sources = PAYLOAD_KEYS.map {|key| payload[key] }.grep(Hash) + [payload]
|
|
28
|
+
path = sources.lazy.flat_map {|source| PATH_KEYS.map {|key| source[key] } }.find {|value| value.is_a?(String) && !value.empty? }
|
|
29
|
+
return if path.nil?
|
|
30
|
+
|
|
31
|
+
path = File.expand_path(path, payload["cwd"].is_a?(String) ? payload["cwd"] : Dir.pwd)
|
|
32
|
+
path if File.file?(path) && ImmosquareCleaner.supported?(path)
|
|
33
|
+
rescue JSON::ParserError
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require "shellwords"
|
|
2
|
+
|
|
3
|
+
module ImmosquareCleaner
|
|
4
|
+
module Processors
|
|
5
|
+
class Go < Base
|
|
6
|
+
|
|
7
|
+
def self.match?(file_path)
|
|
8
|
+
file_path.end_with?(".go")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
if !system("which gofmt > /dev/null 2>&1")
|
|
13
|
+
warn("ERROR: gofmt is not installed. Please install Go with: brew install go")
|
|
14
|
+
return
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
##============================================================##
|
|
18
|
+
## gofmt flags:
|
|
19
|
+
## -s : apply gofmt's simplifications (redundant composite
|
|
20
|
+
## literal types, `s[a:len(s)]` → `s[a:]`...)
|
|
21
|
+
## -w : write the result back to the file in place
|
|
22
|
+
## Indentation stays in tabs: gofmt has no option for it, and
|
|
23
|
+
## converting to spaces would make every Go tool (gopls,
|
|
24
|
+
## `gofmt -l` in CI) flag the file as unformatted.
|
|
25
|
+
##============================================================##
|
|
26
|
+
launch_cmds(["gofmt -s -w #{Shellwords.escape(file_path)}"])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/immosquare-cleaner.rb
CHANGED
|
@@ -7,6 +7,7 @@ require "fileutils"
|
|
|
7
7
|
require_relative "immosquare-cleaner/configuration"
|
|
8
8
|
require_relative "immosquare-cleaner/markdown"
|
|
9
9
|
require_relative "immosquare-cleaner/directory_cleaner"
|
|
10
|
+
require_relative "immosquare-cleaner/hook"
|
|
10
11
|
|
|
11
12
|
##============================================================##
|
|
12
13
|
## Processors
|
|
@@ -19,6 +20,7 @@ require_relative "immosquare-cleaner/processors/json"
|
|
|
19
20
|
require_relative "immosquare-cleaner/processors/markdown"
|
|
20
21
|
require_relative "immosquare-cleaner/processors/shell"
|
|
21
22
|
require_relative "immosquare-cleaner/processors/rust"
|
|
23
|
+
require_relative "immosquare-cleaner/processors/go"
|
|
22
24
|
require_relative "immosquare-cleaner/processors/toml"
|
|
23
25
|
require_relative "immosquare-cleaner/processors/yaml"
|
|
24
26
|
require_relative "immosquare-cleaner/processors/prettier"
|
|
@@ -123,6 +125,7 @@ module ImmosquareCleaner
|
|
|
123
125
|
Processors::Markdown,
|
|
124
126
|
Processors::Shell,
|
|
125
127
|
Processors::Rust,
|
|
128
|
+
Processors::Go,
|
|
126
129
|
Processors::Toml
|
|
127
130
|
].freeze
|
|
128
131
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: immosquare-cleaner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- immosquare
|
|
@@ -149,9 +149,11 @@ dependencies:
|
|
|
149
149
|
- - "<="
|
|
150
150
|
- !ruby/object:Gem::Version
|
|
151
151
|
version: '1000.0'
|
|
152
|
-
description:
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
description: immosquare-cleaner formats Ruby, ERB, JS/TS, Rust, Go, TOML, Markdown,
|
|
153
|
+
Shell, JSON, YAML and CSS files with one consistent house style, delegating each
|
|
154
|
+
format to the right tool (RuboCop, erb_lint, ESLint, rustfmt, gofmt, taplo, shfmt,
|
|
155
|
+
Prettier). Run it on a file, a whole repository, on save, or as a Claude Code, Cursor
|
|
156
|
+
or Gemini CLI hook so every file an AI agent writes comes out formatted.
|
|
155
157
|
email:
|
|
156
158
|
- jules@immosquare.com
|
|
157
159
|
executables:
|
|
@@ -160,13 +162,16 @@ extensions: []
|
|
|
160
162
|
extra_rdoc_files: []
|
|
161
163
|
files:
|
|
162
164
|
- ".erb_linters"
|
|
165
|
+
- LICENSE
|
|
163
166
|
- bin/immosquare-cleaner
|
|
164
167
|
- lib/immosquare-cleaner.rb
|
|
165
168
|
- lib/immosquare-cleaner/configuration.rb
|
|
166
169
|
- lib/immosquare-cleaner/directory_cleaner.rb
|
|
170
|
+
- lib/immosquare-cleaner/hook.rb
|
|
167
171
|
- lib/immosquare-cleaner/markdown.rb
|
|
168
172
|
- lib/immosquare-cleaner/processors/base.rb
|
|
169
173
|
- lib/immosquare-cleaner/processors/erb.rb
|
|
174
|
+
- lib/immosquare-cleaner/processors/go.rb
|
|
170
175
|
- lib/immosquare-cleaner/processors/javascript.rb
|
|
171
176
|
- lib/immosquare-cleaner/processors/json.rb
|
|
172
177
|
- lib/immosquare-cleaner/processors/markdown.rb
|
|
@@ -201,10 +206,13 @@ files:
|
|
|
201
206
|
- linters/rubocop/cop/custom_cops/style/kwarg_priority_order.rb
|
|
202
207
|
- linters/rubocop/cop/style/method_call_with_args_parentheses_override.rb
|
|
203
208
|
- package.json
|
|
204
|
-
homepage: https://github.com/immosquare/
|
|
209
|
+
homepage: https://github.com/immosquare/immosquare-cleaner
|
|
205
210
|
licenses:
|
|
206
211
|
- MIT
|
|
207
|
-
metadata:
|
|
212
|
+
metadata:
|
|
213
|
+
source_code_uri: https://github.com/immosquare/immosquare-cleaner
|
|
214
|
+
changelog_uri: https://github.com/immosquare/immosquare-cleaner/blob/main/CHANGELOG.md
|
|
215
|
+
bug_tracker_uri: https://github.com/immosquare/immosquare-cleaner/issues
|
|
208
216
|
rdoc_options: []
|
|
209
217
|
require_paths:
|
|
210
218
|
- lib
|
|
@@ -222,5 +230,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
222
230
|
requirements: []
|
|
223
231
|
rubygems_version: 4.0.22
|
|
224
232
|
specification_version: 4
|
|
225
|
-
summary:
|
|
233
|
+
summary: One command to format every file of a repository, built to run as an AI agent
|
|
234
|
+
hook.
|
|
226
235
|
test_files: []
|