aia 2.0.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f3c92628b523cd32fa77fa52f1546f1ec43ee9b65c645b33adb508086ef0c13
4
- data.tar.gz: cc9e9aab97552cff87e4b05b001d8330a99a5fea9000c6d2b76f07b1e1a7054e
3
+ metadata.gz: 9fa126ad31719e30c2d357d3573ba4b7832fe99ab082799c0e7b37c3b0d49314
4
+ data.tar.gz: 20706361c420669cb035fb03c996ef28895399ba850985715e44f6b9411ca47a
5
5
  SHA512:
6
- metadata.gz: abf1b9d9f077b6d8aadd6c259e1cf3125007718b7912be857003f4189d57be4c20451093e87c6ec47f0a3be06c4ddf7cf767ffff5dc55be4177241e2d6fa8d7d
7
- data.tar.gz: 14e85d72e471d1bf8572d8fb2b417a6e1e0c641bc34e376b8748dd8b2f55665221fa6ff78966692f0ecce65ee990067c65a898db0d96f718ad713ec8f02048ec
6
+ metadata.gz: 6154106f03fa35cfbf562282eec6512dc210df4b40ae6c900eede45df5a5253f232fc6bbe7c9a0cf930a152558ffde96d45aa1894d8c338af5256f65a9ccbe82
7
+ data.tar.gz: 6ce2ca929686cd6e262f5f009581a087b710129f5d89a0d020d612dffd7bc5b555f794a41cfc38ca3f8a3b1941edfeff7cb08331f2c7ea036dfce2e4372c3ae0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.1] 2026-11-02
4
+
5
+ ### Fixed
6
+
7
+ - **`--chat` startup output is readable again.** ruby_llm 2.1 starts stdio MCP servers with their stderr connected to aia's, so server banners, npm notices, stack traces and validation dumps were printed over the "Connecting MCP servers" spinner and garbled it. That stderr now goes to `~/.config/aia/logs/mcp_servers.log`. Set `logger.mcp.server_stderr` to another path, `STDERR` (the 2.0.0 behavior) or `null` to discard it.
8
+
9
+ ### Changed
10
+
11
+ - `logger.mcp.file` defaults to `~/.config/aia/logs/mcp.log` (was `STDOUT`), so MCP connection warnings no longer print over the spinner. Failed servers are still listed in the startup banner. A config file that sets `file: STDOUT` keeps the old behavior.
12
+ - Log directories are created when they don't exist.
13
+
3
14
  ## [2.0.0] 2026-11-02
4
15
 
