legionio 1.6.32 → 1.6.34

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: 382eadc81bfd7449fe1d3d8c5c9e833795cb17deaab9d6b00c04a0d10508ad88
4
- data.tar.gz: c3df12bdc9300f8c1cf4ace607b623140286c78c7615b35f774809c5ecb7e53e
3
+ metadata.gz: f47bba61ed42d34114fc93779bc2c911b6dd67f03f6d06febaae9424bc0c61cf
4
+ data.tar.gz: c4e45617785c4a31b32f9802b0ec77cc57dceb9ad223b6f71a35a9a54b21c119
5
5
  SHA512:
6
- metadata.gz: eb50b2ab0354df1dbcf053bb6794944ec29265c482bc274dafdc2c42a288e0349a187d07ff5172ad36ed203729a6714e5c2a9601e032c3592e1f8df22276ce39
7
- data.tar.gz: c0a172f265bd7bf5e07bf34460d7f9a5b7be2b872c11e21f5de47e7354a67a0e4e425a7b3ef70d9bc9b54c61ccb920f820ab9b33ab059a38ff9977f0852f560d
6
+ metadata.gz: 92a3fed3a076dc34d63fdb69dbde68d3a73ce4f68c17652dfa862fbc355b8df9ac0e1023edd1a93020806d6af838071dd103dc176b6b32a0d03b51e1f03fec6c
7
+ data.tar.gz: 13dfb3297160e508288d61f3713d8a97ee930b74cd58eab56311116ab2bbb065c88d20ba279ea6c55b6fb62af5623c8222bcf560a88aa0c93e8f24693ba38aca
data/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.6.34] - 2026-03-29
6
+
7
+ ### Fixed
8
+ - `POST /api/logs` no longer raises `NoMethodError: undefined method 'values' for nil` — replaced `Legion::Transport::Messages::Dynamic.new(...).publish` with a direct `Legion::Transport::Exchanges::Logging` publish call; `Dynamic` requires a `function_id` for database lookup which log payloads do not have
9
+ - `legion knowledge` CLI commands (`require_monitor!`, `require_knowledge!`, `require_ingest!`, `require_maintenance!`) now use `Connection.ensure_knowledge` to dynamically load `lex-knowledge` when not yet loaded, instead of raising a generic error
10
+
11
+ ### Added
12
+ - `Connection.ensure_knowledge` — lazily loads the `lex-knowledge` gem on demand, consistent with `ensure_llm` and other lazy loaders
13
+
14
+ ## [1.6.33] - 2026-03-28
15
+
16
+ ### Added
17
+ - `knowledge` registered as top-level CLI subcommand (previously only accessible via `legionio ai knowledge`). Fixes knowledge capture hooks that call `legionio knowledge capture commit/transcript`.
18
+
19
+ ### Fixed
20
+ - Claude Code hook format in `setup claude-code`: PostToolUse and Stop hooks now emit the new `hooks` array wrapper format with `type: command` entries. Detection supports both old and new formats via `hook_commands` helper.
21
+
5
22
  ## [1.6.32] - 2026-03-28
6
23
 
7
24
  ### Added
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'legion/transport/exchanges/logging'
4
+
3
5
  module Legion
4
6
  class API < Sinatra::Base
5
7
  module Routes
@@ -20,9 +22,17 @@ module Legion
20
22
  payload = Legion::API::Routes::Logs.build_log_payload(body, level, source)
21
23
  key = Legion::API::Routes::Logs.routing_key_for(body, level, source)
22
24
 
23
- Legion::Transport::Messages::Dynamic.new(
24
- exchange: 'legion.logging', routing_key: key, **payload
25
- ).publish
25
+ exchange = Legion::Transport::Exchanges::Logging.cached_instance || Legion::Transport::Exchanges::Logging.new
26
+ exchange.publish(
27
+ Legion::JSON.dump(payload),
28
+ routing_key: key,
29
+ content_type: 'application/json',
30
+ content_encoding: 'identity',
31
+ type: 'log',
32
+ persistent: true,
33
+ app_id: 'legion',
34
+ headers: { 'legion_protocol_version' => '2.0' }
35
+ )
26
36
 
