Module: Rails::Hyperdrive::InstallLayout
- Defined in:
- lib/rails/hyperdrive/install_layout.rb
Overview
The registry every artifact kind declares itself in, and the one place install paths and artifact names are built and parsed. Must stay require-free: the MCP server loads it and must not drag in the install machinery.
Defined Under Namespace
Constant Summary collapse
- SKILLS_DIR =
".claude/skills".freeze
- HYPERDRIVE_DIR =
".claude/hyperdrive".freeze
- AGENTS_DIR =
".claude/agents".freeze
- COMMANDS_DIR =
".claude/commands".freeze
- INDEX_PATH =
"#{HYPERDRIVE_DIR}/index.md".freeze
- LOCK_PATH =
".hyperdrive/lock.yml".freeze
- DEFAULT_TARGET =
:claude- KINDS =
{ skill: Kind.new( type: :skill, shape: :dir, section: "skills", key_label: "skill relpath", shipped_label: "skill directory", dir_key: "skills_dir", prefix_key: nil, convention_roots: ->(gem_name) { [File.join("lib", gem_name, "hyperdrive", "skills"), "skills"] }, identity: :frontmatter, frontmatter: :required, install_body: :verbatim, erb: true, collision_rewrites_name: true, eager: false, name_from_dest: ->(dest) { File.basename(File.dirname(dest)) }, dests: { claude: Dest.new(root: SKILLS_DIR, path: ->(name) { "#{SKILLS_DIR}/#{name}/SKILL.md" }) } ), skill_support: Kind.new( type: :skill_support, shape: nil, install_body: :verbatim, collision_rewrites_name: false, eager: false, name_from_dest: ->(dest) { dest.split("/")[2] }, # .claude/skills/<name>/<relpath> dests: {} ), guideline: Kind.new( type: :guideline, shape: :flat, section: "guidelines", key_label: "guideline filename", shipped_label: "guideline", dir_key: nil, prefix_key: nil, convention_roots: ->(gem_name) { [File.join("lib", gem_name, "hyperdrive", "guidelines")] }, identity: :frontmatter, frontmatter: :required, install_body: :strip_frontmatter, erb: true, collision_rewrites_name: false, eager: true, name_from_dest: ->(dest) { File.basename(dest, ".md") }, dests: { claude: Dest.new( root: HYPERDRIVE_DIR, path: ->(name) { "#{HYPERDRIVE_DIR}/guidelines/#{name}.md" } ) } ), agent: Kind.new( type: :agent, shape: :flat, section: "agents", key_label: "agent filename", shipped_label: "agent", dir_key: "agents_dir", prefix_key: nil, convention_roots: ->(_gem_name) { ["agents"] }, identity: :frontmatter, frontmatter: :required, install_body: :verbatim, erb: true, collision_rewrites_name: true, eager: false, name_from_dest: ->(dest) { File.basename(dest, ".md") }, dests: { claude: Dest.new(root: AGENTS_DIR, path: ->(name) { "#{AGENTS_DIR}/#{name}.md" }) } ), command: Kind.new( type: :command, shape: :flat, section: "commands", key_label: "command filename", shipped_label: "command", dir_key: "commands_dir", prefix_key: "command_prefix", convention_roots: ->(_gem_name) { ["commands"] }, identity: :filename_stem, frontmatter: :optional, install_body: :verbatim, erb: true, collision_rewrites_name: false, eager: false, name_from_dest: ->(dest) { File.basename(dest, ".md") }, dests: { claude: Dest.new(root: COMMANDS_DIR, path: ->(name) { "#{COMMANDS_DIR}/#{name}.md" }) } ) }.freeze
- ARTIFACT_TYPES =
KINDS.each_with_object({}) { |(type, kind), h| h[kind.lock_kind] = type }.freeze
Class Method Summary collapse
- .base_name(name) ⇒ Object
-
.content_kinds ⇒ Object
The kinds a companion gem ships, in install order.
- .dest_for(type, final_name, target: DEFAULT_TARGET) ⇒ Object
- .dest_roots(target: DEFAULT_TARGET) ⇒ Object
- .dir_keys ⇒ Object
- .installed_name(type, dest) ⇒ Object
- .kind(type) ⇒ Object
- .postfixed_name(name, source_gem) ⇒ Object
- .sidecar_path(dest) ⇒ Object
- .skill_dir_of(dest) ⇒ Object
Class Method Details
.base_name(name) ⇒ Object
184 185 186 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 184 def base_name(name) name.split("--").first.to_s end |
.content_kinds ⇒ Object
The kinds a companion gem ships, in install order.
151 152 153 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 151 def content_kinds KINDS.values.select(&:section) end |
.dest_for(type, final_name, target: DEFAULT_TARGET) ⇒ Object
163 164 165 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 163 def dest_for(type, final_name, target: DEFAULT_TARGET) KINDS[type]&.dest_for(final_name, target: target) end |
.dest_roots(target: DEFAULT_TARGET) ⇒ Object
159 160 161 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 159 def dest_roots(target: DEFAULT_TARGET) content_kinds.filter_map { |kind| kind.dests[target]&.root }.uniq end |
.dir_keys ⇒ Object
155 156 157 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 155 def dir_keys content_kinds.filter_map(&:dir_key) end |
.installed_name(type, dest) ⇒ Object
171 172 173 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 171 def installed_name(type, dest) KINDS[type]&.installed_name(dest) end |
.kind(type) ⇒ Object
146 147 148 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 146 def kind(type) KINDS[type] end |
.postfixed_name(name, source_gem) ⇒ Object
180 181 182 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 180 def postfixed_name(name, source_gem) "#{name}--#{source_gem}" end |
.sidecar_path(dest) ⇒ Object
167 168 169 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 167 def sidecar_path(dest) "#{dest}.new" end |
.skill_dir_of(dest) ⇒ Object
175 176 177 178 |
# File 'lib/rails/hyperdrive/install_layout.rb', line 175 def skill_dir_of(dest) segments = dest.split("/") File.join(*segments[0, 3]) # .claude/skills/<name> end |