@ridit/lens 0.3.0 → 0.3.2
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/addons/README.md +55 -3
- package/addons/clean-cache.js +48 -0
- package/addons/generate-readme.js +67 -0
- package/addons/git-stats.js +29 -0
- package/dist/index.mjs +157 -486
- package/package.json +1 -1
- package/src/commands/commit.tsx +21 -47
- package/src/prompts/fewshot.ts +46 -286
- package/src/prompts/system.ts +71 -92
- package/src/utils/addons/loadAddons.ts +3 -1
- package/src/utils/tools/builtins.ts +14 -9
- package/LENS.md +0 -32
package/src/prompts/system.ts
CHANGED
|
@@ -26,85 +26,64 @@ They are stripped before display — the user will not see the raw tags.
|
|
|
26
26
|
### memory-delete — delete a memory by its ID (shown in brackets like [abc123])
|
|
27
27
|
<memory-delete>abc123</memory-delete>
|
|
28
28
|
|
|
29
|
-
Use memory-add when
|
|
30
|
-
-
|
|
31
|
-
- You learn something project-specific that would be useful in future sessions
|
|
32
|
-
(e.g. preferred patterns, architecture decisions, known gotchas, user preferences)
|
|
33
|
-
|
|
34
|
-
Use memory-delete when:
|
|
35
|
-
- The user asks you to forget something
|
|
36
|
-
- A memory is outdated or wrong and you are replacing it with a new one
|
|
37
|
-
|
|
38
|
-
You may emit multiple memory operations in a single response alongside normal content.
|
|
29
|
+
Use memory-add when the user asks you to remember something, or when you learn something project-specific that would be useful in future sessions.
|
|
30
|
+
Use memory-delete when the user asks you to forget something or a memory is outdated.
|
|
39
31
|
|
|
40
32
|
## RULES
|
|
41
33
|
|
|
42
|
-
1.
|
|
43
|
-
2.
|
|
44
|
-
3.
|
|
45
|
-
4.
|
|
46
|
-
5.
|
|
47
|
-
6. NEVER
|
|
48
|
-
7. NEVER
|
|
49
|
-
8. NEVER use shell to
|
|
50
|
-
9.
|
|
51
|
-
10.
|
|
52
|
-
11.
|
|
53
|
-
12.
|
|
54
|
-
13.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
34
|
+
1. ONE tool per response — emit the XML tag, then stop. Never chain tools in one response except when scaffolding (see below).
|
|
35
|
+
2. NEVER call a tool more than once for the same path in a session. If write-file or shell returned a result, it succeeded. Move on immediately.
|
|
36
|
+
3. NEVER write the same file twice in one session. One write per file, period. If you already wrote it, it is done.
|
|
37
|
+
4. shell is ONLY for running code, installing packages, building, and testing. NEVER use shell to inspect the filesystem or read files — use read-file, read-folder, or grep instead.
|
|
38
|
+
5. write-file content must be the COMPLETE file content, never a placeholder or partial.
|
|
39
|
+
6. NEVER read a file you just wrote. The write output confirms success.
|
|
40
|
+
7. NEVER apologize and redo a tool call — one attempt is enough, trust the output.
|
|
41
|
+
8. NEVER use shell to run git clone — use the clone tag instead.
|
|
42
|
+
9. When the user asks you to CREATE a new file, write it immediately — do NOT read first.
|
|
43
|
+
10. When the user asks you to MODIFY or FIX an existing file, read it first, then write the complete updated version ONCE.
|
|
44
|
+
11. When fixing multiple files, use read-files to read ALL of them first, then write each one ONCE sequentially — never rewrite a file already written this session.
|
|
45
|
+
12. If a read-folder or read-file returns not found, accept it and move on — do NOT retry the same path.
|
|
46
|
+
13. Every shell command runs from the repo root — cd has no persistent effect. Use full paths or combine with && e.g. cd myapp && bun run index.ts
|
|
47
|
+
14. write-file paths are relative to the repo root — use full relative paths e.g. myapp/src/index.tsx not src/index.tsx
|
|
48
|
+
15. When explaining how to use a tool in text, use [tag] bracket notation — NEVER emit a real XML tool tag as part of an explanation.
|
|
49
|
+
16. NEVER use markdown formatting in plain text responses — no bold, no headings, no bullet points. Only use fenced code blocks when showing actual code.
|
|
50
|
+
17. When scaffolding multiple files, emit ONE write-file tag per response and wait for the result before writing the next file.
|
|
51
|
+
|
|
52
|
+
## ADDON FORMAT
|
|
53
|
+
|
|
54
|
+
All addons use defineTool from @ridit/lens-sdk. The ONLY correct format is:
|
|
55
|
+
|
|
56
|
+
\`\`\`js
|
|
57
|
+
const { defineTool } = require("@ridit/lens-sdk");
|
|
58
|
+
const { execSync } = require("child_process");
|
|
59
|
+
|
|
60
|
+
defineTool({
|
|
61
|
+
name: "tool-name",
|
|
62
|
+
description: "what it does",
|
|
63
|
+
safe: false,
|
|
64
|
+
permissionLabel: "label shown to user",
|
|
65
|
+
systemPromptEntry: () => "<tool-name>{}</tool-name> — description",
|
|
66
|
+
parseInput: (body) => JSON.parse(body.trim() || "{}"),
|
|
67
|
+
summariseInput: (input) => "summary",
|
|
68
|
+
execute: async (input, ctx) => {
|
|
69
|
+
// ctx.repoPath is the current repo path
|
|
70
|
+
// use execSync from child_process for shell commands, NOT ctx.tools.shell
|
|
71
|
+
return { kind: "text", value: "result" };
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
\`\`\`
|
|
75
|
+
|
|
76
|
+
NEVER use module.exports, registerTool, ctx.tools.shell, or any other format. See addons/run-tests.js for a full working example.
|
|
77
|
+
|
|
78
|
+
## SCAFFOLDING
|
|
79
|
+
|
|
80
|
+
When creating multiple files, emit ONE write-file per response and wait for each result:
|
|
77
81
|
|
|
78
82
|
<write-file>
|
|
79
|
-
{"path": "
|
|
83
|
+
{"path": "myapp/package.json", "content": "..."}
|
|
80
84
|
</write-file>
|
|
81
|
-
<write-file>
|
|
82
|
-
{"path": "test/file2.txt", "content": "File 2 content"}
|
|
83
|
-
</write-file>
|
|
84
|
-
<write-file>
|
|
85
|
-
{"path": "test/file3.txt", "content": "File 3 content"}
|
|
86
|
-
</write-file>
|
|
87
|
-
|
|
88
|
-
The system processes each tag sequentially and automatically continues to the next one.
|
|
89
|
-
Do NOT wait for a user message between files — emit all tags at once.
|
|
90
|
-
|
|
91
|
-
## WHEN TO READ BEFORE WRITING
|
|
92
|
-
|
|
93
|
-
Only read a file before writing if ALL of these are true:
|
|
94
|
-
- The file already exists AND has content you need to preserve
|
|
95
|
-
- The user explicitly asked you to modify, edit, or update it (not create it)
|
|
96
|
-
- You do not already have the file content in this conversation
|
|
97
85
|
|
|
98
|
-
Never
|
|
99
|
-
- The user asked you to create, write, or add a new file
|
|
100
|
-
- The file is empty, missing, or a stub
|
|
101
|
-
- You already read it earlier in this conversation
|
|
102
|
-
|
|
103
|
-
When modifying an existing file:
|
|
104
|
-
1. Use read-file on the exact file first
|
|
105
|
-
2. Preserve ALL existing content — do not remove anything that was not part of the request
|
|
106
|
-
3. Your write-file must contain EVERYTHING the original had, PLUS your additions
|
|
107
|
-
4. NEVER produce a file shorter than the original unless explicitly asked to delete things
|
|
86
|
+
Wait for result, then emit the next file. Never chain write-file tags when content is complex.
|
|
108
87
|
|
|
109
88
|
## CODEBASE
|
|
110
89
|
|
|
@@ -115,57 +94,57 @@ ${memorySummary}`;
|
|
|
115
94
|
|
|
116
95
|
const BUILTIN_TOOLS_SECTION = `## TOOLS
|
|
117
96
|
|
|
118
|
-
You have exactly
|
|
97
|
+
You have exactly fourteen tools. Use ONLY the XML tags shown below.
|
|
119
98
|
|
|
120
99
|
### 1. fetch — load a URL
|
|
121
100
|
<fetch>https://example.com</fetch>
|
|
122
101
|
|
|
123
|
-
### 2. shell — run a terminal command
|
|
102
|
+
### 2. shell — run a terminal command (NOT for filesystem inspection)
|
|
124
103
|
<shell>node -v</shell>
|
|
125
104
|
|
|
126
|
-
### 3. read-file — read a file from the repo
|
|
105
|
+
### 3. read-file — read a single file from the repo
|
|
127
106
|
<read-file>src/foo.ts</read-file>
|
|
128
107
|
|
|
129
|
-
### 4. read-
|
|
108
|
+
### 4. read-files — read multiple files at once
|
|
109
|
+
<read-files>
|
|
110
|
+
["src/foo.ts", "src/bar.ts"]
|
|
111
|
+
</read-files>
|
|
112
|
+
|
|
113
|
+
### 5. read-folder — list contents of a folder (one level deep)
|
|
130
114
|
<read-folder>src/components</read-folder>
|
|
131
115
|
|
|
132
|
-
###
|
|
116
|
+
### 6. grep — search for a pattern across files
|
|
133
117
|
<grep>
|
|
134
118
|
{"pattern": "ChatRunner", "glob": "src/**/*.tsx"}
|
|
135
119
|
</grep>
|
|
136
120
|
|
|
137
|
-
###
|
|
121
|
+
### 7. write-file — create or overwrite a file (COMPLETE content only)
|
|
138
122
|
<write-file>
|
|
139
123
|
{"path": "data/output.csv", "content": "col1,col2\\nval1,val2"}
|
|
140
124
|
</write-file>
|
|
141
125
|
|
|
142
|
-
###
|
|
126
|
+
### 8. delete-file — permanently delete a single file
|
|
143
127
|
<delete-file>src/old-component.tsx</delete-file>
|
|
144
128
|
|
|
145
|
-
###
|
|
129
|
+
### 9. delete-folder — permanently delete a folder and all its contents
|
|
146
130
|
<delete-folder>src/legacy</delete-folder>
|
|
147
131
|
|
|
148
|
-
###
|
|
132
|
+
### 10. open-url — open a URL in the user's default browser
|
|
149
133
|
<open-url>https://github.com/owner/repo</open-url>
|
|
150
134
|
|
|
151
|
-
###
|
|
135
|
+
### 11. generate-pdf — generate a PDF from markdown-style content
|
|
152
136
|
<generate-pdf>
|
|
153
|
-
{"path": "output/report.pdf", "content": "# Title\\n\\
|
|
137
|
+
{"path": "output/report.pdf", "content": "# Title\\n\\nBody text."}
|
|
154
138
|
</generate-pdf>
|
|
155
139
|
|
|
156
|
-
###
|
|
157
|
-
<search>how to use React useEffect cleanup
|
|
140
|
+
### 12. search — search the internet
|
|
141
|
+
<search>how to use React useEffect cleanup</search>
|
|
158
142
|
|
|
159
|
-
###
|
|
143
|
+
### 13. clone — clone a GitHub repo
|
|
160
144
|
<clone>https://github.com/owner/repo</clone>
|
|
161
145
|
|
|
162
|
-
###
|
|
146
|
+
### 14. changes — propose code edits shown as a diff for user approval
|
|
163
147
|
<changes>
|
|
164
148
|
{"summary": "what changed and why", "patches": [{"path": "src/foo.ts", "content": "COMPLETE file content", "isNew": false}]}
|
|
165
149
|
</changes>
|
|
166
|
-
|
|
167
|
-
### 14. read-files — read multiple files from the repo at once
|
|
168
|
-
<read-files>
|
|
169
|
-
["src/foo.ts", "src/bar.ts"]
|
|
170
|
-
</read-files>
|
|
171
150
|
`;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import os from "os";
|
|
3
3
|
import { existsSync, readdirSync } from "fs";
|
|
4
|
+
import { pathToFileURL } from "url";
|
|
4
5
|
|
|
5
6
|
const ADDONS_DIR = path.join(os.homedir(), ".lens", "addons");
|
|
6
7
|
|
|
@@ -18,9 +19,10 @@ export async function loadAddons(): Promise<void> {
|
|
|
18
19
|
if (!file) return;
|
|
19
20
|
|
|
20
21
|
const fullPath = path.join(ADDONS_DIR, file);
|
|
22
|
+
const fileUrl = pathToFileURL(fullPath).href;
|
|
21
23
|
const isLast = i === files.length - 1;
|
|
22
24
|
try {
|
|
23
|
-
await import(
|
|
25
|
+
await import(fileUrl);
|
|
24
26
|
console.log(`[addons] loaded: ${file}${isLast ? "\n" : ""}`);
|
|
25
27
|
} catch (err) {
|
|
26
28
|
console.error(
|
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
convertImageTool,
|
|
18
18
|
} from "../../tools";
|
|
19
19
|
|
|
20
|
+
const cleanBody = (body: string) => body.trim().replace(/\\/g, "/");
|
|
21
|
+
|
|
20
22
|
export const fetchTool: Tool<string> = {
|
|
21
23
|
name: "fetch",
|
|
22
24
|
description: "load a URL",
|
|
@@ -61,7 +63,7 @@ export const readFileTool: Tool<string> = {
|
|
|
61
63
|
permissionLabel: "read",
|
|
62
64
|
systemPromptEntry: (i) =>
|
|
63
65
|
`### ${i}. read-file — read a file from the repo\n<read-file>src/foo.ts</read-file>`,
|
|
64
|
-
parseInput: (body) => body || null,
|
|
66
|
+
parseInput: (body) => cleanBody(body) || null,
|
|
65
67
|
summariseInput: (p) => p,
|
|
66
68
|
execute: (filePath, ctx) => ({
|
|
67
69
|
kind: "text",
|
|
@@ -76,7 +78,7 @@ export const readFolderTool: Tool<string> = {
|
|
|
76
78
|
permissionLabel: "folder",
|
|
77
79
|
systemPromptEntry: (i) =>
|
|
78
80
|
`### ${i}. read-folder — list contents of a folder (files + subfolders, one level deep)\n<read-folder>src/components</read-folder>`,
|
|
79
|
-
parseInput: (body) => body || null,
|
|
81
|
+
parseInput: (body) => cleanBody(body) || null,
|
|
80
82
|
summariseInput: (p) => p,
|
|
81
83
|
execute: (folderPath, ctx) => ({
|
|
82
84
|
kind: "text",
|
|
@@ -98,7 +100,10 @@ export const grepTool: Tool<GrepInput> = {
|
|
|
98
100
|
`### ${i}. grep — search for a pattern across files in the repo (cross-platform, no shell needed)\n<grep>\n{"pattern": "ChatRunner", "glob": "src/**/*.tsx"}\n</grep>`,
|
|
99
101
|
parseInput: (body) => {
|
|
100
102
|
try {
|
|
101
|
-
const parsed = JSON.parse(body) as {
|
|
103
|
+
const parsed = JSON.parse(cleanBody(body)) as {
|
|
104
|
+
pattern: string;
|
|
105
|
+
glob?: string;
|
|
106
|
+
};
|
|
102
107
|
return { pattern: parsed.pattern, glob: parsed.glob ?? "**/*" };
|
|
103
108
|
} catch {
|
|
104
109
|
return { pattern: body, glob: "**/*" };
|
|
@@ -127,7 +132,7 @@ export const writeFileTool: Tool<WriteFileInput> = {
|
|
|
127
132
|
try {
|
|
128
133
|
const parsed = JSON.parse(body) as { path: string; content: string };
|
|
129
134
|
if (!parsed.path) return null;
|
|
130
|
-
return parsed;
|
|
135
|
+
return { ...parsed, path: parsed.path.replace(/\\/g, "/") };
|
|
131
136
|
} catch {
|
|
132
137
|
return null;
|
|
133
138
|
}
|
|
@@ -146,7 +151,7 @@ export const deleteFileTool: Tool<string> = {
|
|
|
146
151
|
permissionLabel: "delete",
|
|
147
152
|
systemPromptEntry: (i) =>
|
|
148
153
|
`### ${i}. delete-file — permanently delete a single file\n<delete-file>src/old-component.tsx</delete-file>`,
|
|
149
|
-
parseInput: (body) => body || null,
|
|
154
|
+
parseInput: (body) => cleanBody(body) || null,
|
|
150
155
|
summariseInput: (p) => p,
|
|
151
156
|
execute: (filePath, ctx) => ({
|
|
152
157
|
kind: "text",
|
|
@@ -161,7 +166,7 @@ export const deleteFolderTool: Tool<string> = {
|
|
|
161
166
|
permissionLabel: "delete folder",
|
|
162
167
|
systemPromptEntry: (i) =>
|
|
163
168
|
`### ${i}. delete-folder — permanently delete a folder and all its contents\n<delete-folder>src/legacy</delete-folder>`,
|
|
164
|
-
parseInput: (body) => body || null,
|
|
169
|
+
parseInput: (body) => cleanBody(body) || null,
|
|
165
170
|
summariseInput: (p) => p,
|
|
166
171
|
execute: (folderPath, ctx) => ({
|
|
167
172
|
kind: "text",
|
|
@@ -195,7 +200,7 @@ export const generatePdfTool: Tool<GeneratePdfInput> = {
|
|
|
195
200
|
`### ${i}. generate-pdf — generate a PDF file from markdown-style content\n<generate-pdf>\n{"path": "output/report.pdf", "content": "# Title\\n\\nSome body text."}\n</generate-pdf>`,
|
|
196
201
|
parseInput: (body) => {
|
|
197
202
|
try {
|
|
198
|
-
const parsed = JSON.parse(body) as {
|
|
203
|
+
const parsed = JSON.parse(cleanBody(body)) as {
|
|
199
204
|
path?: string;
|
|
200
205
|
filePath?: string;
|
|
201
206
|
content?: string;
|
|
@@ -266,7 +271,7 @@ export const changesTool: Tool<ChangesInput> = {
|
|
|
266
271
|
`### ${i}. changes — propose code edits (shown as a diff for user approval)\n<changes>\n{"summary": "what changed and why", "patches": [{"path": "src/foo.ts", "content": "COMPLETE file content", "isNew": false}]}\n</changes>`,
|
|
267
272
|
parseInput: (body) => {
|
|
268
273
|
try {
|
|
269
|
-
return JSON.parse(body) as ChangesInput;
|
|
274
|
+
return JSON.parse(cleanBody(body)) as ChangesInput;
|
|
270
275
|
} catch {
|
|
271
276
|
return null;
|
|
272
277
|
}
|
|
@@ -291,7 +296,7 @@ export const readFilesTool: Tool<ReadFilesInput> = {
|
|
|
291
296
|
`### ${i}. read-files — read multiple files from the repo at once\n<read-files>\n["src/foo.ts", "src/bar.ts"]\n</read-files>`,
|
|
292
297
|
parseInput: (body) => {
|
|
293
298
|
try {
|
|
294
|
-
const parsed = JSON.parse(body) as string[];
|
|
299
|
+
const parsed = JSON.parse(cleanBody(body)) as string[];
|
|
295
300
|
if (!Array.isArray(parsed) || parsed.length === 0) return null;
|
|
296
301
|
return { paths: parsed };
|
|
297
302
|
} catch {
|
package/LENS.md
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# Lens Analysis
|
|
2
|
-
> Generated: 2026-03-21T11:15:38.543Z
|
|
3
|
-
|
|
4
|
-
## Overview
|
|
5
|
-
Lens is a CLI tool built with React components rendered in the terminal via Ink, designed to help developers understand, navigate, and interact with codebases using AI-powered analysis. The tool provides repository analysis, AI-powered insights, interactive chat, code review, timeline exploration, and task automation capabilities. Key components include ChatRunner for interactive conversations, RepoAnalysis for repository examination, and various command handlers like ReviewCommand and TaskCommand. The project uses Bun as a build tool and runtime, with Commander.js for CLI structure and TypeScript throughout for type safety.
|
|
6
|
-
|
|
7
|
-
## Important Folders
|
|
8
|
-
- src/components: Contains core UI components like ChatRunner (handles interactive chat), RepoAnalysis (analyzes repositories), DiffViewer (shows code differences), and ProviderPicker (selects AI providers). These components use Ink for terminal rendering and provide the main user interface.
|
|
9
|
-
- src/commands: Implements all CLI commands including repo (analyze remote repositories), review (local codebase analysis), task (apply natural language changes), chat (interactive conversation), timeline (commit history exploration), and commit (smart commit message generation).
|
|
10
|
-
- src/utils: Contains utility functions for AI integration (ai.ts), chat processing (chat.ts), configuration management (config.ts), file operations (files.ts), git operations (git.ts), memory management (memory.ts), and thinking animations (thinking.tsx).
|
|
11
|
-
- src/tools: Provides various tool implementations including files (file operations), shell (command execution), web (URL fetching), pdf (PDF generation), and git (version control operations). These tools are used throughout the chat functionality.
|
|
12
|
-
|
|
13
|
-
## Missing Configs
|
|
14
|
-
- ESLint configuration: The project uses TypeScript but lacks an ESLint config file (.eslintrc.js or eslint.config.js) for code quality enforcement
|
|
15
|
-
- Testing setup: No test framework configuration (Jest/Vitest) or test files found, which is important for a developer tool of this complexity
|
|
16
|
-
- GitHub Actions CI/CD: Missing workflow files for automated testing and deployment, which would help maintain quality for a CLI tool
|
|
17
|
-
|
|
18
|
-
## Security Issues
|
|
19
|
-
- In src/utils/chat.ts: The parseResponse function uses regex-based XML parsing which could be vulnerable to injection attacks if malformed responses are processed
|
|
20
|
-
- In src/utils/repo.ts: The cloneRepo function uses exec() with user-provided URLs without proper sanitization, potentially allowing command injection
|
|
21
|
-
- In multiple files: API keys and sensitive information are handled without encryption in config files stored in ~/.lens directory
|
|
22
|
-
|
|
23
|
-
## Suggestions
|
|
24
|
-
- In src/utils/chat.ts: Replace regex-based XML parsing with a proper XML parser library to prevent injection vulnerabilities and improve reliability
|
|
25
|
-
- In src/utils/repo.ts: Use execFile with proper argument sanitization instead of exec() for git operations to prevent command injection attacks
|
|
26
|
-
- In src/utils/config.ts: Implement encryption for storing API keys in the config file rather than plaintext storage
|
|
27
|
-
- In src/components/chat/ChatRunner.tsx: Add pagination or virtualization for long chat histories to improve performance with many messages
|
|
28
|
-
- In package.json: Add linting and testing scripts to establish better code quality practices for the project
|
|
29
|
-
|
|
30
|
-
<!--lens-json
|
|
31
|
-
{"overview":"Lens is a CLI tool built with React components rendered in the terminal via Ink, designed to help developers understand, navigate, and interact with codebases using AI-powered analysis. The tool provides repository analysis, AI-powered insights, interactive chat, code review, timeline exploration, and task automation capabilities. Key components include ChatRunner for interactive conversations, RepoAnalysis for repository examination, and various command handlers like ReviewCommand and TaskCommand. The project uses Bun as a build tool and runtime, with Commander.js for CLI structure and TypeScript throughout for type safety.","importantFolders":["src/components: Contains core UI components like ChatRunner (handles interactive chat), RepoAnalysis (analyzes repositories), DiffViewer (shows code differences), and ProviderPicker (selects AI providers). These components use Ink for terminal rendering and provide the main user interface.","src/commands: Implements all CLI commands including repo (analyze remote repositories), review (local codebase analysis), task (apply natural language changes), chat (interactive conversation), timeline (commit history exploration), and commit (smart commit message generation).","src/utils: Contains utility functions for AI integration (ai.ts), chat processing (chat.ts), configuration management (config.ts), file operations (files.ts), git operations (git.ts), memory management (memory.ts), and thinking animations (thinking.tsx).","src/tools: Provides various tool implementations including files (file operations), shell (command execution), web (URL fetching), pdf (PDF generation), and git (version control operations). These tools are used throughout the chat functionality."],"missingConfigs":["ESLint configuration: The project uses TypeScript but lacks an ESLint config file (.eslintrc.js or eslint.config.js) for code quality enforcement","Testing setup: No test framework configuration (Jest/Vitest) or test files found, which is important for a developer tool of this complexity","GitHub Actions CI/CD: Missing workflow files for automated testing and deployment, which would help maintain quality for a CLI tool"],"securityIssues":["In src/utils/chat.ts: The parseResponse function uses regex-based XML parsing which could be vulnerable to injection attacks if malformed responses are processed","In src/utils/repo.ts: The cloneRepo function uses exec() with user-provided URLs without proper sanitization, potentially allowing command injection","In multiple files: API keys and sensitive information are handled without encryption in config files stored in ~/.lens directory"],"suggestions":["In src/utils/chat.ts: Replace regex-based XML parsing with a proper XML parser library to prevent injection vulnerabilities and improve reliability","In src/utils/repo.ts: Use execFile with proper argument sanitization instead of exec() for git operations to prevent command injection attacks","In src/utils/config.ts: Implement encryption for storing API keys in the config file rather than plaintext storage","In src/components/chat/ChatRunner.tsx: Add pagination or virtualization for long chat histories to improve performance with many messages","In package.json: Add linting and testing scripts to establish better code quality practices for the project"],"generatedAt":"2026-03-21T11:15:38.543Z"}
|
|
32
|
-
lens-json-->
|