Module: EasyAI::Config::LocalConfig

Defined in:
lib/easyai/config/local_config.rb

Overview

本地配置门面:~/.easyai/config.json 的唯一读写入口

Defined Under Namespace

Classes: Error, IncompatibleVersionError, NotFoundError, ParseError, PlatformNotFoundError, ToolNotConfiguredError

Constant Summary collapse

SCHEMA_VERSION =
'2.0.0'
PLATFORM_DISPLAY_NAMES =
{
  'claude_official' => 'Claude 官方',
  'deepseek' => 'DeepSeek',
  'glm' => 'GLM(Coding Plan)',
  'kimi' => 'Kimi',
  'minimax' => 'MiniMax'
}.freeze

Class Method Summary collapse

Class Method Details

.available_platforms(tool) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/easyai/config/local_config.rb', line 72

def available_platforms(tool)
  return [] unless exists?

  cfg = load
  platforms = cfg.dig(tool, 'platforms')
  platforms.is_a?(Hash) ? platforms.keys : []
rescue Error
  []
end

.config_pathObject

注意:必须每次动态 expand_path,避免常量在加载期 freeze 路径,让 spec 中切换 ENV 后定位失败



23
24
25
# File 'lib/easyai/config/local_config.rb', line 23

def config_path
  File.expand_path('~/.easyai/config.json')
end

.delete_platform(tool, platform) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/easyai/config/local_config.rb', line 124

def delete_platform(tool, platform)
  return unless exists?

  cfg = load
  platforms = cfg.dig(tool, 'platforms')
  return cfg unless platforms.is_a?(Hash) && platforms.key?(platform)

  platforms.delete(platform)
  cfg.delete(tool) if platforms.empty?
  save(cfg)
  cfg
end

.exists?Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/easyai/config/local_config.rb', line 27

def exists?
  File.file?(config_path)
end

.loadObject

Raises:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/easyai/config/local_config.rb', line 31

def load
  path = config_path
  raise NotFoundError, "未找到本地配置文件 #{path},请运行 easyai setup" unless File.file?(path)

  raw = File.read(path)
  data = begin
    JSON.parse(raw)
  rescue JSON::ParserError => e
    raise ParseError,
          "配置解析失败 #{path}: #{e.message};可运行 easyai setup --reset 重新生成"
  end

  version = data['version']
  unless version == SCHEMA_VERSION
    raise IncompatibleVersionError,
          "配置版本 #{version.inspect} 不被支持,期望 #{SCHEMA_VERSION}"
  end

  data
end

.platform_display_name(key) ⇒ Object



68
69
70
# File 'lib/easyai/config/local_config.rb', line 68

def platform_display_name(key)
  PLATFORM_DISPLAY_NAMES.fetch(key, key)
end

.resolve_platform(tool:, platform: nil, verbose: false) {|platform_display_name(selected)| ... } ⇒ Object

解析平台配置。选定平台后会 yield 平台名(如果给了 block),让上层(AIToolBase)负责打印 UI 提示,保持 LocalConfig 的输出最小化。

Yields:



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/easyai/config/local_config.rb', line 84

def resolve_platform(tool:, platform: nil, verbose: false)
  cfg = load
  tool_cfg = cfg[tool]
  platforms = tool_cfg.is_a?(Hash) ? tool_cfg['platforms'] : nil
  if !platforms.is_a?(Hash) || platforms.empty?
    raise ToolNotConfiguredError,
          "工具 #{tool} 未配置任何平台,请运行 easyai setup --tool=#{tool}"
  end

  available = platforms.keys
  selected =
    if platform && !platform.empty?
      unless available.include?(platform)
        raise PlatformNotFoundError,
              "工具 #{tool} 未配置平台 #{platform}(可用:#{available.join(', ')}"
      end

      platform
    elsif available.size == 1
      only = available.first
      puts "使用平台 #{platform_display_name(only)}" if verbose
      only
    else
      interactive_select(tool, available)
    end

  yield(platform_display_name(selected)) if block_given?
  platforms[selected]
end

.save(cfg) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/easyai/config/local_config.rb', line 52

def save(cfg)
  path = config_path
  FileUtils.mkdir_p(File.dirname(path))
  File.write(path, JSON.pretty_generate(cfg))
  File.chmod(0o600, path) unless Gem.win_platform?
  path
end

.upsert_platform(tool, platform, data) ⇒ Object



114
115
116
117
118
119
120
121
122
# File 'lib/easyai/config/local_config.rb', line 114

def upsert_platform(tool, platform, data)
  cfg = exists? ? load : { 'version' => SCHEMA_VERSION }
  cfg['version'] ||= SCHEMA_VERSION
  cfg[tool] ||= { 'platforms' => {} }
  cfg[tool]['platforms'] ||= {}
  cfg[tool]['platforms'][platform] = data
  save(cfg)
  cfg
end