69 lines
2.0 KiB
Ruby
69 lines
2.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'json'
|
|
require 'fileutils'
|
|
require_relative '../file_locations'
|
|
require_relative '../file_verifier'
|
|
|
|
module PluginConfig
|
|
module Operations
|
|
class Base
|
|
attr_reader :plugin, :marketplace, :project, :marketplace_file
|
|
|
|
def initialize(params)
|
|
@plugin = params[:plugin]
|
|
@marketplace = params[:marketplace]
|
|
@project = params[:project]
|
|
@marketplace_file = params[:marketplace_file]
|
|
end
|
|
|
|
private
|
|
|
|
def plugin_key
|
|
"#{plugin}@#{resolved_marketplace}"
|
|
end
|
|
|
|
# The marketplace id this plugin is actually installed under, per
|
|
# installed_plugins.json, falling back to the --marketplace param when
|
|
# no installed entry exists yet (e.g. before first install). Needed
|
|
# because cc-os's os-* plugins install under a `local-plugins`
|
|
# marketplace (symlink into ~/.claude/plugins) rather than whatever
|
|
# marketplace id the caller assumes (e.g. the repo's own `cc-os`),
|
|
# which otherwise produces false "not installed" results.
|
|
def resolved_marketplace
|
|
data = read_json(installed_plugins_path)
|
|
if data && data['plugins']
|
|
match = data['plugins'].keys.find { |k| k.start_with?("#{plugin}@") }
|
|
return match.split('@', 2).last if match
|
|
end
|
|
marketplace
|
|
end
|
|
|
|
def read_json(path)
|
|
return nil unless File.exist?(path)
|
|
|
|
JSON.parse(File.read(path))
|
|
rescue JSON::ParserError
|
|
nil
|
|
end
|
|
|
|
def write_json(path, data)
|
|
FileUtils.mkdir_p(File.dirname(path))
|
|
content = JSON.pretty_generate(data, indent: ' ') + "\n"
|
|
File.write(path, content)
|
|
|
|
verifier = FileVerifier.new(path)
|
|
verifier.verify_written(content)
|
|
end
|
|
|
|
def settings_path
|
|
File.join(project, '.claude', 'settings.json')
|
|
end
|
|
|
|
def installed_plugins_path
|
|
File.join(Dir.home, '.claude', 'plugins', 'installed_plugins.json')
|
|
end
|
|
end
|
|
end
|
|
end
|