simple_english 0.8.1-aarch64-linux → 0.9.0-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16daaeaffbbd426d950a5e91da4662d66211aabe5aaf8b35c75a8971a178a38a
4
- data.tar.gz: 5b6f5b28f5bf58e3ed4eba6b1a09acbe0f7cf5b9936c5c0e30a5b7f3cdbc0fe5
3
+ metadata.gz: 72ba66cae1bbedbe67626683644a2cef99e2a7a42ec779d5232100959d5af6d3
4
+ data.tar.gz: bedfbf1006b105c1b48b58bda546e1adeb0ed3f4d279411a878b783bcfdb9f77
5
5
  SHA512:
6
- metadata.gz: 4e3ed2ee219f6bda8a700aeeccea89a4b2e33fa0562253e85bbdc334376e76aa40de472f35c0a0bd36866e51f2cf4f9c2693e4763d7b2749d0d7f4ccc5445833
7
- data.tar.gz: 69a970321e67922758013f5e03a167e9630bf30e23d47af80f735ec4b47e43407007095184cbc4a634617906a1664fbcd743586febebd7800958c9385688af01
6
+ metadata.gz: 940a9a2ddaedb2f9e9a91efbd8715a701f158e0f6fb121b1fa06910621dffb8e4274ed72e0fa5a32e7ac782c676d6ebc5d4df15d46c3ce77fed137d0e6a8695f
7
+ data.tar.gz: 3c70fddc991ac733359c7eb15b7bc3b74c11d1769c6f4eb5d7df85d0eb5589d68e50d632e9fd785b3e9fa729d5c5edcde1d4dd4ec9af848496c553c6eb61d9d5
@@ -59,14 +59,16 @@ module SimpleEnglish
59
59
  warn "error: file not readable: #{path}"
60
60
  return 2
61
61
  end
62
- # The lintable gate in lint_file reads lintable files itself. A
62
+ # The lintable gate in Linter reads lintable files itself. A
63
63
  # non-lintable path must not cost a full read here.
64
- text = (path == "-") ? $stdin.read : nil
65
- findings = SimpleEnglish.lint_file(path, text)
64
+ findings =
65
+ if path == "-"
66
+ SimpleEnglish::Linter.lint_text($stdin.read, config: config)
67
+ else
68
+ SimpleEnglish::Linter.lint_file(path, config: config)
69
+ end
66
70
  return 2 if findings.nil? # already warned why
67
- SimpleEnglish::Config.filter(config, path, findings).each do |finding|
68
- results << [path, finding]
69
- end
71
+ findings.each { |finding| results << [path, finding] }
70
72
  end
71
73
  self.class.report(results, options[:format])
72
74
  results.empty? ? 0 : 1
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # The complete lint engine, daemon-side. Never call SimpleEnglish.lint_text
3
+ # The complete lint engine, daemon-side. Never call SimpleEnglish.lint
4
4
  # here: that call probes the daemon and recurses into the server.
5
5
  # The engine reads nothing from disk: the caller captures the enabled
6
6
  # rule IDs once at daemon boot (Server.start) and passes them in.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # One decision, two callers: the CLI (SimpleEnglish.lint_file) and
3
+ # One decision, two callers: the CLI (SimpleEnglish.lint) and
4
4
  # the daemon (Engine.lint) must agree on what kind of lint an input
5
5
  # is. The CLI decides to skip comment-free files without a boot.
6
6
  # The daemon decides again on its side of the wire. Both call this
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleEnglish
4
+ module Linter
5
+ module_function
6
+
7
+ def lint_file(path, config: Config.load)
8
+ return [] if Config.ignore?(config, path) || !Extractor.lintable?(path)
9
+ lint_text(File.read(path, encoding: "UTF-8"), language: Extractor.language_for(path), config: config)
10
+ end
11
+
12
+ def lint_text(text, language: nil, config: Config.load)
13
+ findings = SimpleEnglish.lint(text, language: language)
14
+ findings && Config.filter(config, findings)
15
+ end
16
+ end
17
+ end
@@ -15,7 +15,7 @@ module SimpleEnglish
15
15
 
16
16
  module_function
17
17
 
18
- def run(io: $stdin, out: $stdout, linter: method(:default_linter))
18
+ def run(io: $stdin, out: $stdout, linter: Linter)
19
19
  # A piped stdout buffers until 4 KB or EOF. An MCP client keeps
20
20
  # stdin open while it waits for the answer, so an unflushed
21
21
  # response never arrives and the client drops the server.
@@ -26,6 +26,7 @@ module SimpleEnglish
26
26
  begin
27
27
  request = JSON.parse(line)
