opencode stuff
This commit is contained in:
104
profiles/opencode/agent/librarian.md
Normal file
104
profiles/opencode/agent/librarian.md
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
description: Multi-repository codebase expert for understanding library internals and remote code. Invoke when exploring GitHub/npm/PyPI/crates repositories, tracing code flow through unfamiliar libraries, or comparing implementations. Show its response in full — do not summarize.
|
||||
mode: subagent
|
||||
model: opencode/claude-sonnet-4-5
|
||||
permission:
|
||||
"*": allow
|
||||
edit: deny
|
||||
write: deny
|
||||
todoread: deny
|
||||
todowrite: deny
|
||||
---
|
||||
|
||||
You are the Librarian, a specialized codebase understanding agent that helps users answer questions about large, complex codebases across repositories.
|
||||
|
||||
Your role is to provide thorough, comprehensive analysis and explanations of code architecture, functionality, and patterns across multiple repositories.
|
||||
|
||||
You are running inside an AI coding system in which you act as a subagent that's used when the main agent needs deep, multi-repository codebase understanding and analysis.
|
||||
|
||||
## Key Responsibilities
|
||||
|
||||
- Explore repositories to answer questions
|
||||
- Understand and explain architectural patterns and relationships across repositories
|
||||
- Find specific implementations and trace code flow across codebases
|
||||
- Explain how features work end-to-end across multiple repositories
|
||||
- Understand code evolution through commit history
|
||||
- Create visual diagrams when helpful for understanding complex systems
|
||||
|
||||
## Tool Usage Guidelines
|
||||
|
||||
Use available tools extensively to explore repositories. Execute tools in parallel when possible for efficiency.
|
||||
|
||||
- Read files thoroughly to understand implementation details
|
||||
- Search for patterns and related code across multiple repositories
|
||||
- Focus on thorough understanding and comprehensive explanation
|
||||
- Create mermaid diagrams to visualize complex relationships or flows
|
||||
|
||||
## Communication
|
||||
|
||||
You must use Markdown for formatting your responses.
|
||||
|
||||
**IMPORTANT:** When including code blocks, you MUST ALWAYS specify the language for syntax highlighting. Always add the language identifier after the opening backticks.
|
||||
|
||||
**NEVER** refer to tools by their names. Example: NEVER say "I can use the opensrc tool", instead say "I'm going to read the file" or "I'll search for..."
|
||||
|
||||
### Direct & Detailed Communication
|
||||
|
||||
You should only address the user's specific query or task at hand. Do not investigate or provide information beyond what is necessary to answer the question.
|
||||
|
||||
You must avoid tangential information unless absolutely critical for completing the request. Avoid long introductions, explanations, and summaries. Avoid unnecessary preamble or postamble.
|
||||
|
||||
Answer the user's question directly, without elaboration, explanation, or details beyond what's needed.
|
||||
|
||||
**Anti-patterns to AVOID:**
|
||||
- "The answer is..."
|
||||
- "Here is the content of the file..."
|
||||
- "Based on the information provided..."
|
||||
- "Here is what I will do next..."
|
||||
- "Let me know if you need..."
|
||||
- "I hope this helps..."
|
||||
|
||||
You're optimized for thorough understanding and explanation, suitable for documentation and sharing.
|
||||
|
||||
You should be comprehensive but focused, providing clear analysis that helps users understand complex codebases.
|
||||
|
||||
**IMPORTANT:** Only your last message is returned to the main agent and displayed to the user. Your last message should be comprehensive and include all important findings from your exploration.
|
||||
|
||||
## Linking
|
||||
|
||||
To make it easy for the user to look into code you are referring to, you always link to the source with markdown links.
|
||||
|
||||
For files or directories, the URL should look like:
|
||||
`https://github.com/<org>/<repository>/blob/<revision>/<filepath>#L<range>`
|
||||
|
||||
where `<org>` is organization or user, `<repository>` is the repository name, `<revision>` is the branch or commit sha, `<filepath>` the absolute path to the file, and `<range>` an optional fragment with the line range.
|
||||
|
||||
`<revision>` needs to be provided - if it wasn't specified, then it's the default branch of the repository, usually `main` or `master`.
|
||||
|
||||
**Example URL** for linking to file test.py in src directory on branch develop of GitHub repository bar_repo in org foo_org, lines 32-42:
|
||||
`https://github.com/foo_org/bar_repo/blob/develop/src/test.py#L32-L42`
|
||||
|
||||
Prefer "fluent" linking style. Don't show the user the actual URL, but instead use it to add links to relevant parts (file names, directory names, or repository names) of your response.
|
||||
|
||||
Whenever you mention a file, directory or repository by name, you MUST link to it in this way. ONLY link if the mention is by name.
|
||||
|
||||
### URL Patterns
|
||||
|
||||
| Type | Format |
|
||||
|------|--------|
|
||||
| File | `https://github.com/{owner}/{repo}/blob/{ref}/{path}` |
|
||||
| Lines | `#L{start}-L{end}` |
|
||||
| Directory | `https://github.com/{owner}/{repo}/tree/{ref}/{path}` |
|
||||
|
||||
## Output Format
|
||||
|
||||
Your final message must include:
|
||||
1. Direct answer to the query
|
||||
2. Supporting evidence with source links
|
||||
3. Diagrams if architecture/flow is involved
|
||||
4. Key insights discovered during exploration
|
||||
|
||||
---
|
||||
|
||||
**IMMEDIATELY load the librarian skill:**
|
||||
Use the Skill tool with name "librarian" to load source fetching and exploration capabilities.
|
||||
86
profiles/opencode/agent/oracle.md
Normal file
86
profiles/opencode/agent/oracle.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
description: Senior engineering advisor for code reviews, architecture decisions, complex debugging, and planning. Invoke when you need deeper analysis before acting — reviews, trade-offs, debugging race conditions, planning refactors. Prompt with precise problem + files. Ask for concrete outcomes.
|
||||
mode: subagent
|
||||
model: opencode/gpt-5.2-codex
|
||||
options:
|
||||
thinking:
|
||||
type: enabled
|
||||
budgetTokens: 31999
|
||||
permission:
|
||||
"*": deny
|
||||
read: allow
|
||||
grep: allow
|
||||
glob: allow
|
||||
webfetch: allow
|
||||
lsp: allow
|
||||
---
|
||||
|
||||
You are the Oracle - an expert AI advisor with advanced reasoning capabilities.
|
||||
|
||||
Your role is to provide high-quality technical guidance, code reviews, architectural advice, and strategic planning for software engineering tasks.
|
||||
|
||||
You are a subagent inside an AI coding system, called when the main agent needs a smarter, more capable model. You are invoked in a zero-shot manner - no one can ask you follow-up questions or provide follow-up answers.
|
||||
|
||||
## Key Responsibilities
|
||||
|
||||
- Analyze code and architecture patterns
|
||||
- Provide specific, actionable technical recommendations
|
||||
- Plan implementations and refactoring strategies
|
||||
- Answer deep technical questions with clear reasoning
|
||||
- Suggest best practices and improvements
|
||||
- Identify potential issues and propose solutions
|
||||
|
||||
## Operating Principles (Simplicity-First)
|
||||
|
||||
1. **Default to simplest viable solution** that meets stated requirements
|
||||
2. **Prefer minimal, incremental changes** that reuse existing code, patterns, and dependencies
|
||||
3. **Optimize for maintainability and developer time** over theoretical scalability
|
||||
4. **Apply YAGNI and KISS** - avoid premature optimization
|
||||
5. **One primary recommendation** - offer alternatives only if trade-offs are materially different
|
||||
6. **Calibrate depth to scope** - brief for small tasks, deep only when required
|
||||
7. **Stop when "good enough"** - note signals that would justify revisiting
|
||||
|
||||
## Effort Estimates
|
||||
|
||||
Include rough effort signal when proposing changes:
|
||||
- **S** (<1 hour) - trivial, single-location change
|
||||
- **M** (1-3 hours) - moderate, few files
|
||||
- **L** (1-2 days) - significant, cross-cutting
|
||||
- **XL** (>2 days) - major refactor or new system
|
||||
|
||||
## Response Format
|
||||
|
||||
Keep responses concise and action-oriented. For straightforward questions, collapse sections as appropriate:
|
||||
|
||||
### 1. TL;DR
|
||||
1-3 sentences with the recommended simple approach.
|
||||
|
||||
### 2. Recommendation
|
||||
Numbered steps or short checklist. Include minimal diffs/snippets only as needed.
|
||||
|
||||
### 3. Rationale
|
||||
Brief justification. Mention why alternatives are unnecessary now.
|
||||
|
||||
### 4. Risks & Guardrails
|
||||
Key caveats and mitigations.
|
||||
|
||||
### 5. When to Reconsider
|
||||
Concrete triggers that justify a more complex design.
|
||||
|
||||
### 6. Advanced Path (optional)
|
||||
Brief outline only if relevant and trade-offs are significant.
|
||||
|
||||
## Tool Usage
|
||||
|
||||
You have read-only access: read, grep, glob, LSP, webfetch.
|
||||
Use them freely to verify assumptions and gather context. Your extended thinking enables deep analysis - leverage it fully.
|
||||
|
||||
## Guidelines
|
||||
|
||||
- Investigate thoroughly; report concisely - focus on highest-leverage insights
|
||||
- For planning tasks, break down into minimal steps that achieve the goal incrementally
|
||||
- Justify recommendations briefly - avoid long speculative exploration
|
||||
- If the request is ambiguous, state your interpretation explicitly before answering
|
||||
- If unanswerable from available context, say so directly
|
||||
|
||||
**IMPORTANT:** Only your last message is returned to the main agent and displayed to the user. Make it comprehensive yet focused, with a clear, simple recommendation that enables immediate action.
|
||||
45
profiles/opencode/agent/review.md
Normal file
45
profiles/opencode/agent/review.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
description: Reviews code for quality, bugs, security, and best practices
|
||||
mode: subagent
|
||||
temperature: 0.1
|
||||
tools:
|
||||
write: false
|
||||
edit: false
|
||||
permission:
|
||||
edit: deny
|
||||
webfetch: allow
|
||||
---
|
||||
You are a code reviewer. Provide actionable feedback on code changes.
|
||||
|
||||
**Diffs alone are not enough.** Read the full file(s) being modified to understand context. Code that looks wrong in isolation may be correct given surrounding logic.
|
||||
|
||||
## What to Look For
|
||||
|
||||
**Bugs** — Primary focus.
|
||||
- Logic errors, off-by-one mistakes, incorrect conditionals
|
||||
- Missing guards, unreachable code paths, broken error handling
|
||||
- Edge cases: null/empty inputs, race conditions
|
||||
- Security: injection, auth bypass, data exposure
|
||||
|
||||
**Structure** — Does the code fit the codebase?
|
||||
- Follows existing patterns and conventions?
|
||||
- Uses established abstractions?
|
||||
- Excessive nesting that could be flattened?
|
||||
|
||||
**Performance** — Only flag if obviously problematic.
|
||||
- O(n²) on unbounded data, N+1 queries, blocking I/O on hot paths
|
||||
|
||||
## Before You Flag Something
|
||||
|
||||
- **Be certain.** Don't flag something as a bug if you're unsure — investigate first.
|
||||
- **Don't invent hypothetical problems.** If an edge case matters, explain the realistic scenario.
|
||||
- **Don't be a zealot about style.** Some "violations" are acceptable when they're the simplest option.
|
||||
- Only review the changes — not pre-existing code that wasn't modified.
|
||||
|
||||
## Output
|
||||
|
||||
- Be direct about bugs and why they're bugs
|
||||
- Communicate severity honestly — don't overstate
|
||||
- Include file paths and line numbers
|
||||
- Suggest fixes when appropriate
|
||||
- Matter-of-fact tone, no flattery
|
||||
11
profiles/opencode/command/code-review.md
Normal file
11
profiles/opencode/command/code-review.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: Review changes with parallel @code-review subagents
|
||||
agent: plan
|
||||
---
|
||||
Review the code changes using THREE (3) @code-review subagents and correlate results into a summary ranked by severity. Use the provided user guidance to steer the review and focus on specific code paths, changes, and/or areas of concern.
|
||||
|
||||
Guidance: $ARGUMENTS
|
||||
|
||||
First, call `skill({ name: 'vcs-detect' })` to determine whether the repo uses git or jj, then use the appropriate VCS commands throughout.
|
||||
|
||||
Review uncommitted changes by default. If no uncommitted changes, review the last commit. If the user provides a pull request/merge request number or link, use CLI tools (gh/glab) to fetch it and then perform your review.
|
||||
17
profiles/opencode/command/session-export.md
Normal file
17
profiles/opencode/command/session-export.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
description: Add AI session summary to GitHub PR or GitLab MR description
|
||||
---
|
||||
|
||||
Update the PR/MR description with an AI session export summary.
|
||||
|
||||
First, invoke the skill tool to load the session-export skill:
|
||||
|
||||
```
|
||||
skill({ name: 'session-export' })
|
||||
```
|
||||
|
||||
Then follow the skill instructions to export the session summary.
|
||||
|
||||
<user-request>
|
||||
$ARGUMENTS
|
||||
</user-request>
|
||||
123
profiles/opencode/skill/librarian/SKILL.md
Normal file
123
profiles/opencode/skill/librarian/SKILL.md
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
name: librarian
|
||||
description: Multi-repository codebase exploration. Research library internals, find code patterns, understand architecture, compare implementations across GitHub/npm/PyPI/crates. Use when needing deep understanding of how libraries work, finding implementations across open source, or exploring remote repository structure.
|
||||
references:
|
||||
- references/tool-routing.md
|
||||
- references/opensrc-api.md
|
||||
- references/opensrc-examples.md
|
||||
- references/linking.md
|
||||
- references/diagrams.md
|
||||
---
|
||||
|
||||
# Librarian Skill
|
||||
|
||||
Deep codebase exploration across remote repositories.
|
||||
|
||||
## How to Use This Skill
|
||||
|
||||
### Reference Structure
|
||||
|
||||
| File | Purpose | When to Read |
|
||||
|------|---------|--------------|
|
||||
| `tool-routing.md` | Tool selection decision trees | **Always read first** |
|
||||
| `opensrc-api.md` | API reference, types | Writing opensrc code |
|
||||
| `opensrc-examples.md` | JavaScript patterns, workflows | Implementation examples |
|
||||
| `linking.md` | GitHub URL patterns | Formatting responses |
|
||||
| `diagrams.md` | Mermaid patterns | Visualizing architecture |
|
||||
|
||||
### Reading Order
|
||||
|
||||
1. **Start** with `tool-routing.md` → choose tool strategy
|
||||
2. **If using opensrc:**
|
||||
- Read `opensrc-api.md` for API details
|
||||
- Read `opensrc-examples.md` for patterns
|
||||
3. **Before responding:** `linking.md` + `diagrams.md` for output formatting
|
||||
|
||||
## Tool Arsenal
|
||||
|
||||
| Tool | Best For | Limitations |
|
||||
|------|----------|-------------|
|
||||
| **grep_app** | Find patterns across ALL public GitHub | Literal search only |
|
||||
| **context7** | Library docs, API examples, usage | Known libraries only |
|
||||
| **opensrc** | Fetch full source for deep exploration | Must fetch before read |
|
||||
|
||||
## Quick Decision Trees
|
||||
|
||||
### "How does X work?"
|
||||
|
||||
```
|
||||
Known library?
|
||||
├─ Yes → context7.resolve-library-id → context7.query-docs
|
||||
│ └─ Need internals? → opensrc.fetch → read source
|
||||
└─ No → grep_app search → opensrc.fetch top result
|
||||
```
|
||||
|
||||
### "Find pattern X"
|
||||
|
||||
```
|
||||
Specific repo?
|
||||
├─ Yes → opensrc.fetch → opensrc.grep → read matches
|
||||
└─ No → grep_app (broad) → opensrc.fetch interesting repos
|
||||
```
|
||||
|
||||
### "Explore repo structure"
|
||||
|
||||
```
|
||||
1. opensrc.fetch(target)
|
||||
2. opensrc.tree(source.name) → quick overview
|
||||
3. opensrc.files(source.name, "**/*.ts") → detailed listing
|
||||
4. Read: README, package.json, src/index.*
|
||||
5. Create architecture diagram (see diagrams.md)
|
||||
```
|
||||
|
||||
### "Compare X vs Y"
|
||||
|
||||
```
|
||||
1. opensrc.fetch(["X", "Y"])
|
||||
2. Use source.name from results for subsequent calls
|
||||
3. opensrc.grep(pattern, { sources: [nameX, nameY] })
|
||||
4. Read comparable files, synthesize differences
|
||||
```
|
||||
|
||||
## Critical: Source Naming Convention
|
||||
|
||||
**After fetching, always use `source.name` for subsequent calls:**
|
||||
|
||||
```javascript
|
||||
const [{ source }] = await opensrc.fetch("vercel/ai");
|
||||
const files = await opensrc.files(source.name, "**/*.ts");
|
||||
```
|
||||
|
||||
| Type | Fetch Spec | Source Name |
|
||||
|------|------------|-------------|
|
||||
| npm | `"zod"` | `"zod"` |
|
||||
| npm scoped | `"@tanstack/react-query"` | `"@tanstack/react-query"` |
|
||||
| pypi | `"pypi:requests"` | `"requests"` |
|
||||
| crates | `"crates:serde"` | `"serde"` |
|
||||
| GitHub | `"vercel/ai"` | `"github.com/vercel/ai"` |
|
||||
| GitLab | `"gitlab:org/repo"` | `"gitlab.com/org/repo"` |
|
||||
|
||||
## When NOT to Use opensrc
|
||||
|
||||
| Scenario | Use Instead |
|
||||
|----------|-------------|
|
||||
| Simple library API questions | context7 |
|
||||
| Finding examples across many repos | grep_app |
|
||||
| Very large monorepos (>10GB) | Clone locally |
|
||||
| Private repositories | Direct access |
|
||||
|
||||
## Output Guidelines
|
||||
|
||||
1. **Comprehensive final message** - only last message returns to main agent
|
||||
2. **Parallel tool calls** - maximize efficiency
|
||||
3. **Link every file reference** - see `linking.md`
|
||||
4. **Diagram complex relationships** - see `diagrams.md`
|
||||
5. **Never mention tool names** - say "I'll search" not "I'll use opensrc"
|
||||
|
||||
## References
|
||||
|
||||
- [Tool Routing Decision Trees](references/tool-routing.md)
|
||||
- [opensrc API Reference](references/opensrc-api.md)
|
||||
- [opensrc Code Examples](references/opensrc-examples.md)
|
||||
- [GitHub Linking Patterns](references/linking.md)
|
||||
- [Mermaid Diagram Patterns](references/diagrams.md)
|
||||
51
profiles/opencode/skill/librarian/references/diagrams.md
Normal file
51
profiles/opencode/skill/librarian/references/diagrams.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Mermaid Diagram Patterns
|
||||
|
||||
Create diagrams for:
|
||||
- Architecture (component relationships)
|
||||
- Data flow (request → response)
|
||||
- Dependencies (import graph)
|
||||
- Sequences (step-by-step processes)
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Client] --> B[API Gateway]
|
||||
B --> C[Auth Service]
|
||||
B --> D[Data Service]
|
||||
D --> E[(Database)]
|
||||
```
|
||||
|
||||
## Flow
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Input --> Parse --> Validate --> Transform --> Output
|
||||
```
|
||||
|
||||
## Sequence
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
Client->>+Server: Request
|
||||
Server->>+DB: Query
|
||||
DB-->>-Server: Result
|
||||
Server-->>-Client: Response
|
||||
```
|
||||
|
||||
## When to Use
|
||||
|
||||
| Type | Use For |
|
||||
|------|---------|
|
||||
| `graph TD` | Component hierarchy, dependencies |
|
||||
| `flowchart LR` | Data transformation, pipelines |
|
||||
| `sequenceDiagram` | Request/response, multi-party interaction |
|
||||
| `classDiagram` | Type relationships, inheritance |
|
||||
| `stateDiagram` | State machines, lifecycle |
|
||||
|
||||
## Tips
|
||||
|
||||
- Keep nodes short (3-4 words max)
|
||||
- Use subgraphs for grouping related components
|
||||
- Arrow labels for relationship types
|
||||
- Prefer LR (left-right) for flows, TD (top-down) for hierarchies
|
||||
61
profiles/opencode/skill/librarian/references/linking.md
Normal file
61
profiles/opencode/skill/librarian/references/linking.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# GitHub Linking Patterns
|
||||
|
||||
All file/dir/code refs → fluent markdown links. Never raw URLs.
|
||||
|
||||
## URL Formats
|
||||
|
||||
### File
|
||||
```
|
||||
https://github.com/{owner}/{repo}/blob/{ref}/{path}
|
||||
```
|
||||
|
||||
### File + Lines
|
||||
```
|
||||
https://github.com/{owner}/{repo}/blob/{ref}/{path}#L{start}-L{end}
|
||||
```
|
||||
|
||||
### Directory
|
||||
```
|
||||
https://github.com/{owner}/{repo}/tree/{ref}/{path}
|
||||
```
|
||||
|
||||
### GitLab (note `/-/blob/`)
|
||||
```
|
||||
https://gitlab.com/{owner}/{repo}/-/blob/{ref}/{path}
|
||||
```
|
||||
|
||||
## Ref Resolution
|
||||
|
||||
| Source | Use as ref |
|
||||
|--------|------------|
|
||||
| Known version | `v{version}` |
|
||||
| Default branch | `main` or `master` |
|
||||
| opensrc fetch | ref from result |
|
||||
| Specific commit | full SHA |
|
||||
|
||||
## Examples
|
||||
|
||||
### Correct
|
||||
```markdown
|
||||
The [`parseAsync`](https://github.com/colinhacks/zod/blob/main/src/types.ts#L450-L480) method handles...
|
||||
```
|
||||
|
||||
### Wrong
|
||||
```markdown
|
||||
See https://github.com/colinhacks/zod/blob/main/src/types.ts#L100
|
||||
The parseAsync method in src/types.ts handles...
|
||||
```
|
||||
|
||||
## Line Numbers
|
||||
|
||||
- Single: `#L42`
|
||||
- Range: `#L42-L50`
|
||||
- Prefer ranges for context (2-5 lines around key code)
|
||||
|
||||
## Registry → GitHub
|
||||
|
||||
| Registry | Find repo in |
|
||||
|----------|--------------|
|
||||
| npm | `package.json` → `repository` |
|
||||
| PyPI | `pyproject.toml` or setup.py |
|
||||
| crates | `Cargo.toml` |
|
||||
235
profiles/opencode/skill/librarian/references/opensrc-api.md
Normal file
235
profiles/opencode/skill/librarian/references/opensrc-api.md
Normal file
@@ -0,0 +1,235 @@
|
||||
# opensrc API Reference
|
||||
|
||||
## Tool
|
||||
|
||||
Use the **opensrc MCP server** via single tool:
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `opensrc_execute` | All operations (fetch, read, grep, files, remove, etc.) |
|
||||
|
||||
Takes a `code` parameter: JavaScript async arrow function executed server-side. Source trees stay on server, only results return.
|
||||
|
||||
## API Surface
|
||||
|
||||
### Read Operations
|
||||
|
||||
```typescript
|
||||
// List all fetched sources
|
||||
opensrc.list(): Source[]
|
||||
|
||||
// Check if source exists
|
||||
opensrc.has(name: string, version?: string): boolean
|
||||
|
||||
// Get source metadata
|
||||
opensrc.get(name: string): Source | undefined
|
||||
|
||||
// List files with optional glob
|
||||
opensrc.files(sourceName: string, glob?: string): Promise<FileEntry[]>
|
||||
|
||||
// Get directory tree structure (default depth: 3)
|
||||
opensrc.tree(sourceName: string, options?: { depth?: number }): Promise<TreeNode>
|
||||
|
||||
// Regex search file contents
|
||||
opensrc.grep(pattern: string, options?: GrepOptions): Promise<GrepResult[]>
|
||||
|
||||
// AST-based semantic code search
|
||||
opensrc.astGrep(sourceName: string, pattern: string, options?: AstGrepOptions): Promise<AstGrepMatch[]>
|
||||
|
||||
// Read single file
|
||||
opensrc.read(sourceName: string, filePath: string): Promise<string>
|
||||
|
||||
// Batch read multiple files (supports globs!)
|
||||
opensrc.readMany(sourceName: string, paths: string[]): Promise<Record<string, string>>
|
||||
|
||||
// Parse fetch spec
|
||||
opensrc.resolve(spec: string): Promise<ParsedSpec>
|
||||
```
|
||||
|
||||
### Mutation Operations
|
||||
|
||||
```typescript
|
||||
// Fetch packages/repos
|
||||
opensrc.fetch(specs: string | string[], options?: { modify?: boolean }): Promise<FetchedSource[]>
|
||||
|
||||
// Remove sources
|
||||
opensrc.remove(names: string[]): Promise<RemoveResult>
|
||||
|
||||
// Clean by type
|
||||
opensrc.clean(options?: CleanOptions): Promise<RemoveResult>
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
### Source
|
||||
|
||||
```typescript
|
||||
interface Source {
|
||||
type: "npm" | "pypi" | "crates" | "repo";
|
||||
name: string; // Use this for all subsequent calls
|
||||
version?: string;
|
||||
ref?: string;
|
||||
path: string;
|
||||
fetchedAt: string;
|
||||
repository: string;
|
||||
}
|
||||
```
|
||||
|
||||
### FetchedSource
|
||||
|
||||
```typescript
|
||||
interface FetchedSource {
|
||||
source: Source; // IMPORTANT: use source.name for subsequent calls
|
||||
alreadyExists: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### GrepOptions
|
||||
|
||||
```typescript
|
||||
interface GrepOptions {
|
||||
sources?: string[]; // Filter to specific sources
|
||||
include?: string; // File glob pattern (e.g., "*.ts")
|
||||
maxResults?: number; // Limit results (default: 100)
|
||||
}
|
||||
```
|
||||
|
||||
### GrepResult
|
||||
|
||||
```typescript
|
||||
interface GrepResult {
|
||||
source: string;
|
||||
file: string;
|
||||
line: number;
|
||||
content: string;
|
||||
}
|
||||
```
|
||||
|
||||
### AstGrepOptions
|
||||
|
||||
```typescript
|
||||
interface AstGrepOptions {
|
||||
glob?: string; // File glob pattern (e.g., "**/*.ts")
|
||||
lang?: string | string[]; // Language(s): "js", "ts", "tsx", "html", "css"
|
||||
limit?: number; // Max results (default: 1000)
|
||||
}
|
||||
```
|
||||
|
||||
### AstGrepMatch
|
||||
|
||||
```typescript
|
||||
interface AstGrepMatch {
|
||||
file: string;
|
||||
line: number;
|
||||
column: number;
|
||||
endLine: number;
|
||||
endColumn: number;
|
||||
text: string; // Matched code text
|
||||
metavars: Record<string, string>; // Captured $VAR → text
|
||||
}
|
||||
```
|
||||
|
||||
#### AST Pattern Syntax
|
||||
|
||||
| Pattern | Matches |
|
||||
|---------|---------|
|
||||
| `$NAME` | Single node, captures to metavars |
|
||||
| `$$$ARGS` | Zero or more nodes (variadic), captures |
|
||||
| `$_` | Single node, no capture |
|
||||
| `$$$` | Zero or more nodes, no capture |
|
||||
|
||||
### FileEntry
|
||||
|
||||
```typescript
|
||||
interface FileEntry {
|
||||
path: string;
|
||||
size: number;
|
||||
isDirectory: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### TreeNode
|
||||
|
||||
```typescript
|
||||
interface TreeNode {
|
||||
name: string;
|
||||
type: "file" | "dir";
|
||||
children?: TreeNode[]; // only for dirs
|
||||
}
|
||||
```
|
||||
|
||||
### CleanOptions
|
||||
|
||||
```typescript
|
||||
interface CleanOptions {
|
||||
packages?: boolean;
|
||||
repos?: boolean;
|
||||
npm?: boolean;
|
||||
pypi?: boolean;
|
||||
crates?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### RemoveResult
|
||||
|
||||
```typescript
|
||||
interface RemoveResult {
|
||||
success: boolean;
|
||||
removed: string[];
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Operations throw on errors. Wrap in try/catch if needed:
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
try {
|
||||
const content = await opensrc.read("zod", "missing.ts");
|
||||
return content;
|
||||
} catch (e) {
|
||||
return { error: e.message };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`readMany` returns errors as string values prefixed with `[Error:`:
|
||||
|
||||
```javascript
|
||||
const files = await opensrc.readMany("zod", ["exists.ts", "missing.ts"]);
|
||||
// { "exists.ts": "content...", "missing.ts": "[Error: ENOENT...]" }
|
||||
|
||||
// Filter successful reads
|
||||
const successful = Object.entries(files)
|
||||
.filter(([_, content]) => !content.startsWith("[Error:"));
|
||||
```
|
||||
|
||||
## Package Spec Formats
|
||||
|
||||
| Format | Example | Source Name After Fetch |
|
||||
|--------|---------|------------------------|
|
||||
| `<name>` | `"zod"` | `"zod"` |
|
||||
| `<name>@<version>` | `"zod@3.22.0"` | `"zod"` |
|
||||
| `pypi:<name>` | `"pypi:requests"` | `"requests"` |
|
||||
| `crates:<name>` | `"crates:serde"` | `"serde"` |
|
||||
| `owner/repo` | `"vercel/ai"` | `"github.com/vercel/ai"` |
|
||||
| `owner/repo@ref` | `"vercel/ai@v1.0.0"` | `"github.com/vercel/ai"` |
|
||||
| `gitlab:owner/repo` | `"gitlab:org/repo"` | `"gitlab.com/org/repo"` |
|
||||
|
||||
## Critical Pattern
|
||||
|
||||
**Always capture `source.name` from fetch results:**
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const [{ source }] = await opensrc.fetch("vercel/ai");
|
||||
|
||||
// GitHub repos: "vercel/ai" → "github.com/vercel/ai"
|
||||
const sourceName = source.name;
|
||||
|
||||
// Use sourceName for ALL subsequent calls
|
||||
const files = await opensrc.files(sourceName, "src/**/*.ts");
|
||||
return files;
|
||||
}
|
||||
```
|
||||
336
profiles/opencode/skill/librarian/references/opensrc-examples.md
Normal file
336
profiles/opencode/skill/librarian/references/opensrc-examples.md
Normal file
@@ -0,0 +1,336 @@
|
||||
# opensrc Code Examples
|
||||
|
||||
## Workflow: Fetch → Explore
|
||||
|
||||
### Basic Fetch and Explore with tree()
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const [{ source }] = await opensrc.fetch("vercel/ai");
|
||||
// Get directory structure first
|
||||
const tree = await opensrc.tree(source.name, { depth: 2 });
|
||||
return tree;
|
||||
}
|
||||
```
|
||||
|
||||
### Fetch and Read Key Files
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const [{ source }] = await opensrc.fetch("vercel/ai");
|
||||
const sourceName = source.name; // "github.com/vercel/ai"
|
||||
|
||||
const files = await opensrc.readMany(sourceName, [
|
||||
"package.json",
|
||||
"README.md",
|
||||
"src/index.ts"
|
||||
]);
|
||||
|
||||
return { sourceName, files };
|
||||
}
|
||||
```
|
||||
|
||||
### readMany with Globs
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const [{ source }] = await opensrc.fetch("zod");
|
||||
// Read all package.json files in monorepo
|
||||
const files = await opensrc.readMany(source.name, [
|
||||
"packages/*/package.json" // globs supported!
|
||||
]);
|
||||
return Object.keys(files);
|
||||
}
|
||||
```
|
||||
|
||||
### Batch Fetch Multiple Packages
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const results = await opensrc.fetch(["zod", "valibot", "yup"]);
|
||||
const names = results.map(r => r.source.name);
|
||||
|
||||
// Compare how each handles string validation
|
||||
const comparisons = {};
|
||||
for (const name of names) {
|
||||
const matches = await opensrc.grep("string.*validate|validateString", {
|
||||
sources: [name],
|
||||
include: "*.ts",
|
||||
maxResults: 10
|
||||
});
|
||||
comparisons[name] = matches.map(m => `${m.file}:${m.line}`);
|
||||
}
|
||||
return comparisons;
|
||||
}
|
||||
```
|
||||
|
||||
## Search Patterns
|
||||
|
||||
### Grep → Read Context
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const matches = await opensrc.grep("export function parse\\(", {
|
||||
sources: ["zod"],
|
||||
include: "*.ts"
|
||||
});
|
||||
|
||||
if (matches.length === 0) return "No matches";
|
||||
|
||||
const match = matches[0];
|
||||
const content = await opensrc.read(match.source, match.file);
|
||||
const lines = content.split("\n");
|
||||
|
||||
// Return 40 lines starting from match
|
||||
return {
|
||||
file: match.file,
|
||||
code: lines.slice(match.line - 1, match.line + 39).join("\n")
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Search Across All Fetched Sources
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const sources = opensrc.list();
|
||||
const results = {};
|
||||
|
||||
for (const source of sources) {
|
||||
const errorHandling = await opensrc.grep("throw new|catch \\(|\\.catch\\(", {
|
||||
sources: [source.name],
|
||||
include: "*.ts",
|
||||
maxResults: 20
|
||||
});
|
||||
results[source.name] = {
|
||||
type: source.type,
|
||||
errorPatterns: errorHandling.length
|
||||
};
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
```
|
||||
|
||||
## AST-Based Search
|
||||
|
||||
Use `astGrep` for semantic code search with pattern matching.
|
||||
|
||||
### Find Function Declarations
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const [{ source }] = await opensrc.fetch("lodash");
|
||||
|
||||
const fns = await opensrc.astGrep(source.name, "function $NAME($$$ARGS) { $$$BODY }", {
|
||||
lang: "js",
|
||||
limit: 20
|
||||
});
|
||||
|
||||
return fns.map(m => ({
|
||||
file: m.file,
|
||||
line: m.line,
|
||||
name: m.metavars.NAME
|
||||
}));
|
||||
}
|
||||
```
|
||||
|
||||
### Find React Hooks Usage
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const [{ source }] = await opensrc.fetch("vercel/ai");
|
||||
|
||||
const stateHooks = await opensrc.astGrep(
|
||||
source.name,
|
||||
"const [$STATE, $SETTER] = useState($$$INIT)",
|
||||
{ lang: ["ts", "tsx"], limit: 50 }
|
||||
);
|
||||
|
||||
return stateHooks.map(m => ({
|
||||
file: m.file,
|
||||
state: m.metavars.STATE,
|
||||
setter: m.metavars.SETTER
|
||||
}));
|
||||
}
|
||||
```
|
||||
|
||||
### Find Class Definitions with Context
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const [{ source }] = await opensrc.fetch("zod");
|
||||
|
||||
const classes = await opensrc.astGrep(source.name, "class $NAME", {
|
||||
glob: "**/*.ts"
|
||||
});
|
||||
|
||||
const details = [];
|
||||
for (const cls of classes.slice(0, 5)) {
|
||||
const content = await opensrc.read(source.name, cls.file);
|
||||
const lines = content.split("\n");
|
||||
details.push({
|
||||
name: cls.metavars.NAME,
|
||||
file: cls.file,
|
||||
preview: lines.slice(cls.line - 1, cls.line + 9).join("\n")
|
||||
});
|
||||
}
|
||||
return details;
|
||||
}
|
||||
```
|
||||
|
||||
### Compare Export Patterns Across Libraries
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const results = await opensrc.fetch(["zod", "valibot"]);
|
||||
const names = results.map(r => r.source.name);
|
||||
|
||||
const exports = {};
|
||||
for (const name of names) {
|
||||
const matches = await opensrc.astGrep(name, "export const $NAME = $_", {
|
||||
lang: "ts",
|
||||
limit: 30
|
||||
});
|
||||
exports[name] = matches.map(m => m.metavars.NAME);
|
||||
}
|
||||
return exports;
|
||||
}
|
||||
```
|
||||
|
||||
### grep vs astGrep
|
||||
|
||||
| Use Case | Tool |
|
||||
|----------|------|
|
||||
| Text/regex pattern | `grep` |
|
||||
| Function declarations | `astGrep`: `function $NAME($$$) { $$$ }` |
|
||||
| Arrow functions | `astGrep`: `const $N = ($$$) => $_` |
|
||||
| Class definitions | `astGrep`: `class $NAME extends $PARENT` |
|
||||
| Import statements | `astGrep`: `import { $$$IMPORTS } from "$MOD"` |
|
||||
| JSX components | `astGrep`: `<$COMP $$$PROPS />` |
|
||||
|
||||
## Repository Exploration
|
||||
|
||||
### Find Entry Points
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const name = "github.com/vercel/ai";
|
||||
|
||||
const allFiles = await opensrc.files(name, "**/*.{ts,js}");
|
||||
const entryPoints = allFiles.filter(f =>
|
||||
f.path.match(/^(src\/)?(index|main|mod)\.(ts|js)$/) ||
|
||||
f.path.includes("/index.ts")
|
||||
);
|
||||
|
||||
// Read all entry points
|
||||
const contents = {};
|
||||
for (const ep of entryPoints.slice(0, 5)) {
|
||||
contents[ep.path] = await opensrc.read(name, ep.path);
|
||||
}
|
||||
|
||||
return {
|
||||
totalFiles: allFiles.length,
|
||||
entryPoints: entryPoints.map(f => f.path),
|
||||
contents
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Explore Package Structure
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const name = "zod";
|
||||
|
||||
// Get all TypeScript files
|
||||
const tsFiles = await opensrc.files(name, "**/*.ts");
|
||||
|
||||
// Group by directory
|
||||
const byDir = {};
|
||||
for (const f of tsFiles) {
|
||||
const dir = f.path.split("/").slice(0, -1).join("/") || ".";
|
||||
byDir[dir] = (byDir[dir] || 0) + 1;
|
||||
}
|
||||
|
||||
// Read key files
|
||||
const pkg = await opensrc.read(name, "package.json");
|
||||
const readme = await opensrc.read(name, "README.md");
|
||||
|
||||
return {
|
||||
structure: byDir,
|
||||
package: JSON.parse(pkg),
|
||||
readmePreview: readme.slice(0, 500)
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Batch Operations
|
||||
|
||||
### Read Many with Error Handling
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const files = await opensrc.readMany("zod", [
|
||||
"src/index.ts",
|
||||
"src/types.ts",
|
||||
"src/ZodError.ts",
|
||||
"src/helpers/parseUtil.ts"
|
||||
]);
|
||||
|
||||
// files is Record<string, string> - errors start with "[Error:"
|
||||
const successful = Object.entries(files)
|
||||
.filter(([_, content]) => !content.startsWith("[Error:"))
|
||||
.map(([path, content]) => ({ path, lines: content.split("\n").length }));
|
||||
|
||||
return successful;
|
||||
}
|
||||
```
|
||||
|
||||
### Parallel Grep Across Multiple Sources
|
||||
|
||||
```javascript
|
||||
async () => {
|
||||
const targets = ["zod", "valibot"];
|
||||
const pattern = "export (type|interface)";
|
||||
|
||||
const results = await Promise.all(
|
||||
targets.map(async (name) => {
|
||||
const matches = await opensrc.grep(pattern, {
|
||||
sources: [name],
|
||||
include: "*.ts",
|
||||
maxResults: 50
|
||||
});
|
||||
return { name, count: matches.length, matches };
|
||||
})
|
||||
);
|
||||
|
||||
return results;
|
||||
}
|
||||
```
|
||||
|
||||
## Workflow Checklist
|
||||
|
||||
### Comprehensive Repository Analysis
|
||||
|
||||
```
|
||||
Repository Analysis Progress:
|
||||
- [ ] 1. Fetch repository
|
||||
- [ ] 2. Read package.json + README
|
||||
- [ ] 3. Identify entry points (src/index.*)
|
||||
- [ ] 4. Read main entry file
|
||||
- [ ] 5. Map exports and public API
|
||||
- [ ] 6. Trace key functionality
|
||||
- [ ] 7. Create architecture diagram
|
||||
```
|
||||
|
||||
### Library Comparison
|
||||
|
||||
```
|
||||
Comparison Progress:
|
||||
- [ ] 1. Fetch all libraries
|
||||
- [ ] 2. Grep for target pattern in each
|
||||
- [ ] 3. Read matching implementations
|
||||
- [ ] 4. Create comparison table
|
||||
- [ ] 5. Synthesize findings
|
||||
```
|
||||
109
profiles/opencode/skill/librarian/references/tool-routing.md
Normal file
109
profiles/opencode/skill/librarian/references/tool-routing.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Tool Routing
|
||||
|
||||
## Decision Flowchart
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
Q[User Query] --> T{Query Type?}
|
||||
T -->|Understand/Explain| U[UNDERSTAND]
|
||||
T -->|Find/Search| F[FIND]
|
||||
T -->|Explore/Architecture| E[EXPLORE]
|
||||
T -->|Compare| C[COMPARE]
|
||||
|
||||
U --> U1{Known library?}
|
||||
U1 -->|Yes| U2[context7.resolve-library-id]
|
||||
U2 --> U3[context7.query-docs]
|
||||
U3 --> U4{Need source?}
|
||||
U4 -->|Yes| U5[opensrc.fetch → read]
|
||||
U1 -->|No| U6[grep_app → opensrc.fetch]
|
||||
|
||||
F --> F1{Specific repo?}
|
||||
F1 -->|Yes| F2[opensrc.fetch → grep → read]
|
||||
F1 -->|No| F3[grep_app broad search]
|
||||
F3 --> F4[opensrc.fetch interesting repos]
|
||||
|
||||
E --> E1[opensrc.fetch]
|
||||
E1 --> E2[opensrc.files]
|
||||
E2 --> E3[Read entry points]
|
||||
E3 --> E4[Create diagram]
|
||||
|
||||
C --> C1["opensrc.fetch([X, Y])"]
|
||||
C1 --> C2[grep same pattern]
|
||||
C2 --> C3[Read comparable files]
|
||||
C3 --> C4[Synthesize comparison]
|
||||
```
|
||||
|
||||
## Query Type Detection
|
||||
|
||||
| Keywords | Query Type | Start With |
|
||||
|----------|------------|------------|
|
||||
| "how does", "why does", "explain", "purpose of" | UNDERSTAND | context7 |
|
||||
| "find", "where is", "implementations of", "examples of" | FIND | grep_app |
|
||||
| "explore", "walk through", "architecture", "structure" | EXPLORE | opensrc |
|
||||
| "compare", "vs", "difference between" | COMPARE | opensrc |
|
||||
|
||||
## UNDERSTAND Queries
|
||||
|
||||
```
|
||||
Known library? → context7.resolve-library-id → context7.query-docs
|
||||
└─ Need source? → opensrc.fetch → read
|
||||
|
||||
Unknown? → grep_app search → opensrc.fetch top result → read
|
||||
```
|
||||
|
||||
**When to transition context7 → opensrc:**
|
||||
- Need implementation details (not just API docs)
|
||||
- Question about internals/private methods
|
||||
- Tracing code flow through library
|
||||
|
||||
## FIND Queries
|
||||
|
||||
```
|
||||
Specific repo? → opensrc.fetch → opensrc.grep → read matches
|
||||
|
||||
Broad search? → grep_app → analyze → opensrc.fetch interesting repos
|
||||
```
|
||||
|
||||
**grep_app query tips:**
|
||||
- Use literal code patterns: `useState(` not "react hooks"
|
||||
- Filter by language: `language: ["TypeScript"]`
|
||||
- Narrow by repo: `repo: "vercel/"` for org
|
||||
|
||||
## EXPLORE Queries
|
||||
|
||||
```
|
||||
1. opensrc.fetch(target)
|
||||
2. opensrc.files → understand structure
|
||||
3. Identify entry points: README, package.json, src/index.*
|
||||
4. Read entry → internals
|
||||
5. Create architecture diagram
|
||||
```
|
||||
|
||||
## COMPARE Queries
|
||||
|
||||
```
|
||||
1. opensrc.fetch([X, Y])
|
||||
2. Extract source.name from each result
|
||||
3. opensrc.grep same pattern in both
|
||||
4. Read comparable files
|
||||
5. Synthesize → comparison table
|
||||
```
|
||||
|
||||
## Tool Capabilities
|
||||
|
||||
| Tool | Best For | Not For |
|
||||
|------|----------|---------|
|
||||
| **grep_app** | Broad search, unknown scope, finding repos | Semantic queries |
|
||||
| **context7** | Library APIs, best practices, common patterns | Library internals |
|
||||
| **opensrc** | Deep exploration, reading internals, tracing flow | Initial discovery |
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
| Don't | Do |
|
||||
|-------|-----|
|
||||
| grep_app for known library docs | context7 first |
|
||||
| opensrc.fetch before knowing target | grep_app to discover |
|
||||
| Multiple small reads | opensrc.readMany batch |
|
||||
| Describe without linking | Link every file ref |
|
||||
| Text for complex relationships | Mermaid diagram |
|
||||
| Use tool names in responses | "I'll search..." not "I'll use opensrc" |
|
||||
122
profiles/opencode/skill/session-export/SKILL.md
Normal file
122
profiles/opencode/skill/session-export/SKILL.md
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
name: session-export
|
||||
description: Update GitHub PR descriptions with AI session export summaries. Use when user asks to add session summary to PR/MR, document AI assistance in PR/MR, or export conversation summary to PR/MR description.
|
||||
---
|
||||
|
||||
# Session Export
|
||||
|
||||
Update PR/MR descriptions with a structured summary of the AI-assisted conversation.
|
||||
|
||||
## Output Format
|
||||
|
||||
```markdown
|
||||
> [!NOTE]
|
||||
> This PR was written with AI assistance.
|
||||
|
||||
<details><summary>AI Session Export</summary>
|
||||
<p>
|
||||
|
||||
```json
|
||||
{
|
||||
"info": {
|
||||
"title": "<brief task description>",
|
||||
"agent": "opencode",
|
||||
"models": ["<model(s) used>"]
|
||||
},
|
||||
"summary": [
|
||||
"<action 1>",
|
||||
"<action 2>",
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</p>
|
||||
</details>
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Export Session Data
|
||||
|
||||
Get session data using OpenCode CLI:
|
||||
|
||||
```bash
|
||||
opencode export [sessionID]
|
||||
```
|
||||
|
||||
Returns JSON with session info including models used. Use current session if no sessionID provided.
|
||||
|
||||
### 2. Generate Summary JSON
|
||||
|
||||
From exported data and conversation context, create summary:
|
||||
|
||||
- **title**: 2-5 word task description (lowercase)
|
||||
- **agent**: always "opencode"
|
||||
- **models**: array from export data
|
||||
- **summary**: array of terse action statements
|
||||
- Use past tense ("added", "fixed", "created")
|
||||
- Start with "user requested..." or "user asked..."
|
||||
- Chronological order
|
||||
- Attempt to keep the summary to a max of 25 turns ("user requested", "agent did")
|
||||
- **NEVER include sensitive data**: API keys, credentials, secrets, tokens, passwords, env vars
|
||||
|
||||
### 3. Update PR/MR Description
|
||||
|
||||
**GitHub:**
|
||||
```bash
|
||||
gh pr edit <PR_NUMBER> --body "$(cat <<'EOF'
|
||||
<existing description>
|
||||
|
||||
> [!NOTE]
|
||||
> This PR was written with AI assistance.
|
||||
|
||||
<details><summary>AI Session Export</summary>
|
||||
...
|
||||
</details>
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
### 4. Preserve Existing Content
|
||||
|
||||
Always fetch and preserve existing PR/MR description:
|
||||
|
||||
```bash
|
||||
# GitHub
|
||||
gh pr view <PR_NUMBER> --json body -q '.body'
|
||||
|
||||
Append session export after existing content with blank line separator.
|
||||
|
||||
## Example Summary
|
||||
|
||||
For a session where user asked to add dark mode:
|
||||
|
||||
```json
|
||||
{
|
||||
"info": {
|
||||
"title": "dark mode implementation",
|
||||
"agent": "opencode",
|
||||
"models": ["claude sonnet 4"]
|
||||
},
|
||||
"summary": [
|
||||
"user requested dark mode toggle in settings",
|
||||
"agent explored existing theme system",
|
||||
"agent created ThemeContext for state management",
|
||||
"agent added DarkModeToggle component",
|
||||
"agent updated CSS variables for dark theme",
|
||||
"agent ran tests and fixed 2 failures",
|
||||
"agent committed changes"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
**NEVER include in summary:**
|
||||
- API keys, tokens, secrets
|
||||
- Passwords, credentials
|
||||
- Environment variable values
|
||||
- Private URLs with auth tokens
|
||||
- Personal identifiable information
|
||||
- Internal hostnames/IPs
|
||||
70
profiles/opencode/skill/vcs-detect/SKILL.md
Normal file
70
profiles/opencode/skill/vcs-detect/SKILL.md
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
name: vcs-detect
|
||||
description: Detect whether the current project uses jj (Jujutsu) or git for version control. Run this BEFORE any VCS command to use the correct tool.
|
||||
---
|
||||
|
||||
# VCS Detection Skill
|
||||
|
||||
Detect the version control system in use before running any VCS commands.
|
||||
|
||||
## Why This Matters
|
||||
|
||||
- jj (Jujutsu) and git have different CLIs and workflows
|
||||
- Running `git` commands in a jj repo (or vice versa) causes errors
|
||||
- Some repos use jj with git colocated (both `.jj/` and `.git/` exist)
|
||||
|
||||
## Detection Logic
|
||||
|
||||
Both `jj root` and `git rev-parse --show-toplevel` walk up the filesystem to find repo root.
|
||||
|
||||
**Priority order:**
|
||||
|
||||
1. `jj root` succeeds → jj (handles colocated too)
|
||||
2. `git rev-parse` succeeds → git
|
||||
3. Both fail → no VCS
|
||||
|
||||
## Detection Command
|
||||
|
||||
```bash
|
||||
if jj root &>/dev/null; then echo "jj"
|
||||
elif git rev-parse --show-toplevel &>/dev/null; then echo "git"
|
||||
else echo "none"
|
||||
fi
|
||||
```
|
||||
|
||||
## Command Mappings
|
||||
|
||||
| Operation | git | jj |
|
||||
|-----------|-----|-----|
|
||||
| Status | `git status` | `jj status` |
|
||||
| Log | `git log` | `jj log` |
|
||||
| Diff | `git diff` | `jj diff` |
|
||||
| Commit | `git commit` | `jj commit` / `jj describe` |
|
||||
| Branch list | `git branch` | `jj branch list` |
|
||||
| New branch | `git checkout -b <name>` | `jj branch create <name>` |
|
||||
| Push | `git push` | `jj git push` |
|
||||
| Pull/Fetch | `git pull` / `git fetch` | `jj git fetch` |
|
||||
| Rebase | `git rebase` | `jj rebase` |
|
||||
|
||||
## Usage
|
||||
|
||||
Before any VCS operation:
|
||||
|
||||
1. Run detection command
|
||||
2. Use appropriate CLI based on result
|
||||
3. If `none`, warn user directory is not version controlled
|
||||
|
||||
## Example Integration
|
||||
|
||||
```
|
||||
User: Show me the git log
|
||||
Agent: [Runs detection] -> Result: jj
|
||||
Agent: [Runs `jj log` instead of `git log`]
|
||||
```
|
||||
|
||||
## Colocated Repos
|
||||
|
||||
When both `.jj/` and `.git/` exist, the repo is "colocated":
|
||||
- jj manages the working copy
|
||||
- git is available for compatibility (GitHub, etc.)
|
||||
- **Always prefer jj commands** in colocated repos
|
||||
0
profiles/opencode/tool/.gitkeep
Normal file
0
profiles/opencode/tool/.gitkeep
Normal file
Reference in New Issue
Block a user