@probelabs/probe 0.6.0-rc173 → 0.6.0-rc174
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/build/agent/index.js +124 -75
- package/build/agent/probeTool.js +4 -13
- package/build/downloader.js +6 -2
- package/build/extractor.js +6 -2
- package/build/utils/file-lister.js +9 -2
- package/build/utils/symlink-utils.js +63 -0
- package/cjs/agent/ProbeAgent.cjs +121 -71
- package/cjs/index.cjs +124 -74
- package/package.json +2 -2
- package/src/agent/probeTool.js +4 -13
- package/src/downloader.js +6 -2
- package/src/extractor.js +6 -2
- package/src/utils/file-lister.js +9 -2
- package/src/utils/symlink-utils.js +63 -0
package/cjs/index.cjs
CHANGED
|
@@ -104,7 +104,7 @@ var require_package = __commonJS({
|
|
|
104
104
|
// node_modules/dotenv/lib/main.js
|
|
105
105
|
var require_main = __commonJS({
|
|
106
106
|
"node_modules/dotenv/lib/main.js"(exports2, module2) {
|
|
107
|
-
var
|
|
107
|
+
var fs9 = require("fs");
|
|
108
108
|
var path8 = require("path");
|
|
109
109
|
var os4 = require("os");
|
|
110
110
|
var crypto2 = require("crypto");
|
|
@@ -213,7 +213,7 @@ var require_main = __commonJS({
|
|
|
213
213
|
if (options && options.path && options.path.length > 0) {
|
|
214
214
|
if (Array.isArray(options.path)) {
|
|
215
215
|
for (const filepath of options.path) {
|
|
216
|
-
if (
|
|
216
|
+
if (fs9.existsSync(filepath)) {
|
|
217
217
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
218
218
|
}
|
|
219
219
|
}
|
|
@@ -223,7 +223,7 @@ var require_main = __commonJS({
|
|
|
223
223
|
} else {
|
|
224
224
|
possibleVaultPath = path8.resolve(process.cwd(), ".env.vault");
|
|
225
225
|
}
|
|
226
|
-
if (
|
|
226
|
+
if (fs9.existsSync(possibleVaultPath)) {
|
|
227
227
|
return possibleVaultPath;
|
|
228
228
|
}
|
|
229
229
|
return null;
|
|
@@ -272,7 +272,7 @@ var require_main = __commonJS({
|
|
|
272
272
|
const parsedAll = {};
|
|
273
273
|
for (const path9 of optionPaths) {
|
|
274
274
|
try {
|
|
275
|
-
const parsed = DotenvModule.parse(
|
|
275
|
+
const parsed = DotenvModule.parse(fs9.readFileSync(path9, { encoding }));
|
|
276
276
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
277
277
|
} catch (e4) {
|
|
278
278
|
if (debug) {
|
|
@@ -563,6 +563,48 @@ var init_directory_resolver = __esm({
|
|
|
563
563
|
}
|
|
564
564
|
});
|
|
565
565
|
|
|
566
|
+
// src/utils/symlink-utils.js
|
|
567
|
+
async function getEntryType(entry, fullPath) {
|
|
568
|
+
try {
|
|
569
|
+
const stats = await import_fs2.promises.stat(fullPath);
|
|
570
|
+
return {
|
|
571
|
+
isFile: stats.isFile(),
|
|
572
|
+
isDirectory: stats.isDirectory(),
|
|
573
|
+
size: stats.size
|
|
574
|
+
};
|
|
575
|
+
} catch {
|
|
576
|
+
return {
|
|
577
|
+
isFile: entry.isFile(),
|
|
578
|
+
isDirectory: entry.isDirectory(),
|
|
579
|
+
size: 0
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
function getEntryTypeSync(entry, fullPath) {
|
|
584
|
+
try {
|
|
585
|
+
const stats = import_fs.default.statSync(fullPath);
|
|
586
|
+
return {
|
|
587
|
+
isFile: stats.isFile(),
|
|
588
|
+
isDirectory: stats.isDirectory(),
|
|
589
|
+
size: stats.size
|
|
590
|
+
};
|
|
591
|
+
} catch {
|
|
592
|
+
return {
|
|
593
|
+
isFile: entry.isFile(),
|
|
594
|
+
isDirectory: entry.isDirectory(),
|
|
595
|
+
size: 0
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
var import_fs, import_fs2;
|
|
600
|
+
var init_symlink_utils = __esm({
|
|
601
|
+
"src/utils/symlink-utils.js"() {
|
|
602
|
+
"use strict";
|
|
603
|
+
import_fs = __toESM(require("fs"), 1);
|
|
604
|
+
import_fs2 = require("fs");
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
|
|
566
608
|
// src/downloader.js
|
|
567
609
|
function sanitizeError(err) {
|
|
568
610
|
try {
|
|
@@ -1077,10 +1119,11 @@ async function extractBinary(assetPath, outputDir) {
|
|
|
1077
1119
|
const entries = await import_fs_extra2.default.readdir(dir, { withFileTypes: true });
|
|
1078
1120
|
for (const entry of entries) {
|
|
1079
1121
|
const fullPath = import_path2.default.join(dir, entry.name);
|
|
1080
|
-
|
|
1122
|
+
const entryType = await getEntryType(entry, fullPath);
|
|
1123
|
+
if (entryType.isDirectory) {
|
|
1081
1124
|
const result = await findBinary(fullPath);
|
|
1082
1125
|
if (result) return result;
|
|
1083
|
-
} else if (
|
|
1126
|
+
} else if (entryType.isFile) {
|
|
1084
1127
|
if (entry.name === binaryName || entry.name === BINARY_NAME || isWindows && entry.name.endsWith(".exe")) {
|
|
1085
1128
|
return fullPath;
|
|
1086
1129
|
}
|
|
@@ -1293,6 +1336,7 @@ var init_downloader = __esm({
|
|
|
1293
1336
|
import_url2 = require("url");
|
|
1294
1337
|
init_utils();
|
|
1295
1338
|
init_directory_resolver();
|
|
1339
|
+
init_symlink_utils();
|
|
1296
1340
|
exec = (0, import_util.promisify)(import_child_process.exec);
|
|
1297
1341
|
REPO_OWNER = "probelabs";
|
|
1298
1342
|
REPO_NAME = "probe";
|
|
@@ -20478,7 +20522,7 @@ var require_dist_cjs56 = __commonJS({
|
|
|
20478
20522
|
var httpAuthSchemes = (init_httpAuthSchemes2(), __toCommonJS(httpAuthSchemes_exports));
|
|
20479
20523
|
var propertyProvider = require_dist_cjs24();
|
|
20480
20524
|
var sharedIniFileLoader = require_dist_cjs42();
|
|
20481
|
-
var
|
|
20525
|
+
var fs9 = require("fs");
|
|
20482
20526
|
var fromEnvSigningName = ({ logger: logger2, signingName } = {}) => async () => {
|
|
20483
20527
|
logger2?.debug?.("@aws-sdk/token-providers - fromEnvSigningName");
|
|
20484
20528
|
if (!signingName) {
|
|
@@ -20524,7 +20568,7 @@ var require_dist_cjs56 = __commonJS({
|
|
|
20524
20568
|
throw new propertyProvider.TokenProviderError(`Value not present for '${key}' in SSO Token${forRefresh ? ". Cannot refresh" : ""}. ${REFRESH_MESSAGE}`, false);
|
|
20525
20569
|
}
|
|
20526
20570
|
};
|
|
20527
|
-
var { writeFile } =
|
|
20571
|
+
var { writeFile } = fs9.promises;
|
|
20528
20572
|
var writeSSOTokenToFile = (id, ssoToken) => {
|
|
20529
20573
|
const tokenFilepath = sharedIniFileLoader.getSSOTokenFilepath(id);
|
|
20530
20574
|
const tokenString = JSON.stringify(ssoToken, null, 2);
|
|
@@ -38202,22 +38246,22 @@ var init_esm3 = __esm({
|
|
|
38202
38246
|
});
|
|
38203
38247
|
|
|
38204
38248
|
// node_modules/path-scurry/dist/esm/index.js
|
|
38205
|
-
var import_node_path, import_node_url,
|
|
38249
|
+
var import_node_path, import_node_url, import_fs3, actualFS, import_promises, realpathSync, defaultFS, fsFromOption, uncDriveRegexp, uncToDrive, eitherSep, UNKNOWN, IFIFO, IFCHR, IFDIR, IFBLK, IFREG, IFLNK, IFSOCK, IFMT, IFMT_UNKNOWN, READDIR_CALLED, LSTAT_CALLED, ENOTDIR, ENOENT, ENOREADLINK, ENOREALPATH, ENOCHILD, TYPEMASK, entToType, normalizeCache, normalize, normalizeNocaseCache, normalizeNocase, ResolveCache, ChildrenCache, setAsCwd, PathBase, PathWin32, PathPosix, PathScurryBase, PathScurryWin32, PathScurryPosix, PathScurryDarwin, Path, PathScurry;
|
|
38206
38250
|
var init_esm4 = __esm({
|
|
38207
38251
|
"node_modules/path-scurry/dist/esm/index.js"() {
|
|
38208
38252
|
init_esm2();
|
|
38209
38253
|
import_node_path = require("node:path");
|
|
38210
38254
|
import_node_url = require("node:url");
|
|
38211
|
-
|
|
38255
|
+
import_fs3 = require("fs");
|
|
38212
38256
|
actualFS = __toESM(require("node:fs"), 1);
|
|
38213
38257
|
import_promises = require("node:fs/promises");
|
|
38214
38258
|
init_esm3();
|
|
38215
|
-
realpathSync =
|
|
38259
|
+
realpathSync = import_fs3.realpathSync.native;
|
|
38216
38260
|
defaultFS = {
|
|
38217
|
-
lstatSync:
|
|
38218
|
-
readdir:
|
|
38219
|
-
readdirSync:
|
|
38220
|
-
readlinkSync:
|
|
38261
|
+
lstatSync: import_fs3.lstatSync,
|
|
38262
|
+
readdir: import_fs3.readdir,
|
|
38263
|
+
readdirSync: import_fs3.readdirSync,
|
|
38264
|
+
readlinkSync: import_fs3.readlinkSync,
|
|
38221
38265
|
realpathSync,
|
|
38222
38266
|
promises: {
|
|
38223
38267
|
lstat: import_promises.lstat,
|
|
@@ -39328,8 +39372,8 @@ var init_esm4 = __esm({
|
|
|
39328
39372
|
*
|
|
39329
39373
|
* @internal
|
|
39330
39374
|
*/
|
|
39331
|
-
constructor(cwd = process.cwd(), pathImpl, sep4, { nocase, childrenCacheSize = 16 * 1024, fs:
|
|
39332
|
-
this.#fs = fsFromOption(
|
|
39375
|
+
constructor(cwd = process.cwd(), pathImpl, sep4, { nocase, childrenCacheSize = 16 * 1024, fs: fs9 = defaultFS } = {}) {
|
|
39376
|
+
this.#fs = fsFromOption(fs9);
|
|
39333
39377
|
if (cwd instanceof URL || cwd.startsWith("file://")) {
|
|
39334
39378
|
cwd = (0, import_node_url.fileURLToPath)(cwd);
|
|
39335
39379
|
}
|
|
@@ -39887,8 +39931,8 @@ var init_esm4 = __esm({
|
|
|
39887
39931
|
/**
|
|
39888
39932
|
* @internal
|
|
39889
39933
|
*/
|
|
39890
|
-
newRoot(
|
|
39891
|
-
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
39934
|
+
newRoot(fs9) {
|
|
39935
|
+
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs9 });
|
|
39892
39936
|
}
|
|
39893
39937
|
/**
|
|
39894
39938
|
* Return true if the provided path string is an absolute path
|
|
@@ -39916,8 +39960,8 @@ var init_esm4 = __esm({
|
|
|
39916
39960
|
/**
|
|
39917
39961
|
* @internal
|
|
39918
39962
|
*/
|
|
39919
|
-
newRoot(
|
|
39920
|
-
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
39963
|
+
newRoot(fs9) {
|
|
39964
|
+
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs9 });
|
|
39921
39965
|
}
|
|
39922
39966
|
/**
|
|
39923
39967
|
* Return true if the provided path string is an absolute path
|
|
@@ -41126,7 +41170,7 @@ function createWrappedTools(baseTools) {
|
|
|
41126
41170
|
}
|
|
41127
41171
|
return wrappedTools;
|
|
41128
41172
|
}
|
|
41129
|
-
var import_child_process6, import_util11, import_crypto3, import_events,
|
|
41173
|
+
var import_child_process6, import_util11, import_crypto3, import_events, import_fs4, import_fs5, import_path4, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
41130
41174
|
var init_probeTool = __esm({
|
|
41131
41175
|
"src/agent/probeTool.js"() {
|
|
41132
41176
|
"use strict";
|
|
@@ -41135,10 +41179,11 @@ var init_probeTool = __esm({
|
|
|
41135
41179
|
import_util11 = require("util");
|
|
41136
41180
|
import_crypto3 = require("crypto");
|
|
41137
41181
|
import_events = require("events");
|
|
41138
|
-
|
|
41139
|
-
|
|
41182
|
+
import_fs4 = __toESM(require("fs"), 1);
|
|
41183
|
+
import_fs5 = require("fs");
|
|
41140
41184
|
import_path4 = __toESM(require("path"), 1);
|
|
41141
41185
|
init_esm5();
|
|
41186
|
+
init_symlink_utils();
|
|
41142
41187
|
toolCallEmitter = new import_events.EventEmitter();
|
|
41143
41188
|
activeToolExecutions = /* @__PURE__ */ new Map();
|
|
41144
41189
|
wrapToolWithEmitter = (tool4, toolName, baseExecute) => {
|
|
@@ -41244,7 +41289,7 @@ var init_probeTool = __esm({
|
|
|
41244
41289
|
console.log(`[DEBUG] Listing files in directory: ${targetDir}`);
|
|
41245
41290
|
}
|
|
41246
41291
|
try {
|
|
41247
|
-
const files = await
|
|
41292
|
+
const files = await import_fs5.promises.readdir(targetDir, { withFileTypes: true });
|
|
41248
41293
|
const formatSize = (size) => {
|
|
41249
41294
|
if (size < 1024) return `${size}B`;
|
|
41250
41295
|
if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}K`;
|
|
@@ -41252,21 +41297,12 @@ var init_probeTool = __esm({
|
|
|
41252
41297
|
return `${(size / (1024 * 1024 * 1024)).toFixed(1)}G`;
|
|
41253
41298
|
};
|
|
41254
41299
|
const entries = await Promise.all(files.map(async (file) => {
|
|
41255
|
-
const isDirectory = file.isDirectory();
|
|
41256
41300
|
const fullPath = import_path4.default.join(targetDir, file.name);
|
|
41257
|
-
|
|
41258
|
-
try {
|
|
41259
|
-
const stats = await import_fs3.promises.stat(fullPath);
|
|
41260
|
-
size = stats.size;
|
|
41261
|
-
} catch (statError) {
|
|
41262
|
-
if (debug) {
|
|
41263
|
-
console.log(`[DEBUG] Could not stat file ${file.name}:`, statError.message);
|
|
41264
|
-
}
|
|
41265
|
-
}
|
|
41301
|
+
const entryType = await getEntryType(file, fullPath);
|
|
41266
41302
|
return {
|
|
41267
41303
|
name: file.name,
|
|
41268
|
-
isDirectory,
|
|
41269
|
-
size
|
|
41304
|
+
isDirectory: entryType.isDirectory,
|
|
41305
|
+
size: entryType.size
|
|
41270
41306
|
};
|
|
41271
41307
|
}));
|
|
41272
41308
|
entries.sort((a4, b4) => {
|
|
@@ -55485,7 +55521,7 @@ function validateFlowchart(text, options = {}) {
|
|
|
55485
55521
|
const byLine = /* @__PURE__ */ new Map();
|
|
55486
55522
|
const collect = (arr) => {
|
|
55487
55523
|
for (const e4 of arr || []) {
|
|
55488
|
-
if (e4 && (e4.code === "FL-LABEL-PARENS-UNQUOTED" || e4.code === "FL-LABEL-AT-IN-UNQUOTED")) {
|
|
55524
|
+
if (e4 && (e4.code === "FL-LABEL-PARENS-UNQUOTED" || e4.code === "FL-LABEL-AT-IN-UNQUOTED" || e4.code === "FL-LABEL-QUOTE-IN-UNQUOTED")) {
|
|
55489
55525
|
const ln = e4.line ?? 0;
|
|
55490
55526
|
const col = e4.column ?? 1;
|
|
55491
55527
|
const list2 = byLine.get(ln) || [];
|
|
@@ -55566,6 +55602,8 @@ function validateFlowchart(text, options = {}) {
|
|
|
55566
55602
|
const covered = existing.some((r4) => !(endCol < r4.start || startCol > r4.end));
|
|
55567
55603
|
const hasParens = seg.includes("(") || seg.includes(")");
|
|
55568
55604
|
const hasAt = seg.includes("@");
|
|
55605
|
+
const hasQuote = seg.includes('"');
|
|
55606
|
+
const isSingleQuoted = /^'[^]*'$/.test(trimmed);
|
|
55569
55607
|
if (!covered && !isQuoted && !isParenWrapped && hasParens) {
|
|
55570
55608
|
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-PARENS-UNQUOTED", message: "Parentheses inside an unquoted label are not supported by Mermaid.", hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).' });
|
|
55571
55609
|
existing.push({ start: startCol, end: endCol });
|
|
@@ -55576,6 +55614,11 @@ function validateFlowchart(text, options = {}) {
|
|
|
55576
55614
|
existing.push({ start: startCol, end: endCol });
|
|
55577
55615
|
byLine.set(ln, existing);
|
|
55578
55616
|
}
|
|
55617
|
+
if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
|
|
55618
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use " for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility="true""]' });
|
|
55619
|
+
existing.push({ start: startCol, end: endCol });
|
|
55620
|
+
byLine.set(ln, existing);
|
|
55621
|
+
}
|
|
55579
55622
|
i4 = j4;
|
|
55580
55623
|
continue;
|
|
55581
55624
|
} else {
|
|
@@ -79637,11 +79680,11 @@ function loadMCPConfigurationFromPath(configPath) {
|
|
|
79637
79680
|
if (!configPath) {
|
|
79638
79681
|
throw new Error("Config path is required");
|
|
79639
79682
|
}
|
|
79640
|
-
if (!(0,
|
|
79683
|
+
if (!(0, import_fs6.existsSync)(configPath)) {
|
|
79641
79684
|
throw new Error(`MCP configuration file not found: ${configPath}`);
|
|
79642
79685
|
}
|
|
79643
79686
|
try {
|
|
79644
|
-
const content = (0,
|
|
79687
|
+
const content = (0, import_fs6.readFileSync)(configPath, "utf8");
|
|
79645
79688
|
const config = JSON.parse(content);
|
|
79646
79689
|
if (process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1") {
|
|
79647
79690
|
console.error(`[MCP DEBUG] Loaded configuration from: ${configPath}`);
|
|
@@ -79666,9 +79709,9 @@ function loadMCPConfiguration() {
|
|
|
79666
79709
|
].filter(Boolean);
|
|
79667
79710
|
let config = null;
|
|
79668
79711
|
for (const configPath of configPaths) {
|
|
79669
|
-
if ((0,
|
|
79712
|
+
if ((0, import_fs6.existsSync)(configPath)) {
|
|
79670
79713
|
try {
|
|
79671
|
-
const content = (0,
|
|
79714
|
+
const content = (0, import_fs6.readFileSync)(configPath, "utf8");
|
|
79672
79715
|
config = JSON.parse(content);
|
|
79673
79716
|
if (process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1") {
|
|
79674
79717
|
console.error(`[MCP DEBUG] Loaded configuration from: ${configPath}`);
|
|
@@ -79764,11 +79807,11 @@ function parseEnabledServers(config) {
|
|
|
79764
79807
|
}
|
|
79765
79808
|
return servers;
|
|
79766
79809
|
}
|
|
79767
|
-
var
|
|
79810
|
+
var import_fs6, import_path5, import_os3, import_url4, __filename4, __dirname4, DEFAULT_CONFIG;
|
|
79768
79811
|
var init_config = __esm({
|
|
79769
79812
|
"src/agent/mcp/config.js"() {
|
|
79770
79813
|
"use strict";
|
|
79771
|
-
|
|
79814
|
+
import_fs6 = require("fs");
|
|
79772
79815
|
import_path5 = require("path");
|
|
79773
79816
|
import_os3 = require("os");
|
|
79774
79817
|
import_url4 = require("url");
|
|
@@ -82637,7 +82680,7 @@ var ProbeAgent_exports = {};
|
|
|
82637
82680
|
__export(ProbeAgent_exports, {
|
|
82638
82681
|
ProbeAgent: () => ProbeAgent
|
|
82639
82682
|
});
|
|
82640
|
-
var import_dotenv, import_anthropic2, import_openai2, import_google2, import_ai2, import_crypto7, import_events4,
|
|
82683
|
+
var import_dotenv, import_anthropic2, import_openai2, import_google2, import_ai2, import_crypto7, import_events4, import_fs7, import_promises3, import_path7, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
82641
82684
|
var init_ProbeAgent = __esm({
|
|
82642
82685
|
"src/agent/ProbeAgent.js"() {
|
|
82643
82686
|
"use strict";
|
|
@@ -82649,7 +82692,7 @@ var init_ProbeAgent = __esm({
|
|
|
82649
82692
|
import_ai2 = require("ai");
|
|
82650
82693
|
import_crypto7 = require("crypto");
|
|
82651
82694
|
import_events4 = require("events");
|
|
82652
|
-
|
|
82695
|
+
import_fs7 = require("fs");
|
|
82653
82696
|
import_promises3 = require("fs/promises");
|
|
82654
82697
|
import_path7 = require("path");
|
|
82655
82698
|
init_tokenCounter();
|
|
@@ -86743,7 +86786,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
86743
86786
|
let cwd = workingDirectory;
|
|
86744
86787
|
try {
|
|
86745
86788
|
cwd = (0, import_path8.resolve)(cwd);
|
|
86746
|
-
if (!(0,
|
|
86789
|
+
if (!(0, import_fs8.existsSync)(cwd)) {
|
|
86747
86790
|
throw new Error(`Working directory does not exist: ${cwd}`);
|
|
86748
86791
|
}
|
|
86749
86792
|
} catch (error2) {
|
|
@@ -86955,7 +86998,7 @@ function validateExecutionOptions(options = {}) {
|
|
|
86955
86998
|
if (options.workingDirectory) {
|
|
86956
86999
|
if (typeof options.workingDirectory !== "string") {
|
|
86957
87000
|
errors.push("workingDirectory must be a string");
|
|
86958
|
-
} else if (!(0,
|
|
87001
|
+
} else if (!(0, import_fs8.existsSync)(options.workingDirectory)) {
|
|
86959
87002
|
errors.push(`workingDirectory does not exist: ${options.workingDirectory}`);
|
|
86960
87003
|
}
|
|
86961
87004
|
}
|
|
@@ -86968,13 +87011,13 @@ function validateExecutionOptions(options = {}) {
|
|
|
86968
87011
|
warnings
|
|
86969
87012
|
};
|
|
86970
87013
|
}
|
|
86971
|
-
var import_child_process9, import_path8,
|
|
87014
|
+
var import_child_process9, import_path8, import_fs8;
|
|
86972
87015
|
var init_bashExecutor = __esm({
|
|
86973
87016
|
"src/agent/bashExecutor.js"() {
|
|
86974
87017
|
"use strict";
|
|
86975
87018
|
import_child_process9 = require("child_process");
|
|
86976
87019
|
import_path8 = require("path");
|
|
86977
|
-
|
|
87020
|
+
import_fs8 = require("fs");
|
|
86978
87021
|
init_bashCommandUtils();
|
|
86979
87022
|
}
|
|
86980
87023
|
});
|
|
@@ -87170,14 +87213,14 @@ function parseFileToolOptions(options = {}) {
|
|
|
87170
87213
|
defaultPath: options.defaultPath
|
|
87171
87214
|
};
|
|
87172
87215
|
}
|
|
87173
|
-
var import_ai5,
|
|
87216
|
+
var import_ai5, import_fs9, import_path10, import_fs10, editTool, createTool, editSchema, createSchema, editDescription, createDescription, editToolDefinition, createToolDefinition;
|
|
87174
87217
|
var init_edit = __esm({
|
|
87175
87218
|
"src/tools/edit.js"() {
|
|
87176
87219
|
"use strict";
|
|
87177
87220
|
import_ai5 = require("ai");
|
|
87178
|
-
|
|
87221
|
+
import_fs9 = require("fs");
|
|
87179
87222
|
import_path10 = require("path");
|
|
87180
|
-
|
|
87223
|
+
import_fs10 = require("fs");
|
|
87181
87224
|
editTool = (options = {}) => {
|
|
87182
87225
|
const { debug, allowedFolders, defaultPath } = parseFileToolOptions(options);
|
|
87183
87226
|
return (0, import_ai5.tool)({
|
|
@@ -87237,10 +87280,10 @@ Important:
|
|
|
87237
87280
|
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
87238
87281
|
return `Error editing file: Permission denied - ${file_path} is outside allowed directories`;
|
|
87239
87282
|
}
|
|
87240
|
-
if (!(0,
|
|
87283
|
+
if (!(0, import_fs10.existsSync)(resolvedPath2)) {
|
|
87241
87284
|
return `Error editing file: File not found - ${file_path}`;
|
|
87242
87285
|
}
|
|
87243
|
-
const content = await
|
|
87286
|
+
const content = await import_fs9.promises.readFile(resolvedPath2, "utf-8");
|
|
87244
87287
|
if (!content.includes(old_string)) {
|
|
87245
87288
|
return `Error editing file: String not found - the specified old_string was not found in ${file_path}`;
|
|
87246
87289
|
}
|
|
@@ -87257,7 +87300,7 @@ Important:
|
|
|
87257
87300
|
if (newContent === content) {
|
|
87258
87301
|
return `Error editing file: No changes made - old_string and new_string might be the same`;
|
|
87259
87302
|
}
|
|
87260
|
-
await
|
|
87303
|
+
await import_fs9.promises.writeFile(resolvedPath2, newContent, "utf-8");
|
|
87261
87304
|
const replacedCount = replace_all ? occurrences : 1;
|
|
87262
87305
|
if (debug) {
|
|
87263
87306
|
console.error(`[Edit] Successfully edited ${resolvedPath2}, replaced ${replacedCount} occurrence(s)`);
|
|
@@ -87321,13 +87364,13 @@ Important:
|
|
|
87321
87364
|
if (!isPathAllowed(resolvedPath2, allowedFolders)) {
|
|
87322
87365
|
return `Error creating file: Permission denied - ${file_path} is outside allowed directories`;
|
|
87323
87366
|
}
|
|
87324
|
-
if ((0,
|
|
87367
|
+
if ((0, import_fs10.existsSync)(resolvedPath2) && !overwrite) {
|
|
87325
87368
|
return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
|
|
87326
87369
|
}
|
|
87327
87370
|
const dir = (0, import_path10.dirname)(resolvedPath2);
|
|
87328
|
-
await
|
|
87329
|
-
await
|
|
87330
|
-
const action = (0,
|
|
87371
|
+
await import_fs9.promises.mkdir(dir, { recursive: true });
|
|
87372
|
+
await import_fs9.promises.writeFile(resolvedPath2, content, "utf-8");
|
|
87373
|
+
const action = (0, import_fs10.existsSync)(resolvedPath2) && overwrite ? "overwrote" : "created";
|
|
87331
87374
|
const bytes = Buffer.byteLength(content, "utf-8");
|
|
87332
87375
|
if (debug) {
|
|
87333
87376
|
console.error(`[Create] Successfully ${action} ${resolvedPath2}`);
|
|
@@ -87743,10 +87786,10 @@ async function listFilesByLevel(options) {
|
|
|
87743
87786
|
maxFiles = 100,
|
|
87744
87787
|
respectGitignore = true
|
|
87745
87788
|
} = options;
|
|
87746
|
-
if (!
|
|
87789
|
+
if (!import_fs11.default.existsSync(directory)) {
|
|
87747
87790
|
throw new Error(`Directory does not exist: ${directory}`);
|
|
87748
87791
|
}
|
|
87749
|
-
const gitDirExists =
|
|
87792
|
+
const gitDirExists = import_fs11.default.existsSync(import_path11.default.join(directory, ".git"));
|
|
87750
87793
|
if (gitDirExists && respectGitignore) {
|
|
87751
87794
|
try {
|
|
87752
87795
|
return await listFilesUsingGit(directory, maxFiles);
|
|
@@ -87777,8 +87820,11 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
87777
87820
|
while (queue.length > 0 && result.length < maxFiles) {
|
|
87778
87821
|
const { dir, level } = queue.shift();
|
|
87779
87822
|
try {
|
|
87780
|
-
const entries =
|
|
87781
|
-
const files = entries.filter((entry) =>
|
|
87823
|
+
const entries = import_fs11.default.readdirSync(dir, { withFileTypes: true });
|
|
87824
|
+
const files = entries.filter((entry) => {
|
|
87825
|
+
const fullPath = import_path11.default.join(dir, entry.name);
|
|
87826
|
+
return getEntryTypeSync(entry, fullPath).isFile;
|
|
87827
|
+
});
|
|
87782
87828
|
for (const file of files) {
|
|
87783
87829
|
if (result.length >= maxFiles) break;
|
|
87784
87830
|
const filePath = import_path11.default.join(dir, file.name);
|
|
@@ -87786,7 +87832,10 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
87786
87832
|
if (shouldIgnore(relativePath, ignorePatterns)) continue;
|
|
87787
87833
|
result.push(relativePath);
|
|
87788
87834
|
}
|
|
87789
|
-
const dirs = entries.filter((entry) =>
|
|
87835
|
+
const dirs = entries.filter((entry) => {
|
|
87836
|
+
const fullPath = import_path11.default.join(dir, entry.name);
|
|
87837
|
+
return getEntryTypeSync(entry, fullPath).isDirectory;
|
|
87838
|
+
});
|
|
87790
87839
|
for (const subdir of dirs) {
|
|
87791
87840
|
const subdirPath = import_path11.default.join(dir, subdir.name);
|
|
87792
87841
|
const relativeSubdirPath = import_path11.default.relative(directory, subdirPath);
|
|
@@ -87802,11 +87851,11 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
87802
87851
|
}
|
|
87803
87852
|
function loadGitignorePatterns(directory) {
|
|
87804
87853
|
const gitignorePath = import_path11.default.join(directory, ".gitignore");
|
|
87805
|
-
if (!
|
|
87854
|
+
if (!import_fs11.default.existsSync(gitignorePath)) {
|
|
87806
87855
|
return [];
|
|
87807
87856
|
}
|
|
87808
87857
|
try {
|
|
87809
|
-
const content =
|
|
87858
|
+
const content = import_fs11.default.readFileSync(gitignorePath, "utf8");
|
|
87810
87859
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
87811
87860
|
} catch (error2) {
|
|
87812
87861
|
console.error(`Warning: Could not read .gitignore: ${error2.message}`);
|
|
@@ -87824,14 +87873,15 @@ function shouldIgnore(filePath, ignorePatterns) {
|
|
|
87824
87873
|
}
|
|
87825
87874
|
return false;
|
|
87826
87875
|
}
|
|
87827
|
-
var
|
|
87876
|
+
var import_fs11, import_path11, import_util12, import_child_process10, execAsync3;
|
|
87828
87877
|
var init_file_lister = __esm({
|
|
87829
87878
|
"src/utils/file-lister.js"() {
|
|
87830
87879
|
"use strict";
|
|
87831
|
-
|
|
87880
|
+
import_fs11 = __toESM(require("fs"), 1);
|
|
87832
87881
|
import_path11 = __toESM(require("path"), 1);
|
|
87833
87882
|
import_util12 = require("util");
|
|
87834
87883
|
import_child_process10 = require("child_process");
|
|
87884
|
+
init_symlink_utils();
|
|
87835
87885
|
execAsync3 = (0, import_util12.promisify)(import_child_process10.exec);
|
|
87836
87886
|
}
|
|
87837
87887
|
});
|
|
@@ -87846,11 +87896,11 @@ function initializeSimpleTelemetryFromOptions(options) {
|
|
|
87846
87896
|
});
|
|
87847
87897
|
return telemetry;
|
|
87848
87898
|
}
|
|
87849
|
-
var
|
|
87899
|
+
var import_fs12, import_path12, SimpleTelemetry, SimpleAppTracer;
|
|
87850
87900
|
var init_simpleTelemetry = __esm({
|
|
87851
87901
|
"src/agent/simpleTelemetry.js"() {
|
|
87852
87902
|
"use strict";
|
|
87853
|
-
|
|
87903
|
+
import_fs12 = require("fs");
|
|
87854
87904
|
import_path12 = require("path");
|
|
87855
87905
|
SimpleTelemetry = class {
|
|
87856
87906
|
constructor(options = {}) {
|
|
@@ -87866,10 +87916,10 @@ var init_simpleTelemetry = __esm({
|
|
|
87866
87916
|
initializeFileExporter() {
|
|
87867
87917
|
try {
|
|
87868
87918
|
const dir = (0, import_path12.dirname)(this.filePath);
|
|
87869
|
-
if (!(0,
|
|
87870
|
-
(0,
|
|
87919
|
+
if (!(0, import_fs12.existsSync)(dir)) {
|
|
87920
|
+
(0, import_fs12.mkdirSync)(dir, { recursive: true });
|
|
87871
87921
|
}
|
|
87872
|
-
this.stream = (0,
|
|
87922
|
+
this.stream = (0, import_fs12.createWriteStream)(this.filePath, { flags: "a" });
|
|
87873
87923
|
this.stream.on("error", (error2) => {
|
|
87874
87924
|
console.error(`[SimpleTelemetry] Stream error: ${error2.message}`);
|
|
87875
87925
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@probelabs/probe",
|
|
3
|
-
"version": "0.6.0-
|
|
3
|
+
"version": "0.6.0-rc174",
|
|
4
4
|
"description": "Node.js wrapper for the probe code search tool",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"@ai-sdk/openai": "^2.0.10",
|
|
80
80
|
"@anthropic-ai/claude-agent-sdk": "^0.1.46",
|
|
81
81
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
82
|
-
"@probelabs/maid": "^0.0.
|
|
82
|
+
"@probelabs/maid": "^0.0.22",
|
|
83
83
|
"adm-zip": "^0.5.16",
|
|
84
84
|
"ai": "^5.0.0",
|
|
85
85
|
"ajv": "^8.17.1",
|
package/src/agent/probeTool.js
CHANGED
|
@@ -8,6 +8,7 @@ import fs from 'fs';
|
|
|
8
8
|
import { promises as fsPromises } from 'fs';
|
|
9
9
|
import path from 'path';
|
|
10
10
|
import { glob } from 'glob';
|
|
11
|
+
import { getEntryType } from '../utils/symlink-utils.js';
|
|
11
12
|
|
|
12
13
|
// Create an event emitter for tool calls (simplified for single-shot operations)
|
|
13
14
|
export const toolCallEmitter = new EventEmitter();
|
|
@@ -287,23 +288,13 @@ export const listFilesTool = {
|
|
|
287
288
|
|
|
288
289
|
// Format the results as ls-style output
|
|
289
290
|
const entries = await Promise.all(files.map(async (file) => {
|
|
290
|
-
const isDirectory = file.isDirectory();
|
|
291
291
|
const fullPath = path.join(targetDir, file.name);
|
|
292
|
-
|
|
293
|
-
let size = 0;
|
|
294
|
-
try {
|
|
295
|
-
const stats = await fsPromises.stat(fullPath);
|
|
296
|
-
size = stats.size;
|
|
297
|
-
} catch (statError) {
|
|
298
|
-
if (debug) {
|
|
299
|
-
console.log(`[DEBUG] Could not stat file ${file.name}:`, statError.message);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
292
|
+
const entryType = await getEntryType(file, fullPath);
|
|
302
293
|
|
|
303
294
|
return {
|
|
304
295
|
name: file.name,
|
|
305
|
-
isDirectory,
|
|
306
|
-
size
|
|
296
|
+
isDirectory: entryType.isDirectory,
|
|
297
|
+
size: entryType.size
|
|
307
298
|
};
|
|
308
299
|
}));
|
|
309
300
|
|
package/src/downloader.js
CHANGED
|
@@ -14,6 +14,7 @@ import os from 'os';
|
|
|
14
14
|
import { fileURLToPath } from 'url';
|
|
15
15
|
import { ensureBinDirectory } from './utils.js';
|
|
16
16
|
import { getPackageBinDir } from './directory-resolver.js';
|
|
17
|
+
import { getEntryType } from './utils/symlink-utils.js';
|
|
17
18
|
|
|
18
19
|
const exec = promisify(execCallback);
|
|
19
20
|
|
|
@@ -770,10 +771,13 @@ async function extractBinary(assetPath, outputDir) {
|
|
|
770
771
|
for (const entry of entries) {
|
|
771
772
|
const fullPath = path.join(dir, entry.name);
|
|
772
773
|
|
|
773
|
-
|
|
774
|
+
// Use shared utility to follow symlinks and get actual target type
|
|
775
|
+
const entryType = await getEntryType(entry, fullPath);
|
|
776
|
+
|
|
777
|
+
if (entryType.isDirectory) {
|
|
774
778
|
const result = await findBinary(fullPath);
|
|
775
779
|
if (result) return result;
|
|
776
|
-
} else if (
|
|
780
|
+
} else if (entryType.isFile) {
|
|
777
781
|
// Check if this is the binary we're looking for
|
|
778
782
|
if (entry.name === binaryName ||
|
|
779
783
|
entry.name === BINARY_NAME ||
|
package/src/extractor.js
CHANGED
|
@@ -9,6 +9,7 @@ import tar from 'tar';
|
|
|
9
9
|
import AdmZip from 'adm-zip';
|
|
10
10
|
import os from 'os';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
|
+
import { getEntryType } from './utils/symlink-utils.js';
|
|
12
13
|
|
|
13
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
15
|
const __dirname = path.dirname(__filename);
|
|
@@ -148,10 +149,13 @@ async function findBinary(dir, baseDir, binaryName, isWindows) {
|
|
|
148
149
|
continue;
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
+
// Use shared utility to follow symlinks and get actual target type
|
|
153
|
+
const entryType = await getEntryType(entry, fullPath);
|
|
154
|
+
|
|
155
|
+
if (entryType.isDirectory) {
|
|
152
156
|
const result = await findBinary(fullPath, baseDir, binaryName, isWindows);
|
|
153
157
|
if (result) return result;
|
|
154
|
-
} else if (
|
|
158
|
+
} else if (entryType.isFile) {
|
|
155
159
|
// Check if this is the binary we're looking for
|
|
156
160
|
if (entry.name === binaryName ||
|
|
157
161
|
entry.name === BINARY_NAME ||
|
package/src/utils/file-lister.js
CHANGED
|
@@ -7,6 +7,7 @@ import fs from 'fs';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { promisify } from 'util';
|
|
9
9
|
import { exec } from 'child_process';
|
|
10
|
+
import { getEntryTypeSync } from './symlink-utils.js';
|
|
10
11
|
|
|
11
12
|
const execAsync = promisify(exec);
|
|
12
13
|
|
|
@@ -101,7 +102,10 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
101
102
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
102
103
|
|
|
103
104
|
// Process files first (at current level)
|
|
104
|
-
const files = entries.filter(entry =>
|
|
105
|
+
const files = entries.filter(entry => {
|
|
106
|
+
const fullPath = path.join(dir, entry.name);
|
|
107
|
+
return getEntryTypeSync(entry, fullPath).isFile;
|
|
108
|
+
});
|
|
105
109
|
for (const file of files) {
|
|
106
110
|
if (result.length >= maxFiles) break;
|
|
107
111
|
|
|
@@ -115,7 +119,10 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
|
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
// Then add directories to queue for next level
|
|
118
|
-
const dirs = entries.filter(entry =>
|
|
122
|
+
const dirs = entries.filter(entry => {
|
|
123
|
+
const fullPath = path.join(dir, entry.name);
|
|
124
|
+
return getEntryTypeSync(entry, fullPath).isDirectory;
|
|
125
|
+
});
|
|
119
126
|
for (const subdir of dirs) {
|
|
120
127
|
const subdirPath = path.join(dir, subdir.name);
|
|
121
128
|
const relativeSubdirPath = path.relative(directory, subdirPath);
|