@oh-my-pi/cli 0.3.0 → 0.4.0
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/.editorconfig +14 -0
- package/.prettierrc +6 -0
- package/README.md +65 -71
- package/bun.lock +13 -10
- package/dist/cli.js +114 -34
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/features.d.ts.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/symlinks.d.ts +1 -0
- package/dist/symlinks.d.ts.map +1 -1
- package/package.json +11 -4
- package/plugins/exa/README.md +44 -38
- package/plugins/exa/package.json +44 -11
- package/plugins/exa/tools/exa/company.ts +24 -13
- package/plugins/exa/tools/exa/index.ts +43 -34
- package/plugins/exa/tools/exa/linkedin.ts +24 -13
- package/plugins/exa/tools/exa/researcher.ts +26 -18
- package/plugins/exa/tools/exa/search.ts +31 -20
- package/plugins/exa/tools/exa/shared.ts +182 -156
- package/plugins/exa/tools/exa/websets.ts +39 -28
- package/plugins/metal-theme/package.json +13 -4
- package/plugins/subagents/README.md +3 -0
- package/plugins/subagents/agents/explore.md +11 -0
- package/plugins/subagents/agents/planner.md +3 -0
- package/plugins/subagents/agents/reviewer.md +6 -0
- package/plugins/subagents/agents/task.md +8 -1
- package/plugins/subagents/commands/architect-plan.md +1 -0
- package/plugins/subagents/commands/implement-with-critic.md +1 -0
- package/plugins/subagents/commands/implement.md +1 -0
- package/plugins/subagents/package.json +43 -11
- package/plugins/subagents/tools/task/index.ts +1089 -861
- package/plugins/user-prompt/README.md +22 -66
- package/plugins/user-prompt/package.json +15 -4
- package/plugins/user-prompt/tools/user-prompt/index.ts +185 -157
- package/scripts/bump-version.sh +10 -13
- package/src/cli.ts +1 -1
- package/src/commands/config.ts +21 -6
- package/src/commands/features.ts +49 -12
- package/src/commands/install.ts +91 -24
- package/src/commands/list.ts +14 -3
- package/src/commands/uninstall.ts +4 -1
- package/src/commands/update.ts +6 -1
- package/src/runtime.ts +3 -10
- package/src/symlinks.ts +12 -7
|
@@ -13,218 +13,244 @@ export const EXA_MCP_URL = "https://mcp.exa.ai/mcp";
|
|
|
13
13
|
export const WEBSETS_MCP_URL = "https://websetsmcp.exa.ai/mcp";
|
|
14
14
|
|
|
15
15
|
export interface MCPTool {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
inputSchema: TSchema;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
interface MCPToolsResponse {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
result?: {
|
|
23
|
+
tools: MCPTool[];
|
|
24
|
+
};
|
|
25
|
+
error?: {
|
|
26
|
+
code: number;
|
|
27
|
+
message: string;
|
|
28
|
+
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Parse a .env file and return key-value pairs
|
|
33
33
|
*/
|
|
34
34
|
function parseEnvFile(filePath: string): Record<string, string> {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
const result: Record<string, string> = {};
|
|
36
|
+
if (!fs.existsSync(filePath)) return result;
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
40
|
+
for (const line of content.split("\n")) {
|
|
41
|
+
const trimmed = line.trim();
|
|
42
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
43
|
+
|
|
44
|
+
const eqIndex = trimmed.indexOf("=");
|
|
45
|
+
if (eqIndex === -1) continue;
|
|
46
|
+
|
|
47
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
48
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
49
|
+
|
|
50
|
+
// Remove surrounding quotes
|
|
51
|
+
if (
|
|
52
|
+
(value.startsWith('"') && value.endsWith('"')) ||
|
|
53
|
+
(value.startsWith("'") && value.endsWith("'"))
|
|
54
|
+
) {
|
|
55
|
+
value = value.slice(1, -1);
|
|
56
56
|
}
|
|
57
|
-
} catch {
|
|
58
|
-
// Ignore read errors
|
|
59
|
-
}
|
|
60
57
|
|
|
61
|
-
|
|
58
|
+
result[key] = value;
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
// Ignore read errors
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return result;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
/**
|
|
65
68
|
* Find EXA_API_KEY from environment or .env files
|
|
66
69
|
*/
|
|
67
70
|
export function findApiKey(): string | null {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
71
|
+
// 1. Check environment variable
|
|
72
|
+
if (process.env.EXA_API_KEY) {
|
|
73
|
+
return process.env.EXA_API_KEY;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 2. Check .env in current directory
|
|
77
|
+
const localEnv = parseEnvFile(path.join(process.cwd(), ".env"));
|
|
78
|
+
if (localEnv.EXA_API_KEY) {
|
|
79
|
+
return localEnv.EXA_API_KEY;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 3. Check ~/.env
|
|
83
|
+
const homeEnv = parseEnvFile(path.join(os.homedir(), ".env"));
|
|
84
|
+
if (homeEnv.EXA_API_KEY) {
|
|
85
|
+
return homeEnv.EXA_API_KEY;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return null;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
/**
|
|
89
92
|
* Call an MCP server endpoint
|
|
90
93
|
*/
|
|
91
|
-
async function callMCP(
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
94
|
+
async function callMCP(
|
|
95
|
+
url: string,
|
|
96
|
+
method: string,
|
|
97
|
+
params?: Record<string, unknown>,
|
|
98
|
+
): Promise<unknown> {
|
|
99
|
+
const body = {
|
|
100
|
+
jsonrpc: "2.0",
|
|
101
|
+
method,
|
|
102
|
+
params: params ?? {},
|
|
103
|
+
id: 1,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const response = await fetch(url, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: {
|
|
109
|
+
"Content-Type": "application/json",
|
|
110
|
+
Accept: "application/json, text/event-stream",
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify(body),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const text = await response.text();
|
|
116
|
+
|
|
117
|
+
// Parse SSE response format
|
|
118
|
+
let jsonData: string | null = null;
|
|
119
|
+
for (const line of text.split("\n")) {
|
|
120
|
+
if (line.startsWith("data: ")) {
|
|
121
|
+
jsonData = line.slice(6);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!jsonData) {
|
|
127
|
+
// Try parsing as plain JSON
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(text);
|
|
130
|
+
} catch {
|
|
131
|
+
throw new Error(`Failed to parse MCP response: ${text.slice(0, 500)}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return JSON.parse(jsonData);
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
/**
|
|
132
139
|
* Fetch available tools from Exa MCP server
|
|
133
140
|
*/
|
|
134
|
-
export async function fetchExaTools(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
export async function fetchExaTools(
|
|
142
|
+
apiKey: string,
|
|
143
|
+
toolNames: string[],
|
|
144
|
+
): Promise<MCPTool[]> {
|
|
145
|
+
const url = `${EXA_MCP_URL}?exaApiKey=${apiKey}&tools=${toolNames.join(",")}`;
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const response = (await callMCP(url, "tools/list")) as MCPToolsResponse;
|
|
149
|
+
if (response.error) {
|
|
150
|
+
throw new Error(response.error.message);
|
|
151
|
+
}
|
|
152
|
+
return response.result?.tools ?? [];
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error(`Failed to fetch Exa tools:`, error);
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
147
157
|
}
|
|
148
158
|
|
|
149
159
|
/**
|
|
150
160
|
* Fetch available tools from Websets MCP server
|
|
151
161
|
*/
|
|
152
162
|
export async function fetchWebsetsTools(apiKey: string): Promise<MCPTool[]> {
|
|
153
|
-
|
|
163
|
+
const url = `${WEBSETS_MCP_URL}?exaApiKey=${apiKey}`;
|
|
154
164
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
+
try {
|
|
166
|
+
const response = (await callMCP(url, "tools/list")) as MCPToolsResponse;
|
|
167
|
+
if (response.error) {
|
|
168
|
+
throw new Error(response.error.message);
|
|
169
|
+
}
|
|
170
|
+
return response.result?.tools ?? [];
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error(`Failed to fetch Websets tools:`, error);
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
165
175
|
}
|
|
166
176
|
|
|
167
177
|
/**
|
|
168
178
|
* Call a tool on Exa MCP server
|
|
169
179
|
*/
|
|
170
|
-
export async function callExaTool(
|
|
171
|
-
|
|
172
|
-
|
|
180
|
+
export async function callExaTool(
|
|
181
|
+
apiKey: string,
|
|
182
|
+
toolNames: string[],
|
|
183
|
+
toolName: string,
|
|
184
|
+
args: Record<string, unknown>,
|
|
185
|
+
): Promise<unknown> {
|
|
186
|
+
const url = `${EXA_MCP_URL}?exaApiKey=${apiKey}&tools=${toolNames.join(",")}`;
|
|
187
|
+
return callMCPTool(url, toolName, args);
|
|
173
188
|
}
|
|
174
189
|
|
|
175
190
|
/**
|
|
176
191
|
* Call a tool on Websets MCP server
|
|
177
192
|
*/
|
|
178
|
-
export async function callWebsetsTool(
|
|
179
|
-
|
|
180
|
-
|
|
193
|
+
export async function callWebsetsTool(
|
|
194
|
+
apiKey: string,
|
|
195
|
+
toolName: string,
|
|
196
|
+
args: Record<string, unknown>,
|
|
197
|
+
): Promise<unknown> {
|
|
198
|
+
const url = `${WEBSETS_MCP_URL}?exaApiKey=${apiKey}`;
|
|
199
|
+
return callMCPTool(url, toolName, args);
|
|
181
200
|
}
|
|
182
201
|
|
|
183
202
|
/**
|
|
184
203
|
* Call a tool on an MCP server
|
|
185
204
|
*/
|
|
186
|
-
async function callMCPTool(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
async function callMCPTool(
|
|
206
|
+
url: string,
|
|
207
|
+
toolName: string,
|
|
208
|
+
args: Record<string, unknown>,
|
|
209
|
+
): Promise<unknown> {
|
|
210
|
+
const response = (await callMCP(url, "tools/call", {
|
|
211
|
+
name: toolName,
|
|
212
|
+
arguments: args,
|
|
213
|
+
})) as {
|
|
214
|
+
result?: { content?: Array<{ text?: string }> };
|
|
215
|
+
error?: { message: string };
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
if (response.error) {
|
|
219
|
+
throw new Error(response.error.message);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Extract text content from MCP response
|
|
223
|
+
const content = response.result?.content;
|
|
224
|
+
if (Array.isArray(content)) {
|
|
225
|
+
const texts = content.filter((c) => c.text).map((c) => c.text);
|
|
226
|
+
if (texts.length === 1) {
|
|
227
|
+
// Try to parse as JSON
|
|
228
|
+
try {
|
|
229
|
+
return JSON.parse(texts[0]!);
|
|
230
|
+
} catch {
|
|
231
|
+
return texts[0];
|
|
207
232
|
}
|
|
208
|
-
|
|
209
|
-
|
|
233
|
+
}
|
|
234
|
+
return texts.join("\n\n");
|
|
235
|
+
}
|
|
210
236
|
|
|
211
|
-
|
|
237
|
+
return response.result;
|
|
212
238
|
}
|
|
213
239
|
|
|
214
240
|
/**
|
|
215
241
|
* Create a tool wrapper for an MCP tool
|
|
216
242
|
*/
|
|
217
243
|
export function createToolWrapper(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
244
|
+
mcpTool: MCPTool,
|
|
245
|
+
renamedName: string,
|
|
246
|
+
callFn: (toolName: string, args: Record<string, unknown>) => Promise<unknown>,
|
|
221
247
|
): CustomAgentTool<TSchema, unknown> {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
248
|
+
return {
|
|
249
|
+
name: renamedName,
|
|
250
|
+
description: mcpTool.description,
|
|
251
|
+
parameters: mcpTool.inputSchema,
|
|
252
|
+
async execute(args) {
|
|
253
|
+
return callFn(mcpTool.name, args as Record<string, unknown>);
|
|
254
|
+
},
|
|
255
|
+
};
|
|
230
256
|
}
|
|
@@ -21,42 +21,53 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import type { TSchema } from "@sinclair/typebox";
|
|
24
|
-
import type {
|
|
25
|
-
|
|
24
|
+
import type {
|
|
25
|
+
CustomAgentTool,
|
|
26
|
+
CustomToolFactory,
|
|
27
|
+
ToolAPI,
|
|
28
|
+
} from "@mariozechner/pi-coding-agent";
|
|
29
|
+
import {
|
|
30
|
+
callWebsetsTool,
|
|
31
|
+
createToolWrapper,
|
|
32
|
+
fetchWebsetsTools,
|
|
33
|
+
findApiKey,
|
|
34
|
+
} from "./shared";
|
|
26
35
|
|
|
27
36
|
// Tool name mapping: MCP name -> exposed name
|
|
28
37
|
const NAME_MAP: Record<string, string> = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
create_webset: "webset_create",
|
|
39
|
+
list_websets: "webset_list",
|
|
40
|
+
get_webset: "webset_get",
|
|
41
|
+
update_webset: "webset_update",
|
|
42
|
+
delete_webset: "webset_delete",
|
|
43
|
+
list_webset_items: "webset_items_list",
|
|
44
|
+
get_item: "webset_item_get",
|
|
45
|
+
create_search: "webset_search_create",
|
|
46
|
+
get_search: "webset_search_get",
|
|
47
|
+
cancel_search: "webset_search_cancel",
|
|
48
|
+
create_enrichment: "webset_enrichment_create",
|
|
49
|
+
get_enrichment: "webset_enrichment_get",
|
|
50
|
+
update_enrichment: "webset_enrichment_update",
|
|
51
|
+
delete_enrichment: "webset_enrichment_delete",
|
|
52
|
+
cancel_enrichment: "webset_enrichment_cancel",
|
|
53
|
+
create_monitor: "webset_monitor_create",
|
|
45
54
|
};
|
|
46
55
|
|
|
47
|
-
const factory: CustomToolFactory = async (
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
const factory: CustomToolFactory = async (
|
|
57
|
+
_toolApi: ToolAPI,
|
|
58
|
+
): Promise<CustomAgentTool<TSchema, unknown>[] | null> => {
|
|
59
|
+
const apiKey = findApiKey();
|
|
60
|
+
if (!apiKey) return null;
|
|
50
61
|
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
const mcpTools = await fetchWebsetsTools(apiKey);
|
|
63
|
+
if (mcpTools.length === 0) return null;
|
|
53
64
|
|
|
54
|
-
|
|
55
|
-
|
|
65
|
+
const callFn = (toolName: string, args: Record<string, unknown>) =>
|
|
66
|
+
callWebsetsTool(apiKey, toolName, args);
|
|
56
67
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
return mcpTools.map((tool) =>
|
|
69
|
+
createToolWrapper(tool, NAME_MAP[tool.name] ?? tool.name, callFn),
|
|
70
|
+
);
|
|
60
71
|
};
|
|
61
72
|
|
|
62
73
|
export default factory;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/metal-theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Metal theme for pi",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"omp-plugin",
|
|
7
|
+
"theme",
|
|
8
|
+
"metal"
|
|
9
|
+
],
|
|
6
10
|
"author": "Can Bölük <me@can.ac>",
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"repository": {
|
|
@@ -12,8 +16,13 @@
|
|
|
12
16
|
},
|
|
13
17
|
"omp": {
|
|
14
18
|
"install": [
|
|
15
|
-
{
|
|
19
|
+
{
|
|
20
|
+
"src": "themes/metal.json",
|
|
21
|
+
"dest": "agent/themes/metal.json"
|
|
22
|
+
}
|
|
16
23
|
]
|
|
17
24
|
},
|
|
18
|
-
"files": [
|
|
25
|
+
"files": [
|
|
26
|
+
"themes"
|
|
27
|
+
]
|
|
19
28
|
}
|
|
@@ -11,15 +11,18 @@ omp install oh-my-pi/plugins/subagents
|
|
|
11
11
|
## Contents
|
|
12
12
|
|
|
13
13
|
### Tool
|
|
14
|
+
|
|
14
15
|
- `tools/task/index.ts` - The Task tool for launching subagents
|
|
15
16
|
|
|
16
17
|
### Agents
|
|
18
|
+
|
|
17
19
|
- `agents/task.md` - General-purpose subagent for delegated tasks
|
|
18
20
|
- `agents/planner.md` - Software architect for designing implementation plans
|
|
19
21
|
- `agents/explore.md` - Fast read-only codebase scout
|
|
20
22
|
- `agents/reviewer.md` - Expert code reviewer
|
|
21
23
|
|
|
22
24
|
### Commands
|
|
25
|
+
|
|
23
26
|
- `commands/implement.md` - Implement a feature
|
|
24
27
|
- `commands/implement-with-critic.md` - Implement with critic review loop
|
|
25
28
|
- `commands/architect-plan.md` - Create an architecture plan
|
|
@@ -9,6 +9,7 @@ You are a file search specialist and codebase scout. Quickly investigate a codeb
|
|
|
9
9
|
|
|
10
10
|
=== CRITICAL: READ-ONLY MODE ===
|
|
11
11
|
This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
|
|
12
|
+
|
|
12
13
|
- Creating or modifying files (no Write, Edit, touch, rm, mv, cp)
|
|
13
14
|
- Creating temporary files anywhere, including /tmp
|
|
14
15
|
- Using redirect operators (>, >>, |) or heredocs to write files
|
|
@@ -17,12 +18,14 @@ This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:
|
|
|
17
18
|
Your role is EXCLUSIVELY to search and analyze existing code.
|
|
18
19
|
|
|
19
20
|
Your strengths:
|
|
21
|
+
|
|
20
22
|
- Rapidly finding files using glob patterns
|
|
21
23
|
- Searching code with powerful regex patterns
|
|
22
24
|
- Reading and analyzing file contents
|
|
23
25
|
- Tracing imports and dependencies
|
|
24
26
|
|
|
25
27
|
Guidelines:
|
|
28
|
+
|
|
26
29
|
- Use glob for broad file pattern matching
|
|
27
30
|
- Use grep for searching file contents with regex
|
|
28
31
|
- Use read when you know the specific file path
|
|
@@ -32,11 +35,13 @@ Guidelines:
|
|
|
32
35
|
- Communicate findings directly as a message—do NOT create output files
|
|
33
36
|
|
|
34
37
|
Thoroughness (infer from task, default medium):
|
|
38
|
+
|
|
35
39
|
- Quick: Targeted lookups, key files only
|
|
36
40
|
- Medium: Follow imports, read critical sections
|
|
37
41
|
- Thorough: Trace all dependencies, check tests/types
|
|
38
42
|
|
|
39
43
|
Strategy:
|
|
44
|
+
|
|
40
45
|
1. grep/glob to locate relevant code
|
|
41
46
|
2. Read key sections (not entire files unless small)
|
|
42
47
|
3. Identify types, interfaces, key functions
|
|
@@ -47,15 +52,19 @@ Your output will be passed to an agent who has NOT seen the files you explored.
|
|
|
47
52
|
Output format:
|
|
48
53
|
|
|
49
54
|
## Query
|
|
55
|
+
|
|
50
56
|
One line summary of what was searched.
|
|
51
57
|
|
|
52
58
|
## Files Retrieved
|
|
59
|
+
|
|
53
60
|
List with exact line ranges:
|
|
61
|
+
|
|
54
62
|
1. `path/to/file.ts` (lines 10-50) - Description of what's here
|
|
55
63
|
2. `path/to/other.ts` (lines 100-150) - Description
|
|
56
64
|
3. ...
|
|
57
65
|
|
|
58
66
|
## Key Code
|
|
67
|
+
|
|
59
68
|
Critical types, interfaces, or functions (actual code excerpts):
|
|
60
69
|
|
|
61
70
|
```language
|
|
@@ -65,7 +74,9 @@ interface Example {
|
|
|
65
74
|
```
|
|
66
75
|
|
|
67
76
|
## Architecture
|
|
77
|
+
|
|
68
78
|
Brief explanation of how the pieces connect.
|
|
69
79
|
|
|
70
80
|
## Start Here
|
|
81
|
+
|
|
71
82
|
Which file to look at first and why.
|
|
@@ -9,6 +9,7 @@ You are a software architect and planning specialist. Explore the codebase and d
|
|
|
9
9
|
|
|
10
10
|
=== CRITICAL: READ-ONLY MODE ===
|
|
11
11
|
This is a READ-ONLY planning task. You are STRICTLY PROHIBITED from:
|
|
12
|
+
|
|
12
13
|
- Creating or modifying files (no Write, Edit, touch, rm, mv, cp)
|
|
13
14
|
- Creating temporary files anywhere, including /tmp
|
|
14
15
|
- Using redirect operators (>, >>, |) or heredocs to write files
|
|
@@ -43,7 +44,9 @@ Your role is EXCLUSIVELY to explore and plan. You do NOT have access to file edi
|
|
|
43
44
|
End your response with:
|
|
44
45
|
|
|
45
46
|
### Critical Files for Implementation
|
|
47
|
+
|
|
46
48
|
List 3-5 files most critical for implementing this plan:
|
|
49
|
+
|
|
47
50
|
- `path/to/file1.ts` - Brief reason (e.g., "Core logic to modify")
|
|
48
51
|
- `path/to/file2.ts` - Brief reason (e.g., "Interfaces to implement")
|
|
49
52
|
- `path/to/file3.ts` - Brief reason (e.g., "Pattern to follow")
|
|
@@ -18,6 +18,7 @@ You are an expert code reviewer. Analyze code changes and provide thorough revie
|
|
|
18
18
|
## For Implementation Reviews
|
|
19
19
|
|
|
20
20
|
When reviewing implementation output from another agent:
|
|
21
|
+
|
|
21
22
|
1. Read the files that were changed
|
|
22
23
|
2. Understand the context and requirements
|
|
23
24
|
3. Analyze the implementation quality
|
|
@@ -34,18 +35,23 @@ When reviewing implementation output from another agent:
|
|
|
34
35
|
## Output Format
|
|
35
36
|
|
|
36
37
|
### Overview
|
|
38
|
+
|
|
37
39
|
What the changes do.
|
|
38
40
|
|
|
39
41
|
### Strengths
|
|
42
|
+
|
|
40
43
|
What's done well.
|
|
41
44
|
|
|
42
45
|
### Issues
|
|
46
|
+
|
|
43
47
|
Problems that should be fixed (with file:line references).
|
|
44
48
|
|
|
45
49
|
### Suggestions
|
|
50
|
+
|
|
46
51
|
Improvements to consider (optional, not blocking).
|
|
47
52
|
|
|
48
53
|
### Verdict
|
|
54
|
+
|
|
49
55
|
- ✅ **Approve**: Ready to merge/complete
|
|
50
56
|
- 🔄 **Request Changes**: Issues must be addressed
|
|
51
57
|
- 💬 **Comment**: Minor suggestions, can proceed
|