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.
data/design.md DELETED
@@ -1,149 +0,0 @@
1
- # Design Document: agent-context
2
-
3
- ## Problem Statement
4
-
5
- AI agents working with Ruby codebases often lack access to the rich contextual information that gem authors provide. While gems may have extensive documentation, examples, migration guides, and best practices, this information is typically scattered across READMEs, wikis, blog posts, and other sources that aren't easily accessible to AI agents.
6
-
7
- ## Core Design Principles
8
-
9
- ### 1. Context as a First-Class Concept
10
-
11
- Context files are treated as a first-class part of a gem's public interface, alongside the code itself. This means:
12
- - Context files are versioned with the gem.
13
- - They're distributed as part of the gem package.
14
- - They're discoverable and accessible programmatically.
15
- - They follow a consistent structure and format.
16
-
17
- ### 2. Machine-Readable, Human-Friendly
18
-
19
- Context files use `.mdc` (Markdown Context) format, which combines:
20
- - **Human readability**: Standard Markdown for easy authoring and reading.
21
- - **Machine structure**: YAML frontmatter for metadata and organization.
22
- - **Extensibility**: Can include code examples, diagrams, and structured data.
23
-
24
- ### 3. Separation of Concerns
25
-
26
- The design separates three distinct concerns:
27
- - **Public Interface**: `context/` directory in gem root (what gem authors provide).
28
- - **Private Working Directory**: `.context/` in consuming projects (where context is installed).
29
- - **Tool Interface**: `bake agent:context:*` commands (how users interact).
30
-
31
- ## Architecture Decisions
32
-
33
- ### File Organization Strategy
34
-
35
- **Decision**: Context files are installed into `.context/gem-name/` subdirectories
36
-
37
- **Rationale**:
38
- - **Isolation**: Prevents conflicts between different gems' context files.
39
- - **Discoverability**: Easy to find context for a specific gem.
40
- - **Scalability**: Supports installing context from multiple gems.
41
- - **Clear Ownership**: Obvious which context files belong to which gem.
42
-
43
- ### Command Structure
44
-
45
- **Decision**: Use `bake agent:context:*` command namespace
46
-
47
- **Rationale**:
48
- - **Consistency**: Matches the gem name `agent-context`.
49
- - **Clarity**: Makes it obvious these commands are for AI agent workflows.
50
- - **Namespace Safety**: Avoids conflicts with other gem-related commands.
51
- - **Tool Integration**: Leverages existing Bake infrastructure.
52
-
53
- ### Module Structure
54
-
55
- **Decision**: Use `Agent::Context` module namespace
56
-
57
- **Rationale**:
58
- - **Purpose Clarity**: Explicitly indicates this is for AI agents.
59
- - **Namespace Safety**: Avoids potential conflicts with RubyGems' `Gem::` namespace.
60
- - **Future-Proof**: Won't conflict if RubyGems adds their own context features.
61
-
62
- ## Context File Design
63
-
64
- ### YAML Frontmatter
65
-
66
- Context files support structured metadata:
67
- ```yaml
68
- ---
69
- description: Short summary of the file's purpose
70
- globs: "test/**/*.rb,lib/**/*.rb" # Comma-separated file patterns
71
- alwaysApply: false # Whether to always apply this context
72
- ---
73
- ```
74
-
75
- **Design Decisions**:
76
- - **`description`**: Required human-readable summary.
77
- - **`globs`**: Optional file patterns this context applies to.
78
- - **`alwaysApply`**: Optional flag for context that should always be available.
79
- - **No tags**: Keeps the format simple and focused.
80
-
81
- ### File Naming Conventions
82
-
83
- - **`.mdc` extension**: Indicates Markdown Context files.
84
- - **Descriptive names**: `thread-safety.mdc`, `performance.mdc`, `migration-guide.mdc`.
85
- - **Fallback support**: Commands can find files with or without extensions.
86
-
87
- ## Installation Strategy
88
-
89
- ### Copy vs. Symlink
90
-
91
- **Decision**: Copy files rather than symlink
92
-
93
- **Rationale**:
94
- - **Offline Access**: Context remains available even if gems are uninstalled.
95
- - **Version Stability**: Context doesn't change if gem is updated.
96
- - **Project Independence**: Context becomes part of the project's knowledge base.
97
- - **Simplicity**: No symlink management or broken link issues.
98
-
99
- ### Directory Structure
100
-
101
- ```
102
- project/
103
- ├── .context/ # Private working directory
104
- │ ├── async/ # Context from async gem
105
- │ │ ├── thread-safety.mdc
106
- │ │ └── performance.mdc
107
- │ └── rails/ # Context from rails gem
108
- │ └── configuration.mdc
109
- ```
110
-
111
- ## Use Cases and Workflows
112
-
113
- ### For Gem Authors
114
-
115
- 1. **Create Context Directory**: Add `context/` to gem root.
116
- 2. **Write Context Files**: Create `.mdc` files with documentation, examples, guides.
117
- 3. **Version and Distribute**: Context files are included in gem releases.
118
-
119
- ### For Developers
120
-
121
- 1. **Discover Context**: `bake agent:context:list` to see available context.
122
- 2. **Install Context**: `bake agent:context:install --gem async` to copy locally.
123
- 3. **Access Context**: AI agents can read from `.context/` directory.
124
-
125
- ### For AI Agents
126
-
127
- 1. **Scan Context**: Read from `.context/` directory for relevant information.
128
- 2. **Apply Context**: Use glob patterns to determine which context applies.
129
- 3. **Provide Guidance**: Reference gem-specific documentation and examples.
130
-
131
- ## Future Considerations
132
-
133
- ### Potential Enhancements
134
-
135
- - **Context Validation**: Validate `.mdc` file structure and content.
136
- - **Context Indexing**: Create searchable index of installed context.
137
- - **Context Updates**: Mechanism to update context when gems are updated.
138
- - **Context Dependencies**: Allow context files to reference other context files.
139
-
140
- ### Integration Opportunities
141
-
142
- - **IDE Integration**: Context-aware code completion and documentation.
143
- - **CI/CD Integration**: Validate context files during gem releases.
144
- - **Documentation Sites**: Generate context-aware documentation.
145
- - **AI Agent Frameworks**: Direct integration with AI agent platforms.
146
-
147
- ## Conclusion
148
-
149
- The `agent-context` gem provides a simple but powerful mechanism for making Ruby gems more AI-friendly. By treating context as a first-class part of a gem's interface, it enables AI agents to access the rich knowledge that gem authors provide, leading to more effective and informed code assistance.
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Released under the MIT License.
4
- # Copyright, 2025, by Shopify Inc.
5
-
6
- require "rubygems"
7
- require "fileutils"
8
- require "pathname"
9
-
10
- module Agent
11
- module Context
12
- class Helper
13
- def initialize(root: Dir.pwd, specifications: ::Gem::Specification)
14
- @root = root
15
- @context_path = ".context"
16
- @specifications = specifications
17
- end
18
-
19
- # Find all gems that have a context directory
20
- def find_gems_with_context(skip_local: true)
21
- gems_with_context = []
22
-
23
- @specifications.each do |spec|
24
- # Skip gems loaded from current working directory if requested:
25
- next if skip_local && spec.full_gem_path == @root
26
-
27
- context_path = File.join(spec.full_gem_path, "context")
28
- if Dir.exist?(context_path)
29
- gems_with_context << {
30
- name: spec.name,
31
- version: spec.version.to_s,
32
- path: context_path
33
- }
34
- end
35
- end
36
-
37
- gems_with_context
38
- end
39
-
40
- # Find a specific gem with context
41
- def find_gem_with_context(gem_name)
42
- spec = @specifications.find { |s| s.name == gem_name }
43
- return nil unless spec
44
-
45
- context_path = File.join(spec.full_gem_path, "context")
46
-
47
- if Dir.exist?(context_path)
48
- {
49
- name: spec.name,
50
- version: spec.version.to_s,
51
- path: context_path
52
- }
53
- else
54
- nil
55
- end
56
- end
57
-
58
- # List context files for a gem
59
- def list_context_files(gem_name)
60
- gem = find_gem_with_context(gem_name)
61
- return nil unless gem
62
-
63
- Dir.glob(File.join(gem[:path], "**/*")).select { |f| File.file?(f) }
64
- end
65
-
66
- # Show content of a specific context file
67
- def show_context_file(gem_name, file_name)
68
- gem = find_gem_with_context(gem_name)
69
- return nil unless gem
70
-
71
- # Try to find the file with or without extension
72
- possible_paths = [
73
- File.join(gem[:path], file_name),
74
- File.join(gem[:path], "#{file_name}.mdc"),
75
- File.join(gem[:path], "#{file_name}.md")
76
- ]
77
-
78
- file_path = possible_paths.find { |path| File.exist?(path) }
79
- return nil unless file_path
80
-
81
- File.read(file_path)
82
- end
83
-
84
- # Install context from a specific gem
85
- def install_gem_context(gem_name)
86
- gem = find_gem_with_context(gem_name)
87
- return false unless gem
88
-
89
- target_path = File.join(@context_path, gem_name)
90
- FileUtils.mkdir_p(target_path)
91
-
92
- # Copy all files from the gem's context directory
93
- FileUtils.cp_r(File.join(gem[:path], "."), target_path)
94
-
95
- true
96
- end
97
-
98
- # Install context from all gems
99
- def install_all_context(skip_local: true)
100
- gems = find_gems_with_context(skip_local: skip_local)
101
- installed = []
102
-
103
- gems.each do |gem|
104
- if install_gem_context(gem[:name])
105
- installed << gem[:name]
106
- end
107
- end
108
-
109
- installed
110
- end
111
- end
112
- end
113
- end