legionio 1.5.23 → 1.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17deabb2b4dbb36f8f31d6e14d7a63f8f91974de927136695f578ec76754d9c5
4
- data.tar.gz: cfe7c8e815606a027c4fd0fcf93ecc09af5020d2e90fee69e77f3d623496db7a
3
+ metadata.gz: 6413e545fabb634ddda16a99e884701751aa1cdd8245b649799f4836ae0c7360
4
+ data.tar.gz: 4239fd5af0278ba21cf33bbd320e62e67b103d93d36f3f5266eb5269019b7859
5
5
  SHA512:
6
- metadata.gz: c5bf157c87db6916ffd800abfa0e84597f26dd4357ef64e7ce6072fdb20afeba4bf4d78260049107e67923d2aa872e44d58356cdb89ad3b599a8e92db3279a3e
7
- data.tar.gz: 7d030a421b8bcb8f2ffae48d564339a7241b7febd6cd5142a8473dd6e67c4f00b661a571ff80ce0107b3cd69adf268427ad035368eaa1ed4e336afc85bbd5976
6
+ metadata.gz: 2dee1932ef724c587ff8d26c496913cb7b90b1385f7793b3d13c7e3e703440c0b6ad4f7b431215c395ee742cd920afebcda784e29feca058d67a6afb73cb0abb
7
+ data.tar.gz: fd476599db94cf729ed3e5b66f82f1f090b44215222c24e6a8cf8e6d67c9837fd204561c6054f83505b0fc194a3766aef365eadaa46712babb5750dde82383c3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Legion Changelog
2
2
 
3
+ ## [1.6.0] - 2026-03-26
4
+
5
+ ### Added
6
+ - `legion knowledge monitor add/list/remove/status` — multi-directory corpus monitor management
7
+ - `legion knowledge capture commit` — capture git commit as knowledge (hook-compatible)
8
+ - `legion knowledge capture session` — capture session summary as knowledge (hook-compatible)
9
+ - `legion setup claude-code` now installs write-back hooks for automatic knowledge capture
10
+ - `resolve_corpus_path` falls back to first registered monitor when no explicit path given
11
+
3
12
  ## [1.5.23] - 2026-03-26
4
13
 
5
14
  ### Changed
data/CLAUDE.md CHANGED
@@ -9,7 +9,7 @@ The primary gem for the LegionIO framework. An extensible async job engine for s
9
9
 
10
10
  **GitHub**: https://github.com/LegionIO/LegionIO
11
11
  **Gem**: `legionio`
12
- **Version**: 1.4.197
12
+ **Version**: 1.6.0
13
13
  **License**: Apache-2.0
14
14
  **Docker**: `legionio/legion`
15
15
  **Ruby**: >= 3.4
@@ -47,12 +47,13 @@ Legion.start
47
47
  ├── 6. setup_data (legion-data, MySQL/SQLite + migrations, optional)
48
48
  ├── 7. setup_rbac (legion-rbac, optional)
49
49
  ├── 8. setup_llm (legion-llm, AI provider setup + routing, optional)
