opencodekit 0.23.1 → 0.23.3
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/dist/index.js +354 -825
- package/dist/template/.opencode/AGENTS.md +15 -2
- package/dist/template/.opencode/command/init.md +198 -34
- package/dist/template/.opencode/context/fallow.md +137 -0
- package/dist/template/.opencode/opencode.json +12 -315
- package/dist/template/.opencode/plugin/codesearch.ts +730 -0
- package/dist/template/.opencode/plugin/memory/compile.ts +171 -186
- package/dist/template/.opencode/plugin/memory/index-generator.ts +118 -133
- package/dist/template/.opencode/plugin/memory/lint.ts +253 -275
- package/dist/template/.opencode/plugin/memory/tools.ts +224 -268
- package/dist/template/.opencode/plugin/memory/validate.ts +154 -164
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search-preview.ts +13 -30
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search-shared.ts +25 -0
- package/dist/template/.opencode/plugin/sdk/copilot/responses/tool/web-search.ts +17 -34
- package/dist/template/.opencode/plugin/session-summary.ts +0 -2
- package/dist/template/.opencode/plugin/srcwalk.ts +646 -667
- package/dist/template/.opencode/skill/code-navigation/SKILL.md +10 -10
- package/dist/template/.opencode/skill/code-review-and-quality/SKILL.md +1 -1
- package/dist/template/.opencode/skill/condition-based-waiting/example.ts +15 -2
- package/dist/template/.opencode/skill/debugging-and-error-recovery/SKILL.md +1 -1
- package/dist/template/.opencode/skill/deep-module-design/SKILL.md +1 -1
- package/dist/template/.opencode/skill/fallow/SKILL.md +409 -0
- package/dist/template/.opencode/skill/fallow/references/cli-reference.md +1905 -0
- package/dist/template/.opencode/skill/fallow/references/gotchas.md +644 -0
- package/dist/template/.opencode/skill/fallow/references/patterns.md +791 -0
- package/dist/template/.opencode/skill/planning-and-task-breakdown/SKILL.md +1 -1
- package/dist/template/.opencode/skill/srcwalk/SKILL.md +10 -13
- package/dist/template/.opencode/skill/ubiquitous-language/SKILL.md +1 -1
- package/dist/template/.opencode/tool/grepsearch.ts +92 -103
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ version: 1.0.0
|
|
|
5
5
|
tags: [workflow, planning, agent-coordination]
|
|
6
6
|
dependencies: [spec-driven-development]
|
|
7
7
|
agent_types: [planner]
|
|
8
|
-
tools: [TaskCreate, TaskUpdate, memory,
|
|
8
|
+
tools: [TaskCreate, TaskUpdate, memory, grep]
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Planning & Task Breakdown
|
|
@@ -6,7 +6,7 @@ version: 2.1.0
|
|
|
6
6
|
tags: [code-intelligence, search, cli, srcwalk]
|
|
7
7
|
dependencies: []
|
|
8
8
|
agent_types: [planner, worker, reviewer, explorer]
|
|
9
|
-
tools: [bash,
|
|
9
|
+
tools: [bash, srcwalk_read, srcwalk_deps, srcwalk_map, srcwalk_callers, srcwalk_callees, srcwalk_flow, srcwalk_impact]
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Srcwalk — Code Navigation
|
|
@@ -41,9 +41,7 @@ Do not pipe, truncate, or summarize `srcwalk guide`.
|
|
|
41
41
|
|
|
42
42
|
| Tool | Srcwalk command | Purpose |
|
|
43
43
|
|---|---|---|
|
|
44
|
-
| `srcwalk_search` | `srcwalk discover` / `srcwalk trace callers` | AST-aware symbol/content/regex/callers search |
|
|
45
44
|
| `srcwalk_read` | `srcwalk <path>` | Smart file reading: outline or full with sections |
|
|
46
|
-
| `srcwalk_files` | `srcwalk discover --as file` | Glob file finding with token estimates, grouped by dir |
|
|
47
45
|
| `srcwalk_deps` | `srcwalk deps` + exact import scan | Blast-radius: importers + dep-aware dependents (v1.0.0) |
|
|
48
46
|
|
|
49
47
|
### Extended analysis tools
|
|
@@ -65,9 +63,9 @@ Do not pipe, truncate, or summarize `srcwalk guide`.
|
|
|
65
63
|
| Jump to exact line | `srcwalk_read({ path: "file:42" })` |
|
|
66
64
|
| Read a line range | `srcwalk_read({ path: "file:44-89" })` — v1.0.0 shortcut |
|
|
67
65
|
| Read by symbol name | `srcwalk_read({ section: "symbolName" })` |
|
|
68
|
-
| Find
|
|
69
|
-
| Find files by glob | `
|
|
70
|
-
| Multi-symbol search | `
|
|
66
|
+
| Find patterns and symbols | `grep` (exact), `csearch` (multi-keyword) |
|
|
67
|
+
| Find files by glob | `glob` |
|
|
68
|
+
| Multi-symbol search | `grep({ pattern: "A|B|C" })` |
|
|
71
69
|
| Who directly calls this? | `srcwalk_callers` |
|
|
72
70
|
| Who reaches this transitively? | `srcwalk_callers({ depth: 2 })` |
|
|
73
71
|
| What does this call? | `srcwalk_callees` |
|
|
@@ -82,7 +80,7 @@ Do not pipe, truncate, or summarize `srcwalk guide`.
|
|
|
82
80
|
|
|
83
81
|
```
|
|
84
82
|
srcwalk_map({ scope: "." })
|
|
85
|
-
|
|
83
|
+
grep({ pattern: "likely_symbol", path: "src/" })
|
|
86
84
|
srcwalk_read({ path: "src/file.ts:42" }) // jump to line
|
|
87
85
|
srcwalk_read({ path: "src/file.ts:44-89" }) // range shortcut (v1.0.0)
|
|
88
86
|
```
|
|
@@ -100,9 +98,9 @@ Prefer outline/section reads before `full: true`.
|
|
|
100
98
|
### Find and drill into symbols
|
|
101
99
|
|
|
102
100
|
```
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
grep({ pattern: "handleAuth", path: "src/" })
|
|
102
|
+
grep({ pattern: "A|B|C", path: "src/" }) // multi-symbol
|
|
103
|
+
csearch({ query: "auth token login middleware" }) // multi-keyword chunk search
|
|
106
104
|
```
|
|
107
105
|
|
|
108
106
|
### Trace call graph
|
|
@@ -123,7 +121,7 @@ srcwalk_callees({ symbol: "handleAuth", depth: 2, scope: "src" }) // trans
|
|
|
123
121
|
srcwalk_flow({ symbol: "handleAuth", scope: "src" })
|
|
124
122
|
```
|
|
125
123
|
|
|
126
|
-
Use `
|
|
124
|
+
Use `grep` for quick single-hop searches. Use `srcwalk_callers` when you need depth, filters, or aggregation.
|
|
127
125
|
|
|
128
126
|
> Note: `--count-by` and `--depth` are mutually exclusive in `srcwalk_callers` — use one or the other, not both.
|
|
129
127
|
|
|
@@ -143,8 +141,7 @@ srcwalk_impact({ symbol: "handleAuth", scope: "src" }) // heuristic; follow up
|
|
|
143
141
|
|
|
144
142
|
## Critical Rules
|
|
145
143
|
|
|
146
|
-
- **Do NOT** use built-in `read`/`
|
|
147
|
-
- **Do NOT** re-read files already shown in expanded `srcwalk_search` results
|
|
144
|
+
- **Do NOT** use built-in `read`/`find` when srcwalk_* tools can answer; `grep` is preferred for text searches
|
|
148
145
|
- `srcwalk_impact` is heuristic, not proof — verify with `srcwalk_callers` or exact reads
|
|
149
146
|
- `srcwalk_flow` may collapse nested/fluent chains — drill with `srcwalk_callees({ detailed: true })` when inner calls matter
|
|
150
147
|
- Follow `> Next:` footers in output — they suggest the best next command
|
|
@@ -3,19 +3,19 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
3
3
|
const GREP_APP_API = "https://grep.app/api/search";
|
|
4
4
|
|
|
5
5
|
interface SearchResult {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
repo: string;
|
|
7
|
+
path: string;
|
|
8
|
+
content: { snippet: string };
|
|
9
|
+
total_matches: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
interface GrepResponse {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
hits: { hits: SearchResult[] };
|
|
14
|
+
time: number;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export default tool({
|
|
18
|
-
|
|
18
|
+
description: `Search real-world code examples from GitHub repositories via grep.app. Replaces asking "how do others use X?" — use this for finding production patterns and real-world API usage.
|
|
19
19
|
|
|
20
20
|
WHEN: Implementing unfamiliar APIs, looking for production patterns, understanding library integrations.
|
|
21
21
|
SKIP: Searching your own codebase (use grep/srcwalk), looking up docs (use context7), general research (use websearch).
|
|
@@ -31,113 +31,102 @@ Use when:
|
|
|
31
31
|
- Understanding library integrations - see how things work together
|
|
32
32
|
|
|
33
33
|
IMPORTANT: Search for **literal code patterns**, not keywords:
|
|
34
|
-
|
|
35
|
-
❌ Bad: "react tutorial", "best practices", "how to use"
|
|
34
|
+
Good: "useState(", "import React from", "async function"
|
|
36
35
|
|
|
36
|
+
Bad: "react tutorial", "best practices", "how to use"
|
|
37
37
|
Examples:
|
|
38
38
|
grepsearch({ query: "getServerSession", language: "TypeScript" })
|
|
39
39
|
grepsearch({ query: "CORS(", language: "Python", repo: "flask" })
|
|
40
40
|
grepsearch({ query: "export async function POST", path: "route.ts" })
|
|
41
41
|
`,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
.replace(/<[^>]*>/g, "") // Remove HTML tags
|
|
119
|
-
.replace(/</g, "<")
|
|
120
|
-
.replace(/>/g, ">")
|
|
121
|
-
.replace(/&/g, "&")
|
|
122
|
-
.replace(/"/g, '"')
|
|
123
|
-
.split("\n")
|
|
124
|
-
.slice(0, 8)
|
|
125
|
-
.join("\n")
|
|
126
|
-
.trim();
|
|
127
|
-
|
|
128
|
-
return `## ${i + 1}. ${repoName}
|
|
42
|
+
args: {
|
|
43
|
+
query: tool.schema.string().describe("Code pattern to search for (literal text)"),
|
|
44
|
+
language: tool.schema
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe("Filter by language: TypeScript, TSX, Python, Go, Rust, etc."),
|
|
48
|
+
repo: tool.schema.string().optional().describe("Filter by repo: 'owner/repo' or partial match"),
|
|
49
|
+
path: tool.schema.string().optional().describe("Filter by file path: 'src/', '.test.ts', etc."),
|
|
50
|
+
limit: tool.schema.number().optional().describe("Max results to return (default: 10, max: 20)"),
|
|
51
|
+
},
|
|
52
|
+
execute: async (args) => {
|
|
53
|
+
const { query, language, repo, path, limit = 10 } = args;
|
|
54
|
+
|
|
55
|
+
if (!query || query.trim() === "") {
|
|
56
|
+
return "Error: query is required";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Build URL with proper filter parameters
|
|
60
|
+
// grep.app uses filter[lang][0]=TypeScript format, NOT inline lang:TypeScript
|
|
61
|
+
const url = new URL(GREP_APP_API);
|
|
62
|
+
url.searchParams.set("q", query);
|
|
63
|
+
|
|
64
|
+
// Add language filter (grep.app uses filter[lang][0] format)
|
|
65
|
+
if (language) {
|
|
66
|
+
url.searchParams.set("filter[lang][0]", language);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Add repo filter
|
|
70
|
+
if (repo) {
|
|
71
|
+
url.searchParams.set("filter[repo][0]", repo);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Add path filter
|
|
75
|
+
if (path) {
|
|
76
|
+
url.searchParams.set("filter[path][0]", path);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(url.toString(), {
|
|
81
|
+
headers: {
|
|
82
|
+
Accept: "application/json",
|
|
83
|
+
"User-Agent": "OpenCode/1.0",
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
return `Error: grep.app API returned ${response.status}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const data = (await response.json()) as GrepResponse;
|
|
92
|
+
|
|
93
|
+
if (!data.hits?.hits?.length) {
|
|
94
|
+
return `No results found for: ${query}${language ? ` (${language})` : ""}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const maxResults = Math.min(limit, 20);
|
|
98
|
+
const results = data.hits.hits.slice(0, maxResults);
|
|
99
|
+
|
|
100
|
+
const formatted = results.map((hit, i) => {
|
|
101
|
+
const repoName = hit.repo || "unknown";
|
|
102
|
+
const filePath = hit.path || "unknown";
|
|
103
|
+
const snippet = hit.content?.snippet || "";
|
|
104
|
+
|
|
105
|
+
// Clean up HTML from snippet and extract text
|
|
106
|
+
const cleanCode = snippet
|
|
107
|
+
.replace(/<[^>]*>/g, "") // Remove HTML tags
|
|
108
|
+
.replace(/</g, "<")
|
|
109
|
+
.replace(/>/g, ">")
|
|
110
|
+
.replace(/&/g, "&")
|
|
111
|
+
.replace(/"/g, '"')
|
|
112
|
+
.split("\n")
|
|
113
|
+
.slice(0, 8)
|
|
114
|
+
.join("\n")
|
|
115
|
+
.trim();
|
|
116
|
+
|
|
117
|
+
return `## ${i + 1}. ${repoName}
|
|
129
118
|
**File**: ${filePath}
|
|
130
119
|
\`\`\`
|
|
131
120
|
${cleanCode}
|
|
132
121
|
\`\`\``;
|
|
133
|
-
|
|
122
|
+
});
|
|
134
123
|
|
|
135
|
-
|
|
124
|
+
return `Found ${data.hits.hits.length} results (showing ${results.length}) in ${data.time}ms:
|
|
136
125
|
|
|
137
126
|
${formatted.join("\n\n")}`;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
127
|
+
} catch (error: unknown) {
|
|
128
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
129
|
+
return `Error searching grep.app: ${message}`;
|
|
130
|
+
}
|
|
131
|
+
},
|
|
143
132
|
});
|