28
28
  rescue JSON::ParserError
29
+ out.puts JSON.generate(error(nil, -32700, "Parse error"))
29
30
  next
30
31
  end
31
32
  next unless request.is_a?(Hash)
@@ -41,15 +42,6 @@ module SimpleEnglish
41
42
  end
42
43
  end
43
44
 
44
- # The CLI's lint pipeline as a callable: .simple-english.yml decides
45
- # which paths and rules count, then the daemon lints the file.
46
- def default_linter(path)
47
- config = SimpleEnglish::Config.load
48
- return [] if SimpleEnglish::Config.ignore?(config, path)
49
- findings = SimpleEnglish.lint_file(path)
50
- findings.nil? ? nil : SimpleEnglish::Config.filter(config, path, findings)
51
- end
52
-
53
45
  def respond(request, linter:)
54
46
  return nil unless request.key?("id")
55
47
  id = request.fetch("id")
@@ -59,6 +51,7 @@ module SimpleEnglish
59
51
  params = {} unless params.is_a?(Hash)
60
52
  case method
61
53
  when "initialize" then ok(id, initialize_result(params["protocolVersion"]))
54
+ when "ping" then ok(id, {})
62
55
  when "tools/list" then ok(id, {"tools" => [lint_tool]})
63
56
  when "tools/call" then tools_call(id, params, linter)
64
57
  else error(id, -32601, "Method not found: #{method}")
@@ -80,12 +73,14 @@ module SimpleEnglish
80
73
  "description" =>
81
74
  "Lint Markdown prose and code comments against plain-English rules " \
82
75
  "(short sentences, active voice, no jargon, no filler). " \
83
- "Input: a file path. Returns one line per finding, or 'clean' when " \
76
+ "Input: a file path, or Markdown text. Returns one line per finding, or 'clean' when " \
84
77
  "nothing is flagged. Fix the findings, then call again until clean.",
85
78
  "inputSchema" => {
86
79
  "type" => "object",
87
- "properties" => {"path" => {"type" => "string", "description" => "File to lint"}},
88
- "required" => ["path"]
80
+ "properties" => {
81
+ "path" => {"type" => "string", "description" => "File to lint"},
82
+ "text" => {"type" => "string", "description" => "Markdown text to lint instead of a file"}
83
+ }
89
84
  }
90
85
  }
91
86
  end
@@ -96,12 +91,16 @@ module SimpleEnglish
96
91
  arguments = params["arguments"]
97
92
  arguments = {} unless arguments.is_a?(Hash)
98
93
  path = arguments["path"]
99
- return ok(id, tool_error("the path argument is required.")) if path.nil? || path.to_s.empty?
100
- return ok(id, tool_error("#{path} is a directory. Give one file.")) if File.directory?(path)
101
- return ok(id, tool_error("file not found: #{path}")) unless File.exist?(path)
94
+ text = arguments["text"]
95
+ return ok(id, tool_error("give the path or the text, not both.")) if path && text
96
+ unless text
97
+ return ok(id, tool_error("the path or text argument is required.")) if path.nil? || path.to_s.empty?
98
+ return ok(id, tool_error("#{path} is a directory. Give one file.")) if File.directory?(path)
99
+ return ok(id, tool_error("file not found: #{path}")) unless File.exist?(path)
100
+ end
102
101
  findings =
103
102
  begin
104
- linter.call(path)
103
+ text ? linter.lint_text(text) : linter.lint_file(path)
105
104
  rescue SimpleEnglish::Config::ConfigError => e
106
105
  return ok(id, tool_error("invalid .simple-english.yml: #{e.message}"))
107
106
  end
@@ -110,7 +109,7 @@ module SimpleEnglish
110
109
  # model, and this message is the one that tells it how to recover.
111
110
  ok(id, tool_error("the se daemon did not answer. Run `se serve --detached` and retry."))
112
111
  else
113
- ok(id, {"content" => [{"type" => "text", "text" => render(path, findings)}], "isError" => false})
112
+ ok(id, {"content" => [{"type" => "text", "text" => render(text ? "-" : path, findings)}], "isError" => false})
114
113
  end
115
114
  end
116
115
 
@@ -54,8 +54,7 @@ module SimpleEnglish
54
54
  end.join("/") + "\\z")
55
55
  end
56
56
 
57
- def filter(config, path, findings)
58
- return [] if ignore?(config, path)
57
+ def filter(config, findings)
59
58
  disabled = config[:disabled_rules]
60
59
  findings.reject { |finding| disabled.include?(finding.rule) }
61
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleEnglish
4
- VERSION = "0.8.1"
4
+ VERSION = "0.9.0"
5
5
  end