50
- ├── 9. setup_gaia (legion-gaia, cognitive coordination layer, optional)
51
- ├── 10. setup_telemetry (OpenTelemetry, optional)
52
- ├── 11. setup_supervision (process supervision)
53
- ├── 12. load_extensions (parallel require+autobuild on 4-thread pool, then hook_all_actors)
54
- ├── 13. Legion::Crypt.cs (distribute cluster secret)
55
- └── 14. setup_api (start Sinatra/Puma on port 4567)
50
+ ├── 9. setup_apollo (legion-apollo, shared + local knowledge store, optional)
51
+ ├── 10. setup_gaia (legion-gaia, cognitive coordination layer, optional)
52
+ ├── 11. setup_telemetry (OpenTelemetry, optional)
53
+ ├── 12. setup_supervision (process supervision)
54
+ ├── 13. load_extensions (two-phase parallel: require+autobuild on FixedThreadPool, then hook_all_actors)
55
+ ├── 14. Legion::Crypt.cs (distribute cluster secret)
56
+ └── 15. setup_api (start Sinatra/Puma on port 4567)
56
57
  ```
57
58
 
58
59
  Each phase calls `Legion::Readiness.mark_ready(:component)`. All phases are individually toggleable via `Service.new(transport: false, ...)`.
@@ -150,7 +151,7 @@ Legion (lib/legion.rb)
150
151
  │ # Populated by Builders::Routes during autobuild
151
152
 
152
153
  ├── MCP (legion-mcp gem) # Extracted to standalone gem — see legion-mcp/CLAUDE.md
153
- │ └── (41 tools, 2 resources, TierRouter, PatternStore, ContextGuard, Observer, EmbeddingIndex)
154
+ │ └── (58 tools, 2 resources, TierRouter, PatternStore, ContextGuard, Observer, EmbeddingIndex)
154
155
 
155
156
  ├── DigitalWorker # Digital worker platform (AI-as-labor governance)
156
157
  │ ├── Lifecycle # Worker state machine (active/paused/retired/terminated)
@@ -194,7 +195,7 @@ Legion (lib/legion.rb)
194
195
  │ ├── Session # Multi-turn chat session with streaming
195
196
  │ ├── SessionStore # Persistent session save/load/list/resume/fork
196
197
  │ ├── Permissions # Tool permission model (interactive/auto_approve/read_only)
197
- │ ├── ToolRegistry # Chat tool discovery and registration (40 built-in + extension tools)
198
+ │ ├── ToolRegistry # Chat tool discovery and registration (40 built-in tools + extension tools)
198
199
  │ ├── ExtensionTool # permission_tier DSL module for LEX chat tools (:read/:write/:shell)
199
200
  │ ├── ExtensionToolLoader # Lazy discovery of tools/ directories from loaded extensions
200
201
  │ ├── Context # Project awareness (git, language, instructions, extra dirs)
@@ -480,7 +481,7 @@ legion
480
481
 
481
482
  ### MCP Design
482
483
 
483
- Extracted to the `legion-mcp` gem (v0.5.5). See `legion-mcp/CLAUDE.md` for full architecture.
484
+ Extracted to the `legion-mcp` gem (v0.5.9). See `legion-mcp/CLAUDE.md` for full architecture.
484
485
 
485
486
  - `Legion::MCP.server` is memoized singleton — call `Legion::MCP.reset!` in tests
486
487
  - Tool naming: `legion.snake_case_name` (dot namespace, not slash)
@@ -768,7 +769,7 @@ rack-test, rake, rspec, rubocop, rubocop-rspec, simplecov
768
769
 
769
770
  ```bash
770
771
  bundle install
771
- bundle exec rspec # 3194 examples, 0 failures
772
+ bundle exec rspec # ~3500+ examples, 0 failures
772
773
  bundle exec rubocop # 0 offenses
773
774
  ```
774
775
 
data/README.md CHANGED
@@ -8,13 +8,13 @@ Schedule tasks, chain services into dependency graphs, run them concurrently via
8
8
  ╭──────────────────────────────────────╮
9
9
  │ L E G I O N I O │
10
10
  │ │
11
- │ 280+ extensions · 41 MCP tools │
11
+ │ 280+ extensions · 58 MCP tools │
12
12
  │ AI chat CLI · REST API · HA │
13
13
  │ cognitive architecture · Vault │
14
14
  ╰──────────────────────────────────────╯
15
15
  ```
16
16
 
