gencode-ai 0.1.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.
Files changed (274) hide show
  1. package/.env.example +11 -0
  2. package/CLAUDE.md +70 -0
  3. package/LICENSE +21 -0
  4. package/README.md +117 -0
  5. package/dist/agent/agent.d.ts +84 -0
  6. package/dist/agent/agent.d.ts.map +1 -0
  7. package/dist/agent/agent.js +233 -0
  8. package/dist/agent/agent.js.map +1 -0
  9. package/dist/agent/index.d.ts +6 -0
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +6 -0
  12. package/dist/agent/index.js.map +1 -0
  13. package/dist/agent/types.d.ts +47 -0
  14. package/dist/agent/types.d.ts.map +1 -0
  15. package/dist/agent/types.js +5 -0
  16. package/dist/agent/types.js.map +1 -0
  17. package/dist/cli/components/App.d.ts +14 -0
  18. package/dist/cli/components/App.d.ts.map +1 -0
  19. package/dist/cli/components/App.js +395 -0
  20. package/dist/cli/components/App.js.map +1 -0
  21. package/dist/cli/components/CommandSuggestions.d.ts +13 -0
  22. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -0
  23. package/dist/cli/components/CommandSuggestions.js +32 -0
  24. package/dist/cli/components/CommandSuggestions.js.map +1 -0
  25. package/dist/cli/components/Header.d.ts +9 -0
  26. package/dist/cli/components/Header.d.ts.map +1 -0
  27. package/dist/cli/components/Header.js +13 -0
  28. package/dist/cli/components/Header.js.map +1 -0
  29. package/dist/cli/components/Input.d.ts +13 -0
  30. package/dist/cli/components/Input.d.ts.map +1 -0
  31. package/dist/cli/components/Input.js +27 -0
  32. package/dist/cli/components/Input.js.map +1 -0
  33. package/dist/cli/components/Logo.d.ts +2 -0
  34. package/dist/cli/components/Logo.d.ts.map +1 -0
  35. package/dist/cli/components/Logo.js +8 -0
  36. package/dist/cli/components/Logo.js.map +1 -0
  37. package/dist/cli/components/Messages.d.ts +37 -0
  38. package/dist/cli/components/Messages.d.ts.map +1 -0
  39. package/dist/cli/components/Messages.js +106 -0
  40. package/dist/cli/components/Messages.js.map +1 -0
  41. package/dist/cli/components/ModelSelector.d.ts +13 -0
  42. package/dist/cli/components/ModelSelector.d.ts.map +1 -0
  43. package/dist/cli/components/ModelSelector.js +72 -0
  44. package/dist/cli/components/ModelSelector.js.map +1 -0
  45. package/dist/cli/components/Spinner.d.ts +12 -0
  46. package/dist/cli/components/Spinner.d.ts.map +1 -0
  47. package/dist/cli/components/Spinner.js +45 -0
  48. package/dist/cli/components/Spinner.js.map +1 -0
  49. package/dist/cli/components/index.d.ts +12 -0
  50. package/dist/cli/components/index.d.ts.map +1 -0
  51. package/dist/cli/components/index.js +12 -0
  52. package/dist/cli/components/index.js.map +1 -0
  53. package/dist/cli/components/theme.d.ts +31 -0
  54. package/dist/cli/components/theme.d.ts.map +1 -0
  55. package/dist/cli/components/theme.js +36 -0
  56. package/dist/cli/components/theme.js.map +1 -0
  57. package/dist/cli/index-legacy.d.ts +7 -0
  58. package/dist/cli/index-legacy.d.ts.map +1 -0
  59. package/dist/cli/index-legacy.js +431 -0
  60. package/dist/cli/index-legacy.js.map +1 -0
  61. package/dist/cli/index.d.ts +7 -0
  62. package/dist/cli/index.d.ts.map +1 -0
  63. package/dist/cli/index.js +116 -0
  64. package/dist/cli/index.js.map +1 -0
  65. package/dist/cli/ink-cli.d.ts +7 -0
  66. package/dist/cli/ink-cli.d.ts.map +1 -0
  67. package/dist/cli/ink-cli.js +105 -0
  68. package/dist/cli/ink-cli.js.map +1 -0
  69. package/dist/cli/session-picker.d.ts +16 -0
  70. package/dist/cli/session-picker.d.ts.map +1 -0
  71. package/dist/cli/session-picker.js +280 -0
  72. package/dist/cli/session-picker.js.map +1 -0
  73. package/dist/cli/ui.d.ts +61 -0
  74. package/dist/cli/ui.d.ts.map +1 -0
  75. package/dist/cli/ui.js +364 -0
  76. package/dist/cli/ui.js.map +1 -0
  77. package/dist/config/index.d.ts +7 -0
  78. package/dist/config/index.d.ts.map +1 -0
  79. package/dist/config/index.js +6 -0
  80. package/dist/config/index.js.map +1 -0
  81. package/dist/config/manager.d.ts +31 -0
  82. package/dist/config/manager.d.ts.map +1 -0
  83. package/dist/config/manager.js +65 -0
  84. package/dist/config/manager.js.map +1 -0
  85. package/dist/config/types.d.ts +22 -0
  86. package/dist/config/types.d.ts.map +1 -0
  87. package/dist/config/types.js +6 -0
  88. package/dist/config/types.js.map +1 -0
  89. package/dist/index.d.ts +12 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +21 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/memory/index.d.ts +10 -0
  94. package/dist/memory/index.d.ts.map +1 -0
  95. package/dist/memory/index.js +9 -0
  96. package/dist/memory/index.js.map +1 -0
  97. package/dist/memory/init.d.ts +20 -0
  98. package/dist/memory/init.d.ts.map +1 -0
  99. package/dist/memory/init.js +332 -0
  100. package/dist/memory/init.js.map +1 -0
  101. package/dist/memory/manager.d.ts +85 -0
  102. package/dist/memory/manager.d.ts.map +1 -0
  103. package/dist/memory/manager.js +234 -0
  104. package/dist/memory/manager.js.map +1 -0
  105. package/dist/memory/types.d.ts +74 -0
  106. package/dist/memory/types.d.ts.map +1 -0
  107. package/dist/memory/types.js +6 -0
  108. package/dist/memory/types.js.map +1 -0
  109. package/dist/permissions/index.d.ts +7 -0
  110. package/dist/permissions/index.d.ts.map +1 -0
  111. package/dist/permissions/index.js +6 -0
  112. package/dist/permissions/index.js.map +1 -0
  113. package/dist/permissions/manager.d.ts +32 -0
  114. package/dist/permissions/manager.d.ts.map +1 -0
  115. package/dist/permissions/manager.js +79 -0
  116. package/dist/permissions/manager.js.map +1 -0
  117. package/dist/permissions/types.d.ts +14 -0
  118. package/dist/permissions/types.d.ts.map +1 -0
  119. package/dist/permissions/types.js +17 -0
  120. package/dist/permissions/types.js.map +1 -0
  121. package/dist/providers/anthropic.d.ts +20 -0
  122. package/dist/providers/anthropic.d.ts.map +1 -0
  123. package/dist/providers/anthropic.js +185 -0
  124. package/dist/providers/anthropic.js.map +1 -0
  125. package/dist/providers/gemini.d.ts +21 -0
  126. package/dist/providers/gemini.d.ts.map +1 -0
  127. package/dist/providers/gemini.js +241 -0
  128. package/dist/providers/gemini.js.map +1 -0
  129. package/dist/providers/index.d.ts +34 -0
  130. package/dist/providers/index.d.ts.map +1 -0
  131. package/dist/providers/index.js +72 -0
  132. package/dist/providers/index.js.map +1 -0
  133. package/dist/providers/openai.d.ts +19 -0
  134. package/dist/providers/openai.d.ts.map +1 -0
  135. package/dist/providers/openai.js +221 -0
  136. package/dist/providers/openai.js.map +1 -0
  137. package/dist/providers/types.d.ts +125 -0
  138. package/dist/providers/types.d.ts.map +1 -0
  139. package/dist/providers/types.js +6 -0
  140. package/dist/providers/types.js.map +1 -0
  141. package/dist/session/index.d.ts +6 -0
  142. package/dist/session/index.d.ts.map +1 -0
  143. package/dist/session/index.js +6 -0
  144. package/dist/session/index.js.map +1 -0
  145. package/dist/session/manager.d.ts +101 -0
  146. package/dist/session/manager.d.ts.map +1 -0
  147. package/dist/session/manager.js +295 -0
  148. package/dist/session/manager.js.map +1 -0
  149. package/dist/session/types.d.ts +39 -0
  150. package/dist/session/types.d.ts.map +1 -0
  151. package/dist/session/types.js +10 -0
  152. package/dist/session/types.js.map +1 -0
  153. package/dist/tools/builtin/bash.d.ts +7 -0
  154. package/dist/tools/builtin/bash.d.ts.map +1 -0
  155. package/dist/tools/builtin/bash.js +80 -0
  156. package/dist/tools/builtin/bash.js.map +1 -0
  157. package/dist/tools/builtin/edit.d.ts +7 -0
  158. package/dist/tools/builtin/edit.d.ts.map +1 -0
  159. package/dist/tools/builtin/edit.js +32 -0
  160. package/dist/tools/builtin/edit.js.map +1 -0
  161. package/dist/tools/builtin/glob.d.ts +7 -0
  162. package/dist/tools/builtin/glob.d.ts.map +1 -0
  163. package/dist/tools/builtin/glob.js +36 -0
  164. package/dist/tools/builtin/glob.js.map +1 -0
  165. package/dist/tools/builtin/grep.d.ts +7 -0
  166. package/dist/tools/builtin/grep.d.ts.map +1 -0
  167. package/dist/tools/builtin/grep.js +59 -0
  168. package/dist/tools/builtin/grep.js.map +1 -0
  169. package/dist/tools/builtin/read.d.ts +7 -0
  170. package/dist/tools/builtin/read.d.ts.map +1 -0
  171. package/dist/tools/builtin/read.js +29 -0
  172. package/dist/tools/builtin/read.js.map +1 -0
  173. package/dist/tools/builtin/write.d.ts +7 -0
  174. package/dist/tools/builtin/write.d.ts.map +1 -0
  175. package/dist/tools/builtin/write.js +24 -0
  176. package/dist/tools/builtin/write.js.map +1 -0
  177. package/dist/tools/index.d.ts +38 -0
  178. package/dist/tools/index.d.ts.map +1 -0
  179. package/dist/tools/index.js +32 -0
  180. package/dist/tools/index.js.map +1 -0
  181. package/dist/tools/registry.d.ts +22 -0
  182. package/dist/tools/registry.d.ts.map +1 -0
  183. package/dist/tools/registry.js +71 -0
  184. package/dist/tools/registry.js.map +1 -0
  185. package/dist/tools/types.d.ts +62 -0
  186. package/dist/tools/types.d.ts.map +1 -0
  187. package/dist/tools/types.js +126 -0
  188. package/dist/tools/types.js.map +1 -0
  189. package/docs/README.md +16 -0
  190. package/docs/proposals/0001-web-fetch-tool.md +293 -0
  191. package/docs/proposals/0002-web-search-tool.md +306 -0
  192. package/docs/proposals/0003-task-subagents.md +333 -0
  193. package/docs/proposals/0004-plan-mode.md +338 -0
  194. package/docs/proposals/0005-todo-system.md +299 -0
  195. package/docs/proposals/0006-memory-system.md +539 -0
  196. package/docs/proposals/0007-context-management.md +429 -0
  197. package/docs/proposals/0008-checkpointing.md +327 -0
  198. package/docs/proposals/0009-hooks-system.md +343 -0
  199. package/docs/proposals/0010-mcp-integration.md +382 -0
  200. package/docs/proposals/0011-custom-commands.md +374 -0
  201. package/docs/proposals/0012-ask-user-question.md +317 -0
  202. package/docs/proposals/0013-multi-edit-tool.md +345 -0
  203. package/docs/proposals/0014-lsp-tool.md +478 -0
  204. package/docs/proposals/0015-ls-tool.md +407 -0
  205. package/docs/proposals/0016-kill-shell-tool.md +455 -0
  206. package/docs/proposals/0017-background-tasks.md +489 -0
  207. package/docs/proposals/0018-parallel-tool-execution.md +415 -0
  208. package/docs/proposals/0019-session-enhancements.md +462 -0
  209. package/docs/proposals/0020-session-summarization.md +447 -0
  210. package/docs/proposals/0021-skills-system.md +409 -0
  211. package/docs/proposals/0022-plugin-system.md +467 -0
  212. package/docs/proposals/0023-permission-enhancements.md +470 -0
  213. package/docs/proposals/0024-keyboard-shortcuts.md +443 -0
  214. package/docs/proposals/0025-cost-tracking.md +447 -0
  215. package/docs/proposals/0026-git-integration.md +475 -0
  216. package/docs/proposals/0027-enhanced-read-tool.md +514 -0
  217. package/docs/proposals/0028-enhanced-bash-tool.md +511 -0
  218. package/docs/proposals/0029-notebook-edit-tool.md +413 -0
  219. package/docs/proposals/0030-plugin-marketplace.md +360 -0
  220. package/docs/proposals/0031-command-suggestions.md +295 -0
  221. package/docs/proposals/0032-ide-integrations.md +328 -0
  222. package/docs/proposals/0033-enterprise-deployment.md +221 -0
  223. package/docs/proposals/0034-sandboxing.md +273 -0
  224. package/docs/proposals/0035-auto-updater.md +311 -0
  225. package/docs/proposals/0036-enhanced-glob-tool.md +267 -0
  226. package/docs/proposals/0037-enhanced-grep-tool.md +360 -0
  227. package/docs/proposals/0038-interactive-cli-ui.md +373 -0
  228. package/docs/proposals/0039-streaming-enhancements.md +359 -0
  229. package/docs/proposals/0040-multi-provider-enhancements.md +369 -0
  230. package/docs/proposals/README.md +84 -0
  231. package/docs/proposals/TEMPLATE.md +57 -0
  232. package/docs/proposals/research/claude-code-research.md +307 -0
  233. package/examples/agent-demo.ts +115 -0
  234. package/examples/basic.ts +166 -0
  235. package/package.json +50 -0
  236. package/src/agent/agent.ts +276 -0
  237. package/src/agent/index.ts +6 -0
  238. package/src/agent/types.ts +62 -0
  239. package/src/cli/components/App.tsx +565 -0
  240. package/src/cli/components/CommandSuggestions.tsx +58 -0
  241. package/src/cli/components/Header.tsx +36 -0
  242. package/src/cli/components/Input.tsx +60 -0
  243. package/src/cli/components/Logo.tsx +16 -0
  244. package/src/cli/components/Messages.tsx +210 -0
  245. package/src/cli/components/ModelSelector.tsx +135 -0
  246. package/src/cli/components/Spinner.tsx +72 -0
  247. package/src/cli/components/index.ts +21 -0
  248. package/src/cli/components/theme.ts +36 -0
  249. package/src/cli/index.tsx +136 -0
  250. package/src/config/index.ts +7 -0
  251. package/src/config/manager.ts +77 -0
  252. package/src/config/types.ts +25 -0
  253. package/src/index.ts +86 -0
  254. package/src/permissions/index.ts +7 -0
  255. package/src/permissions/manager.ts +97 -0
  256. package/src/permissions/types.ts +29 -0
  257. package/src/providers/anthropic.ts +224 -0
  258. package/src/providers/gemini.ts +295 -0
  259. package/src/providers/index.ts +97 -0
  260. package/src/providers/openai.ts +261 -0
  261. package/src/providers/types.ts +181 -0
  262. package/src/session/index.ts +6 -0
  263. package/src/session/manager.ts +354 -0
  264. package/src/session/types.ts +49 -0
  265. package/src/tools/builtin/bash.ts +92 -0
  266. package/src/tools/builtin/edit.ts +37 -0
  267. package/src/tools/builtin/glob.ts +42 -0
  268. package/src/tools/builtin/grep.ts +67 -0
  269. package/src/tools/builtin/read.ts +34 -0
  270. package/src/tools/builtin/write.ts +27 -0
  271. package/src/tools/index.ts +36 -0
  272. package/src/tools/registry.ts +83 -0
  273. package/src/tools/types.ts +172 -0
  274. package/tsconfig.json +21 -0
