jinzd-ai-cli 0.4.233 → 0.4.235
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/{auth-FSTAKSYF.js → auth-PE3Z5OHS.js} +1 -1
- package/dist/{batch-WWNPYQ6G.js → batch-Y7MHXVR7.js} +2 -2
- package/dist/{chat-index-O56HDGFI.js → chat-index-7HXBWQFH.js} +2 -2
- package/dist/{chat-index-WSI7ULRQ.js → chat-index-WYXYD7YP.js} +1 -1
- package/dist/{chunk-4KM53GLG.js → chunk-2QQKS56X.js} +1 -1
- package/dist/{chunk-NVUCDUXE.js → chunk-5MYPIQ3Y.js} +11 -5
- package/dist/{chunk-NXYXFRPA.js → chunk-7D5EJBHO.js} +3 -3
- package/dist/{chunk-5PKNKJYP.js → chunk-BFTTW5LS.js} +1 -1
- package/dist/{chunk-FQSAK75P.js → chunk-CDOQNIVV.js} +3 -3
- package/dist/{chunk-7KS3RGZ7.js → chunk-DHNYGJYB.js} +2 -2
- package/dist/{chunk-HX67JAK6.js → chunk-FYJGVFXL.js} +87 -54
- package/dist/{chunk-ACTO5C6K.js → chunk-GDXKFWFL.js} +1 -1
- package/dist/{chunk-EZGZOK6E.js → chunk-GFDRC2JZ.js} +1 -1
- package/dist/{chunk-4OAV7QMB.js → chunk-HHYMSEWS.js} +1 -1
- package/dist/{chunk-ZWU7FWHO.js → chunk-JMP3LJC2.js} +38 -91
- package/dist/chunk-KCEO2XJ4.js +420 -0
- package/dist/{chunk-M4FW2NPU.js → chunk-Q5GVANMH.js} +1 -1
- package/dist/{chunk-JVKAL5Q3.js → chunk-RYQBBEMM.js} +33 -3
- package/dist/{chunk-LF3OUJHK.js → chunk-UO3XWZFE.js} +302 -4
- package/dist/{chunk-TJK7AU65.js → chunk-WXFQ6LYN.js} +1 -1
- package/dist/{ci-V5V3JSJC.js → ci-OAFNH3MA.js} +4 -4
- package/dist/{ci-format-XS7LKBO5.js → ci-format-4LSXJNND.js} +2 -2
- package/dist/{constants-UROQJXLY.js → constants-ERIAS7GV.js} +1 -1
- package/dist/{doctor-cli-BY3FIV2B.js → doctor-cli-VFSVWZU6.js} +4 -4
- package/dist/electron-server.js +235 -224
- package/dist/{hub-L2QCRI5M.js → hub-X4EUYRIN.js} +2 -2
- package/dist/index.js +23 -23
- package/dist/{persist-I3JI27OK.js → persist-AMH5SQ4W.js} +3 -3
- package/dist/{pr-IJRUPR5C.js → pr-2CZN5JLE.js} +4 -4
- package/dist/{run-tests-FLCVJ6TK.js → run-tests-DXRJDPFF.js} +2 -2
- package/dist/{run-tests-NNXBS4EL.js → run-tests-YSRET52H.js} +1 -1
- package/dist/{server-W2X3C6GJ.js → server-5ZAXMKRI.js} +21 -20
- package/dist/{server-E6LZB72O.js → server-FGJGXHZD.js} +6 -6
- package/dist/{task-orchestrator-W55VKYTC.js → task-orchestrator-QMERCD77.js} +6 -6
- package/dist/{usage-MZCDTJWB.js → usage-633DUDNT.js} +2 -2
- package/package.json +2 -4
- package/dist/chunk-B5TYJO7V.js +0 -123
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BFTTW5LS.js";
|
|
5
5
|
import "./chunk-5ULLIOVC.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-GDXKFWFL.js";
|
|
7
7
|
import {
|
|
8
8
|
atomicWriteFileSync
|
|
9
9
|
} from "./chunk-IW3Q7AE5.js";
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
getChatIndexStatus,
|
|
7
7
|
loadChatIndex,
|
|
8
8
|
searchChatMemory
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5MYPIQ3Y.js";
|
|
10
10
|
import "./chunk-KHYD3WXE.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-KCEO2XJ4.js";
|
|
12
12
|
import "./chunk-IW3Q7AE5.js";
|
|
13
13
|
export {
|
|
14
14
|
buildChatIndex,
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
embedOne
|
|
6
6
|
} from "./chunk-KHYD3WXE.js";
|
|
7
7
|
import {
|
|
8
|
+
getIndexMtimeMap,
|
|
8
9
|
redactString
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-KCEO2XJ4.js";
|
|
10
11
|
import {
|
|
11
12
|
atomicWriteFileSync
|
|
12
13
|
} from "./chunk-IW3Q7AE5.js";
|
|
@@ -172,14 +173,19 @@ function listSessionFiles() {
|
|
|
172
173
|
const dir = historyDir();
|
|
173
174
|
if (!fs.existsSync(dir)) return [];
|
|
174
175
|
const out = [];
|
|
176
|
+
const indexMtimes = getIndexMtimeMap(dir);
|
|
175
177
|
for (const name of fs.readdirSync(dir)) {
|
|
176
178
|
if (!name.endsWith(".json")) continue;
|
|
177
179
|
const id = name.replace(/\.json$/, "");
|
|
178
180
|
const p = path.join(dir, name);
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
if (indexMtimes && indexMtimes[id] !== void 0) {
|
|
182
|
+
out.push({ id, path: p, mtime: indexMtimes[id] });
|
|
183
|
+
} else {
|
|
184
|
+
try {
|
|
185
|
+
const st = fs.statSync(p);
|
|
186
|
+
out.push({ id, path: p, mtime: st.mtimeMs });
|
|
187
|
+
} catch {
|
|
188
|
+
}
|
|
183
189
|
}
|
|
184
190
|
}
|
|
185
191
|
return out;
|
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
listHooks,
|
|
12
12
|
listInstalledPlugins,
|
|
13
13
|
resetStats
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-GFDRC2JZ.js";
|
|
15
15
|
import {
|
|
16
16
|
ConfigManager
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-BFTTW5LS.js";
|
|
18
18
|
import {
|
|
19
19
|
getGitRoot
|
|
20
20
|
} from "./chunk-HOSJZMQS.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
MCP_PROJECT_CONFIG_NAME,
|
|
27
27
|
MEMORY_FILE_NAME,
|
|
28
28
|
VERSION
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-GDXKFWFL.js";
|
|
30
30
|
|
|
31
31
|
// src/diagnostics/doctor-report.ts
|
|
32
32
|
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
evaluateCiGate,
|
|
4
4
|
normalizeCiThresholds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WXFQ6LYN.js";
|
|
6
6
|
import {
|
|
7
7
|
buildReviewPrompt,
|
|
8
8
|
buildSecurityReviewPrompt,
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
} from "./chunk-QYQI7ZWK.js";
|
|
14
14
|
import {
|
|
15
15
|
ConfigManager
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-BFTTW5LS.js";
|
|
17
17
|
import {
|
|
18
18
|
VERSION
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-GDXKFWFL.js";
|
|
20
20
|
|
|
21
21
|
// src/cli/ci.ts
|
|
22
22
|
import { execFileSync } from "child_process";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
truncateForPersist
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FYJGVFXL.js";
|
|
5
5
|
import {
|
|
6
6
|
APP_NAME,
|
|
7
7
|
CONFIG_DIR_NAME,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
MCP_PROTOCOL_VERSION,
|
|
12
12
|
MCP_TOOL_PREFIX,
|
|
13
13
|
VERSION
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-GDXKFWFL.js";
|
|
15
15
|
import {
|
|
16
16
|
atomicWriteFileSync
|
|
17
17
|
} from "./chunk-IW3Q7AE5.js";
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
runHook,
|
|
15
15
|
runLifecycleHooks,
|
|
16
16
|
runTool
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GFDRC2JZ.js";
|
|
18
18
|
import {
|
|
19
19
|
getDangerLevel,
|
|
20
20
|
isFileWriteTool,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
} from "./chunk-4BKXL7SM.js";
|
|
34
34
|
import {
|
|
35
35
|
runTestsTool
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-Q5GVANMH.js";
|
|
37
37
|
import {
|
|
38
38
|
CONFIG_DIR_NAME,
|
|
39
39
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
@@ -43,15 +43,15 @@ import {
|
|
|
43
43
|
SUBAGENT_ALLOWED_TOOLS,
|
|
44
44
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
45
45
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-GDXKFWFL.js";
|
|
47
47
|
import {
|
|
48
48
|
loadChatIndex,
|
|
49
49
|
searchChatMemory
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-5MYPIQ3Y.js";
|
|
51
51
|
import {
|
|
52
52
|
DEFAULT_PATTERNS,
|
|
53
53
|
redactString
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-KCEO2XJ4.js";
|
|
55
55
|
import {
|
|
56
56
|
atomicWriteFileSync
|
|
57
57
|
} from "./chunk-IW3Q7AE5.js";
|
|
@@ -1318,11 +1318,11 @@ ${content}`;
|
|
|
1318
1318
|
|
|
1319
1319
|
// src/tools/builtin/write-file.ts
|
|
1320
1320
|
import { appendFileSync, mkdirSync } from "fs";
|
|
1321
|
-
import { dirname as
|
|
1321
|
+
import { dirname as dirname3 } from "path";
|
|
1322
1322
|
|
|
1323
1323
|
// src/tools/executor.ts
|
|
1324
1324
|
import chalk3 from "chalk";
|
|
1325
|
-
import { existsSync as
|
|
1325
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
1326
1326
|
import { tmpdir } from "os";
|
|
1327
1327
|
|
|
1328
1328
|
// src/core/readline-internal.ts
|
|
@@ -1529,7 +1529,8 @@ function simpleDiff(oldLines, newLines) {
|
|
|
1529
1529
|
}
|
|
1530
1530
|
|
|
1531
1531
|
// src/tools/permissions.ts
|
|
1532
|
-
import {
|
|
1532
|
+
import { existsSync as existsSync4, realpathSync } from "fs";
|
|
1533
|
+
import { basename as basename2, dirname as dirname2, isAbsolute, resolve as resolve3 } from "path";
|
|
1533
1534
|
function checkPermission(toolName, args, dangerLevel, rules, defaultAction = "confirm") {
|
|
1534
1535
|
for (const rule of rules) {
|
|
1535
1536
|
if (rule.tool !== "*" && rule.tool !== toolName) continue;
|
|
@@ -1574,10 +1575,28 @@ var READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
|
1574
1575
|
function normalizePathForPermission(value) {
|
|
1575
1576
|
return value.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
1576
1577
|
}
|
|
1578
|
+
function canonicalizeWithNearestParent(value) {
|
|
1579
|
+
const missing = [];
|
|
1580
|
+
let cursor = resolve3(value);
|
|
1581
|
+
while (!existsSync4(cursor)) {
|
|
1582
|
+
const parent = dirname2(cursor);
|
|
1583
|
+
if (parent === cursor) return null;
|
|
1584
|
+
missing.unshift(basename2(cursor));
|
|
1585
|
+
cursor = parent;
|
|
1586
|
+
}
|
|
1587
|
+
try {
|
|
1588
|
+
return resolve3(realpathSync(cursor), ...missing);
|
|
1589
|
+
} catch {
|
|
1590
|
+
return null;
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1577
1593
|
function isInsidePath(root, target) {
|
|
1578
1594
|
const absoluteTarget = isAbsolute(target) ? target : resolve3(root, target);
|
|
1579
|
-
const
|
|
1580
|
-
const
|
|
1595
|
+
const canonicalRoot = canonicalizeWithNearestParent(root);
|
|
1596
|
+
const canonicalTarget = canonicalizeWithNearestParent(absoluteTarget);
|
|
1597
|
+
if (!canonicalRoot || !canonicalTarget) return false;
|
|
1598
|
+
const r = normalizePathForPermission(canonicalRoot);
|
|
1599
|
+
const t = normalizePathForPermission(canonicalTarget);
|
|
1581
1600
|
return t === r || t.startsWith(`${r}/`);
|
|
1582
1601
|
}
|
|
1583
1602
|
function extractPathArg(toolName, args) {
|
|
@@ -1629,19 +1648,31 @@ function profileHardDecision(profileName, toolName, args, dangerLevel, ctx) {
|
|
|
1629
1648
|
return null;
|
|
1630
1649
|
}
|
|
1631
1650
|
if (profileName === "workspace-write") {
|
|
1632
|
-
if (dangerLevel === "destructive")
|
|
1651
|
+
if (dangerLevel === "destructive") {
|
|
1652
|
+
return { action: "confirm", reason: "destructive tools always require confirmation", profileName, hardBoundary: true };
|
|
1653
|
+
}
|
|
1633
1654
|
if (dangerLevel === "write" && isExplicitFileWriteTool(toolName)) {
|
|
1634
1655
|
const target = extractPathArg(toolName, args);
|
|
1635
|
-
if (!target)
|
|
1656
|
+
if (!target) {
|
|
1657
|
+
return { action: "confirm", reason: "file write target is not explicit", profileName, hardBoundary: true };
|
|
1658
|
+
}
|
|
1636
1659
|
const allowedRoots = getAllowedWriteRoots(ctx);
|
|
1637
1660
|
if (allowedRoots.length === 0 || !allowedRoots.some((root) => isInsidePath(root, target))) {
|
|
1638
|
-
return { action: "deny", reason: "file write target is outside workspace/temp roots", profileName };
|
|
1661
|
+
return { action: "deny", reason: "file write target is outside workspace/temp roots", profileName, hardBoundary: true };
|
|
1639
1662
|
}
|
|
1640
1663
|
}
|
|
1664
|
+
if (toolName === "bash" || toolName === "run_interactive" || toolName === "task_create") {
|
|
1665
|
+
return {
|
|
1666
|
+
action: "confirm",
|
|
1667
|
+
reason: "shell/process writes cannot be proven to stay inside workspace/temp roots",
|
|
1668
|
+
profileName,
|
|
1669
|
+
hardBoundary: true
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1641
1672
|
return null;
|
|
1642
1673
|
}
|
|
1643
1674
|
if (profileName === "danger-full-access") {
|
|
1644
|
-
if (dangerLevel === "destructive") return { action: "confirm", reason: "destructive tools still require confirmation", profileName };
|
|
1675
|
+
if (dangerLevel === "destructive") return { action: "confirm", reason: "destructive tools still require confirmation", profileName, hardBoundary: true };
|
|
1645
1676
|
return null;
|
|
1646
1677
|
}
|
|
1647
1678
|
return null;
|
|
@@ -1653,7 +1684,8 @@ function checkPermissionWithProfile(toolName, args, dangerLevel, rules, defaultA
|
|
|
1653
1684
|
const combinedRules = [...getProfileRules(profileContext), ...rules];
|
|
1654
1685
|
const profileDefault = profileName === "legacy" ? defaultAction : getProfileDefaultAction(profileName, profileContext);
|
|
1655
1686
|
const action = checkPermission(toolName, args, dangerLevel, combinedRules, profileDefault);
|
|
1656
|
-
if (
|
|
1687
|
+
if (action === "deny") return { action, profileName };
|
|
1688
|
+
if (hard?.action === "confirm") return hard;
|
|
1657
1689
|
return { action, profileName };
|
|
1658
1690
|
}
|
|
1659
1691
|
function formatPermissionProfileWarning(profileName) {
|
|
@@ -1950,7 +1982,7 @@ var theme = new Proxy(DARK_THEME, {
|
|
|
1950
1982
|
});
|
|
1951
1983
|
|
|
1952
1984
|
// src/tools/action-classifier.ts
|
|
1953
|
-
import { existsSync as
|
|
1985
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
1954
1986
|
import { isAbsolute as isAbsolute2, join, resolve as resolve4 } from "path";
|
|
1955
1987
|
var RECENT_DENIED_LIMIT = 50;
|
|
1956
1988
|
var recentlyDenied = [];
|
|
@@ -1993,7 +2025,7 @@ function splitShellWords(command) {
|
|
|
1993
2025
|
}
|
|
1994
2026
|
function readPackageManifest(root) {
|
|
1995
2027
|
const p = join(root, "package.json");
|
|
1996
|
-
if (!
|
|
2028
|
+
if (!existsSync5(p)) return null;
|
|
1997
2029
|
try {
|
|
1998
2030
|
return JSON.parse(readFileSync3(p, "utf-8"));
|
|
1999
2031
|
} catch {
|
|
@@ -2012,7 +2044,7 @@ function manifestHasDependency(root, name) {
|
|
|
2012
2044
|
function lockfileMentions(root, name) {
|
|
2013
2045
|
for (const file of ["package-lock.json", "pnpm-lock.yaml", "yarn.lock"]) {
|
|
2014
2046
|
const p = join(root, file);
|
|
2015
|
-
if (!
|
|
2047
|
+
if (!existsSync5(p)) continue;
|
|
2016
2048
|
try {
|
|
2017
2049
|
if (readFileSync3(p, "utf-8").includes(name)) return true;
|
|
2018
2050
|
} catch {
|
|
@@ -2288,14 +2320,15 @@ var ToolExecutor = class {
|
|
|
2288
2320
|
return { callId: call.id, content: message, isError: true };
|
|
2289
2321
|
}
|
|
2290
2322
|
}
|
|
2291
|
-
|
|
2323
|
+
const requiresHardConfirmation = permission.action === "confirm" && permission.hardBoundary === true;
|
|
2324
|
+
if ((networkPermission?.action === "confirm" || requiresHardConfirmation) && dangerLevel === "safe") {
|
|
2292
2325
|
this.printToolCall(call);
|
|
2293
2326
|
toolCallAlreadyPrinted = true;
|
|
2294
2327
|
const confirmed = await this.confirm(call, "write");
|
|
2295
2328
|
if (!confirmed) {
|
|
2296
2329
|
return {
|
|
2297
2330
|
callId: call.id,
|
|
2298
|
-
content: `[User cancelled] The user declined
|
|
2331
|
+
content: `[User cancelled] The user declined permission for ${call.name}. Do not retry without asking.`,
|
|
2299
2332
|
isError: true
|
|
2300
2333
|
};
|
|
2301
2334
|
}
|
|
@@ -2313,7 +2346,7 @@ var ToolExecutor = class {
|
|
|
2313
2346
|
isError: true
|
|
2314
2347
|
};
|
|
2315
2348
|
}
|
|
2316
|
-
if (classification.decision === "auto-approve") {
|
|
2349
|
+
if (classification.decision === "auto-approve" && !requiresHardConfirmation) {
|
|
2317
2350
|
this.printToolCall(call);
|
|
2318
2351
|
if (dangerLevel === "write") this.printDiffPreview(call);
|
|
2319
2352
|
console.log(theme.warning(` \u26A1 Auto-approved (/auto: ${classification.ruleId})`));
|
|
@@ -2334,7 +2367,7 @@ var ToolExecutor = class {
|
|
|
2334
2367
|
}
|
|
2335
2368
|
}
|
|
2336
2369
|
}
|
|
2337
|
-
if (this.sessionAutoApprove && dangerLevel === "write") {
|
|
2370
|
+
if (this.sessionAutoApprove && dangerLevel === "write" && !requiresHardConfirmation) {
|
|
2338
2371
|
this.printToolCall(call);
|
|
2339
2372
|
if (dangerLevel === "write") this.printDiffPreview(call);
|
|
2340
2373
|
console.log(theme.warning(" \u26A1 Auto-approved (session /yolo mode)"));
|
|
@@ -2578,7 +2611,7 @@ var ToolExecutor = class {
|
|
|
2578
2611
|
const filePath = String(call.arguments["path"] ?? "");
|
|
2579
2612
|
const newContent = String(call.arguments["content"] ?? "");
|
|
2580
2613
|
if (!filePath) return;
|
|
2581
|
-
if (
|
|
2614
|
+
if (existsSync6(filePath)) {
|
|
2582
2615
|
let oldContent;
|
|
2583
2616
|
try {
|
|
2584
2617
|
oldContent = readFileSync4(filePath, "utf-8");
|
|
@@ -2604,7 +2637,7 @@ var ToolExecutor = class {
|
|
|
2604
2637
|
}
|
|
2605
2638
|
} else if (call.name === "edit_file") {
|
|
2606
2639
|
const filePath = String(call.arguments["path"] ?? "");
|
|
2607
|
-
if (!filePath || !
|
|
2640
|
+
if (!filePath || !existsSync6(filePath)) return;
|
|
2608
2641
|
const oldStr = call.arguments["old_str"];
|
|
2609
2642
|
const newStr = call.arguments["new_str"];
|
|
2610
2643
|
if (oldStr !== void 0) {
|
|
@@ -2723,7 +2756,7 @@ var ToolExecutor = class {
|
|
|
2723
2756
|
};
|
|
2724
2757
|
|
|
2725
2758
|
// src/tools/sensitive-paths.ts
|
|
2726
|
-
import { resolve as resolve5, sep as sep2, basename as
|
|
2759
|
+
import { resolve as resolve5, sep as sep2, basename as basename3 } from "path";
|
|
2727
2760
|
import { homedir as homedir2 } from "os";
|
|
2728
2761
|
var home = homedir2();
|
|
2729
2762
|
function norm(p) {
|
|
@@ -2742,7 +2775,7 @@ function homeRel(p) {
|
|
|
2742
2775
|
function classifyWritePath(path3) {
|
|
2743
2776
|
if (!path3) return { sensitive: false };
|
|
2744
2777
|
const abs = norm(path3);
|
|
2745
|
-
const base =
|
|
2778
|
+
const base = basename3(abs);
|
|
2746
2779
|
const rel = homeRel(path3);
|
|
2747
2780
|
if (rel) {
|
|
2748
2781
|
const shellRc = /* @__PURE__ */ new Set([
|
|
@@ -2866,7 +2899,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
|
|
|
2866
2899
|
}
|
|
2867
2900
|
undoStack.push(filePath, `write_file${appendMode ? " (append)" : ""}: ${filePath}`);
|
|
2868
2901
|
fileCheckpoints.snapshot(filePath, ToolExecutor.currentMessageIndex);
|
|
2869
|
-
mkdirSync(
|
|
2902
|
+
mkdirSync(dirname3(filePath), { recursive: true });
|
|
2870
2903
|
if (appendMode) {
|
|
2871
2904
|
appendFileSync(filePath, content, encoding);
|
|
2872
2905
|
} else {
|
|
@@ -2886,7 +2919,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
|
|
|
2886
2919
|
};
|
|
2887
2920
|
|
|
2888
2921
|
// src/tools/builtin/edit-file.ts
|
|
2889
|
-
import { readFileSync as readFileSync5, existsSync as
|
|
2922
|
+
import { readFileSync as readFileSync5, existsSync as existsSync7 } from "fs";
|
|
2890
2923
|
|
|
2891
2924
|
// src/tools/builtin/patch-apply.ts
|
|
2892
2925
|
function parseUnifiedDiff(patch) {
|
|
@@ -3247,7 +3280,7 @@ Note: Path can be absolute or relative to cwd.`,
|
|
|
3247
3280
|
const filePath = String(args["path"] ?? args["file"] ?? "");
|
|
3248
3281
|
const encoding = args["encoding"] ?? "utf-8";
|
|
3249
3282
|
if (!filePath) throw new ToolError("edit_file", "path is required");
|
|
3250
|
-
if (!
|
|
3283
|
+
if (!existsSync7(filePath)) throw new ToolError("edit_file", `File not found: ${filePath}`);
|
|
3251
3284
|
const verdict = classifyWritePath(filePath);
|
|
3252
3285
|
if (verdict.sensitive && subAgentGuard.active) {
|
|
3253
3286
|
throw new ToolError(
|
|
@@ -3413,8 +3446,8 @@ function truncatePreview(str, maxLen = 80) {
|
|
|
3413
3446
|
}
|
|
3414
3447
|
|
|
3415
3448
|
// src/tools/builtin/list-dir.ts
|
|
3416
|
-
import { readdirSync as readdirSync3, statSync as statSync3, existsSync as
|
|
3417
|
-
import { join as join2, basename as
|
|
3449
|
+
import { readdirSync as readdirSync3, statSync as statSync3, existsSync as existsSync8 } from "fs";
|
|
3450
|
+
import { join as join2, basename as basename4 } from "path";
|
|
3418
3451
|
var listDirTool = {
|
|
3419
3452
|
definition: {
|
|
3420
3453
|
name: "list_dir",
|
|
@@ -3436,8 +3469,8 @@ var listDirTool = {
|
|
|
3436
3469
|
async execute(args) {
|
|
3437
3470
|
const dirPath = String(args["path"] ?? process.cwd());
|
|
3438
3471
|
const recursive = Boolean(args["recursive"] ?? false);
|
|
3439
|
-
if (!
|
|
3440
|
-
const targetName =
|
|
3472
|
+
if (!existsSync8(dirPath)) {
|
|
3473
|
+
const targetName = basename4(dirPath).toLowerCase();
|
|
3441
3474
|
const cwd = process.cwd();
|
|
3442
3475
|
const suggestions = [];
|
|
3443
3476
|
try {
|
|
@@ -3514,7 +3547,7 @@ function formatSize(bytes) {
|
|
|
3514
3547
|
}
|
|
3515
3548
|
|
|
3516
3549
|
// src/tools/builtin/grep-files.ts
|
|
3517
|
-
import { readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync4, existsSync as
|
|
3550
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync4, existsSync as existsSync9 } from "fs";
|
|
3518
3551
|
import { readFile } from "fs/promises";
|
|
3519
3552
|
import { join as join3, relative } from "path";
|
|
3520
3553
|
var grepFilesTool = {
|
|
@@ -3567,7 +3600,7 @@ Supports regex. Automatically skips node_modules, dist, .git directories.`,
|
|
|
3567
3600
|
const contextLines = Math.max(0, Number(args["context_lines"] ?? 0));
|
|
3568
3601
|
const maxResults = Math.max(1, Number(args["max_results"] ?? 50));
|
|
3569
3602
|
if (!pattern) throw new ToolError("grep_files", "pattern is required");
|
|
3570
|
-
if (!
|
|
3603
|
+
if (!existsSync9(rootPath)) throw new ToolError("grep_files", `Path not found: ${rootPath}`);
|
|
3571
3604
|
const MAX_PATTERN_LENGTH = 1e3;
|
|
3572
3605
|
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
3573
3606
|
throw new ToolError("grep_files", `Pattern too long (${pattern.length} chars, max ${MAX_PATTERN_LENGTH}). Use a shorter pattern.`);
|
|
@@ -3751,8 +3784,8 @@ function searchInFile(fullPath, displayPath, regex, contextLines, maxResults, re
|
|
|
3751
3784
|
}
|
|
3752
3785
|
|
|
3753
3786
|
// src/tools/builtin/glob-files.ts
|
|
3754
|
-
import { readdirSync as readdirSync5, statSync as statSync5, existsSync as
|
|
3755
|
-
import { join as join4, relative as relative2, basename as
|
|
3787
|
+
import { readdirSync as readdirSync5, statSync as statSync5, existsSync as existsSync10 } from "fs";
|
|
3788
|
+
import { join as join4, relative as relative2, basename as basename5 } from "path";
|
|
3756
3789
|
var globFilesTool = {
|
|
3757
3790
|
definition: {
|
|
3758
3791
|
name: "glob_files",
|
|
@@ -3785,7 +3818,7 @@ Results sorted by most recent modification time. Automatically skips node_module
|
|
|
3785
3818
|
const rootPath = String(args["path"] ?? process.cwd());
|
|
3786
3819
|
const maxResults = Math.max(1, Number(args["max_results"] ?? 100));
|
|
3787
3820
|
if (!pattern) throw new ToolError("glob_files", "pattern is required");
|
|
3788
|
-
if (!
|
|
3821
|
+
if (!existsSync10(rootPath)) throw new ToolError("glob_files", `Path not found: ${rootPath}`);
|
|
3789
3822
|
const regex = globToRegex(pattern);
|
|
3790
3823
|
const matches = [];
|
|
3791
3824
|
collectMatchingFiles(rootPath, rootPath, regex, matches, maxResults);
|
|
@@ -3868,7 +3901,7 @@ function collectMatchingFiles(dirPath, rootPath, regex, results, maxResults) {
|
|
|
3868
3901
|
collectMatchingFiles(fullPath, rootPath, regex, results, maxResults);
|
|
3869
3902
|
} else if (entry.isFile()) {
|
|
3870
3903
|
const relPath = relative2(rootPath, fullPath).replace(/\\/g, "/");
|
|
3871
|
-
if (regex.test(relPath) || regex.test(
|
|
3904
|
+
if (regex.test(relPath) || regex.test(basename5(relPath))) {
|
|
3872
3905
|
try {
|
|
3873
3906
|
const stat = statSync5(fullPath);
|
|
3874
3907
|
results.push({ relPath, absPath: fullPath, mtime: stat.mtimeMs });
|
|
@@ -4603,7 +4636,7 @@ ${preamble}`;
|
|
|
4603
4636
|
|
|
4604
4637
|
// src/tools/builtin/save-last-response.ts
|
|
4605
4638
|
import { mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, rmdirSync as rmdirSync2 } from "fs";
|
|
4606
|
-
import { dirname as
|
|
4639
|
+
import { dirname as dirname4 } from "path";
|
|
4607
4640
|
var lastResponseStore = { content: "" };
|
|
4608
4641
|
function cleanupRejectedTeeFile(filePath) {
|
|
4609
4642
|
try {
|
|
@@ -4611,7 +4644,7 @@ function cleanupRejectedTeeFile(filePath) {
|
|
|
4611
4644
|
} catch {
|
|
4612
4645
|
}
|
|
4613
4646
|
try {
|
|
4614
|
-
rmdirSync2(
|
|
4647
|
+
rmdirSync2(dirname4(filePath));
|
|
4615
4648
|
} catch {
|
|
4616
4649
|
}
|
|
4617
4650
|
}
|
|
@@ -4652,7 +4685,7 @@ Any of these triggers means use save_last_response, NOT write_file:
|
|
|
4652
4685
|
throw new ToolError("save_last_response", "No content to save: AI has not produced any response yet, or the last response was empty.");
|
|
4653
4686
|
}
|
|
4654
4687
|
undoStack.push(filePath, `save_last_response: ${filePath}`);
|
|
4655
|
-
mkdirSync2(
|
|
4688
|
+
mkdirSync2(dirname4(filePath), { recursive: true });
|
|
4656
4689
|
atomicWriteFileSync(filePath, content);
|
|
4657
4690
|
const lines = content.split("\n").length;
|
|
4658
4691
|
return `File saved: ${filePath} (${lines} lines, ${content.length} bytes)`;
|
|
@@ -4664,9 +4697,9 @@ import { join as join6 } from "path";
|
|
|
4664
4697
|
import { homedir as homedir3 } from "os";
|
|
4665
4698
|
|
|
4666
4699
|
// src/memory/persistent-memory.ts
|
|
4667
|
-
import { existsSync as
|
|
4700
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync3, readFileSync as readFileSync7 } from "fs";
|
|
4668
4701
|
import { randomUUID, createHash } from "crypto";
|
|
4669
|
-
import { dirname as
|
|
4702
|
+
import { dirname as dirname5, join as join5, resolve as resolve6 } from "path";
|
|
4670
4703
|
function memoryStorePath(configDir) {
|
|
4671
4704
|
return join5(configDir, MEMORY_STORE_FILE_NAME);
|
|
4672
4705
|
}
|
|
@@ -4707,7 +4740,7 @@ function normalizeEntry(value) {
|
|
|
4707
4740
|
}
|
|
4708
4741
|
function legacyEntriesFromMarkdown(configDir) {
|
|
4709
4742
|
const file = memoryMarkdownPath(configDir);
|
|
4710
|
-
if (!
|
|
4743
|
+
if (!existsSync11(file)) return [];
|
|
4711
4744
|
const content = readFileSync7(file, "utf-8").trim();
|
|
4712
4745
|
if (!content) return [];
|
|
4713
4746
|
const parts = content.split(/\n(?=##\s+\d{4}-\d{2}-\d{2})/g);
|
|
@@ -4724,7 +4757,7 @@ ${chunk}`).digest("hex").slice(0, 12);
|
|
|
4724
4757
|
}
|
|
4725
4758
|
function loadMemoryEntries(configDir) {
|
|
4726
4759
|
const file = memoryStorePath(configDir);
|
|
4727
|
-
if (!
|
|
4760
|
+
if (!existsSync11(file)) return legacyEntriesFromMarkdown(configDir);
|
|
4728
4761
|
const text = readFileSync7(file, "utf-8").trim();
|
|
4729
4762
|
if (!text) return [];
|
|
4730
4763
|
const entries = [];
|
|
@@ -5172,7 +5205,7 @@ function formatResults2(query, data, _requested) {
|
|
|
5172
5205
|
}
|
|
5173
5206
|
|
|
5174
5207
|
// src/agents/agent-config.ts
|
|
5175
|
-
import { existsSync as
|
|
5208
|
+
import { existsSync as existsSync12, readdirSync as readdirSync6, readFileSync as readFileSync8 } from "fs";
|
|
5176
5209
|
import { join as join7 } from "path";
|
|
5177
5210
|
import { homedir as homedir4 } from "os";
|
|
5178
5211
|
var READ_ONLY_TOOLS2 = /* @__PURE__ */ new Set([
|
|
@@ -5268,7 +5301,7 @@ function parseAgentConfig(raw, source, path3) {
|
|
|
5268
5301
|
return cfg;
|
|
5269
5302
|
}
|
|
5270
5303
|
function loadAgentDir(dir, source) {
|
|
5271
|
-
if (!
|
|
5304
|
+
if (!existsSync12(dir)) return [];
|
|
5272
5305
|
const out = [];
|
|
5273
5306
|
for (const file of readdirSync6(dir)) {
|
|
5274
5307
|
if (!file.endsWith(".json")) continue;
|
|
@@ -6000,13 +6033,13 @@ var taskStopTool = {
|
|
|
6000
6033
|
|
|
6001
6034
|
// src/tools/builtin/git-tools.ts
|
|
6002
6035
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
6003
|
-
import { existsSync as
|
|
6036
|
+
import { existsSync as existsSync13 } from "fs";
|
|
6004
6037
|
import { join as join8 } from "path";
|
|
6005
6038
|
function assertGitRepo(cwd) {
|
|
6006
6039
|
let dir = cwd;
|
|
6007
6040
|
const root = dir.split(/[\\/]/)[0] + (dir.includes("\\") ? "\\" : "/");
|
|
6008
6041
|
while (dir && dir !== root) {
|
|
6009
|
-
if (
|
|
6042
|
+
if (existsSync13(join8(dir, ".git"))) return;
|
|
6010
6043
|
const parent = join8(dir, "..");
|
|
6011
6044
|
if (parent === dir) break;
|
|
6012
6045
|
dir = parent;
|
|
@@ -6272,7 +6305,7 @@ ${commitOutput.trim()}`;
|
|
|
6272
6305
|
};
|
|
6273
6306
|
|
|
6274
6307
|
// src/tools/builtin/notebook-edit.ts
|
|
6275
|
-
import { readFileSync as readFileSync9, existsSync as
|
|
6308
|
+
import { readFileSync as readFileSync9, existsSync as existsSync14 } from "fs";
|
|
6276
6309
|
import { writeFile } from "fs/promises";
|
|
6277
6310
|
import { resolve as resolve7, extname as extname2 } from "path";
|
|
6278
6311
|
var notebookEditTool = {
|
|
@@ -6327,7 +6360,7 @@ var notebookEditTool = {
|
|
|
6327
6360
|
if (extname2(absPath).toLowerCase() !== ".ipynb") {
|
|
6328
6361
|
throw new ToolError("notebook_edit", "path must point to a .ipynb file");
|
|
6329
6362
|
}
|
|
6330
|
-
if (!
|
|
6363
|
+
if (!existsSync14(absPath)) {
|
|
6331
6364
|
throw new ToolError("notebook_edit", `Notebook not found: ${filePath}`);
|
|
6332
6365
|
}
|
|
6333
6366
|
const raw = readFileSync9(absPath, "utf-8");
|
|
@@ -6747,7 +6780,7 @@ function estimateToolDefinitionTokens(def) {
|
|
|
6747
6780
|
|
|
6748
6781
|
// src/tools/registry.ts
|
|
6749
6782
|
import { pathToFileURL } from "url";
|
|
6750
|
-
import { existsSync as
|
|
6783
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync4, readdirSync as readdirSync7 } from "fs";
|
|
6751
6784
|
import { join as join9 } from "path";
|
|
6752
6785
|
var ToolRegistry = class {
|
|
6753
6786
|
tools = /* @__PURE__ */ new Map();
|
|
@@ -6909,7 +6942,7 @@ var ToolRegistry = class {
|
|
|
6909
6942
|
* Returns the number of successfully loaded plugins.
|
|
6910
6943
|
*/
|
|
6911
6944
|
async loadPlugins(pluginsDir, allowPlugins = false) {
|
|
6912
|
-
if (!
|
|
6945
|
+
if (!existsSync15(pluginsDir)) {
|
|
6913
6946
|
try {
|
|
6914
6947
|
mkdirSync4(pluginsDir, { recursive: true });
|
|
6915
6948
|
} catch {
|