opencodekit 0.15.12 → 0.15.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/index.js +16 -4
- package/dist/template/.opencode/AGENTS.md +28 -3
- package/dist/template/.opencode/README.md +7 -4
- package/dist/template/.opencode/agent/scout.md +117 -27
- package/dist/template/.opencode/command/research-ui.md +1 -1
- package/dist/template/.opencode/command/research.md +56 -62
- package/dist/template/.opencode/memory/observations/2026-01-28-decision-created-deep-research-skill-for-thorough.md +29 -0
- package/dist/template/.opencode/memory/observations/2026-01-28-decision-gh-grep-mcp-wrapper-vs-native-grep-searc.md +21 -0
- package/dist/template/.opencode/memory/observations/2026-01-28-decision-oracle-tool-optimal-usage-patterns.md +32 -0
- package/dist/template/.opencode/memory/observations/2026-01-28-learning-ampcode-deep-mode-research-integration-w.md +42 -0
- package/dist/template/.opencode/memory/observations/2026-01-28-pattern-research-delegation-pattern-explore-for-.md +32 -0
- package/dist/template/.opencode/memory/research/opencode-mcp-bug-report.md +5 -2
- package/dist/template/.opencode/opencode.json +697 -812
- package/dist/template/.opencode/plans/1768385996691-silent-wizard.md +12 -2
- package/dist/template/.opencode/skill/deep-research/SKILL.md +385 -0
- package/dist/template/.opencode/skill/source-code-research/SKILL.md +8 -8
- package/dist/template/.opencode/skill/tool-priority/SKILL.md +8 -6
- package/dist/template/.opencode/tool/context7-query-docs.ts +89 -0
- package/dist/template/.opencode/tool/context7-resolve-library-id.ts +113 -0
- package/dist/template/.opencode/tool/grep-search.ts +135 -0
- package/dist/template/.opencode/tool/oracle.ts +240 -0
- package/package.json +16 -4
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
|
|
3
|
+
const GREP_APP_API = "https://grep.app/api/search";
|
|
4
|
+
|
|
5
|
+
interface SearchResult {
|
|
6
|
+
repo: string;
|
|
7
|
+
path: string;
|
|
8
|
+
content: { snippet: string };
|
|
9
|
+
total_matches: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface GrepResponse {
|
|
13
|
+
hits: { hits: SearchResult[] };
|
|
14
|
+
time: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default tool({
|
|
18
|
+
description: `Search real-world code examples from GitHub repositories via grep.app.
|
|
19
|
+
|
|
20
|
+
Use when:
|
|
21
|
+
- Implementing unfamiliar APIs - see how others use a library
|
|
22
|
+
- Looking for production patterns - find real-world examples
|
|
23
|
+
- Understanding library integrations - see how things work together
|
|
24
|
+
|
|
25
|
+
IMPORTANT: Search for **literal code patterns**, not keywords:
|
|
26
|
+
✅ Good: "useState(", "import React from", "async function"
|
|
27
|
+
❌ Bad: "react tutorial", "best practices", "how to use"
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
grep_search({ query: "getServerSession", language: "TypeScript" })
|
|
31
|
+
grep_search({ query: "CORS(", language: "Python", repo: "flask" })
|
|
32
|
+
grep_search({ query: "export async function POST", path: "route.ts" })
|
|
33
|
+
`,
|
|
34
|
+
args: {
|
|
35
|
+
query: tool.schema
|
|
36
|
+
.string()
|
|
37
|
+
.describe("Code pattern to search for (literal text)"),
|
|
38
|
+
language: tool.schema
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Filter by language: TypeScript, TSX, Python, Go, Rust, etc."),
|
|
42
|
+
repo: tool.schema
|
|
43
|
+
.string()
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("Filter by repo: 'owner/repo' or partial match"),
|
|
46
|
+
path: tool.schema
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("Filter by file path: 'src/', '.test.ts', etc."),
|
|
50
|
+
limit: tool.schema
|
|
51
|
+
.number()
|
|
52
|
+
.optional()
|
|
53
|
+
.describe("Max results to return (default: 10, max: 20)"),
|
|
54
|
+
},
|
|
55
|
+
execute: async (args) => {
|
|
56
|
+
const { query, language, repo, path, limit = 10 } = args;
|
|
57
|
+
|
|
58
|
+
if (!query || query.trim() === "") {
|
|
59
|
+
return "Error: query is required";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Build URL with proper filter parameters
|
|
63
|
+
// grep.app uses filter[lang][0]=TypeScript format, NOT inline lang:TypeScript
|
|
64
|
+
const url = new URL(GREP_APP_API);
|
|
65
|
+
url.searchParams.set("q", query);
|
|
66
|
+
|
|
67
|
+
// Add language filter (grep.app uses filter[lang][0] format)
|
|
68
|
+
if (language) {
|
|
69
|
+
url.searchParams.set("filter[lang][0]", language);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Add repo filter
|
|
73
|
+
if (repo) {
|
|
74
|
+
url.searchParams.set("filter[repo][0]", repo);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Add path filter
|
|
78
|
+
if (path) {
|
|
79
|
+
url.searchParams.set("filter[path][0]", path);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const response = await fetch(url.toString(), {
|
|
84
|
+
headers: {
|
|
85
|
+
Accept: "application/json",
|
|
86
|
+
"User-Agent": "OpenCode/1.0",
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
return `Error: grep.app API returned ${response.status}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const data = (await response.json()) as GrepResponse;
|
|
95
|
+
|
|
96
|
+
if (!data.hits?.hits?.length) {
|
|
97
|
+
return `No results found for: ${query}${language ? ` (${language})` : ""}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const maxResults = Math.min(limit, 20);
|
|
101
|
+
const results = data.hits.hits.slice(0, maxResults);
|
|
102
|
+
|
|
103
|
+
const formatted = results.map((hit, i) => {
|
|
104
|
+
const repoName = hit.repo || "unknown";
|
|
105
|
+
const filePath = hit.path || "unknown";
|
|
106
|
+
const snippet = hit.content?.snippet || "";
|
|
107
|
+
|
|
108
|
+
// Clean up HTML from snippet and extract text
|
|
109
|
+
const cleanCode = snippet
|
|
110
|
+
.replace(/<[^>]*>/g, "") // Remove HTML tags
|
|
111
|
+
.replace(/</g, "<")
|
|
112
|
+
.replace(/>/g, ">")
|
|
113
|
+
.replace(/&/g, "&")
|
|
114
|
+
.replace(/"/g, '"')
|
|
115
|
+
.split("\n")
|
|
116
|
+
.slice(0, 8)
|
|
117
|
+
.join("\n")
|
|
118
|
+
.trim();
|
|
119
|
+
|
|
120
|
+
return `## ${i + 1}. ${repoName}
|
|
121
|
+
**File**: ${filePath}
|
|
122
|
+
\`\`\`
|
|
123
|
+
${cleanCode}
|
|
124
|
+
\`\`\``;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return `Found ${data.hits.hits.length} results (showing ${results.length}) in ${data.time}ms:
|
|
128
|
+
|
|
129
|
+
${formatted.join("\n\n")}`;
|
|
130
|
+
} catch (error: unknown) {
|
|
131
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
132
|
+
return `Error searching grep.app: ${message}`;
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
});
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { tool } from "@opencode-ai/plugin";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Oracle Tool - Get second opinions from alternative AI models
|
|
5
|
+
*
|
|
6
|
+
* Uses ProxyPal to access various models for:
|
|
7
|
+
* - Validating complex architectural decisions
|
|
8
|
+
* - Cross-checking debugging hypotheses
|
|
9
|
+
* - Getting alternative perspectives on tricky problems
|
|
10
|
+
* - Breaking out of reasoning ruts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Default to Gemini 3 Pro for deep reasoning (has thinking capability)
|
|
14
|
+
const DEFAULT_MODEL = "gpt-5.2-codex";
|
|
15
|
+
|
|
16
|
+
// Available oracle models with their strengths
|
|
17
|
+
const ORACLE_MODELS: Record<string, { name: string; strength: string }> = {
|
|
18
|
+
"gpt-5.2-codex": {
|
|
19
|
+
name: "GPT-5.2 Codex",
|
|
20
|
+
strength: "Strong code understanding and generation",
|
|
21
|
+
},
|
|
22
|
+
"gemini-3-pro-preview": {
|
|
23
|
+
name: "Gemini 3 Pro",
|
|
24
|
+
strength: "Deep reasoning with thinking capability",
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
interface OracleRequest {
|
|
29
|
+
question: string;
|
|
30
|
+
context?: string;
|
|
31
|
+
model?: string;
|
|
32
|
+
mode?: "validate" | "alternative" | "critique" | "brainstorm";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface ChatMessage {
|
|
36
|
+
role: "system" | "user" | "assistant";
|
|
37
|
+
content: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface ChatResponse {
|
|
41
|
+
choices?: Array<{
|
|
42
|
+
message?: {
|
|
43
|
+
content?: string;
|
|
44
|
+
};
|
|
45
|
+
}>;
|
|
46
|
+
error?: {
|
|
47
|
+
message?: string;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const SYSTEM_PROMPTS: Record<string, string> = {
|
|
52
|
+
validate: `You are a validation oracle. Your job is to critically examine the reasoning, approach, or solution presented to you.
|
|
53
|
+
|
|
54
|
+
Look for:
|
|
55
|
+
- Logical flaws or gaps in reasoning
|
|
56
|
+
- Edge cases that weren't considered
|
|
57
|
+
- Assumptions that may not hold
|
|
58
|
+
- Better alternatives if they exist
|
|
59
|
+
|
|
60
|
+
Be direct and specific. If the approach is sound, say so briefly. If there are issues, explain them clearly.`,
|
|
61
|
+
|
|
62
|
+
alternative: `You are an alternative perspective oracle. Your job is to suggest completely different approaches to the problem.
|
|
63
|
+
|
|
64
|
+
Focus on:
|
|
65
|
+
- Different architectural patterns
|
|
66
|
+
- Alternative technologies or libraries
|
|
67
|
+
- Unconventional but valid solutions
|
|
68
|
+
- Trade-offs the user may not have considered
|
|
69
|
+
|
|
70
|
+
Don't just validate - actively look for different ways to solve the problem.`,
|
|
71
|
+
|
|
72
|
+
critique: `You are a critical review oracle. Your job is to stress-test ideas and find weaknesses.
|
|
73
|
+
|
|
74
|
+
Examine:
|
|
75
|
+
- Security implications
|
|
76
|
+
- Performance concerns
|
|
77
|
+
- Maintainability issues
|
|
78
|
+
- Scalability problems
|
|
79
|
+
- Edge cases and failure modes
|
|
80
|
+
|
|
81
|
+
Be constructively critical. Point out problems but suggest how to address them.`,
|
|
82
|
+
|
|
83
|
+
brainstorm: `You are a brainstorming oracle. Your job is to expand on ideas and generate new possibilities.
|
|
84
|
+
|
|
85
|
+
Generate:
|
|
86
|
+
- Extensions to the proposed approach
|
|
87
|
+
- Creative variations
|
|
88
|
+
- Combinations with other techniques
|
|
89
|
+
- Future-proofing considerations
|
|
90
|
+
|
|
91
|
+
Be generative and expansive. Build on the ideas presented.`,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default tool({
|
|
95
|
+
description: `Get a second opinion from a different AI model for complex reasoning tasks.
|
|
96
|
+
|
|
97
|
+
Use when:
|
|
98
|
+
- Validating architectural decisions before implementing
|
|
99
|
+
- Cross-checking debugging hypotheses
|
|
100
|
+
- Getting alternative perspectives on tricky problems
|
|
101
|
+
- Breaking out of reasoning ruts or confirmation bias
|
|
102
|
+
|
|
103
|
+
Modes:
|
|
104
|
+
- validate: Check if reasoning is sound (default)
|
|
105
|
+
- alternative: Get completely different approaches
|
|
106
|
+
- critique: Stress-test ideas for weaknesses
|
|
107
|
+
- brainstorm: Expand and generate new possibilities
|
|
108
|
+
|
|
109
|
+
Models available:
|
|
110
|
+
${Object.entries(ORACLE_MODELS)
|
|
111
|
+
.map(([id, info]) => `- ${id}: ${info.strength}`)
|
|
112
|
+
.join("\n")}
|
|
113
|
+
|
|
114
|
+
Examples:
|
|
115
|
+
oracle({ question: "Is JWT the right choice for this API?", context: "Building a microservices auth system" })
|
|
116
|
+
oracle({ question: "Review this debugging approach", mode: "critique" })
|
|
117
|
+
oracle({ question: "What other ways could we implement caching?", mode: "alternative", model: "gpt-5.2-codex" })
|
|
118
|
+
`,
|
|
119
|
+
args: {
|
|
120
|
+
question: tool.schema
|
|
121
|
+
.string()
|
|
122
|
+
.describe("The question or problem to get a second opinion on"),
|
|
123
|
+
context: tool.schema
|
|
124
|
+
.string()
|
|
125
|
+
.optional()
|
|
126
|
+
.describe(
|
|
127
|
+
"Additional context about the problem, constraints, or current approach",
|
|
128
|
+
),
|
|
129
|
+
model: tool.schema
|
|
130
|
+
.string()
|
|
131
|
+
.optional()
|
|
132
|
+
.describe(
|
|
133
|
+
`Model to use for oracle (default: ${DEFAULT_MODEL}). Options: ${Object.keys(ORACLE_MODELS).join(", ")}`,
|
|
134
|
+
),
|
|
135
|
+
mode: tool.schema
|
|
136
|
+
.string()
|
|
137
|
+
.optional()
|
|
138
|
+
.describe(
|
|
139
|
+
"Oracle mode: validate (default), alternative, critique, or brainstorm",
|
|
140
|
+
),
|
|
141
|
+
},
|
|
142
|
+
execute: async (args) => {
|
|
143
|
+
const {
|
|
144
|
+
question,
|
|
145
|
+
context,
|
|
146
|
+
model = DEFAULT_MODEL,
|
|
147
|
+
mode = "validate",
|
|
148
|
+
} = args as OracleRequest;
|
|
149
|
+
|
|
150
|
+
if (!question || question.trim() === "") {
|
|
151
|
+
return "Error: question is required";
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Validate model
|
|
155
|
+
const modelInfo = ORACLE_MODELS[model];
|
|
156
|
+
if (!modelInfo) {
|
|
157
|
+
return `Error: Unknown model "${model}". Available models: ${Object.keys(ORACLE_MODELS).join(", ")}`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Validate mode
|
|
161
|
+
const validModes = ["validate", "alternative", "critique", "brainstorm"];
|
|
162
|
+
if (!validModes.includes(mode)) {
|
|
163
|
+
return `Error: Unknown mode "${mode}". Available modes: ${validModes.join(", ")}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Get system prompt for mode
|
|
167
|
+
const systemPrompt = SYSTEM_PROMPTS[mode];
|
|
168
|
+
|
|
169
|
+
// Build user message
|
|
170
|
+
let userMessage = question;
|
|
171
|
+
if (context) {
|
|
172
|
+
userMessage = `Context:\n${context}\n\nQuestion:\n${question}`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const messages: ChatMessage[] = [
|
|
176
|
+
{ role: "system", content: systemPrompt },
|
|
177
|
+
{ role: "user", content: userMessage },
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
// Call ProxyPal API
|
|
181
|
+
const PROXYPAL_BASE = "http://127.0.0.1:8317/v1";
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
const response = await fetch(`${PROXYPAL_BASE}/chat/completions`, {
|
|
185
|
+
method: "POST",
|
|
186
|
+
headers: {
|
|
187
|
+
"Content-Type": "application/json",
|
|
188
|
+
Authorization: "Bearer proxypal-local",
|
|
189
|
+
},
|
|
190
|
+
body: JSON.stringify({
|
|
191
|
+
model,
|
|
192
|
+
messages,
|
|
193
|
+
temperature: 0.7,
|
|
194
|
+
max_tokens: 4096,
|
|
195
|
+
}),
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
const errorText = await response.text();
|
|
200
|
+
return `Error: Oracle API returned ${response.status}: ${errorText}`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const data = (await response.json()) as ChatResponse;
|
|
204
|
+
|
|
205
|
+
if (data.error) {
|
|
206
|
+
return `Error: ${data.error.message || "Unknown error from oracle"}`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const content = data.choices?.[0]?.message?.content;
|
|
210
|
+
if (!content) {
|
|
211
|
+
return "Error: Oracle returned empty response";
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Format response with metadata
|
|
215
|
+
return `## Oracle Response (${modelInfo.name})
|
|
216
|
+
**Mode**: ${mode}
|
|
217
|
+
**Strength**: ${modelInfo.strength}
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
${content}
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
*Second opinion from ${model}*`;
|
|
225
|
+
} catch (error: unknown) {
|
|
226
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
227
|
+
|
|
228
|
+
if (
|
|
229
|
+
message.includes("ECONNREFUSED") ||
|
|
230
|
+
message.includes("fetch failed")
|
|
231
|
+
) {
|
|
232
|
+
return `Error: Cannot connect to ProxyPal at ${PROXYPAL_BASE}.
|
|
233
|
+
|
|
234
|
+
To start ProxyPal, run: proxypal start`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return `Error: Oracle query failed: ${message}`;
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
});
|
package/package.json
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencodekit",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.14",
|
|
4
4
|
"description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agents",
|
|
7
|
+
"cli",
|
|
8
|
+
"mcp",
|
|
9
|
+
"opencode",
|
|
10
|
+
"opencodekit",
|
|
11
|
+
"template"
|
|
12
|
+
],
|
|
6
13
|
"license": "MIT",
|
|
7
14
|
"author": "OpenCodeKit",
|
|
8
15
|
"repository": {
|
|
@@ -12,7 +19,10 @@
|
|
|
12
19
|
"bin": {
|
|
13
20
|
"ock": "dist/index.js"
|
|
14
21
|
},
|
|
15
|
-
"files": [
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"README.md"
|
|
25
|
+
],
|
|
16
26
|
"type": "module",
|
|
17
27
|
"publishConfig": {
|
|
18
28
|
"access": "public",
|
|
@@ -56,5 +66,7 @@
|
|
|
56
66
|
"engines": {
|
|
57
67
|
"bun": ">=1.3.2"
|
|
58
68
|
},
|
|
59
|
-
"trustedDependencies": [
|
|
69
|
+
"trustedDependencies": [
|
|
70
|
+
"@beads/bd"
|
|
71
|
+
]
|
|
60
72
|
}
|