27
37
  json_response({ published: true, routing_key: key }, status_code: 201)
28
38
  rescue StandardError => e
@@ -88,6 +88,17 @@ module Legion
88
88
  raise CLI::Error, 'legion-cache gem is not installed (gem install legion-cache)'
89
89
  end
90
90
 
91
+ def ensure_knowledge
92
+ return if @knowledge_ready
93
+
94
+ ensure_settings
95
+ spec = Gem::Specification.find_by_name('lex-knowledge')
96
+ require "#{spec.gem_dir}/lib/legion/extensions/knowledge"
97
+ @knowledge_ready = true
98
+ rescue Gem::MissingSpecError
99
+ raise CLI::Error, 'lex-knowledge gem is not installed (gem install lex-knowledge)'
100
+ end
101
+
91
102
  def ensure_llm
92
103
  return if @llm_ready
93
104
 
@@ -90,9 +90,7 @@ module Legion
90
90
  end
91
91
 
92
92
  def require_monitor!
93
- return if defined?(Legion::Extensions::Knowledge::Runners::Monitor)
94
-
95
- raise CLI::Error, 'lex-knowledge extension is not loaded. Install and enable it first.'
93
+ Connection.ensure_knowledge unless defined?(Legion::Extensions::Knowledge::Runners::Monitor)
96
94
  end
97
95
  end
98
96
  end
@@ -120,15 +118,12 @@ module Legion
120
118
  content = "Git commit: #{sha}\nSubject: #{subject}\n\nDiff stat:\n#{diff_stat}"
121
119
  tags = %w[git commit knowledge-capture]
122
120
 
123
- result = if defined?(Legion::Extensions::Knowledge::Runners::Ingest)
124
- Legion::Extensions::Knowledge::Runners::Ingest.ingest_file(
125
- content: content,
126
- tags: tags,
127
- source: "git:#{sha}"
128
- )
129
- else
130
- { success: false, error: 'lex-knowledge not loaded' }
131
- end
121
+ Connection.ensure_knowledge unless defined?(Legion::Extensions::Knowledge::Runners::Ingest)
122
+ result = Legion::Extensions::Knowledge::Runners::Ingest.ingest_file(
123
+ content: content,
124
+ tags: tags,
125
+ source: "git:#{sha}"
126
+ )
132
127
 
133
128
  out = formatter
134
129
  if options[:json]
@@ -155,15 +150,12 @@ module Legion
155
150
  tags = ['session', 'knowledge-capture', ::Time.now.strftime('%Y-%m-%d')]
156
151
  tags << "repo:#{repo}" unless repo.empty?
157
152
 
158
- result = if defined?(Legion::Extensions::Knowledge::Runners::Ingest)
159
- Legion::Extensions::Knowledge::Runners::Ingest.ingest_file(
160
- content: content,
161
- tags: tags,
162
- source: "session:#{::Time.now.iso8601}"
163
- )
164
- else
165
- { success: false, error: 'lex-knowledge not loaded' }
166
- end
153
+ Connection.ensure_knowledge unless defined?(Legion::Extensions::Knowledge::Runners::Ingest)
154
+ result = Legion::Extensions::Knowledge::Runners::Ingest.ingest_file(
155
+ content: content,
156
+ tags: tags,
157
+ source: "session:#{::Time.now.iso8601}"
158
+ )
167
159
 
168
160
  out = formatter
169
161
  if options[:json]
@@ -473,21 +465,15 @@ module Legion
473
465
  end
474
466
 
475
467
  def require_knowledge!
476
- return if defined?(Legion::Extensions::Knowledge::Runners::Query)
477
-
478
- raise CLI::Error, 'lex-knowledge extension is not loaded. Install and enable it first.'
468
+ Connection.ensure_knowledge unless defined?(Legion::Extensions::Knowledge::Runners::Query)
479
469
  end
