@makeitvisible/cli 0.1.0 → 0.2.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/README.md +43 -0
- package/dist/bin/index.js +696 -82
- package/dist/bin/index.js.map +1 -1
- package/dist/index.d.ts +17 -62
- package/dist/index.js +143 -11
- package/dist/index.js.map +1 -1
- package/dist/types-BmNeVNFe.d.ts +62 -0
- package/dist/video/remotion/index.d.ts +2 -0
- package/dist/video/remotion/index.js +716 -0
- package/dist/video/remotion/index.js.map +1 -0
- package/dist/video/remotion/render.d.ts +111 -0
- package/dist/video/remotion/render.js +110 -0
- package/dist/video/remotion/render.js.map +1 -0
- package/dist/video/renderer.d.ts +154 -0
- package/dist/video/renderer.js +367 -0
- package/dist/video/renderer.js.map +1 -0
- package/package.json +15 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,66 +1,7 @@
|
|
|
1
|
+
import { A as ArtifactSource, a as ArtifactContext } from './types-BmNeVNFe.js';
|
|
2
|
+
export { b as Artifact, c as ArtifactStatus, C as CreateArtifactInput, d as CreateArtifactResponse } from './types-BmNeVNFe.js';
|
|
1
3
|
import { ChatCompletionTool } from 'openai/resources/chat/completions';
|
|
2
4
|
|
|
3
|
-
/**
|
|
4
|
-
* Shared Types for Visible CLI
|
|
5
|
-
*
|
|
6
|
-
* Types related to artifacts generated from code analysis.
|
|
7
|
-
* (Vendored from @visible/shared for standalone package)
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Represents an artifact generated from code analysis.
|
|
11
|
-
* An artifact contains high-level descriptions and guidelines
|
|
12
|
-
* that serve as input for final material generation.
|
|
13
|
-
*/
|
|
14
|
-
interface Artifact {
|
|
15
|
-
id: string;
|
|
16
|
-
title: string;
|
|
17
|
-
description: string;
|
|
18
|
-
source: ArtifactSource;
|
|
19
|
-
context: ArtifactContext;
|
|
20
|
-
guidelines: string[];
|
|
21
|
-
createdAt: Date;
|
|
22
|
-
updatedAt: Date;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* The source of the artifact (PR, commit, code section, etc.)
|
|
26
|
-
*/
|
|
27
|
-
interface ArtifactSource {
|
|
28
|
-
type: "pr" | "commit" | "code-section" | "repository";
|
|
29
|
-
reference: string;
|
|
30
|
-
url?: string;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Context extracted from the code analysis
|
|
34
|
-
*/
|
|
35
|
-
interface ArtifactContext {
|
|
36
|
-
summary: string;
|
|
37
|
-
technicalDetails: string[];
|
|
38
|
-
affectedComponents: string[];
|
|
39
|
-
breakingChanges: boolean;
|
|
40
|
-
keywords: string[];
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Status of an artifact
|
|
44
|
-
*/
|
|
45
|
-
type ArtifactStatus = "draft" | "ready" | "generating" | "completed";
|
|
46
|
-
/**
|
|
47
|
-
* Input for creating a new artifact (from CLI)
|
|
48
|
-
*/
|
|
49
|
-
interface CreateArtifactInput {
|
|
50
|
-
title: string;
|
|
51
|
-
description: string;
|
|
52
|
-
source: ArtifactSource;
|
|
53
|
-
context: ArtifactContext;
|
|
54
|
-
guidelines: string[];
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Response after creating an artifact
|
|
58
|
-
*/
|
|
59
|
-
interface CreateArtifactResponse {
|
|
60
|
-
id: string;
|
|
61
|
-
url: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
5
|
/**
|
|
65
6
|
* Git Analyzer
|
|
66
7
|
*
|
|
@@ -73,12 +14,25 @@ interface CreateArtifactResponse {
|
|
|
73
14
|
* - Identify changed files and their context
|
|
74
15
|
*/
|
|
75
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Code snippet extracted from diff
|
|
19
|
+
*/
|
|
20
|
+
interface DiffCodeSnippet {
|
|
21
|
+
file: string;
|
|
22
|
+
code: string;
|
|
23
|
+
startLine?: number;
|
|
24
|
+
language?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
changeType: "added" | "deleted" | "modified" | "context";
|
|
27
|
+
}
|
|
76
28
|
interface AnalysisResult {
|
|
77
29
|
title: string;
|
|
78
30
|
description: string;
|
|
79
31
|
source: ArtifactSource;
|
|
80
32
|
context: ArtifactContext;
|
|
81
33
|
guidelines: string[];
|
|
34
|
+
/** Code snippets extracted from the diff */
|
|
35
|
+
codeSnippets?: DiffCodeSnippet[];
|
|
82
36
|
}
|
|
83
37
|
/**
|
|
84
38
|
* Analyze a git diff range and produce an artifact
|
|
@@ -228,6 +182,7 @@ interface DetectiveOptions {
|
|
|
228
182
|
projectRoot: string;
|
|
229
183
|
verbose?: boolean;
|
|
230
184
|
maxIterations?: number;
|
|
185
|
+
maxToolCalls?: number;
|
|
231
186
|
onToolCall?: (toolName: string, args: unknown) => void;
|
|
232
187
|
onToolResult?: (toolName: string, result: ToolResult) => void;
|
|
233
188
|
onThinking?: (thought: string) => void;
|
|
@@ -289,4 +244,4 @@ declare function investigateFeature(query: string, options: Omit<DetectiveOption
|
|
|
289
244
|
projectRoot?: string;
|
|
290
245
|
}): Promise<InvestigationResult>;
|
|
291
246
|
|
|
292
|
-
export { AGENT_TOOLS, type AnalysisResult,
|
|
247
|
+
export { AGENT_TOOLS, type AnalysisResult, ArtifactContext, ArtifactSource, type ContextInput, DetectiveAgent, type DetectiveOptions, type DiffCodeSnippet, type InvestigationResult, type PROptions, type ToolContext, type ToolName, type ToolResult, analyzeDiff, analyzePR, artifactGenerator, detectBreakingChangesFromDiff, executeTool, extractContextFromPaths, findDefinition, findReferences, generateTechnicalSummary, getFileStructure, investigateFeature, listDirectory, mergeContexts, readFile, searchFiles, searchTypes };
|
package/dist/index.js
CHANGED
|
@@ -63,6 +63,92 @@ function getCommits(range) {
|
|
|
63
63
|
function getDiffContent(range) {
|
|
64
64
|
return git(`diff ${range}`);
|
|
65
65
|
}
|
|
66
|
+
function extractCodeSnippets(diffContent, maxSnippets = 6) {
|
|
67
|
+
const snippets = [];
|
|
68
|
+
const lines = diffContent.split("\n");
|
|
69
|
+
let currentFile = "";
|
|
70
|
+
let currentHunk = [];
|
|
71
|
+
let currentStartLine = 0;
|
|
72
|
+
let inHunk = false;
|
|
73
|
+
for (const line of lines) {
|
|
74
|
+
if (line.startsWith("diff --git")) {
|
|
75
|
+
if (currentHunk.length > 0 && currentFile) {
|
|
76
|
+
snippets.push(createSnippetFromHunk(currentFile, currentHunk, currentStartLine));
|
|
77
|
+
if (snippets.length >= maxSnippets) break;
|
|
78
|
+
}
|
|
79
|
+
currentHunk = [];
|
|
80
|
+
inHunk = false;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (line.startsWith("+++ b/")) {
|
|
84
|
+
currentFile = line.slice(6);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (line.startsWith("@@")) {
|
|
88
|
+
if (currentHunk.length > 0 && currentFile) {
|
|
89
|
+
snippets.push(createSnippetFromHunk(currentFile, currentHunk, currentStartLine));
|
|
90
|
+
if (snippets.length >= maxSnippets) break;
|
|
91
|
+
}
|
|
92
|
+
const match = line.match(/@@ -\d+(?:,\d+)? \+(\d+)/);
|
|
93
|
+
currentStartLine = match ? parseInt(match[1], 10) : 1;
|
|
94
|
+
currentHunk = [];
|
|
95
|
+
inHunk = true;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (inHunk && currentHunk.length < 15) {
|
|
99
|
+
currentHunk.push(line);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (currentHunk.length > 0 && currentFile && snippets.length < maxSnippets) {
|
|
103
|
+
snippets.push(createSnippetFromHunk(currentFile, currentHunk, currentStartLine));
|
|
104
|
+
}
|
|
105
|
+
return snippets;
|
|
106
|
+
}
|
|
107
|
+
function createSnippetFromHunk(file, hunkLines, startLine) {
|
|
108
|
+
const hasAdditions = hunkLines.some((l) => l.startsWith("+"));
|
|
109
|
+
const hasDeletions = hunkLines.some((l) => l.startsWith("-"));
|
|
110
|
+
let changeType;
|
|
111
|
+
if (hasAdditions && hasDeletions) {
|
|
112
|
+
changeType = "modified";
|
|
113
|
+
} else if (hasAdditions) {
|
|
114
|
+
changeType = "added";
|
|
115
|
+
} else if (hasDeletions) {
|
|
116
|
+
changeType = "deleted";
|
|
117
|
+
} else {
|
|
118
|
+
changeType = "context";
|
|
119
|
+
}
|
|
120
|
+
const code = hunkLines.map((line) => {
|
|
121
|
+
if (line.startsWith("+") || line.startsWith("-") || line.startsWith(" ")) {
|
|
122
|
+
return line.slice(1);
|
|
123
|
+
}
|
|
124
|
+
return line;
|
|
125
|
+
}).join("\n");
|
|
126
|
+
const ext = file.split(".").pop()?.toLowerCase() || "";
|
|
127
|
+
const langMap = {
|
|
128
|
+
ts: "typescript",
|
|
129
|
+
tsx: "typescript",
|
|
130
|
+
js: "javascript",
|
|
131
|
+
jsx: "javascript",
|
|
132
|
+
vue: "vue",
|
|
133
|
+
py: "python",
|
|
134
|
+
rb: "ruby",
|
|
135
|
+
go: "go",
|
|
136
|
+
rs: "rust",
|
|
137
|
+
java: "java",
|
|
138
|
+
css: "css",
|
|
139
|
+
scss: "scss",
|
|
140
|
+
html: "html",
|
|
141
|
+
json: "json"
|
|
142
|
+
};
|
|
143
|
+
return {
|
|
144
|
+
file,
|
|
145
|
+
code,
|
|
146
|
+
startLine,
|
|
147
|
+
language: langMap[ext] || "text",
|
|
148
|
+
description: `${changeType === "added" ? "Added" : changeType === "deleted" ? "Removed" : "Changed"} in ${file}`,
|
|
149
|
+
changeType
|
|
150
|
+
};
|
|
151
|
+
}
|
|
66
152
|
function detectBreakingChanges(commits, diffContent) {
|
|
67
153
|
const breakingPatterns = [
|
|
68
154
|
/BREAKING CHANGE/i,
|
|
@@ -213,12 +299,14 @@ async function analyzeDiff(range) {
|
|
|
213
299
|
breakingChanges,
|
|
214
300
|
keywords
|
|
215
301
|
};
|
|
302
|
+
const codeSnippets = extractCodeSnippets(diffContent);
|
|
216
303
|
return {
|
|
217
304
|
title,
|
|
218
305
|
description,
|
|
219
306
|
source,
|
|
220
307
|
context,
|
|
221
|
-
guidelines
|
|
308
|
+
guidelines,
|
|
309
|
+
codeSnippets
|
|
222
310
|
};
|
|
223
311
|
}
|
|
224
312
|
async function analyzePR(options) {
|
|
@@ -1167,6 +1255,14 @@ Your mission is to investigate a codebase based on a user's query and produce a
|
|
|
1167
1255
|
|
|
1168
1256
|
6. **Document Technical Details**: Note any important patterns, validations, error handling, or edge cases.
|
|
1169
1257
|
|
|
1258
|
+
## Efficiency Rules (Important)
|
|
1259
|
+
|
|
1260
|
+
- Be efficient: use as few tools as possible (aim for 8-12 tool calls).
|
|
1261
|
+
- Prefer targeted \`search_files\` in content or filename over broad directory listing.
|
|
1262
|
+
- Read only the most relevant files; avoid reading the same file multiple times.
|
|
1263
|
+
- If you have enough information to explain the feature, **complete the investigation** even if some sections are partial.
|
|
1264
|
+
- Use empty arrays for unknown sections rather than continuing to search.
|
|
1265
|
+
|
|
1170
1266
|
## Tool Usage Tips
|
|
1171
1267
|
|
|
1172
1268
|
- Use \`search_files\` with searchIn="filename" first for broad discovery
|
|
@@ -1210,6 +1306,7 @@ var DetectiveAgent = class {
|
|
|
1210
1306
|
this.context = { projectRoot: options.projectRoot };
|
|
1211
1307
|
this.options = {
|
|
1212
1308
|
maxIterations: 25,
|
|
1309
|
+
maxToolCalls: 18,
|
|
1213
1310
|
...options
|
|
1214
1311
|
};
|
|
1215
1312
|
this.messages = [{ role: "system", content: SYSTEM_PROMPT }];
|
|
@@ -1228,14 +1325,23 @@ Use the available tools to explore the codebase, understand the feature, and the
|
|
|
1228
1325
|
});
|
|
1229
1326
|
let iterations = 0;
|
|
1230
1327
|
const maxIterations = this.options.maxIterations;
|
|
1328
|
+
const maxToolCalls = this.options.maxToolCalls;
|
|
1231
1329
|
while (iterations < maxIterations) {
|
|
1232
1330
|
iterations++;
|
|
1233
1331
|
try {
|
|
1332
|
+
const shouldForceCompletion = this.toolCallCount >= maxToolCalls || iterations === maxIterations;
|
|
1333
|
+
if (shouldForceCompletion) {
|
|
1334
|
+
this.messages.push({
|
|
1335
|
+
role: "user",
|
|
1336
|
+
content: "Finalize the investigation now using ONLY the information already gathered. Do not call any tools except complete_investigation. Use empty arrays for any section you could not verify."
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
const tools = shouldForceCompletion ? AGENT_TOOLS.filter((tool) => tool.function.name === "complete_investigation") : AGENT_TOOLS;
|
|
1234
1340
|
const response = await this.openai.chat.completions.create({
|
|
1235
|
-
model: "gpt-
|
|
1341
|
+
model: "gpt-5.2",
|
|
1236
1342
|
messages: this.messages,
|
|
1237
|
-
tools
|
|
1238
|
-
tool_choice: "auto",
|
|
1343
|
+
tools,
|
|
1344
|
+
tool_choice: shouldForceCompletion ? "required" : "auto",
|
|
1239
1345
|
temperature: 0.1
|
|
1240
1346
|
});
|
|
1241
1347
|
const message = response.choices[0].message;
|
|
@@ -1243,15 +1349,41 @@ Use the available tools to explore the codebase, understand the feature, and the
|
|
|
1243
1349
|
if (message.content && this.options.onThinking) {
|
|
1244
1350
|
this.options.onThinking(message.content);
|
|
1245
1351
|
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1352
|
+
let toolCalls = message.tool_calls;
|
|
1353
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
1354
|
+
if (!shouldForceCompletion) {
|
|
1355
|
+
this.messages.push({
|
|
1356
|
+
role: "user",
|
|
1357
|
+
content: "Complete the investigation now using the current context. Call complete_investigation with best-effort details and empty arrays where needed."
|
|
1358
|
+
});
|
|
1359
|
+
const forced = await this.openai.chat.completions.create({
|
|
1360
|
+
model: "gpt-5.2",
|
|
1361
|
+
messages: this.messages,
|
|
1362
|
+
tools: AGENT_TOOLS.filter((tool) => tool.function.name === "complete_investigation"),
|
|
1363
|
+
tool_choice: "required",
|
|
1364
|
+
temperature: 0.1
|
|
1365
|
+
});
|
|
1366
|
+
const forcedMessage = forced.choices[0].message;
|
|
1367
|
+
this.messages.push(forcedMessage);
|
|
1368
|
+
if (forcedMessage.tool_calls && forcedMessage.tool_calls.length > 0) {
|
|
1369
|
+
toolCalls = forcedMessage.tool_calls;
|
|
1370
|
+
} else {
|
|
1371
|
+
return {
|
|
1372
|
+
success: false,
|
|
1373
|
+
error: forcedMessage.content ? `Agent finished without tool calls: ${forcedMessage.content}` : "Agent finished without completing investigation",
|
|
1374
|
+
toolCalls: this.toolCallCount
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
} else {
|
|
1378
|
+
return {
|
|
1379
|
+
success: false,
|
|
1380
|
+
error: message.content ? `Agent finished without tool calls: ${message.content}` : "Agent finished without completing investigation",
|
|
1381
|
+
toolCalls: this.toolCallCount
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1252
1384
|
}
|
|
1253
1385
|
const toolResults = [];
|
|
1254
|
-
for (const toolCall of
|
|
1386
|
+
for (const toolCall of toolCalls ?? []) {
|
|
1255
1387
|
const toolName = toolCall.function.name;
|
|
1256
1388
|
let args;
|
|
1257
1389
|
try {
|