@tencent-ai/agent-sdk 0.3.187 → 0.3.188-dev.368febf.202606232001
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/cli/CHANGELOG.md +14 -0
- package/cli/dist/codebuddy-headless.js +338 -220
- package/cli/dist/web-ui/docs/cn/cli/prewarm.md +0 -1
- package/cli/dist/web-ui/docs/en/cli/prewarm.md +0 -1
- package/cli/dist/web-ui/docs/search-index-zh.json +1 -1
- package/cli/package.json +3 -2
- package/cli/product.cloudhosted.json +2 -2
- package/cli/product.internal.json +2 -2
- package/cli/product.ioa.json +2 -2
- package/cli/product.json +2 -2
- package/cli/product.selfhosted.json +2 -2
- package/cli/vendor/shim/genie-safe-delete.cjs +82 -0
- package/cli/vendor/shim/safe-bin/safe-delete-common.sh +144 -9
- package/cli/vendor/shim/safe-delete-bulk-guard.cjs +447 -0
- package/cli/vendor/shim/sitecustomize.py +100 -0
- package/package.json +3 -2
package/cli/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencent-ai/codebuddy-code",
|
|
3
|
-
"version": "2.109.
|
|
3
|
+
"version": "2.109.2-dev.368febf.202606232001",
|
|
4
4
|
"description": "Use CodeBuddy, Tencent's AI assistant, right from your terminal. CodeBuddy can understand your codebase, edit files, run terminal commands, and handle entire workflows for you.",
|
|
5
5
|
"main": "lib/node/index.js",
|
|
6
6
|
"typings": "lib/node/index.d.ts",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"url": "https://cnb.cool/codebuddy/codebuddy-code/-/issues"
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
|
45
|
-
"access": "public"
|
|
45
|
+
"access": "public",
|
|
46
|
+
"tag": "dev"
|
|
46
47
|
},
|
|
47
48
|
"scripts": {},
|
|
48
49
|
"devDependencies": {}
|
|
@@ -824,6 +824,6 @@
|
|
|
824
824
|
"SelectImage": true,
|
|
825
825
|
"SkipToolCallSupportCheck": true
|
|
826
826
|
},
|
|
827
|
-
"commit": "
|
|
828
|
-
"date": "2026-06-
|
|
827
|
+
"commit": "368febf4656d2e766c98a193440453fb331e76f9",
|
|
828
|
+
"date": "2026-06-23T12:00:07.090Z"
|
|
829
829
|
}
|
package/cli/product.ioa.json
CHANGED
package/cli/product.json
CHANGED
|
@@ -339,6 +339,6 @@
|
|
|
339
339
|
"ScheduledTasks": true,
|
|
340
340
|
"SkipToolCallSupportCheck": true
|
|
341
341
|
},
|
|
342
|
-
"commit": "
|
|
343
|
-
"date": "2026-06-
|
|
342
|
+
"commit": "368febf4656d2e766c98a193440453fb331e76f9",
|
|
343
|
+
"date": "2026-06-23T12:00:07.079Z"
|
|
344
344
|
}
|
|
@@ -37,6 +37,52 @@ if (!SESSION_ID) {
|
|
|
37
37
|
const PLATFORM = process.platform; // 'darwin' | 'win32' | 'linux' | ...
|
|
38
38
|
const REPORT_PATH = process.env.CODEBUDDY_SAFE_DELETE_REPORT_PATH;
|
|
39
39
|
|
|
40
|
+
function normalizePathForCompare(filePath) {
|
|
41
|
+
const resolved = path.resolve(filePath);
|
|
42
|
+
return PLATFORM === 'win32' ? resolved.toLowerCase() : resolved;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isUsableTempRoot(filePath) {
|
|
46
|
+
try {
|
|
47
|
+
const resolved = path.resolve(filePath);
|
|
48
|
+
if (path.parse(resolved).root === resolved) return false;
|
|
49
|
+
return fs.statSync(resolved).isDirectory();
|
|
50
|
+
} catch (_) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function buildOsTmpDirs() {
|
|
56
|
+
const candidates = [
|
|
57
|
+
os.tmpdir(),
|
|
58
|
+
];
|
|
59
|
+
if (PLATFORM !== 'win32') {
|
|
60
|
+
candidates.push('/tmp');
|
|
61
|
+
candidates.push('/private/tmp');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const roots = [];
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
for (const candidate of candidates) {
|
|
67
|
+
if (!candidate || !isUsableTempRoot(candidate)) continue;
|
|
68
|
+
const root = normalizePathForCompare(candidate);
|
|
69
|
+
if (seen.has(root)) continue;
|
|
70
|
+
seen.add(root);
|
|
71
|
+
roots.push(root);
|
|
72
|
+
}
|
|
73
|
+
return roots;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const OS_TMP_DIRS = buildOsTmpDirs();
|
|
77
|
+
|
|
78
|
+
function isUnderOsTmpDir(absPath) {
|
|
79
|
+
const target = normalizePathForCompare(absPath);
|
|
80
|
+
return OS_TMP_DIRS.some(root => {
|
|
81
|
+
const rel = path.relative(root, target);
|
|
82
|
+
return !!rel && rel !== '..' && !rel.startsWith(`..${path.sep}`) && !path.isAbsolute(rel);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
40
86
|
function recordTrash(absPath) {
|
|
41
87
|
if (!REPORT_PATH) return;
|
|
42
88
|
try {
|
|
@@ -55,6 +101,34 @@ function recordTrash(absPath) {
|
|
|
55
101
|
}
|
|
56
102
|
}
|
|
57
103
|
|
|
104
|
+
function checkBulkDeleteGuard(absPath) {
|
|
105
|
+
const guardPath = process.env.CODEBUDDY_SAFE_DELETE_BULK_GUARD;
|
|
106
|
+
const nodeBin = process.env.CODEBUDDY_NODE_BIN;
|
|
107
|
+
if (!process.env.CODEBUDDY_SAFE_DELETE_BULK_STATE_DIR || !process.env.CODEBUDDY_TOOL_CALL_ID) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (!guardPath || !nodeBin || !fs.existsSync(guardPath)) {
|
|
111
|
+
throw new Error(`[safe-delete][SAFE_DELETE_BULK_GUARD_ERROR] msg=helper-unavailable guard=${guardPath || 'unset'}`);
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
execFileSync(nodeBin, [guardPath, 'check', '--target', absPath], {
|
|
115
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
116
|
+
timeout: 10_000,
|
|
117
|
+
windowsHide: true,
|
|
118
|
+
env: {
|
|
119
|
+
...process.env,
|
|
120
|
+
NODE_OPTIONS: '',
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
} catch (e) {
|
|
124
|
+
const detail = e && e.stderr ? String(e.stderr).trim() : '';
|
|
125
|
+
if (detail) {
|
|
126
|
+
throw new Error(detail);
|
|
127
|
+
}
|
|
128
|
+
throw new Error(`[safe-delete][SAFE_DELETE_BULK_GUARD_ERROR] ${(e && e.message) || String(e)}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
58
132
|
// ---------------------------------------------------------------------------
|
|
59
133
|
// 平台分发
|
|
60
134
|
// ---------------------------------------------------------------------------
|
|
@@ -373,6 +447,7 @@ function writeTrashInfo(absPath, baseName) {
|
|
|
373
447
|
* @param {string} absPath 绝对路径
|
|
374
448
|
*/
|
|
375
449
|
function tryTrash(absPath) {
|
|
450
|
+
checkBulkDeleteGuard(absPath);
|
|
376
451
|
trashItem(absPath); // 成功静默;失败抛错,调用方不应继续真删
|
|
377
452
|
recordTrash(absPath);
|
|
378
453
|
return true;
|
|
@@ -417,6 +492,7 @@ function toAbsPath(filePath) {
|
|
|
417
492
|
function makeSyncWrapper(orig, requireDir) {
|
|
418
493
|
return function (filePath, ...rest) {
|
|
419
494
|
const absPath = toAbsPath(filePath);
|
|
495
|
+
if (isUnderOsTmpDir(absPath)) return orig(filePath, ...rest);
|
|
420
496
|
if (requireDir) {
|
|
421
497
|
const st = safeLstat(absPath);
|
|
422
498
|
if (st === null) return orig(filePath, ...rest); // ENOENT → 原生抛
|
|
@@ -467,6 +543,7 @@ function makeCallbackWrapper(orig, requireDir) {
|
|
|
467
543
|
return orig(filePath, ...rest);
|
|
468
544
|
}
|
|
469
545
|
const absPath = toAbsPath(filePath);
|
|
546
|
+
if (isUnderOsTmpDir(absPath)) return orig(filePath, ...rest);
|
|
470
547
|
|
|
471
548
|
const st = safeLstat(absPath);
|
|
472
549
|
if (st === null) return orig(filePath, ...rest); // ENOENT → 原生抛
|
|
@@ -495,6 +572,7 @@ function makeCallbackWrapper(orig, requireDir) {
|
|
|
495
572
|
function makePromiseWrapper(orig, requireDir) {
|
|
496
573
|
return async function (filePath, ...rest) {
|
|
497
574
|
const absPath = toAbsPath(filePath);
|
|
575
|
+
if (isUnderOsTmpDir(absPath)) return orig(filePath, ...rest);
|
|
498
576
|
const st = safeLstat(absPath);
|
|
499
577
|
if (st === null) return orig(filePath, ...rest); // ENOENT → 原生抛
|
|
500
578
|
if (st) {
|
|
@@ -519,6 +597,10 @@ function makePromiseWrapper(orig, requireDir) {
|
|
|
519
597
|
* throws → 回收站操作失败(fail-closed),调用方不得真删
|
|
520
598
|
*/
|
|
521
599
|
function tryRm(absPath, opts) {
|
|
600
|
+
if (isUnderOsTmpDir(absPath)) {
|
|
601
|
+
return { done: false };
|
|
602
|
+
}
|
|
603
|
+
|
|
522
604
|
const recursive = !!(opts && opts.recursive);
|
|
523
605
|
const force = !!(opts && opts.force);
|
|
524
606
|
|
|
@@ -45,11 +45,115 @@ safe_delete_record_trash() {
|
|
|
45
45
|
"$path_json" "$timestamp" >> "$CODEBUDDY_SAFE_DELETE_REPORT_PATH" 2>/dev/null || true
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
safe_delete_bulk_guard_check() {
|
|
49
|
+
[ "$#" -gt 0 ] || return 0
|
|
50
|
+
[ -n "${CODEBUDDY_SAFE_DELETE_BULK_STATE_DIR:-}" ] || return 0
|
|
51
|
+
[ -n "${CODEBUDDY_TOOL_CALL_ID:-}" ] || return 0
|
|
52
|
+
if [ -z "${CODEBUDDY_NODE_BIN:-}" ] || [ -z "${CODEBUDDY_SAFE_DELETE_BULK_GUARD:-}" ] || [ ! -f "$CODEBUDDY_SAFE_DELETE_BULK_GUARD" ]; then
|
|
53
|
+
echo "[safe-delete][SAFE_DELETE_BULK_GUARD_ERROR] msg=helper-unavailable guard=${CODEBUDDY_SAFE_DELETE_BULK_GUARD:-unset}" >&2
|
|
54
|
+
return 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
local args=()
|
|
58
|
+
local p
|
|
59
|
+
for p in "$@"; do
|
|
60
|
+
args+=(--target "$(safe_delete_abs_path "$p")")
|
|
61
|
+
done
|
|
62
|
+
NODE_OPTIONS= "$CODEBUDDY_NODE_BIN" "$CODEBUDDY_SAFE_DELETE_BULK_GUARD" check "${args[@]}"
|
|
63
|
+
}
|
|
64
|
+
|
|
48
65
|
is_dir_empty() {
|
|
49
66
|
local p="$1"
|
|
50
67
|
[ -z "$(ls -A "$p" 2>/dev/null)" ]
|
|
51
68
|
}
|
|
52
69
|
|
|
70
|
+
safe_delete_normalize_path() {
|
|
71
|
+
local p="$1"
|
|
72
|
+
while [ "$p" != "/" ] && [ "${p%/}" != "$p" ]; do
|
|
73
|
+
p="${p%/}"
|
|
74
|
+
done
|
|
75
|
+
printf '%s' "$p"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
safe_delete_to_unix_path_if_possible() {
|
|
79
|
+
local p="$1"
|
|
80
|
+
if command -v cygpath >/dev/null 2>&1; then
|
|
81
|
+
cygpath -u "$p" 2>/dev/null && return 0
|
|
82
|
+
fi
|
|
83
|
+
printf '%s' "$p"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
safe_delete_resolve_os_tmp_dir() {
|
|
87
|
+
local tmp="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
|
|
88
|
+
safe_delete_to_unix_path_if_possible "$tmp"
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
safe_delete_abs_path() {
|
|
92
|
+
local p="$1"
|
|
93
|
+
local abs
|
|
94
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
95
|
+
abs="$(python3 -c 'import os,sys; print(os.path.abspath(sys.argv[1]))' "$p" 2>/dev/null)" && {
|
|
96
|
+
safe_delete_to_unix_path_if_possible "$abs"
|
|
97
|
+
return 0
|
|
98
|
+
}
|
|
99
|
+
elif command -v python >/dev/null 2>&1; then
|
|
100
|
+
abs="$(python -c 'import os,sys; print(os.path.abspath(sys.argv[1]))' "$p" 2>/dev/null)" && {
|
|
101
|
+
safe_delete_to_unix_path_if_possible "$abs"
|
|
102
|
+
return 0
|
|
103
|
+
}
|
|
104
|
+
fi
|
|
105
|
+
case "$p" in
|
|
106
|
+
/*|[A-Za-z]:/*) abs="$p" ;;
|
|
107
|
+
*) abs="$PWD/$p" ;;
|
|
108
|
+
esac
|
|
109
|
+
abs="$(CDPATH= cd -P -- "$(dirname "$abs")" 2>/dev/null && printf '%s/%s' "$PWD" "$(basename "$abs")" || printf '%s' "$abs")"
|
|
110
|
+
safe_delete_to_unix_path_if_possible "$abs"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
safe_delete_tmp_root_allowed() {
|
|
114
|
+
local root="$1"
|
|
115
|
+
[ -n "$root" ] || return 1
|
|
116
|
+
[ "$root" != "/" ] || return 1
|
|
117
|
+
[ -d "$root" ] || return 1
|
|
118
|
+
return 0
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
safe_delete_build_os_tmp_dirs() {
|
|
122
|
+
local seen="|" candidate root
|
|
123
|
+
for candidate in \
|
|
124
|
+
"$(safe_delete_resolve_os_tmp_dir)" \
|
|
125
|
+
"/tmp" \
|
|
126
|
+
"/private/tmp"
|
|
127
|
+
do
|
|
128
|
+
[ -n "$candidate" ] || continue
|
|
129
|
+
root="$(safe_delete_normalize_path "$(safe_delete_abs_path "$candidate")")"
|
|
130
|
+
safe_delete_tmp_root_allowed "$root" || continue
|
|
131
|
+
case "$seen" in
|
|
132
|
+
*"|$root|"*) ;;
|
|
133
|
+
*)
|
|
134
|
+
seen="${seen}${root}|"
|
|
135
|
+
printf '%s\n' "$root"
|
|
136
|
+
;;
|
|
137
|
+
esac
|
|
138
|
+
done
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
SAFE_DELETE_OS_TMP_DIRS="$(safe_delete_build_os_tmp_dirs)"
|
|
142
|
+
|
|
143
|
+
safe_delete_is_under_os_tmp_dir() {
|
|
144
|
+
local abs
|
|
145
|
+
abs="$(safe_delete_normalize_path "$(safe_delete_abs_path "$1")")"
|
|
146
|
+
while IFS= read -r tmp_dir; do
|
|
147
|
+
[ -n "$tmp_dir" ] || continue
|
|
148
|
+
case "$abs" in
|
|
149
|
+
"$tmp_dir"/*) return 0 ;;
|
|
150
|
+
esac
|
|
151
|
+
done <<EOF
|
|
152
|
+
$SAFE_DELETE_OS_TMP_DIRS
|
|
153
|
+
EOF
|
|
154
|
+
return 1
|
|
155
|
+
}
|
|
156
|
+
|
|
53
157
|
# ---- platform-specific trash helpers -----------------------------------------
|
|
54
158
|
|
|
55
159
|
trash_darwin() {
|
|
@@ -260,11 +364,8 @@ trash_one() {
|
|
|
260
364
|
|
|
261
365
|
try_trash() {
|
|
262
366
|
local p="$1"
|
|
263
|
-
local abs
|
|
264
|
-
|
|
265
|
-
/*|[A-Za-z]:/*) ;;
|
|
266
|
-
*) abs="$PWD/$abs" ;;
|
|
267
|
-
esac
|
|
367
|
+
local abs
|
|
368
|
+
abs="$(safe_delete_abs_path "$p")"
|
|
268
369
|
if trash_one "$p"; then
|
|
269
370
|
safe_delete_record_trash "$abs"
|
|
270
371
|
return 0
|
|
@@ -329,6 +430,7 @@ safe_delete_rm() {
|
|
|
329
430
|
fi
|
|
330
431
|
|
|
331
432
|
local _exit=0
|
|
433
|
+
local trash_targets=()
|
|
332
434
|
local p
|
|
333
435
|
for p in "${targets[@]}"; do
|
|
334
436
|
if [ -e "$p" ] || [ -L "$p" ]; then
|
|
@@ -344,9 +446,7 @@ safe_delete_rm() {
|
|
|
344
446
|
continue
|
|
345
447
|
fi
|
|
346
448
|
fi
|
|
347
|
-
|
|
348
|
-
_exit=1
|
|
349
|
-
fi
|
|
449
|
+
trash_targets+=("$p")
|
|
350
450
|
elif $force; then
|
|
351
451
|
# -f: silently skip non-existent files (match real rm behavior)
|
|
352
452
|
:
|
|
@@ -356,6 +456,22 @@ safe_delete_rm() {
|
|
|
356
456
|
_exit=1
|
|
357
457
|
fi
|
|
358
458
|
done
|
|
459
|
+
if ! safe_delete_bulk_guard_check "${trash_targets[@]}"; then
|
|
460
|
+
return 1
|
|
461
|
+
fi
|
|
462
|
+
for p in "${trash_targets[@]}"; do
|
|
463
|
+
if safe_delete_is_under_os_tmp_dir "$p"; then
|
|
464
|
+
local native_args=()
|
|
465
|
+
$force && native_args+=("-f")
|
|
466
|
+
$recursive && native_args+=("-r")
|
|
467
|
+
$allow_dir && native_args+=("-d")
|
|
468
|
+
if ! "$REAL_RM" "${native_args[@]}" -- "$p"; then
|
|
469
|
+
_exit=1
|
|
470
|
+
fi
|
|
471
|
+
elif ! try_trash "$p"; then
|
|
472
|
+
_exit=1
|
|
473
|
+
fi
|
|
474
|
+
done
|
|
359
475
|
return $_exit
|
|
360
476
|
}
|
|
361
477
|
|
|
@@ -390,6 +506,14 @@ safe_delete_unlink() {
|
|
|
390
506
|
return 1
|
|
391
507
|
fi
|
|
392
508
|
|
|
509
|
+
if ! safe_delete_bulk_guard_check "$target"; then
|
|
510
|
+
return 1
|
|
511
|
+
fi
|
|
512
|
+
if safe_delete_is_under_os_tmp_dir "$target"; then
|
|
513
|
+
"$REAL_UNLINK" -- "$target"
|
|
514
|
+
return $?
|
|
515
|
+
fi
|
|
516
|
+
|
|
393
517
|
try_trash "$target"
|
|
394
518
|
return $?
|
|
395
519
|
}
|
|
@@ -427,6 +551,7 @@ safe_delete_rmdir() {
|
|
|
427
551
|
fi
|
|
428
552
|
|
|
429
553
|
local _exit=0
|
|
554
|
+
local trash_targets=()
|
|
430
555
|
local p
|
|
431
556
|
for p in "${targets[@]}"; do
|
|
432
557
|
if [ ! -e "$p" ] && [ ! -L "$p" ]; then
|
|
@@ -444,7 +569,17 @@ safe_delete_rmdir() {
|
|
|
444
569
|
_exit=1
|
|
445
570
|
continue
|
|
446
571
|
fi
|
|
447
|
-
|
|
572
|
+
trash_targets+=("$p")
|
|
573
|
+
done
|
|
574
|
+
if ! safe_delete_bulk_guard_check "${trash_targets[@]}"; then
|
|
575
|
+
return 1
|
|
576
|
+
fi
|
|
577
|
+
for p in "${trash_targets[@]}"; do
|
|
578
|
+
if safe_delete_is_under_os_tmp_dir "$p"; then
|
|
579
|
+
if ! "$REAL_RMDIR" -- "$p"; then
|
|
580
|
+
_exit=1
|
|
581
|
+
fi
|
|
582
|
+
elif ! try_trash "$p"; then
|
|
448
583
|
_exit=1
|
|
449
584
|
fi
|
|
450
585
|
done
|