480
470
 
481
471
  def require_ingest!
482
- return if defined?(Legion::Extensions::Knowledge::Runners::Ingest)
483
-
484
- raise CLI::Error, 'lex-knowledge extension is not loaded. Install and enable it first.'
472
+ Connection.ensure_knowledge unless defined?(Legion::Extensions::Knowledge::Runners::Ingest)
485
473
  end
486
474
 
487
475
  def require_maintenance!
488
- return if defined?(Legion::Extensions::Knowledge::Runners::Maintenance)
489
-
490
- raise CLI::Error, 'lex-knowledge extension is not loaded. Install and enable it first.'
476
+ Connection.ensure_knowledge unless defined?(Legion::Extensions::Knowledge::Runners::Maintenance)
491
477
  end
492
478
 
493
479
  def knowledge_query
@@ -350,8 +350,8 @@ module Legion
350
350
 
351
351
  hooks = existing['hooks'] || {}
352
352
 
353
- has_commit = Array(hooks['PostToolUse']).any? { |h| h['command']&.include?('knowledge capture commit') }
354
- has_transcript = Array(hooks['Stop']).any? { |h| h['command']&.include?('knowledge capture transcript') }
353
+ has_commit = Array(hooks['PostToolUse']).any? { |h| hook_commands(h).any? { |c| c.include?('knowledge capture commit') } }
354
+ has_transcript = Array(hooks['Stop']).any? { |h| hook_commands(h).any? { |c| c.include?('knowledge capture transcript') } }
355
355
  if has_commit && has_transcript && !options[:force]
356
356
  puts ' Write-back hooks already present (use --force to overwrite)' unless options[:json]
357
357
  return
@@ -363,15 +363,14 @@ module Legion
363
363
  unless has_commit
364
364
  hooks['PostToolUse'] << {
365
365
  'matcher' => 'Bash',
366
- 'command' => 'legionio knowledge capture commit',
367
- 'timeout' => 10_000
366
+ 'hooks' => [{ 'type' => 'command', 'command' => 'legionio knowledge capture commit', 'timeout' => 10_000 }]
368
367
  }
369
368
  end
370
369
 
371
370
  unless has_transcript
372
371
  hooks['Stop'] << {
373
- 'command' => 'legionio knowledge capture transcript',
374
- 'timeout' => 30_000
372
+ 'matcher' => '',
373
+ 'hooks' => [{ 'type' => 'command', 'command' => 'legionio knowledge capture transcript', 'timeout' => 30_000 }]
375
374
  }
376
375
  end
377
376
 
@@ -381,6 +380,13 @@ module Legion
381
380
  puts ' Installed write-back hooks for knowledge capture' unless options[:json]
382
381
  end
383
382
 
383
+ def hook_commands(hook_entry)
384
+ # Support both old format (command at top level) and new format (hooks array)
385
+ cmds = Array(hook_entry['hooks']).filter_map { |h| h['command'] }
386
+ cmds << hook_entry['command'] if hook_entry['command']
387
+ cmds
388
+ end
389
+
384
390
  def write_mcp_servers_json(_out, path, installed)
385
391
  existing = load_json_file(path)
386
392
  servers = existing['mcpServers'] || {}
data/lib/legion/cli.rb CHANGED
@@ -254,6 +254,9 @@ module Legion
254
254
  subcommand 'init', Legion::CLI::Init
255
255
 
256
256
  # --- Interactive & shortcuts ---
257
+ desc 'knowledge SUBCOMMAND', 'Search and manage the document knowledge base'
258
+ subcommand 'knowledge', Legion::CLI::Knowledge
259
+
257
260
  desc 'codegen SUBCOMMAND', 'Manage self-generating functions'
258
261
  subcommand 'codegen', CodegenCommand
259
262
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Legion
4
- VERSION = '1.6.32'
4
+ VERSION = '1.6.34'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legionio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.32
4
+ version: 1.6.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity