kairos-chain 3.12.0 → 3.14.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/bin/kairos-chain +18 -0
  4. data/bin/kairos-plugin-project +57 -0
  5. data/lib/kairos_mcp/initializer.rb +57 -2
  6. data/lib/kairos_mcp/plugin_projector.rb +433 -0
  7. data/lib/kairos_mcp/protocol.rb +57 -0
  8. data/lib/kairos_mcp/skillset.rb +11 -0
  9. data/lib/kairos_mcp/tools/system_upgrade.rb +22 -0
  10. data/lib/kairos_mcp/version.rb +1 -1
  11. data/lib/kairos_mcp.rb +48 -0
  12. data/templates/skillsets/agent/config/agent.yml +14 -0
  13. data/templates/skillsets/agent/lib/agent/session.rb +31 -0
  14. data/templates/skillsets/agent/plugin/SKILL.md +33 -0
  15. data/templates/skillsets/agent/plugin/agents/monitor.md +23 -0
  16. data/templates/skillsets/agent/skillset.json +5 -1
  17. data/templates/skillsets/agent/test/test_agent_complexity_review.rb +585 -0
  18. data/templates/skillsets/agent/tools/agent_step.rb +429 -1
  19. data/templates/skillsets/llm_client/lib/llm_client/claude_code_adapter.rb +24 -3
  20. data/templates/skillsets/llm_client/tools/llm_call.rb +6 -3
  21. data/templates/skillsets/plugin_projector/lib/plugin_projector.rb +18 -0
  22. data/templates/skillsets/plugin_projector/plugin/SKILL.md +34 -0
  23. data/templates/skillsets/plugin_projector/plugin/hooks.json +13 -0
  24. data/templates/skillsets/plugin_projector/skillset.json +19 -0
  25. data/templates/skillsets/plugin_projector/tools/plugin_project.rb +96 -0
  26. data/templates/skillsets/skillset_creator/lib/skillset_creator/scaffold_generator.rb +43 -7
  27. data/templates/skillsets/skillset_creator/plugin/SKILL.md +30 -0
  28. data/templates/skillsets/skillset_creator/skillset.json +4 -1
  29. data/templates/skillsets/skillset_creator/tools/sc_scaffold.rb +9 -2
  30. data/templates/skillsets/skillset_exchange/plugin/SKILL.md +40 -0
  31. data/templates/skillsets/skillset_exchange/plugin/agents/reviewer.md +24 -0
  32. data/templates/skillsets/skillset_exchange/plugin/hooks.json +13 -0
  33. data/templates/skillsets/skillset_exchange/skillset.json +6 -1
  34. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e4f14b45f5ece26ac4279095f818d8772efcf5ae0d1dfb95924e2f69a2c2bcc
4
- data.tar.gz: a51ac4d001f7e5c5c17491fdb168da11b04d17502972d80d1119ac99f2243acf
3
+ metadata.gz: 59afbb969508bd1ec45bb4d35f28cd70cc84516d88ba5dc047c07f056bc70a0b
4
+ data.tar.gz: 8dff4c368684c5de32a6691fe2c7c2edf0adbed7a3114211ee4343583ae5b67a
5
5
  SHA512:
6
- metadata.gz: 0cb3cba2544bbb1244945199b783db04da81573dfde6d45d8c1c46d0c310e0fe26e9c521b7983263e66ec2d363c5614f630336ecdd10af056ca3ea9cb8b5ccf6
7
- data.tar.gz: 64ef0f93ebc9922c5acc8bbc6f0733734e9be5445c810f51f1c2b4f55c975764f39277bf07d48a5d1477010fdb7b1c7dfe9452f88bcf3db0ed8bbd1339caf3f9
6
+ metadata.gz: 93131bc0d3ced8749a875ed0a316ec1107ef6a9ecfed61cb5a6f111c2bad6b5331884bc55d2669b2223730c8153c4754bc2209c5d39adf374dc4fba2272eb515
7
+ data.tar.gz: a2358fedff75942a10b73223c8b2e43f6d8f68b3d976be256c580682363e4cf3eae7052ce68f2707f04454cbf2317e46e8f28319d28b82aa789ed7849d353d32
data/CHANGELOG.md CHANGED
@@ -4,6 +4,92 @@ All notable changes to the `kairos-chain` gem will be documented in this file.
4
4
 
5
5
  This project follows [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [3.14.0] - 2026-04-12
8
+
9
+ ### Added
10
+
11
+ - **SkillSet Plugin Projection** — Self-referential dual-mode Claude Code integration.
12
+ Projects SkillSet artifacts (skills, agents, hooks) to `.claude/` structure.
13
+ - **PluginProjector** (`plugin_projector.rb`, ~430 lines): dual-mode (Project + Plugin),
14
+ atomic writes, digest-based no-op, manifest tracking, stale cleanup
15
+ - **Ruby introspection**: `<!-- AUTO_TOOLS -->` marker dynamically generates tool docs
16
+ - **L1 knowledge meta skill**: `<!-- AUTO_KNOWLEDGE_LIST -->` projects knowledge catalog
17
+ - **Self-referential SkillSet**: `plugin_projector` projects its own SKILL.md and hooks
18
+ - **Auto-init + auto-install**: first MCP connection initializes `.kairos/` and installs
19
+ 9 core SkillSets (no external dependencies)
20
+ - **Auto-generate `.mcp.json`**: `kairos-chain init` creates MCP config with absolute paths
21
+ - **Plugin artifacts for 3 SkillSets**: agent (SKILL.md + monitor agent),
22
+ skillset_exchange (SKILL.md + reviewer agent + hooks), skillset_creator (SKILL.md)
23
+ - **Scaffold `has_plugin` option**: `sc_scaffold` generates `plugin/` directory
24
+ - **Auto-projection on upgrade**: `system_upgrade apply` and `skillset upgrade --apply`
25
+ trigger re-projection after SkillSet changes
26
+ - **Security**: SAFE_NAME_PATTERN, safe_path boundary checks, ALLOWED_HOOK_COMMANDS warning,
27
+ atomic writes for settings.json auto-reload safety
28
+ - **30 tests**, 3-LLM reviewed (Claude Opus 4.6 + Codex GPT-5.4 + Cursor Composer-2)
29
+
30
+ - **2-step setup**: `kairos-chain init` + `claude` (no manual system_upgrade needed)
31
+
32
+ ### Changed
33
+
34
+ - **Seed `skills/kairos-chain/SKILL.md`**: revised to delegate per-SkillSet workflow details
35
+ to individual SKILL.md files (agent, skillset_exchange, etc.)
36
+ - **`collect_knowledge_entries`**: extracted to `KairosMcp` module (shared by protocol.rb,
37
+ plugin_project tool, and CLI)
38
+ - **Core SkillSets**: auto-install limited to 9 SkillSets without external dependencies
39
+ (excludes multiuser/PostgreSQL, hestia/networking, etc.)
40
+
41
+ ### Fixed
42
+
43
+ - **`.mcp.json` absolute paths**: relative `--data-dir` paths caused MCP connection failures
44
+ when Claude Code resolved from different working directory
45
+ - **Non-Claude clients**: projection skipped when `.claude/` directory doesn't exist,
46
+ preventing unintended artifact creation for Cursor/Codex
47
+
48
+ ## [3.13.0] - 2026-04-02
49
+
50
+ ### Added
51
+
52
+ - **Complexity-driven review for Agent auto mode** — New Gate 5.5a/b (pre-ACT) and
53
+ Gate 6.5 (post-ACT) in the Agent autonomous OODA loop.
54
+ - **Structural complexity assessment** with 7 signals: `high_risk`, `many_steps`,
55
+ `design_scope`, `l0_change`, `core_files`, `multi_file`, `state_mutation`
56
+ - **LLM self-assessment merge**: DECIDE prompt requests `complexity_hint`; merge rule
57
+ caps LLM at structural + 1 level (prevents over-reporting)
58
+ - **Gate 5.5a**: L0 changes always checkpoint with multi-LLM review prompt generation
59
+ - **Gate 5.5b**: High complexity triggers Persona Assembly review (inner retry loop
60
+ with max re-DECIDE attempts, risk/loop/complexity re-checks per revision)
61
+ - **Gate 6.5**: Medium complexity runs post-ACT lightweight advisory review
62
+ - Low complexity: no overhead (unchanged flow)
63
+ - Parse failures default to REVISE (never silent APPROVE)
64
+ - Persona definitions loaded from L1 knowledge with hardcoded fallback
65
+ - Configuration: `complexity_review` section in `agent.yml` (personas, retries,
66
+ L0 checkpoint policy, post-ACT toggle)
67
+ - New `review` phase config in `agent.yml` (max_llm_calls, max_tool_calls)
68
+ - Session: `save_review_result`, `load_review_result`, `save_progress_amendment`
69
+ - Tests: 37 new (complexity assessment, persona review parsing, config, session, prompts)
70
+
71
+ ### Fixed
72
+
73
+ - **`llm_call.rb` eager adapter loading** — All provider adapters were unconditionally
74
+ required at startup, crashing with `LoadError` when optional gems (`faraday`,
75
+ `aws-sdk`) were not installed. Now lazy-loads adapters in `build_adapter()`;
76
+ only `claude_code_adapter` and base modules loaded at startup.
77
+ - **`claude_code_adapter` recursive MCP server loading** — `claude -p` subprocess
78
+ loaded `.mcp.json` and spawned additional MCP server instances, causing deadlocks
79
+ (stdio) or port conflicts (HTTP). Fixed with `--mcp-config '{"mcpServers":{}}'`
80
+ and `--no-session-persistence`.
81
+ - **`claude_code_adapter` missing timeout** — `Open3.capture3` had no timeout,
82
+ risking indefinite hangs. Wrapped with `Timeout.timeout` (default 120s,
83
+ configurable via `timeout_seconds` in `llm_client.yml`).
84
+
85
+ ### Design Process
86
+
87
+ - Complexity review design: 2R x 2 LLMs (Claude Team, Cursor Composer) → APPROVED
88
+ - Complexity review impl: R1 x 3 LLMs (Claude Team, Cursor, Codex) → fixes applied
89
+ - Codex found off-by-one in retry counter and cycle number (both fixed)
90
+ - R2 (Claude Team) → APPROVED
91
+ - llm_client fixes: reported by SUSHI self-maintenance MCP project, verified in upstream
92
+
7
93
  ## [3.12.0] - 2026-04-02
8
94
 
9
95
  ### Added
data/bin/kairos-chain CHANGED
@@ -143,6 +143,24 @@ when 'skillset'
143
143
  puts "Updated #{r[:name]}: v#{r[:from]} -> v#{r[:to]} (#{r[:files_updated]} files)"
144
144
  end
145
145
  puts "Done. #{results.size} SkillSet(s) upgraded."
146
+
147
+ # Re-project plugin artifacts if any SkillSets changed
148
+ if results.any?
149
+ begin
150
+ require 'kairos_mcp/plugin_projector'
151
+ project_root = KairosMcp.project_root
152
+ mode = KairosMcp.projection_mode
153
+ projector = KairosMcp::PluginProjector.new(project_root, mode: mode)
154
+ enabled = manager.enabled_skillsets
155
+ knowledge = KairosMcp.collect_knowledge_entries
156
+ if projector.project_if_changed!(enabled, knowledge_entries: knowledge)
157
+ puts "Plugin artifacts projected. Run /reload-plugins in Claude Code."
158
+ end
159
+ rescue => e
160
+ # Non-fatal: projection is optional
161
+ $stderr.puts "Plugin projection skipped: #{e.message}"
162
+ end
163
+ end
146
164
  else
147
165
  puts "SkillSet upgrades available:"
148
166
  puts ""
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # CLI script for plugin projection.
5
+ # Used by Claude Code hooks and manual invocation.
6
+ #
7
+ # Usage:
8
+ # kairos-plugin-project # Full projection
9
+ # kairos-plugin-project --if-changed # Skip if digest unchanged
10
+ # kairos-plugin-project --json # Output additionalContext JSON
11
+ # kairos-plugin-project --status # Show projection status
12
+ # kairos-plugin-project --verify # Verify projected files
13
+
14
+ require_relative '../lib/kairos_mcp'
15
+ require_relative '../lib/kairos_mcp/plugin_projector'
16
+ require_relative '../lib/kairos_mcp/skillset_manager'
17
+
18
+ project_root = KairosMcp.project_root
19
+ mode = KairosMcp.projection_mode
20
+ projector = KairosMcp::PluginProjector.new(project_root, mode: mode)
21
+
22
+ if ARGV.include?('--status')
23
+ require 'json'
24
+ puts JSON.pretty_generate(projector.status)
25
+ exit 0
26
+ end
27
+
28
+ if ARGV.include?('--verify')
29
+ require 'json'
30
+ result = projector.verify
31
+ puts JSON.pretty_generate(result)
32
+ exit(result[:valid] ? 0 : 1)
33
+ end
34
+
35
+ manager = KairosMcp::SkillSetManager.new
36
+ enabled = manager.enabled_skillsets
37
+ knowledge_entries = KairosMcp.collect_knowledge_entries
38
+
39
+ json_mode = ARGV.include?('--json')
40
+
41
+ if ARGV.include?('--if-changed')
42
+ changed = projector.project_if_changed!(enabled, knowledge_entries: knowledge_entries)
43
+ if changed
44
+ if json_mode
45
+ puts '{"additionalContext": "Plugin projection updated. Run /reload-plugins to activate new skills."}'
46
+ else
47
+ $stderr.puts "Plugin projection updated. Run /reload-plugins to activate new skills."
48
+ end
49
+ end
50
+ else
51
+ projector.project!(enabled, knowledge_entries: knowledge_entries)
52
+ if json_mode
53
+ puts '{"additionalContext": "Plugin projection complete. Run /reload-plugins to activate."}'
54
+ else
55
+ $stderr.puts "Plugin projection complete."
56
+ end
57
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'digest'
5
+ require 'json'
5
6
  require 'yaml'
6
7
  require 'time'
7
8
  require_relative '../kairos_mcp'
@@ -51,7 +52,8 @@ module KairosMcp
51
52
  copy_templates
52
53
  copy_knowledge_templates
53
54
  write_meta
54
-
55
+ generate_mcp_json unless @quiet
56
+
55
57
  log ""
56
58
  log "KairosChain data directory initialized successfully!"
57
59
  log ""
@@ -61,7 +63,7 @@ module KairosMcp
61
63
  log " kairos-chain # stdio mode (for Claude Code / Cursor)"
62
64
  log " kairos-chain --http # HTTP mode (for remote)"
63
65
  log ""
64
- print_mcp_config
66
+ print_mcp_config unless @generated_mcp_json
65
67
  end
66
68
 
67
69
  private
@@ -190,6 +192,59 @@ module KairosMcp
190
192
  log " }"
191
193
  end
192
194
 
195
+ # Generate .mcp.json in the project root (parent of .kairos/)
196
+ def generate_mcp_json
197
+ @generated_mcp_json = false
198
+ project_root = File.dirname(@data_dir)
199
+ mcp_json_path = File.join(project_root, '.mcp.json')
200
+ data_dir_absolute = File.expand_path(@data_dir)
201
+
202
+ mcp_content = JSON.pretty_generate({
203
+ "mcpServers" => {
204
+ "kairos-chain" => {
205
+ "command" => "kairos-chain",
206
+ "args" => ["--data-dir", data_dir_absolute]
207
+ }
208
+ }
209
+ })
210
+
211
+ if File.exist?(mcp_json_path)
212
+ existing = File.read(mcp_json_path)
213
+ if existing.include?('kairos-chain')
214
+ log " .mcp.json: kairos-chain already configured (skipped)"
215
+ @generated_mcp_json = true
216
+ return
217
+ end
218
+
219
+ # .mcp.json exists but doesn't have kairos-chain
220
+ $stderr.puts ""
221
+ $stderr.puts " .mcp.json already exists at: #{mcp_json_path}"
222
+ $stderr.puts " Add kairos-chain MCP server to it? (y/N): "
223
+ answer = $stdin.gets&.strip
224
+ if answer&.downcase == 'y'
225
+ begin
226
+ existing_json = JSON.parse(existing)
227
+ existing_json['mcpServers'] ||= {}
228
+ existing_json['mcpServers']['kairos-chain'] = {
229
+ 'command' => 'kairos-chain',
230
+ 'args' => ['--data-dir', data_dir_absolute]
231
+ }
232
+ File.write(mcp_json_path, JSON.pretty_generate(existing_json) + "\n")
233
+ log " .mcp.json: kairos-chain added to existing configuration"
234
+ @generated_mcp_json = true
235
+ rescue JSON::ParserError
236
+ log " .mcp.json: invalid JSON, skipping. Please add kairos-chain manually."
237
+ end
238
+ else
239
+ log " .mcp.json: skipped. Add kairos-chain manually (see below)."
240
+ end
241
+ else
242
+ File.write(mcp_json_path, mcp_content + "\n")
243
+ log " .mcp.json: created with kairos-chain MCP server configuration"
244
+ @generated_mcp_json = true
245
+ end
246
+ end
247
+
193
248
  def relative_path(path)
194
249
  path.sub("#{@data_dir}/", '')
195
250
  end