@bike4mind/cli 0.2.28-feat-questmaster-progress-indicators.18753 → 0.2.28-feat-get-file-structure-tool.18750
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/dist/{chunk-JJBDHUGY.js → chunk-6QZAOJPA.js} +1 -1
- package/dist/{chunk-VGYTNJXN.js → chunk-AXOBK7TG.js} +1 -1
- package/dist/{chunk-UNOJBVD2.js → chunk-NTNJJRSU.js} +4 -4
- package/dist/{chunk-ZEMWV6IR.js → chunk-WXWRI3H7.js} +1 -1
- package/dist/{create-NGI7IIQ4.js → create-FAXYW2LN.js} +2 -2
- package/dist/index.js +128 -25
- package/dist/{mementoService-X35OMHVC.js → mementoService-GSZ2SFDS.js} +2 -2
- package/dist/{src-CBU6EAO3.js → src-FCYHV43K.js} +1 -1
- package/dist/{subtractCredits-RL6JVDMI.js → subtractCredits-OIVXTWEI.js} +2 -2
- package/dist/treeSitterEngine-4SGFQDY3.js +330 -0
- package/package.json +8 -6
|
@@ -9181,7 +9181,7 @@ var QuestMaster = class {
|
|
|
9181
9181
|
if (!this.quest) {
|
|
9182
9182
|
throw new Error("No quest context available");
|
|
9183
9183
|
}
|
|
9184
|
-
await this.onStatusUpdate(this.quest, "
|
|
9184
|
+
await this.onStatusUpdate(this.quest, "Processing quest plan...");
|
|
9185
9185
|
const defaultResponse = {
|
|
9186
9186
|
type: "narrative",
|
|
9187
9187
|
meta: {
|
|
@@ -9263,7 +9263,7 @@ var QuestMaster = class {
|
|
|
9263
9263
|
}
|
|
9264
9264
|
if (extracted.length > 0) {
|
|
9265
9265
|
this.logger.log("Successfully extracted QuestMaster data:", extracted);
|
|
9266
|
-
await this.onStatusUpdate(this.quest, "
|
|
9266
|
+
await this.onStatusUpdate(this.quest, "Extracted QuestMaster data");
|
|
9267
9267
|
const validQuests = extracted.filter((quest) => quest !== null && typeof quest === "object" && quest.id && quest.title && quest.description);
|
|
9268
9268
|
if (validQuests.length === 0) {
|
|
9269
9269
|
throw new Error("No valid quests found after filtering");
|
|
@@ -9356,7 +9356,7 @@ var QuestMaster = class {
|
|
|
9356
9356
|
questResponse = defaultResponse;
|
|
9357
9357
|
this.logger.error("Invalid quest response structure, using default");
|
|
9358
9358
|
}
|
|
9359
|
-
await this.onStatusUpdate(this.quest, "
|
|
9359
|
+
await this.onStatusUpdate(this.quest, "Saving quest plan...");
|
|
9360
9360
|
console.log("\u{1F3AF} Creating QuestMasterPlan with userId:", this.userId);
|
|
9361
9361
|
const questMasterPlan = await this.db.questMasterPlans.create({
|
|
9362
9362
|
notebookId: this.quest.sessionId,
|
|
@@ -9678,7 +9678,7 @@ HANDLING VERBOSE INPUT:
|
|
|
9678
9678
|
}
|
|
9679
9679
|
const { history = [] } = options;
|
|
9680
9680
|
this.logger.log(`Creating quest plan with ${history.length} history messages for context`);
|
|
9681
|
-
await this.onStatusUpdate(this.quest, "
|
|
9681
|
+
await this.onStatusUpdate(this.quest, "Creating quest plan...");
|
|
9682
9682
|
if (isGPT5ModelWithToolSupport(model)) {
|
|
9683
9683
|
this.logger.log(`Using function calling approach for GPT-5 model: ${model}`);
|
|
9684
9684
|
try {
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getEffectiveApiKey,
|
|
6
6
|
getOpenWeatherKey,
|
|
7
7
|
getSerperKey
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AXOBK7TG.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigStore
|
|
11
11
|
} from "./chunk-23T2XGSZ.js";
|
|
@@ -13,8 +13,8 @@ import {
|
|
|
13
13
|
selectActiveBackgroundAgents,
|
|
14
14
|
useCliStore
|
|
15
15
|
} from "./chunk-TVW4ZESU.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-6QZAOJPA.js";
|
|
17
|
+
import "./chunk-WXWRI3H7.js";
|
|
18
18
|
import {
|
|
19
19
|
BFLImageService,
|
|
20
20
|
BaseStorage,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
OpenAIBackend,
|
|
27
27
|
OpenAIImageService,
|
|
28
28
|
XAIImageService
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-NTNJJRSU.js";
|
|
30
30
|
import {
|
|
31
31
|
AiEvents,
|
|
32
32
|
ApiKeyEvents,
|
|
@@ -3806,6 +3806,7 @@ var DEFAULT_TOOL_CATEGORIES = {
|
|
|
3806
3806
|
grep_search: "prompt_default",
|
|
3807
3807
|
glob_files: "prompt_default",
|
|
3808
3808
|
get_file_tree: "prompt_default",
|
|
3809
|
+
get_file_structure: "prompt_default",
|
|
3809
3810
|
git_status: "prompt_default",
|
|
3810
3811
|
git_diff: "prompt_default",
|
|
3811
3812
|
git_log: "prompt_default",
|
|
@@ -6059,8 +6060,8 @@ async function processAndStoreImages(images, context) {
|
|
|
6059
6060
|
const buffer = await downloadImage(image);
|
|
6060
6061
|
const fileType = await fileTypeFromBuffer2(buffer);
|
|
6061
6062
|
const filename = `${uuidv45()}.${fileType?.ext}`;
|
|
6062
|
-
const
|
|
6063
|
-
return
|
|
6063
|
+
const path19 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
6064
|
+
return path19;
|
|
6064
6065
|
}));
|
|
6065
6066
|
}
|
|
6066
6067
|
async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
|
|
@@ -7386,8 +7387,8 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
7386
7387
|
const buffer = await downloadImage2(imageUrl);
|
|
7387
7388
|
const fileType = await fileTypeFromBuffer3(buffer);
|
|
7388
7389
|
const filename = `${uuidv46()}.${fileType?.ext}`;
|
|
7389
|
-
const
|
|
7390
|
-
return
|
|
7390
|
+
const path19 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
7391
|
+
return path19;
|
|
7391
7392
|
}
|
|
7392
7393
|
async function generateFullMask(imageBuffer) {
|
|
7393
7394
|
const sharp = (await import("sharp")).default;
|
|
@@ -11624,7 +11625,7 @@ async function generateFileDeletePreview(args) {
|
|
|
11624
11625
|
if (!existsSync7(args.path)) {
|
|
11625
11626
|
return `[File does not exist: ${args.path}]`;
|
|
11626
11627
|
}
|
|
11627
|
-
const stats = await import("fs/promises").then((
|
|
11628
|
+
const stats = await import("fs/promises").then((fs15) => fs15.stat(args.path));
|
|
11628
11629
|
return `[File will be deleted]
|
|
11629
11630
|
|
|
11630
11631
|
Path: ${args.path}
|
|
@@ -11915,21 +11916,21 @@ var NoOpStorage = class extends BaseStorage {
|
|
|
11915
11916
|
async upload(input, destination, options) {
|
|
11916
11917
|
return `/tmp/${destination}`;
|
|
11917
11918
|
}
|
|
11918
|
-
async download(
|
|
11919
|
+
async download(path19) {
|
|
11919
11920
|
throw new Error("Download not supported in CLI");
|
|
11920
11921
|
}
|
|
11921
|
-
async delete(
|
|
11922
|
+
async delete(path19) {
|
|
11922
11923
|
}
|
|
11923
|
-
async getSignedUrl(
|
|
11924
|
-
return `/tmp/${
|
|
11924
|
+
async getSignedUrl(path19) {
|
|
11925
|
+
return `/tmp/${path19}`;
|
|
11925
11926
|
}
|
|
11926
|
-
getPublicUrl(
|
|
11927
|
-
return `/tmp/${
|
|
11927
|
+
getPublicUrl(path19) {
|
|
11928
|
+
return `/tmp/${path19}`;
|
|
11928
11929
|
}
|
|
11929
|
-
async getPreview(
|
|
11930
|
-
return `/tmp/${
|
|
11930
|
+
async getPreview(path19) {
|
|
11931
|
+
return `/tmp/${path19}`;
|
|
11931
11932
|
}
|
|
11932
|
-
async getMetadata(
|
|
11933
|
+
async getMetadata(path19) {
|
|
11933
11934
|
return { size: 0, contentType: "application/octet-stream" };
|
|
11934
11935
|
}
|
|
11935
11936
|
};
|
|
@@ -13801,7 +13802,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
13801
13802
|
// package.json
|
|
13802
13803
|
var package_default = {
|
|
13803
13804
|
name: "@bike4mind/cli",
|
|
13804
|
-
version: "0.2.28-feat-
|
|
13805
|
+
version: "0.2.28-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
13805
13806
|
type: "module",
|
|
13806
13807
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
13807
13808
|
license: "UNLICENSED",
|
|
@@ -13896,10 +13897,12 @@ var package_default = {
|
|
|
13896
13897
|
sharp: "^0.34.5",
|
|
13897
13898
|
speakeasy: "^2.0.0",
|
|
13898
13899
|
tiktoken: "^1.0.16",
|
|
13900
|
+
"tree-sitter-wasms": "^0.1.13",
|
|
13899
13901
|
turndown: "^7.2.0",
|
|
13900
13902
|
unpdf: "^0.10.0",
|
|
13901
13903
|
uuid: "^9.0.1",
|
|
13902
13904
|
voyageai: "^0.0.4",
|
|
13905
|
+
"web-tree-sitter": "0.25.10",
|
|
13903
13906
|
xlsx: "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
|
13904
13907
|
yargs: "^17.7.2",
|
|
13905
13908
|
yauzl: "^3.1.3",
|
|
@@ -13909,10 +13912,10 @@ var package_default = {
|
|
|
13909
13912
|
},
|
|
13910
13913
|
devDependencies: {
|
|
13911
13914
|
"@bike4mind/agents": "0.1.0",
|
|
13912
|
-
"@bike4mind/common": "2.49.1-feat-
|
|
13913
|
-
"@bike4mind/mcp": "1.28.3-feat-
|
|
13914
|
-
"@bike4mind/services": "2.47.2-feat-
|
|
13915
|
-
"@bike4mind/utils": "2.4.2-feat-
|
|
13915
|
+
"@bike4mind/common": "2.49.1-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
13916
|
+
"@bike4mind/mcp": "1.28.3-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
13917
|
+
"@bike4mind/services": "2.47.2-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
13918
|
+
"@bike4mind/utils": "2.4.2-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
13916
13919
|
"@types/better-sqlite3": "^7.6.13",
|
|
13917
13920
|
"@types/diff": "^5.0.9",
|
|
13918
13921
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -13929,7 +13932,7 @@ var package_default = {
|
|
|
13929
13932
|
optionalDependencies: {
|
|
13930
13933
|
"@vscode/ripgrep": "^1.17.0"
|
|
13931
13934
|
},
|
|
13932
|
-
gitHead: "
|
|
13935
|
+
gitHead: "9a81a7d11946ea54b9a47fe35897e36fc7541c65"
|
|
13933
13936
|
};
|
|
13934
13937
|
|
|
13935
13938
|
// src/config/constants.ts
|
|
@@ -15609,6 +15612,99 @@ function createFindDefinitionTool() {
|
|
|
15609
15612
|
};
|
|
15610
15613
|
}
|
|
15611
15614
|
|
|
15615
|
+
// src/tools/getFileStructure/index.ts
|
|
15616
|
+
import { existsSync as existsSync9, promises as fs14, statSync as statSync6 } from "fs";
|
|
15617
|
+
import path18 from "path";
|
|
15618
|
+
|
|
15619
|
+
// src/tools/getFileStructure/formatter.ts
|
|
15620
|
+
var SECTIONS = [
|
|
15621
|
+
{ title: "IMPORTS", kind: "import", exportable: false },
|
|
15622
|
+
{ title: "EXPORTS", kind: "export", exportable: false },
|
|
15623
|
+
{ title: "FUNCTIONS", kind: "function", exportable: true },
|
|
15624
|
+
{ title: "CLASSES", kind: "class", exportable: true },
|
|
15625
|
+
{ title: "INTERFACES", kind: "interface", exportable: true },
|
|
15626
|
+
{ title: "TYPES", kind: "type", exportable: true },
|
|
15627
|
+
{ title: "ENUMS", kind: "enum", exportable: true }
|
|
15628
|
+
];
|
|
15629
|
+
function formatStructureOutput(filePath, items, fileSize, lineCount) {
|
|
15630
|
+
const sizeStr = fileSize < 1024 ? `${fileSize} B` : `${(fileSize / 1024).toFixed(1)} KB`;
|
|
15631
|
+
const lines = [`File: ${filePath} (${sizeStr}, ${lineCount} lines)`, ""];
|
|
15632
|
+
for (const section of SECTIONS) {
|
|
15633
|
+
const sectionItems = items.filter((i) => i.kind === section.kind);
|
|
15634
|
+
formatSection(lines, section.title, sectionItems, (item) => {
|
|
15635
|
+
const prefix = section.exportable && item.exported ? "export " : "";
|
|
15636
|
+
return `L${item.line}: ${prefix}${item.name}`;
|
|
15637
|
+
});
|
|
15638
|
+
}
|
|
15639
|
+
return lines.join("\n").trimEnd();
|
|
15640
|
+
}
|
|
15641
|
+
function formatSection(lines, title, items, format) {
|
|
15642
|
+
lines.push(`${title} (${items.length}):`);
|
|
15643
|
+
if (items.length === 0) {
|
|
15644
|
+
lines.push(" (none)");
|
|
15645
|
+
} else {
|
|
15646
|
+
for (const item of items) {
|
|
15647
|
+
lines.push(` ${format(item)}`);
|
|
15648
|
+
}
|
|
15649
|
+
}
|
|
15650
|
+
lines.push("");
|
|
15651
|
+
}
|
|
15652
|
+
|
|
15653
|
+
// src/tools/getFileStructure/index.ts
|
|
15654
|
+
var MAX_FILE_SIZE3 = 10 * 1024 * 1024;
|
|
15655
|
+
function createGetFileStructureTool() {
|
|
15656
|
+
return {
|
|
15657
|
+
toolFn: async (value) => {
|
|
15658
|
+
const params = value;
|
|
15659
|
+
try {
|
|
15660
|
+
const cwd = process.cwd();
|
|
15661
|
+
const resolvedPath = path18.resolve(cwd, params.path);
|
|
15662
|
+
if (!resolvedPath.startsWith(cwd)) {
|
|
15663
|
+
return "Error: Access denied - cannot read files outside of current working directory";
|
|
15664
|
+
}
|
|
15665
|
+
if (!existsSync9(resolvedPath)) {
|
|
15666
|
+
return `Error: File not found: ${params.path}`;
|
|
15667
|
+
}
|
|
15668
|
+
const stats = statSync6(resolvedPath);
|
|
15669
|
+
if (stats.isDirectory()) {
|
|
15670
|
+
return `Error: Path is a directory, not a file: ${params.path}`;
|
|
15671
|
+
}
|
|
15672
|
+
if (stats.size > MAX_FILE_SIZE3) {
|
|
15673
|
+
return `Error: File too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Max: ${MAX_FILE_SIZE3 / 1024 / 1024}MB`;
|
|
15674
|
+
}
|
|
15675
|
+
const ext = path18.extname(resolvedPath).toLowerCase();
|
|
15676
|
+
const { getLanguageForExtension, parseFileStructure, getSupportedLanguages } = await import("./treeSitterEngine-4SGFQDY3.js");
|
|
15677
|
+
const languageId = getLanguageForExtension(ext);
|
|
15678
|
+
if (!languageId) {
|
|
15679
|
+
const supported = getSupportedLanguages();
|
|
15680
|
+
return `Error: Unsupported file type "${ext}". Supported languages: ${supported.join(", ")}`;
|
|
15681
|
+
}
|
|
15682
|
+
const sourceCode = await fs14.readFile(resolvedPath, "utf-8");
|
|
15683
|
+
const lineCount = sourceCode.split("\n").length;
|
|
15684
|
+
const items = await parseFileStructure(sourceCode, languageId);
|
|
15685
|
+
return formatStructureOutput(params.path, items, stats.size, lineCount);
|
|
15686
|
+
} catch (error) {
|
|
15687
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
15688
|
+
return `Error analyzing file structure: ${errorMessage}`;
|
|
15689
|
+
}
|
|
15690
|
+
},
|
|
15691
|
+
toolSchema: {
|
|
15692
|
+
name: "get_file_structure",
|
|
15693
|
+
description: "Extract the high-level structure of a source file (imports, exports, functions, classes, interfaces, types) using AST parsing. Returns a concise outline with line numbers. Much more efficient than file_read when you only need to understand what a file contains or exports. Use this before file_read to decide which parts of a large file to read.",
|
|
15694
|
+
parameters: {
|
|
15695
|
+
type: "object",
|
|
15696
|
+
properties: {
|
|
15697
|
+
path: {
|
|
15698
|
+
type: "string",
|
|
15699
|
+
description: "Path to the source file (relative to cwd or absolute within cwd). Supported: .ts, .tsx, .js, .jsx, .mjs, .cjs, .py"
|
|
15700
|
+
}
|
|
15701
|
+
},
|
|
15702
|
+
required: ["path"]
|
|
15703
|
+
}
|
|
15704
|
+
}
|
|
15705
|
+
};
|
|
15706
|
+
}
|
|
15707
|
+
|
|
15612
15708
|
// src/index.tsx
|
|
15613
15709
|
process.removeAllListeners("warning");
|
|
15614
15710
|
process.on("warning", (warning) => {
|
|
@@ -15917,7 +16013,14 @@ function CliApp() {
|
|
|
15917
16013
|
sessionId: newSession.id
|
|
15918
16014
|
}) : null;
|
|
15919
16015
|
const findDefinitionTool = createFindDefinitionTool();
|
|
15920
|
-
const
|
|
16016
|
+
const getFileStructureTool = createGetFileStructureTool();
|
|
16017
|
+
const cliTools = [
|
|
16018
|
+
agentDelegateTool,
|
|
16019
|
+
...backgroundTools,
|
|
16020
|
+
writeTodosTool,
|
|
16021
|
+
findDefinitionTool,
|
|
16022
|
+
getFileStructureTool
|
|
16023
|
+
];
|
|
15921
16024
|
if (skillTool) {
|
|
15922
16025
|
cliTools.push(skillTool);
|
|
15923
16026
|
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/tools/getFileStructure/treeSitterEngine.ts
|
|
4
|
+
import { createRequire } from "module";
|
|
5
|
+
import { readFileSync } from "fs";
|
|
6
|
+
|
|
7
|
+
// src/tools/getFileStructure/types.ts
|
|
8
|
+
var EXTENSION_TO_LANGUAGE = {
|
|
9
|
+
".ts": "typescript",
|
|
10
|
+
".tsx": "tsx",
|
|
11
|
+
".js": "javascript",
|
|
12
|
+
".jsx": "javascript",
|
|
13
|
+
".mjs": "javascript",
|
|
14
|
+
".cjs": "javascript",
|
|
15
|
+
".py": "python"
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/tools/getFileStructure/queries/typescript.ts
|
|
19
|
+
var typescriptQueries = {
|
|
20
|
+
imports: `
|
|
21
|
+
(import_statement
|
|
22
|
+
source: (string) @source
|
|
23
|
+
) @import
|
|
24
|
+
`,
|
|
25
|
+
exports: `
|
|
26
|
+
(export_statement
|
|
27
|
+
declaration: (function_declaration
|
|
28
|
+
name: (identifier) @name)
|
|
29
|
+
) @export
|
|
30
|
+
|
|
31
|
+
(export_statement
|
|
32
|
+
declaration: (class_declaration
|
|
33
|
+
name: (type_identifier) @name)
|
|
34
|
+
) @export
|
|
35
|
+
|
|
36
|
+
(export_statement
|
|
37
|
+
declaration: (interface_declaration
|
|
38
|
+
name: (type_identifier) @name)
|
|
39
|
+
) @export
|
|
40
|
+
|
|
41
|
+
(export_statement
|
|
42
|
+
declaration: (type_alias_declaration
|
|
43
|
+
name: (type_identifier) @name)
|
|
44
|
+
) @export
|
|
45
|
+
|
|
46
|
+
(export_statement
|
|
47
|
+
declaration: (enum_declaration
|
|
48
|
+
name: (identifier) @name)
|
|
49
|
+
) @export
|
|
50
|
+
|
|
51
|
+
(export_statement
|
|
52
|
+
declaration: (lexical_declaration
|
|
53
|
+
(variable_declarator
|
|
54
|
+
name: (identifier) @name))
|
|
55
|
+
) @export
|
|
56
|
+
|
|
57
|
+
(export_statement
|
|
58
|
+
(export_clause
|
|
59
|
+
(export_specifier
|
|
60
|
+
name: (identifier) @name))
|
|
61
|
+
) @export
|
|
62
|
+
`,
|
|
63
|
+
functions: `
|
|
64
|
+
(function_declaration
|
|
65
|
+
name: (identifier) @name
|
|
66
|
+
) @function
|
|
67
|
+
|
|
68
|
+
(lexical_declaration
|
|
69
|
+
(variable_declarator
|
|
70
|
+
name: (identifier) @name
|
|
71
|
+
value: (arrow_function)
|
|
72
|
+
)
|
|
73
|
+
) @function
|
|
74
|
+
`,
|
|
75
|
+
classes: `
|
|
76
|
+
(class_declaration
|
|
77
|
+
name: (type_identifier) @name
|
|
78
|
+
) @class
|
|
79
|
+
`,
|
|
80
|
+
interfaces: `
|
|
81
|
+
(interface_declaration
|
|
82
|
+
name: (type_identifier) @name
|
|
83
|
+
) @interface
|
|
84
|
+
`,
|
|
85
|
+
types: `
|
|
86
|
+
(type_alias_declaration
|
|
87
|
+
name: (type_identifier) @name
|
|
88
|
+
) @type
|
|
89
|
+
|
|
90
|
+
(enum_declaration
|
|
91
|
+
name: (identifier) @name
|
|
92
|
+
) @enum
|
|
93
|
+
`
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// src/tools/getFileStructure/queries/javascript.ts
|
|
97
|
+
var javascriptQueries = {
|
|
98
|
+
imports: `
|
|
99
|
+
(import_statement
|
|
100
|
+
source: (string) @source
|
|
101
|
+
) @import
|
|
102
|
+
`,
|
|
103
|
+
exports: `
|
|
104
|
+
(export_statement
|
|
105
|
+
declaration: (function_declaration
|
|
106
|
+
name: (identifier) @name)
|
|
107
|
+
) @export
|
|
108
|
+
|
|
109
|
+
(export_statement
|
|
110
|
+
declaration: (class_declaration
|
|
111
|
+
name: (identifier) @name)
|
|
112
|
+
) @export
|
|
113
|
+
|
|
114
|
+
(export_statement
|
|
115
|
+
declaration: (lexical_declaration
|
|
116
|
+
(variable_declarator
|
|
117
|
+
name: (identifier) @name))
|
|
118
|
+
) @export
|
|
119
|
+
|
|
120
|
+
(export_statement
|
|
121
|
+
(export_clause
|
|
122
|
+
(export_specifier
|
|
123
|
+
name: (identifier) @name))
|
|
124
|
+
) @export
|
|
125
|
+
`,
|
|
126
|
+
functions: `
|
|
127
|
+
(function_declaration
|
|
128
|
+
name: (identifier) @name
|
|
129
|
+
) @function
|
|
130
|
+
|
|
131
|
+
(lexical_declaration
|
|
132
|
+
(variable_declarator
|
|
133
|
+
name: (identifier) @name
|
|
134
|
+
value: (arrow_function)
|
|
135
|
+
)
|
|
136
|
+
) @function
|
|
137
|
+
`,
|
|
138
|
+
classes: `
|
|
139
|
+
(class_declaration
|
|
140
|
+
name: (identifier) @name
|
|
141
|
+
) @class
|
|
142
|
+
`,
|
|
143
|
+
// JavaScript has no interface keyword
|
|
144
|
+
interfaces: "",
|
|
145
|
+
// JavaScript has no type aliases or enums
|
|
146
|
+
types: ""
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// src/tools/getFileStructure/queries/python.ts
|
|
150
|
+
var pythonQueries = {
|
|
151
|
+
imports: `
|
|
152
|
+
(import_statement
|
|
153
|
+
name: (dotted_name) @source
|
|
154
|
+
) @import
|
|
155
|
+
|
|
156
|
+
(import_from_statement
|
|
157
|
+
module_name: (dotted_name) @source
|
|
158
|
+
) @import_from
|
|
159
|
+
`,
|
|
160
|
+
// Python uses __all__ convention, not language-level exports
|
|
161
|
+
exports: "",
|
|
162
|
+
functions: `
|
|
163
|
+
(function_definition
|
|
164
|
+
name: (identifier) @name
|
|
165
|
+
) @function
|
|
166
|
+
`,
|
|
167
|
+
classes: `
|
|
168
|
+
(class_definition
|
|
169
|
+
name: (identifier) @name
|
|
170
|
+
) @class
|
|
171
|
+
`,
|
|
172
|
+
// Python has no interface keyword (Protocol is a runtime construct)
|
|
173
|
+
interfaces: "",
|
|
174
|
+
// Python has no type alias syntax at the grammar level
|
|
175
|
+
types: ""
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// src/tools/getFileStructure/queries/index.ts
|
|
179
|
+
var LANGUAGE_QUERIES = {
|
|
180
|
+
typescript: typescriptQueries,
|
|
181
|
+
tsx: typescriptQueries,
|
|
182
|
+
javascript: javascriptQueries,
|
|
183
|
+
python: pythonQueries
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// src/tools/getFileStructure/treeSitterEngine.ts
|
|
187
|
+
var require2 = createRequire(import.meta.url);
|
|
188
|
+
var TreeSitter;
|
|
189
|
+
var parserInitialized = false;
|
|
190
|
+
var languageCache = /* @__PURE__ */ new Map();
|
|
191
|
+
function locateTreeSitterWasm() {
|
|
192
|
+
return require2.resolve("web-tree-sitter/tree-sitter.wasm");
|
|
193
|
+
}
|
|
194
|
+
function locateLanguageWasm(language) {
|
|
195
|
+
return require2.resolve(`tree-sitter-wasms/out/tree-sitter-${language}.wasm`);
|
|
196
|
+
}
|
|
197
|
+
async function ensureInitialized() {
|
|
198
|
+
if (parserInitialized) return;
|
|
199
|
+
try {
|
|
200
|
+
const moduleName = "web-tree-sitter";
|
|
201
|
+
TreeSitter = await import(
|
|
202
|
+
/* webpackIgnore: true */
|
|
203
|
+
moduleName
|
|
204
|
+
);
|
|
205
|
+
} catch {
|
|
206
|
+
throw new Error(
|
|
207
|
+
"web-tree-sitter is not available. Install it with: pnpm add web-tree-sitter tree-sitter-wasms --filter @bike4mind/cli"
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
const wasmPath = locateTreeSitterWasm();
|
|
211
|
+
const wasmBinary = readFileSync(wasmPath);
|
|
212
|
+
await TreeSitter.Parser.init({
|
|
213
|
+
locateFile: (scriptName) => {
|
|
214
|
+
if (scriptName === "tree-sitter.wasm") {
|
|
215
|
+
return wasmPath;
|
|
216
|
+
}
|
|
217
|
+
return scriptName;
|
|
218
|
+
},
|
|
219
|
+
wasmBinary
|
|
220
|
+
});
|
|
221
|
+
parserInitialized = true;
|
|
222
|
+
}
|
|
223
|
+
async function loadLanguage(languageId) {
|
|
224
|
+
const cached = languageCache.get(languageId);
|
|
225
|
+
if (cached) return cached;
|
|
226
|
+
const wasmPath = locateLanguageWasm(languageId);
|
|
227
|
+
const language = await TreeSitter.Language.load(wasmPath);
|
|
228
|
+
languageCache.set(languageId, language);
|
|
229
|
+
return language;
|
|
230
|
+
}
|
|
231
|
+
function runQuery(language, rootNode, querySource, kind) {
|
|
232
|
+
if (!querySource.trim()) return [];
|
|
233
|
+
const items = [];
|
|
234
|
+
const query = new TreeSitter.Query(language, querySource);
|
|
235
|
+
try {
|
|
236
|
+
const matches = query.matches(rootNode);
|
|
237
|
+
for (const match of matches) {
|
|
238
|
+
const nameCapture = match.captures.find((c) => c.name === "name");
|
|
239
|
+
const sourceCapture = match.captures.find((c) => c.name === "source");
|
|
240
|
+
if (kind === "import") {
|
|
241
|
+
const importCapture = match.captures.find((c) => c.name === "import" || c.name === "import_from");
|
|
242
|
+
const node = importCapture?.node || sourceCapture?.node;
|
|
243
|
+
if (node) {
|
|
244
|
+
items.push({
|
|
245
|
+
kind: "import",
|
|
246
|
+
name: sourceCapture?.node.text.replace(/['"]/g, "") || "",
|
|
247
|
+
line: node.startPosition.row + 1,
|
|
248
|
+
details: node.text
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
} else if (nameCapture) {
|
|
252
|
+
items.push({
|
|
253
|
+
kind,
|
|
254
|
+
name: nameCapture.node.text,
|
|
255
|
+
line: nameCapture.node.startPosition.row + 1,
|
|
256
|
+
...kind === "export" && { exported: true }
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
} finally {
|
|
261
|
+
query.delete();
|
|
262
|
+
}
|
|
263
|
+
return items;
|
|
264
|
+
}
|
|
265
|
+
var QUERY_CATEGORIES = [
|
|
266
|
+
["imports", "import"],
|
|
267
|
+
["exports", "export"],
|
|
268
|
+
["functions", "function"],
|
|
269
|
+
["classes", "class"],
|
|
270
|
+
["interfaces", "interface"],
|
|
271
|
+
["types", "type"]
|
|
272
|
+
];
|
|
273
|
+
async function parseFileStructure(sourceCode, languageId) {
|
|
274
|
+
await ensureInitialized();
|
|
275
|
+
const queries = LANGUAGE_QUERIES[languageId];
|
|
276
|
+
if (!queries) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
`No query definitions for language: ${languageId}. Supported: ${getSupportedLanguages().join(", ")}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
const language = await loadLanguage(languageId);
|
|
282
|
+
const parser = new TreeSitter.Parser();
|
|
283
|
+
let tree = null;
|
|
284
|
+
try {
|
|
285
|
+
parser.setLanguage(language);
|
|
286
|
+
tree = parser.parse(sourceCode);
|
|
287
|
+
if (!tree) {
|
|
288
|
+
throw new Error("Failed to parse source code");
|
|
289
|
+
}
|
|
290
|
+
const allItems = [];
|
|
291
|
+
for (const [queryKey, kind] of QUERY_CATEGORIES) {
|
|
292
|
+
allItems.push(...runQuery(language, tree.rootNode, queries[queryKey], kind));
|
|
293
|
+
}
|
|
294
|
+
return deduplicateItems(allItems);
|
|
295
|
+
} finally {
|
|
296
|
+
tree?.delete();
|
|
297
|
+
parser.delete();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function deduplicateItems(items) {
|
|
301
|
+
const exportNames = /* @__PURE__ */ new Set();
|
|
302
|
+
const definitionNames = /* @__PURE__ */ new Set();
|
|
303
|
+
for (const item of items) {
|
|
304
|
+
if (item.kind === "export") {
|
|
305
|
+
exportNames.add(item.name);
|
|
306
|
+
} else if (item.kind !== "import") {
|
|
307
|
+
definitionNames.add(item.name);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const result = [];
|
|
311
|
+
for (const item of items) {
|
|
312
|
+
if (item.kind === "export" && definitionNames.has(item.name)) continue;
|
|
313
|
+
if (item.kind !== "export" && item.kind !== "import" && exportNames.has(item.name)) {
|
|
314
|
+
item.exported = true;
|
|
315
|
+
}
|
|
316
|
+
result.push(item);
|
|
317
|
+
}
|
|
318
|
+
return result;
|
|
319
|
+
}
|
|
320
|
+
function getSupportedLanguages() {
|
|
321
|
+
return Object.keys(LANGUAGE_QUERIES);
|
|
322
|
+
}
|
|
323
|
+
function getLanguageForExtension(ext) {
|
|
324
|
+
return EXTENSION_TO_LANGUAGE[ext] || null;
|
|
325
|
+
}
|
|
326
|
+
export {
|
|
327
|
+
getLanguageForExtension,
|
|
328
|
+
getSupportedLanguages,
|
|
329
|
+
parseFileStructure
|
|
330
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.28-feat-
|
|
3
|
+
"version": "0.2.28-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -95,10 +95,12 @@
|
|
|
95
95
|
"sharp": "^0.34.5",
|
|
96
96
|
"speakeasy": "^2.0.0",
|
|
97
97
|
"tiktoken": "^1.0.16",
|
|
98
|
+
"tree-sitter-wasms": "^0.1.13",
|
|
98
99
|
"turndown": "^7.2.0",
|
|
99
100
|
"unpdf": "^0.10.0",
|
|
100
101
|
"uuid": "^9.0.1",
|
|
101
102
|
"voyageai": "^0.0.4",
|
|
103
|
+
"web-tree-sitter": "0.25.10",
|
|
102
104
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
|
103
105
|
"yargs": "^17.7.2",
|
|
104
106
|
"yauzl": "^3.1.3",
|
|
@@ -108,10 +110,10 @@
|
|
|
108
110
|
},
|
|
109
111
|
"devDependencies": {
|
|
110
112
|
"@bike4mind/agents": "0.1.0",
|
|
111
|
-
"@bike4mind/common": "2.49.1-feat-
|
|
112
|
-
"@bike4mind/mcp": "1.28.3-feat-
|
|
113
|
-
"@bike4mind/services": "2.47.2-feat-
|
|
114
|
-
"@bike4mind/utils": "2.4.2-feat-
|
|
113
|
+
"@bike4mind/common": "2.49.1-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
114
|
+
"@bike4mind/mcp": "1.28.3-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
115
|
+
"@bike4mind/services": "2.47.2-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
116
|
+
"@bike4mind/utils": "2.4.2-feat-get-file-structure-tool.18750+9a81a7d11",
|
|
115
117
|
"@types/better-sqlite3": "^7.6.13",
|
|
116
118
|
"@types/diff": "^5.0.9",
|
|
117
119
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -128,5 +130,5 @@
|
|
|
128
130
|
"optionalDependencies": {
|
|
129
131
|
"@vscode/ripgrep": "^1.17.0"
|
|
130
132
|
},
|
|
131
|
-
"gitHead": "
|
|
133
|
+
"gitHead": "9a81a7d11946ea54b9a47fe35897e36fc7541c65"
|
|
132
134
|
}
|