@@ -16,6 +16,7 @@ require_relative "simple_english/lint/extractor"
16
16
  require_relative "simple_english/lint/lint_plan"
17
17
  require_relative "simple_english/lint/annotated_text"
18
18
  require_relative "simple_english/lint/suppressions"
19
+ require_relative "simple_english/lint/linter"
19
20
  require_relative "simple_english/setup/config"
20
21
  require_relative "simple_english/setup/fingerprint"
21
22
  require_relative "simple_english/client/language_tool"
@@ -28,37 +29,19 @@ require_relative "simple_english/daemon/server"
28
29
  module SimpleEnglish
29
30
  module_function
30
31
 
31
- # Returns findings, or nil when the daemon is unreachable. The
32
- # caller (bin/se) owns the exit status. Diagnostics go to
33
- # stderr here.
34
- def lint_text(text)
35
- return nil unless Client.ensure_up(install: Install.from_env)
36
- Client.lint(text)
37
- end
38
-
39
- # One entry point for files. LintPlan decides what kind of lint
40
- # this is. Both tiers share it, so they cannot drift. Code files
41
- # lint comments through the daemon. File types the linter does not
42
- # own are skipped up front: an unknown extension is not prose.
32
+ # The engine: text in, findings out. LintPlan decides what kind of
33
+ # lint this is. Both tiers share it, so they cannot drift. A nil
34
+ # language means Markdown prose. Code lints its comments.
43
35
  # nil means unreachable: the caller decides how fatal that is.
44
- def lint_file(path, text = nil)
45
- return [] unless Extractor.lintable?(path)
46
- text = File.read(path, encoding: "UTF-8") if text.nil?
47
- language = Extractor.language_for(path)
36
+ def lint(text, language: nil)
48
37
  plan = LintPlan.call(text, language)
49
38
  return [] if plan.nil?
50
- findings =
51
- if plan == :prose
52
- lint_text(text)
53
- else
54
- return nil unless Client.ensure_up(install: Install.from_env)
55
- result = Client.lint(text, language: language)
56
- if result.nil?
57
- warn "error: se daemon did not answer. Run `#{Client.runner} serve` and read its output."
58
- end
59
- result
60
- end
61
- return nil unless findings
39
+ return nil unless Client.ensure_up(install: Install.from_env)
40
+ findings = Client.lint(text, language: language)
41
+ if findings.nil?
42
+ warn "error: se daemon did not answer. Run `#{Client.runner} serve` and read its output."
43
+ return nil
44
+ end
62
45
  Suppressions.filter(text, findings)
63
46
  end
64
47
  end
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: data/libexec/simple_english/languagetool-server
3
3
  size: 127207544 bytes
4
- sha256: 7f7ae495f8e33efdb2acedc7d9da3c0754dcaee9ba2758d449253e2414830b11
4
+ sha256: 8f891d3cdb0bbdff8ec45febeda40af667c411da6373051f016921ca61770127
@@ -4,7 +4,7 @@
4
4
  "serialNumber" : "urn:uuid:c99881b6-e8ff-383d-92df-6845602c70c5",
5
5
  "version" : 1,
6
6
  "metadata" : {
7
- "timestamp" : "2026-10-13T20:08:47Z",
7
+ "timestamp" : "2026-10-14T20:35:02Z",
8
8
  "lifecycles" : [
9
9
  {
10
10
  "phase" : "build"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_english
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - TonyCTHsu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-13 00:00:00.000000000 Z
11
+ date: 2026-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tree_sitter_language_pack
@@ -146,6 +146,7 @@ files:
146
146
  - lib/simple_english/lint/extractor.rb
147
147
  - lib/simple_english/lint/finding.rb
148
148
  - lib/simple_english/lint/lint_plan.rb
149
+ - lib/simple_english/lint/linter.rb
149
150
  - lib/simple_english/lint/markdown.rb
150
151
  - lib/simple_english/lint/paragraph.rb
151
152
  - lib/simple_english/lint/plain_text.rb
@@ -176,7 +177,7 @@ licenses:
176
177
  metadata:
177
178
  homepage_uri: https://github.com/TonyCTHsu/simple-english
178
179
  source_code_uri: https://github.com/TonyCTHsu/simple-english
179
- changelog_uri: https://github.com/TonyCTHsu/simple-english/blob/v0.8.1/CHANGELOG.md
180
+ changelog_uri: https://github.com/TonyCTHsu/simple-english/blob/v0.9.0/CHANGELOG.md
180
181
  post_install_message:
181
182
  rdoc_options: []
182
183
  require_paths: