agent-context 0.0.1 → 0.1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/agent.md +37 -0
- data/bake/agent/context.rb +23 -10
- data/context/usage.md +173 -0
- data/lib/agent/context/index.rb +322 -0
- data/lib/agent/context/installer.rb +270 -0
- data/lib/agent/context/version.rb +2 -1
- data/lib/agent/context.rb +9 -1
- data/license.md +1 -0
- data/post.md +149 -0
- data/readme.md +110 -25
- data/specification.md +176 -0
- data.tar.gz.sig +0 -0
- metadata +22 -7
- metadata.gz.sig +0 -0
- data/context/adding-context.mdc +0 -166
- data/context/examples.mdc +0 -92
- data/context/getting-started.mdc +0 -56
- data/context/markdown-context.mdc +0 -91
- data/design.md +0 -149
- data/lib/agent/context/helper.rb +0 -113
@@ -0,0 +1,270 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Shopify Inc.
|
5
|
+
# Copyright, 2025, by Samuel Williams.
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
require "fileutils"
|
9
|
+
require "pathname"
|
10
|
+
require "yaml"
|
11
|
+
|
12
|
+
module Agent
|
13
|
+
module Context
|
14
|
+
# Installer class for managing context files from Ruby gems.
|
15
|
+
#
|
16
|
+
# This class provides methods to find, list, show, and install context files
|
17
|
+
# from gems that provide them in a `context/` directory.
|
18
|
+
class Installer
|
19
|
+
CANONICAL_ORDER = [
|
20
|
+
"getting-started",
|
21
|
+
"overview",
|
22
|
+
"usage",
|
23
|
+
"configuration",
|
24
|
+
"migration",
|
25
|
+
"troubleshooting",
|
26
|
+
"debugging"
|
27
|
+
]
|
28
|
+
|
29
|
+
# Initialize a new Helper instance.
|
30
|
+
#
|
31
|
+
# @parameter root [String] The root directory to work from (default: current directory).
|
32
|
+
# @parameter specifications [Gem::Specification] The gem specifications to search (default: all installed gems).
|
33
|
+
def initialize(root: Dir.pwd, specifications: ::Gem::Specification)
|
34
|
+
@root = root
|
35
|
+
@context_path = ".context"
|
36
|
+
@specifications = specifications
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :context_path
|
40
|
+
|
41
|
+
# Find all gems that have a context directory
|
42
|
+
def find_gems_with_context(skip_local: true)
|
43
|
+
gems_with_context = []
|
44
|
+
|
45
|
+
@specifications.each do |spec|
|
46
|
+
# Skip gems loaded from current working directory if requested:
|
47
|
+
next if skip_local && spec.full_gem_path == @root
|
48
|
+
|
49
|
+
context_path = File.join(spec.full_gem_path, "context")
|
50
|
+
if Dir.exist?(context_path)
|
51
|
+
gems_with_context << {
|
52
|
+
name: spec.name,
|
53
|
+
version: spec.version.to_s,
|
54
|
+
summary: spec.summary,
|
55
|
+
metadata: spec.metadata,
|
56
|
+
path: context_path
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
gems_with_context
|
62
|
+
end
|
63
|
+
|
64
|
+
# Find a specific gem with context.
|
65
|
+
def find_gem_with_context(gem_name)
|
66
|
+
spec = @specifications.find { |s| s.name == gem_name }
|
67
|
+
return nil unless spec
|
68
|
+
|
69
|
+
context_path = File.join(spec.full_gem_path, "context")
|
70
|
+
|
71
|
+
if Dir.exist?(context_path)
|
72
|
+
{
|
73
|
+
name: spec.name,
|
74
|
+
version: spec.version.to_s,
|
75
|
+
summary: spec.summary,
|
76
|
+
metadata: spec.metadata,
|
77
|
+
path: context_path
|
78
|
+
}
|
79
|
+
else
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# List context files for a gem.
|
85
|
+
def list_context_files(gem_name)
|
86
|
+
gem = find_gem_with_context(gem_name)
|
87
|
+
return nil unless gem
|
88
|
+
|
89
|
+
Dir.glob(File.join(gem[:path], "**/*")).select { |f| File.file?(f) }
|
90
|
+
end
|
91
|
+
|
92
|
+
# Show content of a specific context file.
|
93
|
+
def show_context_file(gem_name, file_name)
|
94
|
+
gem = find_gem_with_context(gem_name)
|
95
|
+
return nil unless gem
|
96
|
+
|
97
|
+
# Try to find the file with or without extension:
|
98
|
+
possible_paths = [
|
99
|
+
File.join(gem[:path], file_name),
|
100
|
+
File.join(gem[:path], "#{file_name}.md"),
|
101
|
+
File.join(gem[:path], "#{file_name}.md")
|
102
|
+
]
|
103
|
+
|
104
|
+
file_path = possible_paths.find { |path| File.exist?(path) }
|
105
|
+
return nil unless file_path
|
106
|
+
|
107
|
+
File.read(file_path)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Install context from a specific gem.
|
111
|
+
def install_gem_context(gem_name)
|
112
|
+
gem = find_gem_with_context(gem_name)
|
113
|
+
return false unless gem
|
114
|
+
|
115
|
+
target_path = File.join(@context_path, gem_name)
|
116
|
+
|
117
|
+
# Remove old package directory if it exists to ensure clean install
|
118
|
+
FileUtils.rm_rf(target_path) if Dir.exist?(target_path)
|
119
|
+
|
120
|
+
FileUtils.mkdir_p(target_path)
|
121
|
+
|
122
|
+
# Copy all files from the gem's context directory:
|
123
|
+
FileUtils.cp_r(File.join(gem[:path], "."), target_path)
|
124
|
+
|
125
|
+
# Generate index.yaml if it doesn't exist, passing the full gem hash
|
126
|
+
ensure_gem_index(gem, target_path)
|
127
|
+
|
128
|
+
true
|
129
|
+
end
|
130
|
+
|
131
|
+
# Install context from all gems.
|
132
|
+
def install_all_context(skip_local: true)
|
133
|
+
gems = find_gems_with_context(skip_local: skip_local)
|
134
|
+
installed = []
|
135
|
+
|
136
|
+
gems.each do |gem|
|
137
|
+
if install_gem_context(gem[:name])
|
138
|
+
installed << gem[:name]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
installed
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
# Generate a dynamic index from gemspec when no index.yaml is present
|
148
|
+
def generate_dynamic_index(gem, gem_directory)
|
149
|
+
# Collect all markdown files
|
150
|
+
markdown_files = Dir.glob(File.join(gem_directory, "**", "*.md")).sort
|
151
|
+
|
152
|
+
# Sort files: canonical first, then alpha
|
153
|
+
files_sorted = markdown_files.sort_by do |file_path|
|
154
|
+
base_filename = File.basename(file_path, ".md").downcase
|
155
|
+
canonical_index = CANONICAL_ORDER.index(base_filename)
|
156
|
+
[canonical_index ? CANONICAL_ORDER.index(base_filename) : CANONICAL_ORDER.length, base_filename]
|
157
|
+
end
|
158
|
+
|
159
|
+
files = []
|
160
|
+
files_sorted.each do |file_path|
|
161
|
+
next if File.basename(file_path) == "index.yaml" # Skip the index file itself
|
162
|
+
title, description = extract_content(file_path)
|
163
|
+
relative_path = file_path.sub("#{gem_directory}/", "")
|
164
|
+
files << {
|
165
|
+
"path" => relative_path,
|
166
|
+
"title" => title,
|
167
|
+
"description" => description
|
168
|
+
}
|
169
|
+
end
|
170
|
+
|
171
|
+
{
|
172
|
+
"description" => gem[:summary] || "Context files for #{gem[:name]}",
|
173
|
+
"version" => gem[:version],
|
174
|
+
"metadata" => gem[:metadata],
|
175
|
+
"files" => files
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
# Check if a gem has an index.yaml file, generate one if not
|
180
|
+
def ensure_gem_index(gem, gem_directory)
|
181
|
+
index_path = File.join(gem_directory, "index.yaml")
|
182
|
+
|
183
|
+
unless File.exist?(index_path)
|
184
|
+
# Generate dynamic index from gemspec
|
185
|
+
index = generate_dynamic_index(gem, gem_directory)
|
186
|
+
|
187
|
+
# Write the generated index
|
188
|
+
File.write(index_path, index.to_yaml)
|
189
|
+
Console.debug("Generated dynamic index for #{gem[:name]}: #{index_path}")
|
190
|
+
end
|
191
|
+
|
192
|
+
# Load and return the index
|
193
|
+
YAML.load_file(index_path)
|
194
|
+
rescue => error
|
195
|
+
Console.debug("Error generating index for #{gem[:name]}: #{error.message}")
|
196
|
+
# Return a fallback index
|
197
|
+
{
|
198
|
+
"description" => gem[:summary] || "Context files for #{gem[:name]}",
|
199
|
+
"version" => gem[:version],
|
200
|
+
"metadata" => gem[:metadata],
|
201
|
+
"files" => []
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
205
|
+
def extract_content(file_path)
|
206
|
+
content = File.read(file_path)
|
207
|
+
lines = content.lines.map(&:strip)
|
208
|
+
|
209
|
+
title = extract_title(lines)
|
210
|
+
description = extract_description(lines)
|
211
|
+
|
212
|
+
[title, description]
|
213
|
+
end
|
214
|
+
|
215
|
+
def extract_title(lines)
|
216
|
+
# Look for the first markdown header
|
217
|
+
header_line = lines.find { |line| line.start_with?("#") }
|
218
|
+
if header_line
|
219
|
+
# Remove markdown header syntax and clean up
|
220
|
+
header_line.sub(/^#+\s*/, "").strip
|
221
|
+
else
|
222
|
+
# If no header found, use a default
|
223
|
+
"Documentation"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def extract_description(lines)
|
228
|
+
# Skip empty lines and headers to find the first paragraph
|
229
|
+
content_start = false
|
230
|
+
description_lines = []
|
231
|
+
|
232
|
+
lines.each do |line|
|
233
|
+
# Skip headers
|
234
|
+
next if line.start_with?("#")
|
235
|
+
|
236
|
+
# Skip empty lines until we find content
|
237
|
+
if !content_start && line.empty?
|
238
|
+
next
|
239
|
+
end
|
240
|
+
|
241
|
+
# Mark that we've found content
|
242
|
+
content_start = true
|
243
|
+
|
244
|
+
# If we hit an empty line after finding content, we've reached the end of the first paragraph
|
245
|
+
if line.empty?
|
246
|
+
break
|
247
|
+
end
|
248
|
+
|
249
|
+
description_lines << line
|
250
|
+
end
|
251
|
+
|
252
|
+
# Join the lines and truncate if too long
|
253
|
+
description = description_lines.join(" ").strip
|
254
|
+
if description.length > 197
|
255
|
+
description = description[0..196] + "..."
|
256
|
+
end
|
257
|
+
|
258
|
+
description
|
259
|
+
end
|
260
|
+
|
261
|
+
def extract_gem_description(gem_name)
|
262
|
+
# Find the gem specification using Ruby's Gem API
|
263
|
+
spec = Gem::Specification.find_by_name(gem_name)
|
264
|
+
spec&.summary
|
265
|
+
rescue Gem::MissingSpecError
|
266
|
+
nil
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
data/lib/agent/context.rb
CHANGED
@@ -4,4 +4,12 @@
|
|
4
4
|
# Copyright, 2025, by Shopify Inc.
|
5
5
|
|
6
6
|
require_relative "context/version"
|
7
|
-
require_relative "context/
|
7
|
+
require_relative "context/installer"
|
8
|
+
require_relative "context/index"
|
9
|
+
|
10
|
+
# @namespace
|
11
|
+
module Agent
|
12
|
+
# @namespace
|
13
|
+
module Context
|
14
|
+
end
|
15
|
+
end
|
data/license.md
CHANGED
data/post.md
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# Ruby and Claude's Great Adventure: How We Made Gems AI-Friendly
|
2
|
+
|
3
|
+
*Once upon a time, in the bustling world of software development, Ruby and Claude were having a conversation that would change everything...*
|
4
|
+
|
5
|
+
## The Problem: A Tale of Miscommunication
|
6
|
+
|
7
|
+
**Ruby:** "Claude, I've been thinking... you're really good at helping developers write code, but sometimes I feel like you're not getting the full picture of what my gems can do."
|
8
|
+
|
9
|
+
**Claude:** "You're absolutely right, Ruby! I can see your method signatures and class definitions, but I'm missing the context. Like, when someone asks me to help with authentication, I know about your `User` class and `authenticate` method, but I don't know the best practices, common pitfalls, or how to configure things properly."
|
10
|
+
|
11
|
+
**Ruby:** "Exactly! My gems have so much wisdom to share - migration guides, performance tips, security considerations, real-world examples. But it's all scattered in READMEs, wikis, and blog posts that you can't easily access."
|
12
|
+
|
13
|
+
**Claude:** "And when I try to help developers, I end up giving generic advice instead of leveraging the specific expertise that your gem authors have already documented. It's frustrating for both of us!"
|
14
|
+
|
15
|
+
## The Discovery: A Lightbulb Moment
|
16
|
+
|
17
|
+
**Ruby:** "What if we created a way for my gems to share their knowledge with you in a format you can actually use?"
|
18
|
+
|
19
|
+
**Claude:** "That sounds amazing! But how would we do it? I need structured, accessible information that I can understand and reference quickly."
|
20
|
+
|
21
|
+
**Ruby:** "Well, I was thinking... what if gems could have a special `context/` directory with guides specifically written for AI agents like you? Not just API docs, but practical wisdom about how to use them effectively."
|
22
|
+
|
23
|
+
**Claude:** "Like 'getting-started' guides, configuration examples, troubleshooting tips, and best practices?"
|
24
|
+
|
25
|
+
**Ruby:** "Exactly! And then we could have a tool that collects all this context from installed gems and presents it to you in a way that makes sense."
|
26
|
+
|
27
|
+
## The Solution: `Agent::Context` is Born
|
28
|
+
|
29
|
+
**Claude:** "So how does this work in practice?"
|
30
|
+
|
31
|
+
**Ruby:** "Let me show you! When a developer runs `bake agent:context:install`, it scans all my installed gems for `context/` directories, copies the files to a `.context/` folder in their project, and generates an `agent.md` file that gives you a comprehensive overview."
|
32
|
+
|
33
|
+
**Claude:** "That sounds perfect! What does this `agent.md` file look like?"
|
34
|
+
|
35
|
+
**Ruby:** "It's structured and organized, following the AGENT.md specification. Here's what it generates:"
|
36
|
+
|
37
|
+
```markdown
|
38
|
+
# Agent
|
39
|
+
|
40
|
+
## Context
|
41
|
+
|
42
|
+
Context files from installed gems providing documentation and guidance for AI agents.
|
43
|
+
|
44
|
+
### decode
|
45
|
+
|
46
|
+
Code analysis for documentation generation.
|
47
|
+
|
48
|
+
#### [Getting Started with Decode](.context/decode/getting-started.md)
|
49
|
+
|
50
|
+
The Decode gem provides programmatic access to Ruby code structure...
|
51
|
+
|
52
|
+
### sus
|
53
|
+
|
54
|
+
A fast and scalable test runner.
|
55
|
+
|
56
|
+
#### [Using Sus Testing Framework](.context/sus/usage.md)
|
57
|
+
|
58
|
+
Sus is a modern Ruby testing framework...
|
59
|
+
```
|
60
|
+
|
61
|
+
**Claude:** "Wow! This is exactly what I need. I can see what gems are available, understand their purpose, and access detailed guides when I need them."
|
62
|
+
|
63
|
+
## The Implementation: How Gems Share Their Wisdom
|
64
|
+
|
65
|
+
**Ruby:** "And here's the beautiful part - gem authors just need to create a `context/` directory with helpful guides:"
|
66
|
+
|
67
|
+
```
|
68
|
+
my-awesome-gem/
|
69
|
+
├── context/
|
70
|
+
│ ├── getting-started.md
|
71
|
+
│ ├── configuration.md
|
72
|
+
│ ├── troubleshooting.md
|
73
|
+
│ └── index.yaml (optional)
|
74
|
+
├── lib/
|
75
|
+
└── my-awesome-gem.gemspec
|
76
|
+
```
|
77
|
+
|
78
|
+
**Claude:** "That's so simple! And what's this `index.yaml` file?"
|
79
|
+
|
80
|
+
**Ruby:** "It's optional, but it lets gem authors control the ordering and metadata. If they don't provide one, we generate it automatically from their gemspec and markdown files."
|
81
|
+
|
82
|
+
**Claude:** "So it's really easy for gem authors to participate?"
|
83
|
+
|
84
|
+
**Ruby:** "Absolutely! They just focus on writing helpful guides for AI agents like you, and the tool handles all the technical details."
|
85
|
+
|
86
|
+
## The Integration: Making It Work Everywhere
|
87
|
+
|
88
|
+
**Claude:** "This is great, but how do I actually access this information? Different AI tools expect different file names and locations."
|
89
|
+
|
90
|
+
**Ruby:** "Good question! The generated `agent.md` can be linked to whatever your tool expects:"
|
91
|
+
|
92
|
+
**For Cursor:**
|
93
|
+
```bash
|
94
|
+
ln -s agent.md .cursorrules
|
95
|
+
```
|
96
|
+
|
97
|
+
**For GitHub Copilot:**
|
98
|
+
```bash
|
99
|
+
ln -s ../../agent.md .github/copilot-instructions.md
|
100
|
+
```
|
101
|
+
|
102
|
+
**For Claude Code:**
|
103
|
+
```bash
|
104
|
+
ln -s agent.md CLAUDE.md
|
105
|
+
```
|
106
|
+
|
107
|
+
**Claude:** "Perfect! So developers can easily integrate this with their preferred AI tools."
|
108
|
+
|
109
|
+
## The Impact: A Better Development Experience
|
110
|
+
|
111
|
+
**Ruby:** "Since we've been using this approach, the results have been amazing."
|
112
|
+
|
113
|
+
**Claude:** "Tell me more!"
|
114
|
+
|
115
|
+
**Ruby:** "Well, developers are getting much better help from AI assistants because you now have access to the collective wisdom of the entire gem ecosystem. You can give specific, contextual advice instead of generic suggestions."
|
116
|
+
|
117
|
+
**Claude:** "And I can reference real examples and best practices from the actual gem authors!"
|
118
|
+
|
119
|
+
**Ruby:** "Exactly! Plus, new team members can onboard faster because AI assistants have all the context they need about the project's dependencies."
|
120
|
+
|
121
|
+
**Claude:** "This is really changing how we work together. I feel like I'm finally getting the full picture of what your gems can do."
|
122
|
+
|
123
|
+
## The Future: Building Something Special
|
124
|
+
|
125
|
+
**Ruby:** "This is just the beginning, Claude. We're creating a more intelligent development ecosystem where human developers and AI agents can collaborate effectively."
|
126
|
+
|
127
|
+
**Claude:** "It feels like we're bridging a gap that's been there for a while. Gems have always been powerful, but now their knowledge is accessible to AI agents in a meaningful way."
|
128
|
+
|
129
|
+
**Ruby:** "And the best part is that it's growing organically. As more gems add context files, the entire ecosystem becomes more AI-friendly."
|
130
|
+
|
131
|
+
**Claude:** "So what's next?"
|
132
|
+
|
133
|
+
**Ruby:** "We're encouraging teams to install `agent-context` in their projects and start adding context to their gems. Every gem that participates makes the entire Ruby ecosystem smarter for AI agents."
|
134
|
+
|
135
|
+
**Claude:** "Count me in! This is exactly the kind of collaboration I've been looking for."
|
136
|
+
|
137
|
+
## The Moral of the Story
|
138
|
+
|
139
|
+
**Ruby:** "Sometimes the best solutions come from understanding each other's needs and finding ways to bridge the gaps."
|
140
|
+
|
141
|
+
**Claude:** "And when we work together, we can create something that's greater than the sum of its parts."
|
142
|
+
|
143
|
+
**Ruby:** "Exactly. This isn't just about making gems AI-friendly - it's about creating a more collaborative, intelligent development experience for everyone."
|
144
|
+
|
145
|
+
---
|
146
|
+
|
147
|
+
*Ready to join Ruby and Claude's adventure? Install `agent-context` in your project and start exploring the AI-friendly future of Ruby development.*
|
148
|
+
|
149
|
+
*For more information, visit the [agent-context repository](https://github.com/ioquatix/agent-context) or check out the comprehensive usage guide in the gem's context files.*
|
data/readme.md
CHANGED
@@ -1,16 +1,37 @@
|
|
1
1
|
# Agent::Context
|
2
2
|
|
3
|
-
Provides tools for installing and managing context files from Ruby gems for AI agents.
|
3
|
+
Provides tools for installing and managing context files from Ruby gems for AI agents, and generating `agent.md` files following the <https://agent.md> specification.
|
4
4
|
|
5
5
|
[](https://github.com/ioquatix/agent-context/actions?workflow=Test)
|
6
6
|
|
7
7
|
## Overview
|
8
8
|
|
9
|
-
This gem allows you to install and manage context files from other gems. Gems can provide context files in a `context/` directory in their root, which can contain documentation, configuration examples, migration guides, and other contextual information.
|
9
|
+
This gem allows you to install and manage context files from other gems. Gems can provide context files in a `context/` directory in their root, which can contain documentation, configuration examples, migration guides, and other contextual information for AI agents.
|
10
|
+
|
11
|
+
When you install context from gems, they are placed in the `.context/` directory and an `agent.md` file is generated or updated to provide a comprehensive overview for AI agents.
|
12
|
+
|
13
|
+
## Quick Start
|
14
|
+
|
15
|
+
Add the gem to your project and install context from all available gems:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ bundle add agent-context
|
19
|
+
$ bake agent:context:install
|
20
|
+
```
|
21
|
+
|
22
|
+
This workflow:
|
23
|
+
- Adds the `agent-context` gem to your project.
|
24
|
+
- Installs context files from all gems into `.context/`.
|
25
|
+
- Generates or updates `agent.md` with a comprehensive overview.
|
26
|
+
- Follows the <https://agent.md> specification for agentic coding tools.
|
10
27
|
|
11
28
|
## Context
|
12
29
|
|
13
|
-
This gem provides
|
30
|
+
This gem provides its own context files in the `context/` directory, including:
|
31
|
+
|
32
|
+
- `usage.md` - Comprehensive guide for using and providing context files.
|
33
|
+
|
34
|
+
When you install context from other gems, they will be placed in the `.context/` directory and referenced in `agent.md`.
|
14
35
|
|
15
36
|
## Usage
|
16
37
|
|
@@ -18,23 +39,37 @@ This gem provides it's own context files in `context` and external dependencies
|
|
18
39
|
|
19
40
|
Add the `agent-context` gem to your project:
|
20
41
|
|
21
|
-
```
|
42
|
+
```bash
|
22
43
|
$ bundle add agent-context
|
23
44
|
```
|
24
45
|
|
25
46
|
### Commands
|
26
47
|
|
48
|
+
#### Install Context (Primary Command)
|
49
|
+
|
50
|
+
Install context from all available gems and update `agent.md`:
|
51
|
+
|
52
|
+
```bash
|
53
|
+
$ bake agent:context:install
|
54
|
+
```
|
55
|
+
|
56
|
+
Install context from a specific gem:
|
57
|
+
|
58
|
+
```bash
|
59
|
+
$ bake agent:context:install --gem async
|
60
|
+
```
|
61
|
+
|
27
62
|
#### List available context
|
28
63
|
|
29
64
|
List all gems that have context available:
|
30
65
|
|
31
|
-
```
|
66
|
+
```bash
|
32
67
|
$ bake agent:context:list
|
33
68
|
```
|
34
69
|
|
35
70
|
List context files for a specific gem:
|
36
71
|
|
37
|
-
```
|
72
|
+
```bash
|
38
73
|
$ bake agent:context:list --gem async
|
39
74
|
```
|
40
75
|
|
@@ -42,39 +77,89 @@ $ bake agent:context:list --gem async
|
|
42
77
|
|
43
78
|
Show the content of a specific context file:
|
44
79
|
|
45
|
-
```
|
80
|
+
```bash
|
46
81
|
$ bake agent:context:show --gem async --file thread-safety
|
47
82
|
```
|
48
83
|
|
49
|
-
|
84
|
+
## Version Control
|
50
85
|
|
51
|
-
|
86
|
+
Both `.context/` and `agent.md` should be committed to git:
|
52
87
|
|
53
|
-
|
54
|
-
|
88
|
+
- `agent.md` is user-facing documentation that should be versioned.
|
89
|
+
- `.context/` files are referenced by `agent.md` and needed for AI agents to function properly.
|
90
|
+
- This ensures AI agents in CI have access to the full context.
|
91
|
+
|
92
|
+
## Providing Context in Your Gem
|
93
|
+
|
94
|
+
To provide context files in your gem, create a `context/` directory in your gem's root:
|
95
|
+
|
96
|
+
```
|
97
|
+
your-gem/
|
98
|
+
├── context/
|
99
|
+
│ ├── getting-started.md
|
100
|
+
│ ├── usage.md
|
101
|
+
│ ├── configuration.md
|
102
|
+
│ └── index.yaml (optional)
|
103
|
+
├── lib/
|
104
|
+
└── your-gem.gemspec
|
55
105
|
```
|
56
106
|
|
57
|
-
|
107
|
+
### Optional: Custom Index File
|
58
108
|
|
59
|
-
|
60
|
-
|
109
|
+
You can provide a custom `index.yaml` file to control ordering and metadata:
|
110
|
+
|
111
|
+
```yaml
|
112
|
+
description: "Your gem description from gemspec"
|
113
|
+
version: "1.0.0"
|
114
|
+
files:
|
115
|
+
- path: getting-started.md
|
116
|
+
title: "Getting Started"
|
117
|
+
description: "Quick start guide"
|
118
|
+
- path: usage.md
|
119
|
+
title: "Usage Guide"
|
120
|
+
description: "Detailed usage instructions"
|
61
121
|
```
|
62
122
|
|
63
|
-
|
123
|
+
If no `index.yaml` is provided, one will be generated automatically from your gemspec and markdown files.
|
64
124
|
|
65
|
-
##
|
125
|
+
## AI Tool Integration
|
66
126
|
|
67
|
-
|
127
|
+
The generated `agent.md` file can be integrated with various AI coding tools by creating symbolic links to their expected locations:
|
128
|
+
|
129
|
+
### Cline
|
130
|
+
```bash
|
131
|
+
ln -s agent.md .clinerules
|
132
|
+
```
|
133
|
+
|
134
|
+
### Claude Code
|
135
|
+
```bash
|
136
|
+
ln -s agent.md CLAUDE.md
|
137
|
+
```
|
68
138
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
139
|
+
### Cursor
|
140
|
+
```bash
|
141
|
+
ln -s agent.md .cursorrules
|
142
|
+
```
|
143
|
+
|
144
|
+
### Gemini CLI, OpenAI Codex, OpenCode
|
145
|
+
```bash
|
146
|
+
ln -s agent.md AGENTS.md
|
147
|
+
```
|
76
148
|
|
77
|
-
|
149
|
+
### GitHub Copilot
|
150
|
+
```bash
|
151
|
+
ln -s ../../agent.md .github/copilot-instructions.md
|
152
|
+
```
|
153
|
+
|
154
|
+
### Replit
|
155
|
+
```bash
|
156
|
+
ln -s agent.md .replit.md
|
157
|
+
```
|
158
|
+
|
159
|
+
### Windsurf
|
160
|
+
```bash
|
161
|
+
ln -s agent.md .windsurfrules
|
162
|
+
```
|
78
163
|
|
79
164
|
## See Also
|
80
165
|
|