@sean.holung/minicode 0.3.4 → 0.3.6
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 +25 -47
- package/dist/scripts/run-benchmarks.js +73 -28
- package/dist/src/agent/config.js +51 -66
- package/dist/src/agent/editable-config.js +50 -58
- package/dist/src/agent/home-env.js +74 -0
- package/dist/src/benchmark/runner.js +142 -59
- package/dist/src/cli/config-slash-command.js +15 -13
- package/dist/src/indexer/project-index.js +49 -13
- package/dist/src/serve/agent-bridge.js +99 -31
- package/dist/src/serve/mcp-server.js +70 -21
- package/dist/src/serve/server.js +198 -8
- package/dist/src/session/session-preview.js +14 -0
- package/dist/src/shared/graph-search.js +80 -0
- package/dist/src/shared/graph-selection.js +40 -0
- package/dist/src/shared/graph-symbols.js +82 -0
- package/dist/src/shared/symbol-resolution.js +33 -0
- package/dist/src/tools/find-path.js +15 -6
- package/dist/src/tools/find-references.js +7 -2
- package/dist/src/tools/get-dependencies.js +8 -3
- package/dist/src/tools/read-symbol.js +9 -3
- package/dist/src/tools/registry.js +4 -1
- package/dist/src/tools/search-code-map.js +18 -3
- package/dist/src/web/app.js +646 -87
- package/dist/src/web/index.html +68 -6
- package/dist/src/web/style.css +208 -1
- package/dist/tests/benchmark-harness.test.js +100 -0
- package/dist/tests/config-api.test.js +5 -5
- package/dist/tests/config-integration.test.js +130 -56
- package/dist/tests/config-slash-command.test.js +12 -11
- package/dist/tests/config.test.js +12 -4
- package/dist/tests/editable-config.test.js +15 -12
- package/dist/tests/file-tools.test.js +34 -1
- package/dist/tests/find-path.test.js +43 -2
- package/dist/tests/find-references.test.js +49 -0
- package/dist/tests/get-dependencies.test.js +23 -0
- package/dist/tests/graph-onboarding.test.js +10 -1
- package/dist/tests/graph-search.test.js +66 -0
- package/dist/tests/graph-selection.test.js +58 -0
- package/dist/tests/graph-symbols.test.js +45 -0
- package/dist/tests/home-env.test.js +56 -0
- package/dist/tests/indexer.test.js +6 -0
- package/dist/tests/read-symbol.test.js +35 -0
- package/dist/tests/request-tracker.test.js +15 -0
- package/dist/tests/run-benchmarks.test.js +117 -33
- package/dist/tests/search-code-map.test.js +2 -0
- package/dist/tests/serve.integration.test.js +338 -9
- package/dist/tests/session-preview.test.js +56 -0
- package/dist/tests/session-ui.test.js +4 -0
- package/dist/tests/settings-ui.test.js +18 -0
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js +2 -1
- package/node_modules/@minicode/agent-sdk/dist/src/agent/agent.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/index.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/types.d.ts +3 -0
- package/node_modules/@minicode/agent-sdk/dist/src/indexer/types.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/registry.d.ts +3 -0
- package/node_modules/@minicode/agent-sdk/dist/src/tools/registry.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/registry.js +4 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/registry.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/run-command.d.ts +11 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/run-command.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/run-command.js +4 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/run-command.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/search.d.ts.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/src/tools/search.js +16 -8
- package/node_modules/@minicode/agent-sdk/dist/src/tools/search.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/tests/file-tools.test.js +19 -2
- package/node_modules/@minicode/agent-sdk/dist/tests/file-tools.test.js.map +1 -1
- package/node_modules/@minicode/agent-sdk/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { readFile, stat } from "node:fs/promises";
|
|
2
2
|
import { resolveWorkspacePath, validateFileReadSize, expectNonEmptyString, expectOptionalBoolean, } from "@minicode/agent-sdk";
|
|
3
3
|
import { getSymbolDisplayName } from "../indexer/symbol-names.js";
|
|
4
|
+
import { formatAmbiguousSymbolMatches, resolveSymbolInput, } from "../shared/symbol-resolution.js";
|
|
4
5
|
const LEADING_CONTEXT_LINES = 3;
|
|
5
6
|
export function createReadSymbolTool(config, projectIndex) {
|
|
6
7
|
return {
|
|
7
8
|
name: "read_symbol",
|
|
8
9
|
description: "Read a specific function, class, or type definition by name. " +
|
|
9
10
|
"Returns the symbol's source code, referenced types, callers, and callees. " +
|
|
11
|
+
"If a bare name matches multiple symbols, returns disambiguation candidates. " +
|
|
10
12
|
"PREFER this over read_file for .ts/.tsx/.js/.jsx — use the code map to find symbol names.",
|
|
11
13
|
inputSchema: {
|
|
12
14
|
type: "object",
|
|
@@ -26,10 +28,14 @@ export function createReadSymbolTool(config, projectIndex) {
|
|
|
26
28
|
execute: async (input) => {
|
|
27
29
|
const name = expectNonEmptyString(input, "name");
|
|
28
30
|
const includeBody = expectOptionalBoolean(input, "includeBody") ?? true;
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
+
const resolution = resolveSymbolInput(projectIndex, name);
|
|
32
|
+
if (resolution.status === "missing") {
|
|
31
33
|
return `Symbol "${name}" not found in the project index. Try using search to find it, or use read_file to read the full file.`;
|
|
32
34
|
}
|
|
35
|
+
if (resolution.status === "ambiguous") {
|
|
36
|
+
return formatAmbiguousSymbolMatches("read_symbol", name, resolution.matches);
|
|
37
|
+
}
|
|
38
|
+
const symbol = resolution.symbol;
|
|
33
39
|
const filePath = resolveWorkspacePath(symbol.filePath, config.workspaceRoot);
|
|
34
40
|
const fileStat = await stat(filePath);
|
|
35
41
|
if (!fileStat.isFile()) {
|
|
@@ -75,7 +81,7 @@ export function createReadSymbolTool(config, projectIndex) {
|
|
|
75
81
|
if (calls.length > 0) {
|
|
76
82
|
parts.push("", "## Calls", "", calls.map((s) => `- ${s}`).join("\n"));
|
|
77
83
|
}
|
|
78
|
-
const cone = projectIndex.getDependencyCone(
|
|
84
|
+
const cone = projectIndex.getDependencyCone(symbol.qualifiedName, 1);
|
|
79
85
|
const typeRefs = cone.filter((s) => s.qualifiedName !== symbol.qualifiedName &&
|
|
80
86
|
(s.kind === "interface" || s.kind === "type"));
|
|
81
87
|
if (typeRefs.length > 0) {
|
|
@@ -14,6 +14,9 @@ export function createToolRegistry(config, projectIndex) {
|
|
|
14
14
|
? {
|
|
15
15
|
afterWrite: (relPath, content) => projectIndex.reindexFile(relPath, content),
|
|
16
16
|
afterEdit: (relPath, content) => projectIndex.reindexFile(relPath, content),
|
|
17
|
+
afterCommand: async () => {
|
|
18
|
+
await projectIndex.refreshFromWorkspace();
|
|
19
|
+
},
|
|
17
20
|
}
|
|
18
21
|
: undefined;
|
|
19
22
|
const tools = [
|
|
@@ -22,7 +25,7 @@ export function createToolRegistry(config, projectIndex) {
|
|
|
22
25
|
createEditFileTool(config, hooks ? { afterEdit: hooks.afterEdit } : undefined),
|
|
23
26
|
createSearchTool(config),
|
|
24
27
|
createListFilesTool(config),
|
|
25
|
-
createRunCommandTool(config),
|
|
28
|
+
createRunCommandTool(config, hooks ? { afterCommand: hooks.afterCommand } : undefined),
|
|
26
29
|
];
|
|
27
30
|
if (projectIndex) {
|
|
28
31
|
tools.splice(1, 0, createReadSymbolTool(config, projectIndex));
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { expectNonEmptyString, expectOptionalNumber } from "@minicode/agent-sdk";
|
|
2
2
|
import { getSymbolDisplayName, getSymbolLookupNames } from "../indexer/symbol-names.js";
|
|
3
3
|
const DEFAULT_LIMIT = 30;
|
|
4
|
+
function compareMatchedSymbols(pattern, a, b) {
|
|
5
|
+
const lowerPattern = pattern.toLowerCase();
|
|
6
|
+
const aDisplay = getSymbolDisplayName(a).toLowerCase();
|
|
7
|
+
const bDisplay = getSymbolDisplayName(b).toLowerCase();
|
|
8
|
+
const aExact = Number(aDisplay === lowerPattern || a.qualifiedName.toLowerCase() === lowerPattern || a.name.toLowerCase() === lowerPattern);
|
|
9
|
+
const bExact = Number(bDisplay === lowerPattern || b.qualifiedName.toLowerCase() === lowerPattern || b.name.toLowerCase() === lowerPattern);
|
|
10
|
+
if (aExact !== bExact) {
|
|
11
|
+
return bExact - aExact;
|
|
12
|
+
}
|
|
13
|
+
return Number(b.exported) - Number(a.exported) ||
|
|
14
|
+
aDisplay.localeCompare(bDisplay) ||
|
|
15
|
+
a.filePath.localeCompare(b.filePath) ||
|
|
16
|
+
a.startLine - b.startLine ||
|
|
17
|
+
a.qualifiedName.localeCompare(b.qualifiedName);
|
|
18
|
+
}
|
|
4
19
|
function matchesPattern(text, pattern) {
|
|
5
20
|
const lowerText = text.toLowerCase();
|
|
6
21
|
const lowerPattern = pattern.toLowerCase();
|
|
@@ -11,7 +26,7 @@ export function createSearchCodeMapTool(projectIndex) {
|
|
|
11
26
|
name: "search_code_map",
|
|
12
27
|
description: "Search the full project index for symbols by name or substring. " +
|
|
13
28
|
"Use when the code map is truncated and you need to find a symbol not listed. " +
|
|
14
|
-
"Returns qualified names and file paths; use read_symbol with the result.",
|
|
29
|
+
"Returns disambiguated display names, qualified names, and file paths; use read_symbol with the result.",
|
|
15
30
|
inputSchema: {
|
|
16
31
|
type: "object",
|
|
17
32
|
properties: {
|
|
@@ -53,9 +68,9 @@ export function createSearchCodeMapTool(projectIndex) {
|
|
|
53
68
|
return false;
|
|
54
69
|
}
|
|
55
70
|
return true;
|
|
56
|
-
});
|
|
71
|
+
}).sort((a, b) => compareMatchedSymbols(pattern, a, b));
|
|
57
72
|
const shown = matches.slice(skip, skip + limit);
|
|
58
|
-
const lines = shown.map((s) => `- ${getSymbolDisplayName(s)} (${s.kind}) — ${s.filePath}`);
|
|
73
|
+
const lines = shown.map((s) => `- ${getSymbolDisplayName(s)} (${s.kind}) — ${s.filePath}:${s.startLine} — qualified: ${s.qualifiedName}`);
|
|
59
74
|
const remaining = matches.length - skip - shown.length;
|
|
60
75
|
const footer = remaining > 0
|
|
61
76
|
? `\n... and ${remaining} more (use skip: ${skip + limit}, limit: ${limit} for next page)`
|