Class: KairosMcp::PluginProjector::HostProfile

Inherits:
Object
  • Object
show all
Defined in:
lib/kairos_mcp/plugin_projector.rb

Overview

Host-specific projection profile (2026-07-02, Codex support). Encapsulates per-host layout / context-file / instruction-mode delivery differences so the projection engine stays host-agnostic. See log/20260702_codex_projection_and_mcp_reviewer_implementation_plan.md

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key:, output_subdir:, context_file:, instruction_mode_delivery:, manifest_suffix:, hooks_strategy:, skill_projection:, agents_subdir:, agents_format:) ⇒ HostProfile

Returns a new instance of HostProfile.

Parameters:

  • skill_projection (Symbol)

    :own (project skills into this host) or :reuse_claude (host reads .claude/skills/ directly — skip skill projection).

  • agents_subdir (String)

    subdir under output_root for agents ('agents' or 'agent').

  • agents_format (Symbol)

    :claude (verbatim) or :opencode (frontmatter converted).



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/kairos_mcp/plugin_projector.rb', line 45

def initialize(key:, output_subdir:, context_file:, instruction_mode_delivery:, manifest_suffix:,
               hooks_strategy:, skill_projection:, agents_subdir:, agents_format:)
  @key = key
  @output_subdir = output_subdir
  @context_file = context_file
  @instruction_mode_delivery = instruction_mode_delivery
  @manifest_suffix = manifest_suffix
  @hooks_strategy = hooks_strategy
  @skill_projection = skill_projection
  @agents_subdir = agents_subdir
  @agents_format = agents_format
end

Instance Attribute Details

#agents_formatObject (readonly)

Returns the value of attribute agents_format.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def agents_format
  @agents_format
end

#agents_subdirObject (readonly)

Returns the value of attribute agents_subdir.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def agents_subdir
  @agents_subdir
end

#context_fileObject (readonly)

Returns the value of attribute context_file.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def context_file
  @context_file
end

#hooks_strategyObject (readonly)

Returns the value of attribute hooks_strategy.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def hooks_strategy
  @hooks_strategy
end

#instruction_mode_deliveryObject (readonly)

Returns the value of attribute instruction_mode_delivery.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def instruction_mode_delivery
  @instruction_mode_delivery
end

#keyObject (readonly)

Returns the value of attribute key.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def key
  @key
end

#manifest_suffixObject (readonly)

Returns the value of attribute manifest_suffix.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def manifest_suffix
  @manifest_suffix
end

#output_subdirObject (readonly)

Returns the value of attribute output_subdir.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def output_subdir
  @output_subdir
end

#skill_projectionObject (readonly)

Returns the value of attribute skill_projection.



38
39
40
# File 'lib/kairos_mcp/plugin_projector.rb', line 38

def skill_projection
  @skill_projection
end

Class Method Details

.claude_codeObject

Claude Code: .claude/ layout, CLAUDE.md with @-import pointer, hooks in settings.json.



64
65
66
67
68
69
# File 'lib/kairos_mcp/plugin_projector.rb', line 64

def self.claude_code
  new(key: 'claude', output_subdir: '.claude', context_file: 'CLAUDE.md',
      instruction_mode_delivery: :import, manifest_suffix: nil,
      hooks_strategy: :claude_settings,
      skill_projection: :own, agents_subdir: 'agents', agents_format: :claude)
end

.codexObject

Codex CLI: .codex/ layout, AGENTS.md with inlined body (Codex does not resolve @-import). Hooks go to /.codex/hooks.json — same event structure as Claude, read natively by Codex.



73
74
75
76
77
78
# File 'lib/kairos_mcp/plugin_projector.rb', line 73

def self.codex
  new(key: 'codex', output_subdir: '.codex', context_file: 'AGENTS.md',
      instruction_mode_delivery: :inline, manifest_suffix: 'codex',
      hooks_strategy: :codex_hooks_json,
      skill_projection: :own, agents_subdir: 'agents', agents_format: :claude)
end

.for(host) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/kairos_mcp/plugin_projector.rb', line 90

def self.for(host)
  return host if host.is_a?(HostProfile)
  case host.to_s
  when 'claude', 'claude_code', 'claude-code' then claude_code
  when 'codex' then codex
  when 'opencode', 'open-code' then opencode
  else raise ArgumentError, "unknown projection host: #{host.inspect}"
  end
end

.opencodeObject

OpenCode: reads .claude/skills/ natively, so skills are NOT re-projected (Claude co-use assumption). AGENTS.md carries the inlined mode body (shared with Codex). Agents convert to .opencode/agent/ with OpenCode frontmatter. Hooks are JS/TS plugins → skipped.



83
84
85
86
87
88
# File 'lib/kairos_mcp/plugin_projector.rb', line 83

def self.opencode
  new(key: 'opencode', output_subdir: '.opencode', context_file: 'AGENTS.md',
      instruction_mode_delivery: :inline, manifest_suffix: 'opencode',
      hooks_strategy: :opencode_plugin,
      skill_projection: :reuse_claude, agents_subdir: 'agent', agents_format: :opencode)
end

Instance Method Details

#manifest_filename(base) ⇒ Object

Legacy manifest names carry no suffix so existing .kairos/ manifests keep working.



59
60
61
# File 'lib/kairos_mcp/plugin_projector.rb', line 59

def manifest_filename(base)
  @manifest_suffix ? "#{base}.#{@manifest_suffix}.json" : "#{base}.json"
end