17
- **Ruby >= 3.4** | **v1.4.197** | **Apache-2.0** | [@Esity](https://github.com/Esity)
17
+ **Ruby >= 3.4** | **v1.5.20** | **Apache-2.0** | [@Esity](https://github.com/Esity)
18
18
 
19
19
  ---
20
20
 
@@ -33,7 +33,7 @@ When A completes, B runs. B triggers C, D, and E in parallel. Conditions gate ex
33
33
  But that's just the foundation. LegionIO is also:
34
34
 
35
35
  - **An AI coding assistant** — interactive chat with tools, code review, commit messages, PR generation, and multi-agent workflows
36
- - **An MCP server** — 35 tools that let any AI agent run tasks, manage extensions, and query your infrastructure
36
+ - **An MCP server** — 58 tools that let any AI agent run tasks, manage extensions, and query your infrastructure
37
37
  - **A cognitive computing platform** — 242 brain-modeled extensions across 18 cognitive domains
38
38
  - **A digital worker platform** — AI-as-labor with governance, risk tiers, and cost tracking
39
39
 
@@ -49,7 +49,7 @@ For the AI features:
49
49
 
50
50
  ```bash
51
51
  legion # launch the interactive TTY shell
52
- legion chat # interactive AI REPL with 10 built-in tools
52
+ legion chat # interactive AI REPL with 40 built-in tools
53
53
  legion commit # AI-generated commit message from staged changes
54
54
  legion review # AI code review of your code
55
55
  ```
@@ -162,7 +162,7 @@ legion chat prompt "explain main.rb" # single-prompt mode
162
162
  echo "fix the bug" | legion chat prompt - # pipe from stdin
163
163
  ```
164
164
 
165
- **10 built-in tools**: read_file, write_file, edit_file, search_files, search_content, run_command, save_memory, search_memory, web_search, spawn_agent
165
+ **40 built-in tools**: read_file, write_file, edit_file, search_files, search_content, run_command, save_memory, search_memory, web_search, spawn_agent, search_traces, query_knowledge, ingest_knowledge, consolidate_memory, relate_knowledge, knowledge_maintenance, knowledge_stats, summarize_traces, list_extensions, manage_tasks, system_status, view_events, cost_summary, reflect, manage_schedules, worker_status, detect_anomalies, view_trends, trigger_dream, generate_insights, budget_status, provider_health, model_comparison, shadow_eval_status, entity_extract, arbitrage_status, escalation_status, graph_explore, scheduling_status, memory_status
166
166
 
167
167
  **Slash commands**: `/help` `/quit` `/cost` `/status` `/clear` `/new` `/save` `/load` `/sessions` `/compact` `/fetch URL` `/search QUERY` `/diff` `/copy` `/rewind` `/memory` `/agent` `/agents` `/plan` `/swarm` `/review` `/permissions` `/personality` `/model` `/edit` `/commit` `/workers` `/dream`
168
168
 
@@ -200,6 +200,39 @@ legion memory search "testing"
200
200
  legion memory forget 3
201
201
  ```
202
202
 
203
+ ### Knowledge
204
+
205
+ Query and manage the Apollo shared knowledge store and local knowledge index:
206
+
207
+ ```bash
208
+ legion knowledge query "how does transport routing work?"
209
+ legion knowledge retrieve "embedding cosine similarity" --scope global
210
+ legion knowledge ingest /path/to/docs/
211
+ legion knowledge status # index stats, embedding coverage
212
+ legion knowledge health # detect orphans, quality metrics
213
+ legion knowledge maintain # cleanup orphans, reindex
214
+ legion knowledge quality # quality report
215
+ ```
216
+
217
+ ### Mind Growth
218
+
219
+ Autonomous cognitive architecture expansion system. Analyzes gaps, proposes new cognitive extensions, and builds them via a staged pipeline:
220
+
221
+ ```bash
222
+ legion mind-growth status # current growth cycle state
223
+ legion mind-growth analyze # gap analysis against 5 reference models
224
+ legion mind-growth propose # propose a new concept
225
+ legion mind-growth evaluate <id> # evaluate a proposal
226
+ legion mind-growth build <id> # run staged build pipeline
227
+ legion mind-growth list # list proposals
228
+ legion mind-growth approve <id> # manually approve
229
+ legion mind-growth reject <id> # manually reject
230
+ legion mind-growth profile # cognitive profile across all models
231
+ legion mind-growth health # extension fitness validation
232
+ ```
233
+
234
+ Requires `lex-mind-growth`. Also exposes 6 MCP tools in the `legion.mind_growth_*` namespace.
235
+
203
236
  ### Digital Workers
204
237
 
205
238
  AI-as-labor with governance, risk tiers, and cost tracking:
@@ -326,7 +359,7 @@ legion mcp http # streamable HTTP on localhost:9393
326
359
  legion mcp http --port 8080 --host 0.0.0.0
327
360
  ```
328
361
 
329
- **41 tools** in the `legion.*` namespace:
362
+ **58 tools** in the `legion.*` namespace:
330
363
 
331
364
  | Category | Tools |
332
365
  |----------|-------|
@@ -340,6 +373,8 @@ legion mcp http --port 8080 --host 0.0.0.0
340
373
  | **Workers** | `list_workers`, `show_worker`, `worker_lifecycle`, `worker_costs`, `team_summary` |
341
374
  | **RBAC** | `rbac_assignments`, `rbac_check`, `rbac_grants` |
342
375
  | **Analytics** | `routing_stats` |
376
+ | **Knowledge** | `query_knowledge`, `knowledge_health` |
377
+ | **Mind Growth** | `mind_growth_status`, `mind_growth_analyze`, `mind_growth_propose`, `mind_growth_evaluate`, `mind_growth_build`, `mind_growth_profile` |
343
378
 
344
379
  **Resources**: `legion://runners` (full runner catalog), `legion://extensions/{name}` (extension detail)
345
380
 
@@ -475,19 +510,21 @@ Before any Legion code loads, the executable applies three performance optimizat
475
510
  ```
476
511
  legion start
477
512
  └── Legion::Service
478
- ├── 1. Logging (legion-logging)
479
- ├── 2. Settings (legion-settings — /etc/legionio, ~/legionio, ./settings)
480
- ├── 3. Crypt (legion-crypt — Vault connection)
481
- ├── 4. Transport (legion-transport — RabbitMQ)
482
- ├── 5. Cache (legion-cache — Redis/Memcached)
483
- ├── 6. Data (legion-data — database + migrations)
484
- ├── 7. RBAC (legion-rbac — optional role-based access control)
485
- ├── 8. LLM (legion-llm — AI provider setup + routing)
486
- ├── 9. GAIA (legion-gaiacognitive coordination layer)
487
- ├── 10. Supervision (process supervision)
488
- ├── 11. Extensions (discover + load 280+ LEX gems, filtered by role profile)
489
- ├── 12. Cluster Secret (distribute via Vault or memory)
490
- └── 13. API (Sinatra/Puma on port 4567)
513
+ ├── 1. Logging (legion-logging)
514
+ ├── 2. Settings (legion-settings — /etc/legionio, ~/legionio, ./settings)
515
+ ├── 3. Crypt (legion-crypt — Vault connection)
516
+ ├── 4. Transport (legion-transport — RabbitMQ)
517
+ ├── 5. Cache (legion-cache — Redis/Memcached)
518
+ ├── 6. Data (legion-data — database + migrations)
519
+ ├── 7. RBAC (legion-rbac — optional role-based access control)
520
+ ├── 8. LLM (legion-llm — AI provider setup + routing)
521
+ ├── 9. Apollo (legion-apolloshared/local knowledge store)
522
+ ├── 10. GAIA (legion-gaia — cognitive coordination layer)
523
+ ├── 11. Telemetry (OpenTelemetry optional)
524
+ ├── 12. Supervision (process supervision)
525
+ ├── 13. Extensions (two-phase parallel load: require+autobuild, then hook_all_actors)
526
+ ├── 14. Cluster Secret (distribute via Vault or memory)
527
+ └── 15. API (Sinatra/Puma on port 4567)
491
528
  ```
492
529
 
493
530
  Each phase registers with `Legion::Readiness`. All phases are individually toggleable.
@@ -2,6 +2,184 @@
2
2
 
3
3
  module Legion
4
4
  module CLI
5
+ class MonitorCommand < Thor
6
+ def self.exit_on_failure?
7
+ true
8
+ end
9
+
10
+ class_option :json, type: :boolean, default: false, desc: 'Output as JSON'
11
+ class_option :no_color, type: :boolean, default: false, desc: 'Disable color output'
12
+
13
+ desc 'add PATH', 'Add a directory to corpus monitors'
14
+ option :extensions, type: :string, desc: 'Comma-separated file extensions to watch (e.g. md,rb)'
15
+ option :label, type: :string, desc: 'Human-readable label for this monitor'
16
+ def add(path)
17
+ require_monitor!
18
+ exts = options[:extensions]&.split(',')&.map(&:strip)
19
+ result = Legion::Extensions::Knowledge::Runners::Monitor.add_monitor(
20
+ path: path,
21
+ extensions: exts,
22
+ label: options[:label]
23
+ )
24
+ out = formatter
25
+ if options[:json]
26
+ out.json(result)
27
+ elsif result[:success]
28
+ out.success("Monitor added: #{path}")
29
+ else
30
+ out.warn("Failed to add monitor: #{result[:error]}")
31
+ end
32
+ end
33
+
34
+ desc 'list', 'List registered corpus monitors'
35
+ def list
36
+ require_monitor!
37
+ monitors = Legion::Extensions::Knowledge::Runners::Monitor.list_monitors
38
+ out = formatter
39
+ if options[:json]
40
+ out.json(monitors)
41
+ elsif monitors.nil? || monitors.empty?
42
+ out.warn('No monitors registered')
43
+ else
44
+ out.header('Knowledge Monitors')
45
+ monitors.each do |m|
46
+ label = m[:label] ? " [#{m[:label]}]" : ''
47
+ exts = m[:extensions]&.join(', ')
48
+ puts " #{m[:path]}#{label}"
49
+ puts " Extensions: #{exts}" if exts && !exts.empty?
50
+ end
51
+ end
52
+ end
53
+ default_task :list
54
+
55
+ desc 'remove IDENTIFIER', 'Remove a corpus monitor by path or label'
56
+ def remove(identifier)
57
+ require_monitor!
58
+ result = Legion::Extensions::Knowledge::Runners::Monitor.remove_monitor(identifier:)
59
+ out = formatter
60
+ if options[:json]
61
+ out.json(result)
62
+ elsif result[:success]
63
+ out.success("Monitor removed: #{identifier}")
64
+ else
65
+ out.warn("Failed to remove monitor: #{result[:error]}")
66
+ end
67
+ end
68
+
69
+ desc 'status', 'Show monitor status (counts)'
70
+ def status
71
+ require_monitor!
72
+ result = Legion::Extensions::Knowledge::Runners::Monitor.monitor_status
73
+ out = formatter
74
+ if options[:json]
75
+ out.json(result)
76
+ else
77
+ out.header('Monitor Status')
78
+ out.detail({
79
+ 'Total monitors' => result[:total_monitors].to_s,
80
+ 'Total files' => result[:total_files].to_s
81
+ })
82
+ end
83
+ end
84
+
85
+ no_commands do
86
+ def formatter
87
+ @formatter ||= Output::Formatter.new(json: options[:json], color: !options[:no_color])
88
+ end
89
+
90
+ def require_monitor!
91
+ return if defined?(Legion::Extensions::Knowledge::Runners::Monitor)
92
+
93
+ raise CLI::Error, 'lex-knowledge extension is not loaded. Install and enable it first.'
94
+ end
95
+ end
96
+ end
97
+
98
+ class CaptureCommand < Thor
99
+ def self.exit_on_failure?
100
+ true
101
+ end
102
+
103
+ class_option :json, type: :boolean, default: false, desc: 'Output as JSON'
104
+ class_option :no_color, type: :boolean, default: false, desc: 'Disable color output'
105
+
106
+ desc 'commit', 'Capture the last git commit as knowledge'
107
+ def commit
108
+ log_line = `git log -1 --format='%H %s' 2>/dev/null`.strip
109
+ diff_stat = `git diff HEAD~1 --stat 2>/dev/null`.strip
110
+
111
+ if log_line.empty?
112
+ formatter.warn('No git commit found')
113
+ return
114
+ end
115
+
116
+ sha, *subject_parts = log_line.split
117
+ subject = subject_parts.join(' ')
118
+ content = "Git commit: #{sha}\nSubject: #{subject}\n\nDiff stat:\n#{diff_stat}"
119
+ tags = %w[git commit knowledge-capture]
120
+
121
+ result = if defined?(Legion::Extensions::Knowledge::Runners::Ingest)
122
+ Legion::Extensions::Knowledge::Runners::Ingest.ingest_file(
123
+ content: content,
124
+ tags: tags,
125
+ source: "git:#{sha}"
126
+ )
127
+ else
128
+ { success: false, error: 'lex-knowledge not loaded' }
129
+ end
130
+
131
+ out = formatter
132
+ if options[:json]
133
+ out.json(result)
134
+ elsif result[:success]
135
+ out.success("Captured commit #{sha[0, 8]}: #{subject}")
136
+ else
137
+ out.warn("Capture failed: #{result[:error]}")
138
+ end
139
+ end
140
+
141
+ desc 'session', 'Capture a session note from stdin'
142
+ def session
143
+ input = $stdin.gets(nil) if $stdin.ready? rescue nil # rubocop:disable Style/RescueModifier
144
+ input = input.to_s.strip
145
+
146
+ if input.empty?
147
+ formatter.warn('No session input provided (pipe text to stdin)')
148
+ return
149
+ end
150
+
151
+ repo = `git rev-parse --show-toplevel 2>/dev/null`.strip.split('/').last
152
+ content = "Session note (#{::Time.now.strftime('%Y-%m-%d')}):\n\n#{input}"
153
+ tags = ['session', 'knowledge-capture', ::Time.now.strftime('%Y-%m-%d')]
154
+ tags << "repo:#{repo}" unless repo.empty?
155
+
156
+ result = if defined?(Legion::Extensions::Knowledge::Runners::Ingest)
157
+ Legion::Extensions::Knowledge::Runners::Ingest.ingest_file(
158
+ content: content,
159
+ tags: tags,
160
+ source: "session:#{::Time.now.iso8601}"
161
+ )
162
+ else
163
+ { success: false, error: 'lex-knowledge not loaded' }
164
+ end
165
+
166
+ out = formatter
167
+ if options[:json]
168
+ out.json(result)
169
+ elsif result[:success]
170
+ out.success('Session captured')
171
+ else
172
+ out.warn("Capture failed: #{result[:error]}")
173
+ end
174
+ end
175
+
176
+ no_commands do
177
+ def formatter
178
+ @formatter ||= Output::Formatter.new(json: options[:json], color: !options[:no_color])
179
+ end
180
+ end
181
+ end
182
+
5
183
  class Knowledge < Thor
6
184
  def self.exit_on_failure?
7
185
  true
@@ -161,6 +339,12 @@ module Legion
161
339
  end
162
340
  end
163
341
 
342
+ desc 'monitor SUBCOMMAND', 'Manage knowledge corpus monitors'
343
+ subcommand 'monitor', MonitorCommand
344
+
345
+ desc 'capture SUBCOMMAND', 'Capture knowledge from git commits or sessions'
346
+ subcommand 'capture', CaptureCommand
347
+
164
348
  no_commands do # rubocop:disable Metrics/BlockLength
165
349
  def formatter
166
350
  @formatter ||= Output::Formatter.new(json: options[:json], color: !options[:no_color])
@@ -199,6 +383,9 @@ module Legion
199
383
  def resolve_corpus_path
200
384
  if options[:corpus_path]
201
385
  options[:corpus_path]
386
+ elsif defined?(Legion::Extensions::Knowledge::Runners::Monitor)
387
+ monitors = Legion::Extensions::Knowledge::Runners::Monitor.resolve_monitors
388
+ monitors.first&.dig(:path) || legacy_corpus_path || ::Dir.pwd
202
389
  elsif defined?(Legion::Settings)
203
390
  Legion::Settings.dig(:knowledge, :corpus_path) || ::Dir.pwd
204
391
  else
@@ -206,6 +393,12 @@ module Legion
206
393
  end
207
394
  end
208
395
 
396
+ def legacy_corpus_path
397
+ return unless defined?(Legion::Settings)
398
+
399
+ Legion::Settings.dig(:knowledge, :corpus_path)
400
+ end
401
+
209
402
  def print_sources(sources, out, verbose:)
210
403
  return out.warn('No sources found') if sources.empty?
211
404
 
@@ -78,6 +78,7 @@ module Legion
78
78
 
79
79
  install_claude_mcp(installed)
80
80
  install_claude_skill(installed)
81
+ install_claude_hooks(installed)
81
82
 
82
83
  if options[:json]
83
84
  out.json(platform: 'claude-code', installed: installed)
@@ -343,6 +344,43 @@ module Legion
343
344
  puts " Wrote slash command skill to #{skill_path}" unless options[:json]
344
345
  end
345
346
 
347
+ def install_claude_hooks(installed)
348
+ settings_path = File.expand_path('~/.claude/settings.json')
349
+ existing = load_json_file(settings_path)
350
+
351
+ hooks = existing['hooks'] || {}
352
+
353
+ has_commit = Array(hooks['PostToolUse']).any? { |h| h['command']&.include?('knowledge capture commit') }
354
+ has_session = Array(hooks['Stop']).any? { |h| h['command']&.include?('knowledge capture session') }
355
+ if has_commit && has_session && !options[:force]
356
+ puts ' Write-back hooks already present (use --force to overwrite)' unless options[:json]
357
+ return
358
+ end
359
+
360
+ hooks['PostToolUse'] ||= []
361
+ hooks['Stop'] ||= []
362
+
363
+ unless has_commit
364
+ hooks['PostToolUse'] << {
365
+ 'matcher' => 'Bash',
366
+ 'command' => 'legionio knowledge capture commit',
367
+ 'timeout' => 10_000
368
+ }
369
+ end
370
+
371
+ unless has_session
372
+ hooks['Stop'] << {
373
+ 'command' => 'legionio knowledge capture session',
374
+ 'timeout' => 15_000
375
+ }
376
+ end
377
+
378
+ existing['hooks'] = hooks
379
+ write_json_file(settings_path, existing)
380
+ installed << 'hooks'
381
+ puts ' Installed write-back hooks for knowledge capture' unless options[:json]
382
+ end
383
+
346
384
  def write_mcp_servers_json(_out, path, installed)
347
385
  existing = load_json_file(path)
348
386
  servers = existing['mcpServers'] || {}
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Legion
4
- VERSION = '1.5.23'
4
+ VERSION = '1.6.0'
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.5.23
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity