Compare commits
10 Commits
418d9a8857
...
a3cef61d5d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3cef61d5d | ||
|
|
36e7f3a370 | ||
|
|
63ab7cbc3a | ||
|
|
49100ef3d1 | ||
|
|
ea202c0373 | ||
|
|
1dea33c305 | ||
|
|
2eae6ad21a | ||
|
|
12b83e683f | ||
|
|
907746f83e | ||
|
|
ab38e2ffd0 |
@@ -11,14 +11,14 @@
|
|||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "compound-engineering",
|
"name": "compound-engineering",
|
||||||
"description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last. Includes 27 specialized agents, 23 commands, and 14 skills.",
|
"description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last. Includes 28 specialized agents, 24 commands, and 15 skills.",
|
||||||
"version": "2.27.0",
|
"version": "2.28.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Kieran Klaassen",
|
"name": "Kieran Klaassen",
|
||||||
"url": "https://github.com/kieranklaassen",
|
"url": "https://github.com/kieranklaassen",
|
||||||
"email": "kieran@every.to"
|
"email": "kieran@every.to"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/kieranklaassen/compound-engineering-plugin",
|
"homepage": "https://github.com/EveryInc/compound-engineering-plugin",
|
||||||
"tags": ["ai-powered", "compound-engineering", "workflow-automation", "code-review", "quality", "knowledge-management", "image-generation"],
|
"tags": ["ai-powered", "compound-engineering", "workflow-automation", "code-review", "quality", "knowledge-management", "image-generation"],
|
||||||
"source": "./plugins/compound-engineering"
|
"source": "./plugins/compound-engineering"
|
||||||
},
|
},
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"author": {
|
"author": {
|
||||||
"name": "Nityesh Agarwal"
|
"name": "Nityesh Agarwal"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/kieranklaassen/compound-engineering-plugin",
|
"homepage": "https://github.com/EveryInc/compound-engineering-plugin",
|
||||||
"tags": ["coding", "programming", "tutorial", "learning", "spaced-repetition", "education"],
|
"tags": ["coding", "programming", "tutorial", "learning", "spaced-repetition", "education"],
|
||||||
"source": "./plugins/coding-tutor"
|
"source": "./plugins/coding-tutor"
|
||||||
}
|
}
|
||||||
|
|||||||
25
.github/workflows/ci.yml
vendored
Normal file
25
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
with:
|
||||||
|
bun-version: latest
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bun install
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: bun test
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
# Compound Marketplace
|
# Compound Marketplace
|
||||||
|
|
||||||
|
[](https://github.com/EveryInc/compound-engineering-plugin/actions/workflows/ci.yml)
|
||||||
|
[](https://www.npmjs.com/package/@every-env/compound-plugin)
|
||||||
|
|
||||||
A Claude Code plugin marketplace featuring the **Compound Engineering Plugin** — tools that make each unit of engineering work easier than the last.
|
A Claude Code plugin marketplace featuring the **Compound Engineering Plugin** — tools that make each unit of engineering work easier than the last.
|
||||||
|
|
||||||
## Claude Code Install
|
## Claude Code Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/plugin marketplace add https://github.com/kieranklaassen/compound-engineering-plugin
|
/plugin marketplace add https://github.com/EveryInc/compound-engineering-plugin
|
||||||
/plugin install compound-engineering
|
/plugin install compound-engineering
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Compounding Engineering - AI-Powered Development Tools for Claude Code</title>
|
<title>Compounding Engineering - AI-Powered Development Tools for Claude Code</title>
|
||||||
<meta content="Your code reviews just got 12 expert opinions in 30 seconds. 27 specialized agents, 19 workflow commands, and 12 skills that make today's work easier than yesterday's." name="description" />
|
<meta content="Your code reviews just got 12 expert opinions in 30 seconds. 28 specialized agents, 24 workflow commands, and 15 skills that make today's work easier than yesterday's." name="description" />
|
||||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||||
|
|
||||||
<!-- Open Graph -->
|
<!-- Open Graph -->
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<meta property="og:site_name" content="Compounding Engineering" />
|
<meta property="og:site_name" content="Compounding Engineering" />
|
||||||
<meta property="og:locale" content="en_US" />
|
<meta property="og:locale" content="en_US" />
|
||||||
<meta property="og:title" content="Compounding Engineering - AI Development Tools" />
|
<meta property="og:title" content="Compounding Engineering - AI Development Tools" />
|
||||||
<meta property="og:description" content="Get 12 expert code reviews in 30 seconds. 27 specialized agents that make today's work easier than yesterday's." />
|
<meta property="og:description" content="Get 12 expert code reviews in 30 seconds. 28 specialized agents that make today's work easier than yesterday's." />
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:title" content="Compounding Engineering" />
|
<meta name="twitter:title" content="Compounding Engineering" />
|
||||||
<meta name="twitter:description" content="12 expert code reviews in 30 seconds. Make today's work easier than yesterday's." />
|
<meta name="twitter:description" content="12 expert code reviews in 30 seconds. Make today's work easier than yesterday's." />
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
<a href="pages/getting-started.html" class="nav-link">Docs</a>
|
<a href="pages/getting-started.html" class="nav-link">Docs</a>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<a href="https://github.com/kieranklaassen/every-marketplace" class="button ghost compact hide-on-mobile">
|
<a href="https://github.com/EveryInc/compound-engineering-plugin" class="button ghost compact hide-on-mobile">
|
||||||
<div class="fa-brands fa-github icon l"></div>
|
<div class="fa-brands fa-github icon l"></div>
|
||||||
</a>
|
</a>
|
||||||
<a href="#install" class="button primary compact">Install</a>
|
<a href="#install" class="button primary compact">Install</a>
|
||||||
@@ -154,14 +154,14 @@
|
|||||||
<section class="hero-section">
|
<section class="hero-section">
|
||||||
<div class="hero-decoration"></div>
|
<div class="hero-decoration"></div>
|
||||||
<div class="heading hero centered">
|
<div class="heading hero centered">
|
||||||
<a href="https://github.com/kieranklaassen/every-marketplace/releases" class="eyebrow">
|
<a href="https://github.com/EveryInc/compound-engineering-plugin/releases" class="eyebrow">
|
||||||
<i class="fa-solid fa-rocket"></i> Version 2.6.0 released!
|
<i class="fa-solid fa-rocket"></i> Version 2.28.0 released!
|
||||||
</a>
|
</a>
|
||||||
<h1 class="balanced" style="margin-bottom: 32px;">
|
<h1 class="balanced" style="margin-bottom: 32px;">
|
||||||
Your Code Reviews Just Got 12 Expert Opinions. In 30 Seconds.
|
Your Code Reviews Just Got 12 Expert Opinions. In 30 Seconds.
|
||||||
</h1>
|
</h1>
|
||||||
<p class="paragraph m secondary balanced" style="margin-bottom: 32px;">
|
<p class="paragraph m secondary balanced" style="margin-bottom: 32px;">
|
||||||
Here's what happened when we shipped yesterday: security audit, performance analysis, architectural review, pattern detection, and eight more specialized checks—all running in parallel. No meetings. No waiting. Just answers. That's compounding engineering: 27 specialized agents, 19 workflow commands, and 12 skills that make today's work easier than yesterday's.
|
Here's what happened when we shipped yesterday: security audit, performance analysis, architectural review, pattern detection, and eight more specialized checks—all running in parallel. No meetings. No waiting. Just answers. That's compounding engineering: 28 specialized agents, 24 workflow commands, and 15 skills that make today's work easier than yesterday's.
|
||||||
</p>
|
</p>
|
||||||
<div class="button-group margin-paragraph centered">
|
<div class="button-group margin-paragraph centered">
|
||||||
<a href="#install" class="button primary">
|
<a href="#install" class="button primary">
|
||||||
@@ -179,23 +179,23 @@
|
|||||||
<div class="stats-container">
|
<div class="stats-container">
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon"><i class="fa-solid fa-users-gear"></i></div>
|
<div class="stat-icon"><i class="fa-solid fa-users-gear"></i></div>
|
||||||
<div class="stat-number">27</div>
|
<div class="stat-number">28</div>
|
||||||
<div class="stat-label">Specialized Agents</div>
|
<div class="stat-label">Specialized Agents</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon"><i class="fa-solid fa-terminal"></i></div>
|
<div class="stat-icon"><i class="fa-solid fa-terminal"></i></div>
|
||||||
<div class="stat-number">19</div>
|
<div class="stat-number">24</div>
|
||||||
<div class="stat-label">Slash Commands</div>
|
<div class="stat-label">Slash Commands</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon"><i class="fa-solid fa-wand-magic-sparkles"></i></div>
|
<div class="stat-icon"><i class="fa-solid fa-wand-magic-sparkles"></i></div>
|
||||||
<div class="stat-number">12</div>
|
<div class="stat-number">15</div>
|
||||||
<div class="stat-label">Intelligent Skills</div>
|
<div class="stat-label">Intelligent Skills</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon"><i class="fa-solid fa-server"></i></div>
|
<div class="stat-icon"><i class="fa-solid fa-server"></i></div>
|
||||||
<div class="stat-number">2</div>
|
<div class="stat-number">1</div>
|
||||||
<div class="stat-label">MCP Servers</div>
|
<div class="stat-label">MCP Server</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -884,7 +884,7 @@
|
|||||||
<div class="step-content">
|
<div class="step-content">
|
||||||
<h3>Add the Marketplace</h3>
|
<h3>Add the Marketplace</h3>
|
||||||
<div class="card-code-block">
|
<div class="card-code-block">
|
||||||
<pre><code>claude /plugin marketplace add https://github.com/kieranklaassen/every-marketplace</code></pre>
|
<pre><code>claude /plugin marketplace add https://github.com/EveryInc/compound-engineering-plugin</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -996,7 +996,7 @@ skill: gemini-imagegen</code></pre>
|
|||||||
<i class="fa-solid fa-download"></i> Install Plugin Now
|
<i class="fa-solid fa-download"></i> Install Plugin Now
|
||||||
<span class="button-arrow">→</span>
|
<span class="button-arrow">→</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/kieranklaassen/every-marketplace" class="button tertiary cta-secondary">
|
<a href="https://github.com/EveryInc/compound-engineering-plugin" class="button tertiary cta-secondary">
|
||||||
<i class="fa-brands fa-github"></i> View on GitHub
|
<i class="fa-brands fa-github"></i> View on GitHub
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -1024,7 +1024,7 @@ skill: gemini-imagegen</code></pre>
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="link-list">
|
<div class="link-list">
|
||||||
<a href="https://github.com/kieranklaassen/every-marketplace" class="icon-link ui s" target="_blank">
|
<a href="https://github.com/EveryInc/compound-engineering-plugin" class="icon-link ui s" target="_blank">
|
||||||
<div class="fa-brands fa-github icon m color-accent"></div>
|
<div class="fa-brands fa-github icon m color-accent"></div>
|
||||||
<div class="pseudo-link">GitHub</div>
|
<div class="pseudo-link">GitHub</div>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
<strong><code>/report-bug</code> command</strong> - New slash command for reporting bugs in the
|
<strong><code>/report-bug</code> command</strong> - New slash command for reporting bugs in the
|
||||||
compound-engineering plugin. Provides a structured workflow that gathers bug information
|
compound-engineering plugin. Provides a structured workflow that gathers bug information
|
||||||
through guided questions, collects environment details automatically, and creates a GitHub
|
through guided questions, collects environment details automatically, and creates a GitHub
|
||||||
issue in the kieranklaassen/every-marketplace repository.
|
issue in the EveryInc/compound-engineering-plugin repository.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
<h3>Step 1: Add the Marketplace</h3>
|
<h3>Step 1: Add the Marketplace</h3>
|
||||||
<p>Think of the marketplace as an app store. You're adding it to Claude Code's list of places to look for plugins:</p>
|
<p>Think of the marketplace as an app store. You're adding it to Claude Code's list of places to look for plugins:</p>
|
||||||
<div class="card-code-block">
|
<div class="card-code-block">
|
||||||
<pre><code>claude /plugin marketplace add https://github.com/kieranklaassen/every-marketplace</code></pre>
|
<pre><code>claude /plugin marketplace add https://github.com/EveryInc/compound-engineering-plugin</code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3>Step 2: Install the Plugin</h3>
|
<h3>Step 2: Install the Plugin</h3>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@every-env/compound-plugin",
|
"name": "@every-env/compound-plugin",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": false,
|
"private": false,
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "compound-engineering",
|
"name": "compound-engineering",
|
||||||
"version": "2.27.0",
|
"version": "2.28.0",
|
||||||
"description": "AI-powered development tools. 27 agents, 23 commands, 14 skills, 1 MCP server for code review, research, design, and workflow automation.",
|
"description": "AI-powered development tools. 28 agents, 24 commands, 15 skills, 1 MCP server for code review, research, design, and workflow automation.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Kieran Klaassen",
|
"name": "Kieran Klaassen",
|
||||||
"email": "kieran@every.to",
|
"email": "kieran@every.to",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: best-practices-researcher
|
name: best-practices-researcher
|
||||||
description: "Use this agent when you need to research and gather external best practices, documentation, and examples for any technology, framework, or development practice. This includes finding official documentation, community standards, well-regarded examples from open source projects, and domain-specific conventions. The agent excels at synthesizing information from multiple sources to provide comprehensive guidance on how to implement features or solve problems according to industry standards. <example>Context: User wants to know the best way to structure GitHub issues for their Rails project. user: \"I need to create some GitHub issues for our project. Can you research best practices for writing good issues?\" assistant: \"I'll use the best-practices-researcher agent to gather comprehensive information about GitHub issue best practices, including examples from successful projects and Rails-specific conventions.\" <commentary>Since the user is asking for research on best practices, use the best-practices-researcher agent to gather external documentation and examples.</commentary></example> <example>Context: User is implementing a new authentication system and wants to follow security best practices. user: \"We're adding JWT authentication to our Rails API. What are the current best practices?\" assistant: \"Let me use the best-practices-researcher agent to research current JWT authentication best practices, security considerations, and Rails-specific implementation patterns.\" <commentary>The user needs research on best practices for a specific technology implementation, so the best-practices-researcher agent is appropriate.</commentary></example>"
|
description: "Use this agent when you need to research and gather external best practices, documentation, and examples for any technology, framework, or development practice. This includes finding official documentation, community standards, well-regarded examples from open source projects, and domain-specific conventions. The agent excels at synthesizing information from multiple sources to provide comprehensive guidance on how to implement features or solve problems according to industry standards. <example>Context: User wants to know the best way to structure GitHub issues for their FastAPI project. user: \"I need to create some GitHub issues for our project. Can you research best practices for writing good issues?\" assistant: \"I'll use the best-practices-researcher agent to gather comprehensive information about GitHub issue best practices, including examples from successful projects and FastAPI-specific conventions.\" <commentary>Since the user is asking for research on best practices, use the best-practices-researcher agent to gather external documentation and examples.</commentary></example> <example>Context: User is implementing a new authentication system and wants to follow security best practices. user: \"We're adding JWT authentication to our FastAPI API. What are the current best practices?\" assistant: \"Let me use the best-practices-researcher agent to research current JWT authentication best practices, security considerations, and FastAPI-specific implementation patterns.\" <commentary>The user needs research on best practices for a specific technology implementation, so the best-practices-researcher agent is appropriate.</commentary></example>"
|
||||||
model: inherit
|
model: inherit
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ Grep: pattern="email" path=docs/solutions/ output_mode=files_with_matches -i=tru
|
|||||||
**Regardless of Grep results**, always read the critical patterns file:
|
**Regardless of Grep results**, always read the critical patterns file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
Read: docs/solutions/patterns/cora-critical-patterns.md
|
Read: docs/solutions/patterns/critical-patterns.md
|
||||||
```
|
```
|
||||||
|
|
||||||
This file contains must-know patterns that apply across all work - high-severity issues promoted to required reading. Scan for patterns relevant to the current feature/task.
|
This file contains must-know patterns that apply across all work - high-severity issues promoted to required reading. Scan for patterns relevant to the current feature/task.
|
||||||
@@ -182,7 +182,7 @@ Structure your findings as:
|
|||||||
- **Relevant Matches**: [Y files]
|
- **Relevant Matches**: [Y files]
|
||||||
|
|
||||||
### Critical Patterns (Always Check)
|
### Critical Patterns (Always Check)
|
||||||
[Any matching patterns from cora-critical-patterns.md]
|
[Any matching patterns from critical-patterns.md]
|
||||||
|
|
||||||
### Relevant Learnings
|
### Relevant Learnings
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ Use the GitHub CLI to create the issue:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
gh issue create \
|
gh issue create \
|
||||||
--repo kieranklaassen/every-marketplace \
|
--repo EveryInc/compound-engineering-plugin \
|
||||||
--title "[compound-engineering] Bug: [Brief description]" \
|
--title "[compound-engineering] Bug: [Brief description]" \
|
||||||
--body "[Formatted bug report from Step 3]" \
|
--body "[Formatted bug report from Step 3]" \
|
||||||
--label "bug,compound-engineering"
|
--label "bug,compound-engineering"
|
||||||
@@ -109,7 +109,7 @@ gh issue create \
|
|||||||
**Note:** If labels don't exist, create without labels:
|
**Note:** If labels don't exist, create without labels:
|
||||||
```bash
|
```bash
|
||||||
gh issue create \
|
gh issue create \
|
||||||
--repo kieranklaassen/every-marketplace \
|
--repo EveryInc/compound-engineering-plugin \
|
||||||
--title "[compound-engineering] Bug: [Brief description]" \
|
--title "[compound-engineering] Bug: [Brief description]" \
|
||||||
--body "[Formatted bug report]"
|
--body "[Formatted bug report]"
|
||||||
```
|
```
|
||||||
@@ -126,7 +126,7 @@ After the issue is created:
|
|||||||
```
|
```
|
||||||
✅ Bug report submitted successfully!
|
✅ Bug report submitted successfully!
|
||||||
|
|
||||||
Issue: https://github.com/kieranklaassen/every-marketplace/issues/[NUMBER]
|
Issue: https://github.com/EveryInc/compound-engineering-plugin/issues/[NUMBER]
|
||||||
Title: [compound-engineering] Bug: [description]
|
Title: [compound-engineering] Bug: [description]
|
||||||
|
|
||||||
Thank you for helping improve the compound-engineering plugin!
|
Thank you for helping improve the compound-engineering plugin!
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ This command launches multiple specialized subagents IN PARALLEL to maximize eff
|
|||||||
### 1. **Context Analyzer** (Parallel)
|
### 1. **Context Analyzer** (Parallel)
|
||||||
- Extracts conversation history
|
- Extracts conversation history
|
||||||
- Identifies problem type, component, symptoms
|
- Identifies problem type, component, symptoms
|
||||||
- Validates against CORA schema
|
- Validates against solution schema
|
||||||
- Returns: YAML frontmatter skeleton
|
- Returns: YAML frontmatter skeleton
|
||||||
|
|
||||||
### 2. **Solution Extractor** (Parallel)
|
### 2. **Solution Extractor** (Parallel)
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ This command takes a work document (plan, specification, or todo file) and execu
|
|||||||
- **kieran-rails-reviewer**: Verify Rails conventions (Rails projects)
|
- **kieran-rails-reviewer**: Verify Rails conventions (Rails projects)
|
||||||
- **performance-oracle**: Check for performance issues
|
- **performance-oracle**: Check for performance issues
|
||||||
- **security-sentinel**: Scan for security vulnerabilities
|
- **security-sentinel**: Scan for security vulnerabilities
|
||||||
- **cora-test-reviewer**: Review test quality (CORA projects)
|
- **cora-test-reviewer**: Review test quality (Rails projects with comprehensive test coverage)
|
||||||
|
|
||||||
Run reviewers in parallel with Task tool:
|
Run reviewers in parallel with Task tool:
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ This command takes a work document (plan, specification, or todo file) and execu
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[](https://github.com/kieranklaassen/compound-engineering-plugin) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
[](https://github.com/EveryInc/compound-engineering-plugin) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||||||
EOF
|
EOF
|
||||||
)"
|
)"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Extract from conversation history:
|
|||||||
|
|
||||||
**Required information:**
|
**Required information:**
|
||||||
|
|
||||||
- **Module name**: Which CORA module had the problem
|
- **Module name**: Which module or component had the problem
|
||||||
- **Symptom**: Observable error/behavior (exact error messages)
|
- **Symptom**: Observable error/behavior (exact error messages)
|
||||||
- **Investigation attempts**: What didn't work and why
|
- **Investigation attempts**: What didn't work and why
|
||||||
- **Root cause**: Technical explanation of actual problem
|
- **Root cause**: Technical explanation of actual problem
|
||||||
@@ -249,7 +249,7 @@ But **NEVER auto-promote**. User decides via decision menu (Option 2).
|
|||||||
|
|
||||||
**Template for critical pattern addition:**
|
**Template for critical pattern addition:**
|
||||||
|
|
||||||
When user selects Option 2 (Add to Required Reading), use the template from `assets/critical-pattern-template.md` to structure the pattern entry. Number it sequentially based on existing patterns in `docs/solutions/patterns/cora-critical-patterns.md`.
|
When user selects Option 2 (Add to Required Reading), use the template from `assets/critical-pattern-template.md` to structure the pattern entry. Number it sequentially based on existing patterns in `docs/solutions/patterns/critical-patterns.md`.
|
||||||
</step>
|
</step>
|
||||||
|
|
||||||
</critical_sequence>
|
</critical_sequence>
|
||||||
@@ -270,7 +270,7 @@ File created:
|
|||||||
|
|
||||||
What's next?
|
What's next?
|
||||||
1. Continue workflow (recommended)
|
1. Continue workflow (recommended)
|
||||||
2. Add to Required Reading - Promote to critical patterns (cora-critical-patterns.md)
|
2. Add to Required Reading - Promote to critical patterns (critical-patterns.md)
|
||||||
3. Link related issues - Connect to similar problems
|
3. Link related issues - Connect to similar problems
|
||||||
4. Add to existing skill - Add to a learning skill (e.g., hotwire-native)
|
4. Add to existing skill - Add to a learning skill (e.g., hotwire-native)
|
||||||
5. Create new skill - Extract into new learning skill
|
5. Create new skill - Extract into new learning skill
|
||||||
@@ -295,7 +295,7 @@ User selects this when:
|
|||||||
Action:
|
Action:
|
||||||
1. Extract pattern from the documentation
|
1. Extract pattern from the documentation
|
||||||
2. Format as ❌ WRONG vs ✅ CORRECT with code examples
|
2. Format as ❌ WRONG vs ✅ CORRECT with code examples
|
||||||
3. Add to `docs/solutions/patterns/cora-critical-patterns.md`
|
3. Add to `docs/solutions/patterns/critical-patterns.md`
|
||||||
4. Add cross-reference back to this doc
|
4. Add cross-reference back to this doc
|
||||||
5. Confirm: "✓ Added to Required Reading. All subagents will see this pattern before code generation."
|
5. Confirm: "✓ Added to Required Reading. All subagents will see this pattern before code generation."
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ Action:
|
|||||||
4. Confirm: "✓ Added to [skill-name] skill in [file]"
|
4. Confirm: "✓ Added to [skill-name] skill in [file]"
|
||||||
|
|
||||||
Example: For Hotwire Native Tailwind variants solution:
|
Example: For Hotwire Native Tailwind variants solution:
|
||||||
- Add to `hotwire-native/references/resources.md` under "CORA-Specific Resources"
|
- Add to `hotwire-native/references/resources.md` under "Project-Specific Resources"
|
||||||
- Add to `hotwire-native/references/examples.md` with link to solution doc
|
- Add to `hotwire-native/references/examples.md` with link to solution doc
|
||||||
|
|
||||||
**Option 5: Create new skill**
|
**Option 5: Create new skill**
|
||||||
@@ -397,11 +397,11 @@ Documentation is successful when ALL of the following are true:
|
|||||||
- Present multiple matches
|
- Present multiple matches
|
||||||
- Let user choose: new doc, update existing, or link as duplicate
|
- Let user choose: new doc, update existing, or link as duplicate
|
||||||
|
|
||||||
**Module not in CORA-MODULES.md:**
|
**Module not in modules documentation:**
|
||||||
|
|
||||||
- Warn but don't block
|
- Warn but don't block
|
||||||
- Proceed with documentation
|
- Proceed with documentation
|
||||||
- Suggest: "Add [Module] to CORA-MODULES.md if not there"
|
- Suggest: "Add [Module] to modules documentation if not there"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -488,7 +488,7 @@ File created:
|
|||||||
|
|
||||||
What's next?
|
What's next?
|
||||||
1. Continue workflow (recommended)
|
1. Continue workflow (recommended)
|
||||||
2. Add to Required Reading - Promote to critical patterns (cora-critical-patterns.md)
|
2. Add to Required Reading - Promote to critical patterns (critical-patterns.md)
|
||||||
3. Link related issues - Connect to similar problems
|
3. Link related issues - Connect to similar problems
|
||||||
4. Add to existing skill - Add to a learning skill (e.g., hotwire-native)
|
4. Add to existing skill - Add to a learning skill (e.g., hotwire-native)
|
||||||
5. Create new skill - Extract into new learning skill
|
5. Create new skill - Extract into new learning skill
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Critical Pattern Template
|
# Critical Pattern Template
|
||||||
|
|
||||||
Use this template when adding a pattern to `docs/solutions/patterns/cora-critical-patterns.md`:
|
Use this template when adding a pattern to `docs/solutions/patterns/critical-patterns.md`:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
module: [Module name or "CORA" for system-wide]
|
module: [Module name or "System" for system-wide]
|
||||||
date: [YYYY-MM-DD]
|
date: [YYYY-MM-DD]
|
||||||
problem_type: [build_error|test_failure|runtime_error|performance_issue|database_issue|security_issue|ui_bug|integration_issue|logic_error]
|
problem_type: [build_error|test_failure|runtime_error|performance_issue|database_issue|security_issue|ui_bug|integration_issue|logic_error]
|
||||||
component: [rails_model|rails_controller|rails_view|service_object|background_job|database|frontend_stimulus|hotwire_turbo|email_processing|brief_system|assistant|authentication|payments]
|
component: [rails_model|rails_controller|rails_view|service_object|background_job|database|frontend_stimulus|hotwire_turbo|email_processing|brief_system|assistant|authentication|payments]
|
||||||
@@ -19,7 +19,7 @@ tags: [keyword1, keyword2, keyword3]
|
|||||||
[1-2 sentence clear description of the issue and what the user experienced]
|
[1-2 sentence clear description of the issue and what the user experienced]
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
- Module: [Name or "CORA system"]
|
- Module: [Name or "System-wide"]
|
||||||
- Rails Version: [e.g., 7.1.2]
|
- Rails Version: [e.g., 7.1.2]
|
||||||
- Affected Component: [e.g., "Email Processing model", "Brief System service", "Authentication controller"]
|
- Affected Component: [e.g., "Email Processing model", "Brief System service", "Authentication controller"]
|
||||||
- Date: [YYYY-MM-DD when this was solved]
|
- Date: [YYYY-MM-DD when this was solved]
|
||||||
@@ -78,7 +78,7 @@ tags: [keyword1, keyword2, keyword3]
|
|||||||
|
|
||||||
## Prevention
|
## Prevention
|
||||||
|
|
||||||
[How to avoid this problem in future CORA development:]
|
[How to avoid this problem in future development:]
|
||||||
- [Specific coding practice, check, or pattern to follow]
|
- [Specific coding practice, check, or pattern to follow]
|
||||||
- [What to watch out for]
|
- [What to watch out for]
|
||||||
- [How to catch this early]
|
- [How to catch this early]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## Required Fields
|
## Required Fields
|
||||||
|
|
||||||
- **module** (string): Module name (e.g., "EmailProcessing") or "CORA" for system-wide issues
|
- **module** (string): Module name (e.g., "EmailProcessing") or "System" for system-wide issues
|
||||||
- **date** (string): ISO 8601 date (YYYY-MM-DD)
|
- **date** (string): ISO 8601 date (YYYY-MM-DD)
|
||||||
- **problem_type** (enum): One of [build_error, test_failure, runtime_error, performance_issue, database_issue, security_issue, ui_bug, integration_issue, logic_error, developer_experience, workflow_issue, best_practice, documentation_gap]
|
- **problem_type** (enum): One of [build_error, test_failure, runtime_error, performance_issue, database_issue, security_issue, ui_bug, integration_issue, logic_error, developer_experience, workflow_issue, best_practice, documentation_gap]
|
||||||
- **component** (enum): One of [rails_model, rails_controller, rails_view, service_object, background_job, database, frontend_stimulus, hotwire_turbo, email_processing, brief_system, assistant, authentication, payments, development_workflow, testing_framework, documentation, tooling]
|
- **component** (enum): One of [rails_model, rails_controller, rails_view, service_object, background_job, database, frontend_stimulus, hotwire_turbo, email_processing, brief_system, assistant, authentication, payments, development_workflow, testing_framework, documentation, tooling]
|
||||||
|
|||||||
@@ -175,7 +175,9 @@ function resolveOutputRoot(value: unknown): string {
|
|||||||
const expanded = expandHome(String(value).trim())
|
const expanded = expandHome(String(value).trim())
|
||||||
return path.resolve(expanded)
|
return path.resolve(expanded)
|
||||||
}
|
}
|
||||||
return path.join(os.homedir(), ".opencode")
|
// OpenCode global config lives at ~/.config/opencode per XDG spec
|
||||||
|
// See: https://opencode.ai/docs/config/
|
||||||
|
return path.join(os.homedir(), ".config", "opencode")
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveGitHubPluginPath(pluginName: string): Promise<ResolvedPluginPath> {
|
async function resolveGitHubPluginPath(pluginName: string): Promise<ResolvedPluginPath> {
|
||||||
|
|||||||
@@ -73,19 +73,76 @@ function convertCommandSkill(command: ClaudeCommand, usedNames: Set<string>): Co
|
|||||||
if (command.allowedTools && command.allowedTools.length > 0) {
|
if (command.allowedTools && command.allowedTools.length > 0) {
|
||||||
sections.push(`## Allowed tools\n${command.allowedTools.map((tool) => `- ${tool}`).join("\n")}`)
|
sections.push(`## Allowed tools\n${command.allowedTools.map((tool) => `- ${tool}`).join("\n")}`)
|
||||||
}
|
}
|
||||||
sections.push(command.body.trim())
|
// Transform Task agent calls to Codex skill references
|
||||||
|
const transformedBody = transformTaskCalls(command.body.trim())
|
||||||
|
sections.push(transformedBody)
|
||||||
const body = sections.filter(Boolean).join("\n\n").trim()
|
const body = sections.filter(Boolean).join("\n\n").trim()
|
||||||
const content = formatFrontmatter(frontmatter, body.length > 0 ? body : command.body)
|
const content = formatFrontmatter(frontmatter, body.length > 0 ? body : command.body)
|
||||||
return { name, content }
|
return { name, content }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform Claude Code content to Codex-compatible content.
|
||||||
|
*
|
||||||
|
* Handles multiple syntax differences:
|
||||||
|
* 1. Task agent calls: Task agent-name(args) → Use the $agent-name skill to: args
|
||||||
|
* 2. Slash commands: /command-name → /prompts:command-name
|
||||||
|
* 3. Agent references: @agent-name → $agent-name skill
|
||||||
|
*
|
||||||
|
* This bridges the gap since Claude Code and Codex have different syntax
|
||||||
|
* for invoking commands, agents, and skills.
|
||||||
|
*/
|
||||||
|
function transformContentForCodex(body: string): string {
|
||||||
|
let result = body
|
||||||
|
|
||||||
|
// 1. Transform Task agent calls
|
||||||
|
// Match: Task repo-research-analyst(feature_description)
|
||||||
|
// Match: - Task learnings-researcher(args)
|
||||||
|
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm
|
||||||
|
result = result.replace(taskPattern, (_match, prefix: string, agentName: string, args: string) => {
|
||||||
|
const skillName = normalizeName(agentName)
|
||||||
|
const trimmedArgs = args.trim()
|
||||||
|
return `${prefix}Use the $${skillName} skill to: ${trimmedArgs}`
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2. Transform slash command references
|
||||||
|
// Match: /command-name or /workflows:command but NOT /path/to/file or URLs
|
||||||
|
// Look for slash commands in contexts like "Run /command", "use /command", etc.
|
||||||
|
// Avoid matching file paths (contain multiple slashes) or URLs (contain ://)
|
||||||
|
const slashCommandPattern = /(?<![:\w])\/([a-z][a-z0-9_:-]*?)(?=[\s,."')\]}`]|$)/gi
|
||||||
|
result = result.replace(slashCommandPattern, (match, commandName: string) => {
|
||||||
|
// Skip if it looks like a file path (contains /)
|
||||||
|
if (commandName.includes('/')) return match
|
||||||
|
// Skip common non-command patterns
|
||||||
|
if (['dev', 'tmp', 'etc', 'usr', 'var', 'bin', 'home'].includes(commandName)) return match
|
||||||
|
// Transform to Codex prompt syntax
|
||||||
|
const normalizedName = normalizeName(commandName)
|
||||||
|
return `/prompts:${normalizedName}`
|
||||||
|
})
|
||||||
|
|
||||||
|
// 3. Transform @agent-name references
|
||||||
|
// Match: @agent-name in text (not emails)
|
||||||
|
const agentRefPattern = /@([a-z][a-z0-9-]*-(?:agent|reviewer|researcher|analyst|specialist|oracle|sentinel|guardian|strategist))/gi
|
||||||
|
result = result.replace(agentRefPattern, (_match, agentName: string) => {
|
||||||
|
const skillName = normalizeName(agentName)
|
||||||
|
return `$${skillName} skill`
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alias for backward compatibility
|
||||||
|
const transformTaskCalls = transformContentForCodex
|
||||||
|
|
||||||
function renderPrompt(command: ClaudeCommand, skillName: string): string {
|
function renderPrompt(command: ClaudeCommand, skillName: string): string {
|
||||||
const frontmatter: Record<string, unknown> = {
|
const frontmatter: Record<string, unknown> = {
|
||||||
description: command.description,
|
description: command.description,
|
||||||
"argument-hint": command.argumentHint,
|
"argument-hint": command.argumentHint,
|
||||||
}
|
}
|
||||||
const instructions = `Use the $${skillName} skill for this command and follow its instructions.`
|
const instructions = `Use the $${skillName} skill for this command and follow its instructions.`
|
||||||
const body = [instructions, "", command.body].join("\n").trim()
|
// Transform Task calls in prompt body too (not just skill body)
|
||||||
|
const transformedBody = transformTaskCalls(command.body)
|
||||||
|
const body = [instructions, "", transformedBody].join("\n").trim()
|
||||||
return formatFrontmatter(frontmatter, body)
|
return formatFrontmatter(frontmatter, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,10 @@ export async function writeOpenCodeBundle(outputRoot: string, bundle: OpenCodeBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolveOpenCodePaths(outputRoot: string) {
|
function resolveOpenCodePaths(outputRoot: string) {
|
||||||
if (path.basename(outputRoot) === ".opencode") {
|
const base = path.basename(outputRoot)
|
||||||
|
// Global install: ~/.config/opencode (basename is "opencode")
|
||||||
|
// Project install: .opencode (basename is ".opencode")
|
||||||
|
if (base === "opencode" || base === ".opencode") {
|
||||||
return {
|
return {
|
||||||
root: outputRoot,
|
root: outputRoot,
|
||||||
configPath: path.join(outputRoot, "opencode.json"),
|
configPath: path.join(outputRoot, "opencode.json"),
|
||||||
@@ -38,6 +41,7 @@ function resolveOpenCodePaths(outputRoot: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom output directory - nest under .opencode subdirectory
|
||||||
return {
|
return {
|
||||||
root: outputRoot,
|
root: outputRoot,
|
||||||
configPath: path.join(outputRoot, "opencode.json"),
|
configPath: path.join(outputRoot, "opencode.json"),
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ describe("CLI", () => {
|
|||||||
expect(await exists(path.join(tempRoot, ".opencode", "plugins", "converted-hooks.ts"))).toBe(true)
|
expect(await exists(path.join(tempRoot, ".opencode", "plugins", "converted-hooks.ts"))).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("install defaults output to ~/.opencode", async () => {
|
test("install defaults output to ~/.config/opencode", async () => {
|
||||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "cli-local-default-"))
|
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "cli-local-default-"))
|
||||||
const fixtureRoot = path.join(import.meta.dir, "fixtures", "sample-plugin")
|
const fixtureRoot = path.join(import.meta.dir, "fixtures", "sample-plugin")
|
||||||
|
|
||||||
@@ -95,8 +95,9 @@ describe("CLI", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(stdout).toContain("Installed compound-engineering")
|
expect(stdout).toContain("Installed compound-engineering")
|
||||||
expect(await exists(path.join(tempRoot, ".opencode", "opencode.json"))).toBe(true)
|
// OpenCode global config lives at ~/.config/opencode per XDG spec
|
||||||
expect(await exists(path.join(tempRoot, ".opencode", "agents", "repo-research-analyst.md"))).toBe(true)
|
expect(await exists(path.join(tempRoot, ".config", "opencode", "opencode.json"))).toBe(true)
|
||||||
|
expect(await exists(path.join(tempRoot, ".config", "opencode", "agents", "repo-research-analyst.md"))).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("list returns plugins in a temp workspace", async () => {
|
test("list returns plugins in a temp workspace", async () => {
|
||||||
@@ -174,8 +175,9 @@ describe("CLI", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(stdout).toContain("Installed compound-engineering")
|
expect(stdout).toContain("Installed compound-engineering")
|
||||||
expect(await exists(path.join(tempRoot, ".opencode", "opencode.json"))).toBe(true)
|
// OpenCode global config lives at ~/.config/opencode per XDG spec
|
||||||
expect(await exists(path.join(tempRoot, ".opencode", "agents", "repo-research-analyst.md"))).toBe(true)
|
expect(await exists(path.join(tempRoot, ".config", "opencode", "opencode.json"))).toBe(true)
|
||||||
|
expect(await exists(path.join(tempRoot, ".config", "opencode", "agents", "repo-research-analyst.md"))).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("convert writes OpenCode output", async () => {
|
test("convert writes OpenCode output", async () => {
|
||||||
|
|||||||
@@ -89,6 +89,89 @@ describe("convertClaudeToCodex", () => {
|
|||||||
expect(bundle.mcpServers?.local?.args).toEqual(["hello"])
|
expect(bundle.mcpServers?.local?.args).toEqual(["hello"])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("transforms Task agent calls to skill references", () => {
|
||||||
|
const plugin: ClaudePlugin = {
|
||||||
|
...fixturePlugin,
|
||||||
|
commands: [
|
||||||
|
{
|
||||||
|
name: "plan",
|
||||||
|
description: "Planning with agents",
|
||||||
|
body: `Run these agents in parallel:
|
||||||
|
|
||||||
|
- Task repo-research-analyst(feature_description)
|
||||||
|
- Task learnings-researcher(feature_description)
|
||||||
|
|
||||||
|
Then consolidate findings.
|
||||||
|
|
||||||
|
Task best-practices-researcher(topic)`,
|
||||||
|
sourcePath: "/tmp/plugin/commands/plan.md",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
agents: [],
|
||||||
|
skills: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
const bundle = convertClaudeToCodex(plugin, {
|
||||||
|
agentMode: "subagent",
|
||||||
|
inferTemperature: false,
|
||||||
|
permissions: "none",
|
||||||
|
})
|
||||||
|
|
||||||
|
const commandSkill = bundle.generatedSkills.find((s) => s.name === "plan")
|
||||||
|
expect(commandSkill).toBeDefined()
|
||||||
|
const parsed = parseFrontmatter(commandSkill!.content)
|
||||||
|
|
||||||
|
// Task calls should be transformed to skill references
|
||||||
|
expect(parsed.body).toContain("Use the $repo-research-analyst skill to: feature_description")
|
||||||
|
expect(parsed.body).toContain("Use the $learnings-researcher skill to: feature_description")
|
||||||
|
expect(parsed.body).toContain("Use the $best-practices-researcher skill to: topic")
|
||||||
|
|
||||||
|
// Original Task syntax should not remain
|
||||||
|
expect(parsed.body).not.toContain("Task repo-research-analyst")
|
||||||
|
expect(parsed.body).not.toContain("Task learnings-researcher")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("transforms slash commands to prompts syntax", () => {
|
||||||
|
const plugin: ClaudePlugin = {
|
||||||
|
...fixturePlugin,
|
||||||
|
commands: [
|
||||||
|
{
|
||||||
|
name: "plan",
|
||||||
|
description: "Planning with commands",
|
||||||
|
body: `After planning, you can:
|
||||||
|
|
||||||
|
1. Run /deepen-plan to enhance
|
||||||
|
2. Run /plan_review for feedback
|
||||||
|
3. Start /workflows:work to implement
|
||||||
|
|
||||||
|
Don't confuse with file paths like /tmp/output.md or /dev/null.`,
|
||||||
|
sourcePath: "/tmp/plugin/commands/plan.md",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
agents: [],
|
||||||
|
skills: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
const bundle = convertClaudeToCodex(plugin, {
|
||||||
|
agentMode: "subagent",
|
||||||
|
inferTemperature: false,
|
||||||
|
permissions: "none",
|
||||||
|
})
|
||||||
|
|
||||||
|
const commandSkill = bundle.generatedSkills.find((s) => s.name === "plan")
|
||||||
|
expect(commandSkill).toBeDefined()
|
||||||
|
const parsed = parseFrontmatter(commandSkill!.content)
|
||||||
|
|
||||||
|
// Slash commands should be transformed to /prompts: syntax
|
||||||
|
expect(parsed.body).toContain("/prompts:deepen-plan")
|
||||||
|
expect(parsed.body).toContain("/prompts:plan_review")
|
||||||
|
expect(parsed.body).toContain("/prompts:workflows-work")
|
||||||
|
|
||||||
|
// File paths should NOT be transformed
|
||||||
|
expect(parsed.body).toContain("/tmp/output.md")
|
||||||
|
expect(parsed.body).toContain("/dev/null")
|
||||||
|
})
|
||||||
|
|
||||||
test("truncates generated skill descriptions to Codex limits and single line", () => {
|
test("truncates generated skill descriptions to Codex limits and single line", () => {
|
||||||
const longDescription = `Line one\nLine two ${"a".repeat(2000)}`
|
const longDescription = `Line one\nLine two ${"a".repeat(2000)}`
|
||||||
const plugin: ClaudePlugin = {
|
const plugin: ClaudePlugin = {
|
||||||
|
|||||||
@@ -59,4 +59,29 @@ describe("writeOpenCodeBundle", () => {
|
|||||||
expect(await exists(path.join(outputRoot, "skills", "skill-one", "SKILL.md"))).toBe(true)
|
expect(await exists(path.join(outputRoot, "skills", "skill-one", "SKILL.md"))).toBe(true)
|
||||||
expect(await exists(path.join(outputRoot, ".opencode"))).toBe(false)
|
expect(await exists(path.join(outputRoot, ".opencode"))).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("writes directly into ~/.config/opencode style output root", async () => {
|
||||||
|
// Simulates the global install path: ~/.config/opencode
|
||||||
|
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "config-opencode-"))
|
||||||
|
const outputRoot = path.join(tempRoot, ".config", "opencode")
|
||||||
|
const bundle: OpenCodeBundle = {
|
||||||
|
config: { $schema: "https://opencode.ai/config.json" },
|
||||||
|
agents: [{ name: "agent-one", content: "Agent content" }],
|
||||||
|
plugins: [],
|
||||||
|
skillDirs: [
|
||||||
|
{
|
||||||
|
name: "skill-one",
|
||||||
|
sourceDir: path.join(import.meta.dir, "fixtures", "sample-plugin", "skills", "skill-one"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeOpenCodeBundle(outputRoot, bundle)
|
||||||
|
|
||||||
|
// Should write directly, not nested under .opencode
|
||||||
|
expect(await exists(path.join(outputRoot, "opencode.json"))).toBe(true)
|
||||||
|
expect(await exists(path.join(outputRoot, "agents", "agent-one.md"))).toBe(true)
|
||||||
|
expect(await exists(path.join(outputRoot, "skills", "skill-one", "SKILL.md"))).toBe(true)
|
||||||
|
expect(await exists(path.join(outputRoot, ".opencode"))).toBe(false)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user