@@ -0,0 +1,293 @@
1
+ # Proposal: WebFetch Tool
2
+
3
+ - **Proposal ID**: 0001
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Implement a WebFetch tool that fetches content from URLs, converts HTML to markdown, and optionally processes the content with an AI model. This enables the agent to access web documentation, API references, and external resources during coding tasks.
12
+
13
+ ## Motivation
14
+
15
+ Currently, mycode cannot access web content. This limits the agent's ability to:
16
+
17
+ 1. **Read documentation**: Can't fetch API docs or library references
18
+ 2. **Access examples**: Can't retrieve code examples from GitHub gists
19
+ 3. **Verify information**: Can't check current versions or changelogs
20
+ 4. **Gather context**: Can't read linked resources in user messages
21
+ 5. **Stay current**: Can't access up-to-date information beyond training cutoff
22
+
23
+ A WebFetch tool enables the agent to access web resources as needed.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code's WebFetch tool provides intelligent web content retrieval:
28
+
29
+ ### Tool Definition
30
+ ```typescript
31
+ WebFetch({
32
+ url: "https://example.com/docs",
33
+ prompt: "Extract the API endpoint documentation"
34
+ })
35
+ ```
36
+
37
+ ### Key Features
38
+ - Fetches URL content and converts HTML to markdown
39
+ - Processes content with AI model using provided prompt
40
+ - 15-minute self-cleaning cache for repeated requests
41
+ - HTTP auto-upgrade to HTTPS
42
+ - Redirect handling with notification
43
+ - Large content summarization
44
+
45
+ ### Example Usage
46
+ ```
47
+ User: What's the latest version of React?
48
+
49
+ Agent: Let me check the React documentation.
50
+ [WebFetch: https://react.dev/versions]
51
+
52
+ Based on the React documentation, the latest version is React 19...
53
+ ```
54
+
55
+ ### Redirect Handling
56
+ When a URL redirects to a different host:
57
+ ```
58
+ The URL redirected to: https://new-host.com/page
59
+ Please make a new WebFetch request with this URL.
60
+ ```
61
+
62
+ ## Detailed Design
63
+
64
+ ### API Design
65
+
66
+ ```typescript
67
+ // src/tools/web-fetch/types.ts
68
+ interface WebFetchInput {
69
+ url: string; // URL to fetch (must be valid)
70
+ prompt: string; // Instructions for processing content
71
+ }
72
+
73
+ interface WebFetchOutput {
74
+ success: boolean;
75
+ content?: string; // Processed content
76
+ redirectUrl?: string; // If redirect to different host
77
+ error?: string;
78
+ metadata?: {
79
+ title: string;
80
+ contentLength: number;
81
+ contentType: string;
82
+ fetchedAt: Date;
83
+ cached: boolean;
84
+ };
85
+ }
86
+
87
+ interface WebFetchConfig {
88
+ maxContentSize: number; // Default: 5MB
89
+ timeout: number; // Default: 30000ms
90
+ cacheTimeout: number; // Default: 15 minutes
91
+ userAgent: string; // Custom user agent
92
+ allowedDomains?: string[]; // Whitelist (optional)
93
+ blockedDomains?: string[]; // Blacklist (optional)
94
+ }
95
+ ```
96
+
97
+ ```typescript
98
+ // src/tools/web-fetch/web-fetch-tool.ts
99
+ const webFetchTool: Tool<WebFetchInput> = {
100
+ name: 'WebFetch',
101
+ description: `Fetch content from a URL and process it with AI.
102
+
103
+ Features:
104
+ - Converts HTML to clean markdown
105
+ - Processes content based on your prompt
106
+ - 15-minute cache for repeated requests
107
+ - Auto-upgrades HTTP to HTTPS
108
+
109
+ Usage notes:
110
+ - URL must be fully-formed and valid
111
+ - Prompt should describe what to extract
112
+ - For redirects to different hosts, make a new request with the provided URL
113
+ `,
114
+ parameters: z.object({
115
+ url: z.string().url(),
116
+ prompt: z.string().min(1)
117
+ }),
118
+ execute: async (input, context) => { ... }
119
+ };
120
+ ```
121
+
122
+ ### Implementation Approach
123
+
124
+ 1. **URL Validation**: Validate and normalize URLs
125
+ 2. **Caching**: Implement 15-minute cache with automatic cleanup
126
+ 3. **HTML to Markdown**: Use turndown or similar library
127
+ 4. **Content Processing**: Use current provider to process with prompt
128
+ 5. **Redirect Handling**: Detect cross-host redirects
129
+ 6. **Size Limits**: Truncate large content with summary
130
+
131
+ ```typescript
132
+ // Core fetch logic
133
+ async function fetchAndProcess(url: string, prompt: string, context: ToolContext): Promise<WebFetchOutput> {
134
+ // Check cache first
135
+ const cached = cache.get(url);
136
+ if (cached && !cached.expired) {
137
+ return processWithPrompt(cached.content, prompt, context);
138
+ }
139
+
140
+ // Fetch URL
141
+ const response = await fetch(url, {
142
+ redirect: 'manual',
143
+ headers: { 'User-Agent': config.userAgent }
144
+ });
145
+
146
+ // Handle redirects
147
+ if (response.status >= 300 && response.status < 400) {
148
+ const redirectUrl = response.headers.get('Location');
149
+ if (isExternalRedirect(url, redirectUrl)) {
150
+ return { success: true, redirectUrl };
151
+ }
152
+ return fetchAndProcess(redirectUrl, prompt, context);
153
+ }
154
+
155
+ // Convert HTML to markdown
156
+ const html = await response.text();
157
+ const markdown = htmlToMarkdown(html);
158
+
159
+ // Cache the content
160
+ cache.set(url, markdown, config.cacheTimeout);
161
+
162
+ // Process with AI
163
+ return processWithPrompt(markdown, prompt, context);
164
+ }
165
+ ```
166
+
167
+ ### File Changes
168
+
169
+ | File | Action | Description |
170
+ |------|--------|-------------|
171
+ | `src/tools/web-fetch/types.ts` | Create | Type definitions |
172
+ | `src/tools/web-fetch/web-fetch-tool.ts` | Create | Tool implementation |
173
+ | `src/tools/web-fetch/html-converter.ts` | Create | HTML to markdown conversion |
174
+ | `src/tools/web-fetch/cache.ts` | Create | URL content cache |
175
+ | `src/tools/web-fetch/index.ts` | Create | Module exports |
176
+ | `src/tools/index.ts` | Modify | Register tool |
177
+ | `package.json` | Modify | Add turndown dependency |
178
+
179
+ ## User Experience
180
+
181
+ ### Basic Usage
182
+ ```
183
+ User: What does the lodash debounce function do?
184
+
185
+ Agent: Let me check the lodash documentation.
186
+ [WebFetch: https://lodash.com/docs#debounce]
187
+
188
+ The lodash `debounce` function creates a debounced version of a function
189
+ that delays invoking until after `wait` milliseconds have elapsed since
190
+ the last time the debounced function was invoked...
191
+ ```
192
+
193
+ ### Redirect Notification
194
+ ```
195
+ Agent: [WebFetch: https://old-docs.example.com/api]
196
+
197
+ The URL redirected to a different host: https://new-docs.example.com/api
198
+ Let me fetch from the new location.
199
+
200
+ [WebFetch: https://new-docs.example.com/api]
201
+ ...
202
+ ```
203
+
204
+ ### Error Handling
205
+ ```
206
+ Agent: [WebFetch: https://private-server.internal/docs]
207
+
208
+ Unable to fetch URL: Connection refused
209
+ The URL may be inaccessible from my environment.
210
+ ```
211
+
212
+ ### Cache Indicator
213
+ ```
214
+ Agent: [WebFetch: https://react.dev/docs] (cached)
215
+ ```
216
+
217
+ ## Alternatives Considered
218
+
219
+ ### Alternative 1: Raw HTML Return
220
+ Return raw HTML without processing.
221
+
222
+ **Pros**: Simpler, faster
223
+ **Cons**: Harder for agent to parse, wastes context
224
+ **Decision**: Rejected - Markdown conversion is essential
225
+
226
+ ### Alternative 2: Browser Automation
227
+ Use Puppeteer/Playwright for JS-rendered sites.
228
+
229
+ **Pros**: Better for dynamic sites
230
+ **Cons**: Heavy dependency, slower, more complex
231
+ **Decision**: Deferred - Start with simple fetch, add later if needed
232
+
233
+ ### Alternative 3: No AI Processing
234
+ Just return markdown without prompt-based processing.
235
+
236
+ **Pros**: Simpler, no extra API calls
237
+ **Cons**: Large pages waste context, less useful output
238
+ **Decision**: Rejected - Processing adds significant value
239
+
240
+ ## Security Considerations
241
+
242
+ 1. **SSRF Prevention**: Block internal/private IPs (localhost, 10.x, 192.168.x, etc.)
243
+ 2. **Domain Restrictions**: Support allowlist/blocklist configuration
244
+ 3. **Content Size**: Limit maximum content size
245
+ 4. **Timeout**: Enforce request timeout
246
+ 5. **Protocol**: Only allow HTTP/HTTPS
247
+ 6. **Credentials**: Never send credentials or cookies
248
+ 7. **User Agent**: Use identifiable user agent string
249
+
250
+ ```typescript
251
+ // SSRF protection
252
+ const BLOCKED_HOSTS = [
253
+ 'localhost', '127.0.0.1', '0.0.0.0',
254
+ /^10\./,
255
+ /^192\.168\./,
256
+ /^172\.(1[6-9]|2[0-9]|3[0-1])\./,
257
+ /^169\.254\./, // Link-local
258
+ /^::1$/, // IPv6 localhost
259
+ ];
260
+ ```
261
+
262
+ ## Testing Strategy
263
+
264
+ 1. **Unit Tests**:
265
+ - URL validation
266
+ - HTML to markdown conversion
267
+ - Cache behavior
268
+ - SSRF protection
269
+
270
+ 2. **Integration Tests**:
271
+ - End-to-end fetch and process
272
+ - Redirect handling
273
+ - Error cases
274
+
275
+ 3. **Manual Testing**:
276
+ - Various website types
277
+ - Large pages
278
+ - Redirect chains
279
+
280
+ ## Migration Path
281
+
282
+ 1. **Phase 1**: Basic fetch and markdown conversion
283
+ 2. **Phase 2**: AI processing with prompt
284
+ 3. **Phase 3**: Caching system
285
+ 4. **Phase 4**: Domain restrictions and security hardening
286
+
287
+ No breaking changes to existing functionality.
288
+
289
+ ## References
290
+
291
+ - [Claude Code WebFetch Documentation](https://code.claude.com/docs/en/tools)
292
+ - [Turndown (HTML to Markdown)](https://github.com/mixmark-io/turndown)
293
+ - [OWASP SSRF Prevention](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html)
@@ -0,0 +1,306 @@
1
+ # Proposal: WebSearch Tool
2
+
3
+ - **Proposal ID**: 0002
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Implement a WebSearch tool that enables the agent to search the web and use results to inform responses. This provides access to current information, recent documentation, and up-to-date technical resources beyond the model's training cutoff.
12
+
13
+ ## Motivation
14
+
15
+ Currently, mycode cannot search the web. This limits the agent when:
16
+
17
+ 1. **Outdated information**: Model knowledge has a cutoff date
18
+ 2. **New libraries**: Can't find docs for recently released packages
19
+ 3. **Current events**: Can't access recent security advisories, updates
20
+ 4. **Error debugging**: Can't search for recent solutions to errors
21
+ 5. **Best practices**: Can't find current community recommendations
22
+
23
+ A WebSearch tool enables access to current web information.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code's WebSearch tool provides intelligent web searching:
28
+
29
+ ### Tool Definition
30
+ ```typescript
31
+ WebSearch({
32
+ query: "React 19 new features 2025",
33
+ allowed_domains: ["react.dev", "github.com"], // Optional
34
+ blocked_domains: ["spam-site.com"] // Optional
35
+ })
36
+ ```
37
+
38
+ ### Key Features
39
+ - Returns formatted search results with links
40
+ - Supports domain filtering (allow/block lists)
41
+ - Results include titles and URLs as markdown hyperlinks
42
+ - Requires source citation in responses
43
+ - Minimum 2-character query
44
+
45
+ ### Example Usage
46
+ ```
47
+ User: What's new in TypeScript 5.4?
48
+
49
+ Agent: Let me search for the latest TypeScript updates.
50
+ [WebSearch: "TypeScript 5.4 new features 2025"]
51
+
52
+ Based on my search, TypeScript 5.4 introduces:
53
+ - NoInfer utility type for better type inference
54
+ - Improved narrowing for closures
55
+ ...
56
+
57
+ Sources:
58
+ - [TypeScript 5.4 Release Notes](https://www.typescriptlang.org/docs/...)
59
+ - [What's New in TypeScript 5.4](https://devblogs.microsoft.com/...)
60
+ ```
61
+
62
+ ### Source Citation Requirement
63
+ Claude Code mandates including sources after answering:
64
+ ```
65
+ [Your answer here]
66
+
67
+ Sources:
68
+ - [Source Title 1](https://example.com/1)
69
+ - [Source Title 2](https://example.com/2)
70
+ ```
71
+
72
+ ## Detailed Design
73
+
74
+ ### API Design
75
+
76
+ ```typescript
77
+ // src/tools/web-search/types.ts
78
+ interface WebSearchInput {
79
+ query: string; // Search query (min 2 chars)
80
+ allowed_domains?: string[]; // Only include these domains
81
+ blocked_domains?: string[]; // Exclude these domains
82
+ }
83
+
84
+ interface SearchResult {
85
+ title: string;
86
+ url: string;
87
+ snippet: string;
88
+ domain: string;
89
+ }
90
+
91
+ interface WebSearchOutput {
92
+ success: boolean;
93
+ results?: SearchResult[];
94
+ query: string;
95
+ error?: string;
96
+ metadata?: {
97
+ resultCount: number;
98
+ searchTime: number;
99
+ };
100
+ }
101
+
102
+ interface WebSearchConfig {
103
+ provider: 'google' | 'bing' | 'duckduckgo' | 'serper';
104
+ apiKey?: string;
105
+ maxResults: number; // Default: 10
106
+ timeout: number; // Default: 10000ms
107
+ safeSearch: boolean; // Default: true
108
+ }
109
+ ```
110
+
111
+ ```typescript
112
+ // src/tools/web-search/web-search-tool.ts
113
+ const webSearchTool: Tool<WebSearchInput> = {
114
+ name: 'WebSearch',
115
+ description: `Search the web for current information.
116
+
117
+ Use this tool when you need:
118
+ - Up-to-date information beyond your knowledge cutoff
119
+ - Current documentation or release notes
120
+ - Recent solutions to technical problems
121
+ - Current best practices
122
+
123
+ IMPORTANT: After answering, include a "Sources:" section with all relevant URLs as markdown hyperlinks.
124
+
125
+ Example:
126
+ [Your answer]
127
+
128
+ Sources:
129
+ - [Title 1](https://url1)
130
+ - [Title 2](https://url2)
131
+ `,
132
+ parameters: z.object({
133
+ query: z.string().min(2),
134
+ allowed_domains: z.array(z.string()).optional(),
135
+ blocked_domains: z.array(z.string()).optional()
136
+ }),
137
+ execute: async (input, context) => { ... }
138
+ };
139
+ ```
140
+
141
+ ### Implementation Approach
142
+
143
+ 1. **Search Provider**: Integrate with search API (Serper, Google, Bing, or DuckDuckGo)
144
+ 2. **Query Processing**: Clean and optimize search queries
145
+ 3. **Domain Filtering**: Apply allow/block lists to results
146
+ 4. **Result Formatting**: Format results as markdown with links
147
+ 5. **Rate Limiting**: Respect API rate limits
148
+
149
+ ```typescript
150
+ // Search provider abstraction
151
+ interface SearchProvider {
152
+ search(query: string, options: SearchOptions): Promise<SearchResult[]>;
153
+ }
154
+
155
+ // Serper.dev implementation (recommended)
156
+ class SerperProvider implements SearchProvider {
157
+ async search(query: string, options: SearchOptions): Promise<SearchResult[]> {
158
+ const response = await fetch('https://google.serper.dev/search', {
159
+ method: 'POST',
160
+ headers: {
161
+ 'X-API-KEY': this.apiKey,
162
+ 'Content-Type': 'application/json'
163
+ },
164
+ body: JSON.stringify({
165
+ q: query,
166
+ num: options.maxResults
167
+ })
168
+ });
169
+
170
+ const data = await response.json();
171
+ return data.organic.map(r => ({
172
+ title: r.title,
173
+ url: r.link,
174
+ snippet: r.snippet,
175
+ domain: new URL(r.link).hostname
176
+ }));
177
+ }
178
+ }
179
+ ```
180
+
181
+ ### File Changes
182
+
183
+ | File | Action | Description |
184
+ |------|--------|-------------|
185
+ | `src/tools/web-search/types.ts` | Create | Type definitions |
186
+ | `src/tools/web-search/web-search-tool.ts` | Create | Tool implementation |
187
+ | `src/tools/web-search/providers/` | Create | Search provider implementations |
188
+ | `src/tools/web-search/index.ts` | Create | Module exports |
189
+ | `src/tools/index.ts` | Modify | Register tool |
190
+ | `src/config/settings-manager.ts` | Modify | Add search config |
191
+
192
+ ## User Experience
193
+
194
+ ### Basic Search
195
+ ```
196
+ User: How do I use the new Bun test runner?
197
+
198
+ Agent: Let me search for the latest Bun testing documentation.
199
+ [WebSearch: "Bun test runner documentation 2025"]
200
+
201
+ Based on my search, here's how to use Bun's test runner:
202
+
203
+ 1. Create a test file with `.test.ts` extension
204
+ 2. Import `expect` and `test` from `bun:test`
205
+ 3. Run with `bun test`
206
+
207
+ ```typescript
208
+ import { expect, test } from "bun:test";
209
+
210
+ test("2 + 2", () => {
211
+ expect(2 + 2).toBe(4);
212
+ });
213
+ ```
214
+
215
+ Sources:
216
+ - [Bun Test Runner](https://bun.sh/docs/cli/test)
217
+ - [Bun Testing Guide](https://bun.sh/guides/test/run-tests)
218
+ ```
219
+
220
+ ### Domain-Filtered Search
221
+ ```
222
+ User: Search for React hooks best practices, only from official sources
223
+
224
+ Agent: [WebSearch: "React hooks best practices", allowed_domains: ["react.dev", "reactjs.org"]]
225
+
226
+ Here are the best practices from official React documentation...
227
+
228
+ Sources:
229
+ - [Rules of Hooks](https://react.dev/reference/rules/rules-of-hooks)
230
+ ```
231
+
232
+ ### Error Case
233
+ ```
234
+ Agent: [WebSearch: "..."]
235
+
236
+ I wasn't able to perform the web search. This might be due to:
237
+ - No search API configured
238
+ - Rate limit exceeded
239
+ - Network connectivity issues
240
+
241
+ I'll answer based on my training data instead...
242
+ ```
243
+
244
+ ## Alternatives Considered
245
+
246
+ ### Alternative 1: Scraping-Based Search
247
+ Scrape Google/Bing results directly.
248
+
249
+ **Pros**: No API costs
250
+ **Cons**: Terms of service violations, blocking, reliability
251
+ **Decision**: Rejected - Use proper search APIs
252
+
253
+ ### Alternative 2: Single Provider Only
254
+ Only support one search provider.
255
+
256
+ **Pros**: Simpler implementation
257
+ **Cons**: Lock-in, single point of failure
258
+ **Decision**: Rejected - Provider abstraction adds flexibility
259
+
260
+ ### Alternative 3: No Domain Filtering
261
+ Skip allow/block list feature.
262
+
263
+ **Pros**: Simpler
264
+ **Cons**: Less control over result quality
265
+ **Decision**: Rejected - Filtering adds significant value
266
+
267
+ ## Security Considerations
268
+
269
+ 1. **API Key Security**: Store search API keys securely
270
+ 2. **Query Sanitization**: Sanitize search queries
271
+ 3. **Result Validation**: Validate returned URLs
272
+ 4. **Rate Limiting**: Prevent abuse of search API
273
+ 5. **Safe Search**: Enable safe search by default
274
+ 6. **Content Filtering**: Consider filtering adult/malicious content
275
+
276
+ ## Testing Strategy
277
+
278
+ 1. **Unit Tests**:
279
+ - Query validation
280
+ - Domain filtering logic
281
+ - Result formatting
282
+
283
+ 2. **Integration Tests**:
284
+ - Provider integration (with mock)
285
+ - End-to-end search flow
286
+
287
+ 3. **Manual Testing**:
288
+ - Various query types
289
+ - Domain filtering
290
+ - Error handling
291
+
292
+ ## Migration Path
293
+
294
+ 1. **Phase 1**: Basic search with Serper provider
295
+ 2. **Phase 2**: Domain filtering
296
+ 3. **Phase 3**: Additional providers
297
+ 4. **Phase 4**: Search result caching
298
+
299
+ Configuration required: User must provide search API key.
300
+
301
+ ## References
302
+
303
+ - [Claude Code WebSearch Documentation](https://code.claude.com/docs/en/tools)
304
+ - [Serper API](https://serper.dev/)
305
+ - [Google Custom Search API](https://developers.google.com/custom-search)
306
+ - [Bing Web Search API](https://www.microsoft.com/en-us/bing/apis/bing-web-search-api)