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.
Files changed (23) hide show
  1. package/README.md +4 -4
  2. package/dist/index.js +16 -4
  3. package/dist/template/.opencode/AGENTS.md +28 -3
  4. package/dist/template/.opencode/README.md +7 -4
  5. package/dist/template/.opencode/agent/scout.md +117 -27
  6. package/dist/template/.opencode/command/research-ui.md +1 -1
  7. package/dist/template/.opencode/command/research.md +56 -62
  8. package/dist/template/.opencode/memory/observations/2026-01-28-decision-created-deep-research-skill-for-thorough.md +29 -0
  9. package/dist/template/.opencode/memory/observations/2026-01-28-decision-gh-grep-mcp-wrapper-vs-native-grep-searc.md +21 -0
  10. package/dist/template/.opencode/memory/observations/2026-01-28-decision-oracle-tool-optimal-usage-patterns.md +32 -0
  11. package/dist/template/.opencode/memory/observations/2026-01-28-learning-ampcode-deep-mode-research-integration-w.md +42 -0
  12. package/dist/template/.opencode/memory/observations/2026-01-28-pattern-research-delegation-pattern-explore-for-.md +32 -0
  13. package/dist/template/.opencode/memory/research/opencode-mcp-bug-report.md +5 -2
  14. package/dist/template/.opencode/opencode.json +697 -812
  15. package/dist/template/.opencode/plans/1768385996691-silent-wizard.md +12 -2
  16. package/dist/template/.opencode/skill/deep-research/SKILL.md +385 -0
  17. package/dist/template/.opencode/skill/source-code-research/SKILL.md +8 -8
  18. package/dist/template/.opencode/skill/tool-priority/SKILL.md +8 -6
  19. package/dist/template/.opencode/tool/context7-query-docs.ts +89 -0
  20. package/dist/template/.opencode/tool/context7-resolve-library-id.ts +113 -0
  21. package/dist/template/.opencode/tool/grep-search.ts +135 -0
  22. package/dist/template/.opencode/tool/oracle.ts +240 -0
  23. 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(/&lt;/g, "<")
112
+ .replace(/&gt;/g, ">")
113
+ .replace(/&amp;/g, "&")
114
+ .replace(/&quot;/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.12",
3
+ "version": "0.15.14",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
- "keywords": ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
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": ["dist", "README.md"],
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": ["@beads/bd"]
69
+ "trustedDependencies": [
70
+ "@beads/bd"
71
+ ]
60
72
  }