5
16
  AIA 2.0 rebuilds the CLI on [robot_lab](https://github.com/MadBomber/robot_lab): every session is a crew of robots, MCP servers come from ruby_llm 2.1's built-in client, and any provider RubyLLM registers can be used. This entry summarizes everything since 1.1.1, the last 1.x release, including the `2.0.0.pre.alpha` and `2.0.0.pre.beta2` pre-releases.
@@ -162,10 +162,15 @@ defaults:
162
162
  file: STDOUT
163
163
  level: warn
164
164
  flush: true
165
+ # MCP connection logging goes to a file so warnings never interleave
166
+ # with the "Connecting MCP servers" spinner; failures still appear in
167
+ # the startup banner's FAILED list.
165
168
  mcp:
166
- file: STDOUT
169
+ file: ~/.config/aia/logs/mcp.log
167
170
  level: warn
168
171
  flush: true
172
+ # stderr of stdio MCP server processes: a file path, STDERR, or null
173
+ server_stderr: ~/.config/aia/logs/mcp_servers.log
169
174
 
170
175
  # ---------------------------------------------------------------------------
171
176
  # Pipeline/Workflow Configuration
data/lib/aia/logger.rb CHANGED
@@ -18,8 +18,9 @@
18
18
  # file: STDOUT
19
19
  # level: warn
20
20
  # mcp:
21
- # file: STDOUT
21
+ # file: ~/.config/aia/logs/mcp.log
22
22
  # level: warn
23
+ # server_stderr: ~/.config/aia/logs/mcp_servers.log # stdio server stderr
23
24
  #
24
25
  # Lumberjack provides structured logging, context isolation,
25
26
  # automatic log file rolling, and multi-process safe file writes.
@@ -30,6 +31,7 @@
30
31
  # AIA::LoggerManager.clear_test_logs! # between tests
31
32
  # entries = AIA::LoggerManager.aia_logger.device.entries # inspect logs
32
33
 
34
+ require 'fileutils'
33
35
  require 'lumberjack'
34
36
 
35
37
  module AIA
@@ -287,6 +289,7 @@ module AIA
287
289
  Lumberjack::Device::Writer.new($stderr, autoflush: flush)
288
290
  else
289
291
  path = File.expand_path(file)
292
+ FileUtils.mkdir_p(File.dirname(path))
290
293
  # Daily date rolling via Logger::LogDevice, which also makes the
291
294
  # file safe for multiple loggers to write to
292
295
  Lumberjack::Device::LogFile.new(
@@ -0,0 +1,102 @@
1
+ # lib/aia/patches/mcp_stdio_stderr.rb
2
+ #
3
+ # Redirect the stderr of stdio MCP server processes away from the terminal.
4
+ #
5
+ # ruby_llm 2.1's RubyLLM::MCP::Stdio#start launches each server with
6
+ # Open3.popen2, so the child inherits aia's stderr ("Its stderr is the
7
+ # parent's"). Every server banner, npm notice, stack trace and Python
8
+ # validation dump then lands on the terminal, interleaved with the
9
+ # TTY::Spinner::Multi "Connecting MCP servers" display, which corrupts it.
10
+ # (ruby_llm-mcp 1.x used popen3 and drained stderr, so aia 1.x was quiet.)
11
+ #
12
+ # The destination comes from AIA.config.logger.mcp.server_stderr:
13
+ # a file path - appended to (default: ~/.config/aia/logs/mcp_servers.log)
14
+ # STDERR - the old passthrough behavior
15
+ # null - discard (also: none, /dev/null)
16
+ #
17
+ # Stdio#start has no hook for spawn options, so this re-implements its
18
+ # three-line body. It is guarded against drift: if a future ruby_llm drops
19
+ # Stdio#start, the patch is skipped with a warning instead of breaking MCP.
20
+
21
+ require 'fileutils'
22
+ require 'open3'
23
+
24
+ module AIA
25
+ module MCPStdioStderr
26
+ DEFAULT_PATH = '~/.config/aia/logs/mcp_servers.log'.freeze
27
+ DISCARD = %w[NULL NONE /DEV/NULL].freeze
28
+
29
+ class << self
30
+ # The spawn option value for a server's stderr.
31
+ #
32
+ # @param setting [String, nil] logger.mcp.server_stderr
33
+ # @return [Array(String, String), nil] [path, mode] for Process.spawn's
34
+ # err: option, or nil to inherit the parent's stderr
35
+ def spawn_target(setting = configured_setting)
36
+ value = setting.to_s.strip
37
+ value = DEFAULT_PATH if value.empty?
38
+
39
+ case value.upcase
40
+ when 'STDERR' then nil
41
+ when *DISCARD then [File::NULL, 'w']
42
+ else log_file_target(value)
43
+ end
44
+ end
45
+
46
+ # Spawn options for Open3 with the stderr redirect added.
47
+ #
48
+ # @param options [Hash] options ruby_llm would pass (e.g. chdir:)
49
+ # @param target [Array, nil] from .spawn_target
50
+ # @return [Hash]
51
+ def spawn_options(options, target = spawn_target)
52
+ target ? options.merge(err: target) : options
53
+ end
54
+
55
+ # Install the patch onto RubyLLM::MCP::Stdio (idempotent).
56
+ #
57
+ # @return [Class, nil] the patched class, or nil when it can't be patched
58
+ def install!(stdio = stdio_class)
59
+ return unless stdio&.private_method_defined?(:start)
60
+
61
+ stdio.prepend(StdioPatch) unless stdio.ancestors.include?(StdioPatch)
62
+ stdio
63
+ end
64
+
65
+ private
66
+
67
+ def configured_setting
68
+ AIA.config&.logger&.mcp&.server_stderr
69
+ rescue StandardError
70
+ nil # config not loaded yet (or malformed): fall back to the default file
71
+ end
72
+
73
+ def log_file_target(value)
74
+ path = File.expand_path(value)
75
+ FileUtils.mkdir_p(File.dirname(path))
76
+ [path, 'a']
77
+ rescue SystemCallError
78
+ [File::NULL, 'w'] # unwritable location: still keep the terminal clean
79
+ end
80
+
81
+ def stdio_class
82
+ RubyLLM::MCP::Stdio if defined?(RubyLLM::MCP::Stdio)
83
+ end
84
+ end
85
+
86
+ # Prepended onto RubyLLM::MCP::Stdio.
87
+ module StdioPatch
88
+ private
89
+
90
+ def start
91
+ options = @directory ? { chdir: @directory } : {}
92
+ options = MCPStdioStderr.spawn_options(options)
93
+ @stdin, @stdout, @process = Open3.popen2(@env, *@command, **options)
94
+ @buffer = +''
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ unless AIA::MCPStdioStderr.install!
101
+ warn 'AIA: RubyLLM::MCP::Stdio#start not found; MCP server stderr will reach the terminal'
102
+ end
data/lib/aia/version.rb CHANGED
@@ -1,13 +1,5 @@
1
1
  # lib/aia/version.rb
2
- #
3
- # This file defines the version of the AIA application.
4
- # The VERSION constant defines the current version of the AIA application,
5
- # which is read from the .version file in the project root.
6
2
 
7
- # The AIA module serves as the namespace for the AIA application, which
8
- # provides an interface for interacting with AI models and managing prompts.
9
3
  module AIA
10
- # The VERSION constant defines the current version of the AIA application,
11
- # which is read from the .version file in the project root.
12
- VERSION = File.read(File.join(File.dirname(__FILE__), '..', '..', '.version')).strip
4
+ VERSION = '2.0.1'.freeze
13
5
  end
data/lib/aia.rb CHANGED
@@ -53,6 +53,7 @@ require_relative 'aia/robot_sync'
53
53
  require_relative 'aia/robot_builder'
54
54
  require_relative 'aia/directive_processor'
55
55
  require_relative 'aia/variable_input_collector'
56
+ require_relative 'aia/patches/mcp_stdio_stderr'
56
57
  require_relative 'aia/ui_presenter'
57
58
  require_relative 'aia/input_collector'
58
59
  require_relative 'aia/handler_context'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aia
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
@@ -418,7 +418,6 @@ executables:
418
418
  extensions: []
419
419
  extra_rdoc_files: []
420
420
  files:
421
- - ".version"
422
421
  - CHANGELOG.md
423
422
  - LICENSE
424
423
  - README.md
@@ -470,6 +469,7 @@ files:
470
469
  - lib/aia/model_registry.rb
471
470
  - lib/aia/network_builder.rb
472
471
  - lib/aia/network_memory_manager.rb
472
+ - lib/aia/patches/mcp_stdio_stderr.rb
473
473
  - lib/aia/patches/ruby_llm_streaming_error.rb
474
474
  - lib/aia/patches/ruby_llm_tool_error.rb
475
475
  - lib/aia/patches/ruby_llm_tool_param_compat.rb
data/.version DELETED
@@ -1 +0,0 @@
1
- 2.0.0