@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tencent-ai/codebuddy-code",
3
- "version": "2.109.1",
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": "bd65832d49c4ca8fac14fbf709684cc34f73f9a3",
828
- "date": "2026-06-22T01:24:08.210Z"
827
+ "commit": "368febf4656d2e766c98a193440453fb331e76f9",
828
+ "date": "2026-06-23T12:00:07.090Z"
829
829
  }
@@ -703,6 +703,6 @@
703
703
  }
704
704
  }
705
705
  },
706
- "commit": "bd65832d49c4ca8fac14fbf709684cc34f73f9a3",
707
- "date": "2026-06-22T01:24:08.206Z"
706
+ "commit": "368febf4656d2e766c98a193440453fb331e76f9",
707
+ "date": "2026-06-23T12:00:07.080Z"
708
708
  }
@@ -1106,6 +1106,6 @@
1106
1106
  }
1107
1107
  }
1108
1108
  },
1109
- "commit": "bd65832d49c4ca8fac14fbf709684cc34f73f9a3",
1110
- "date": "2026-06-22T01:24:08.207Z"
1109
+ "commit": "368febf4656d2e766c98a193440453fb331e76f9",
1110
+ "date": "2026-06-23T12:00:07.090Z"
1111
1111
  }
package/cli/product.json CHANGED
@@ -1757,6 +1757,6 @@
1757
1757
  "deferLoading": true
1758
1758
  }
1759
1759
  ],
1760
- "commit": "bd65832d49c4ca8fac14fbf709684cc34f73f9a3",
1761
- "date": "2026-06-22T01:24:08.211Z"
1760
+ "commit": "368febf4656d2e766c98a193440453fb331e76f9",
1761
+ "date": "2026-06-23T12:00:07.089Z"
1762
1762
  }
@@ -339,6 +339,6 @@
339
339
  "ScheduledTasks": true,
340
340
  "SkipToolCallSupportCheck": true
341
341
  },
342
- "commit": "bd65832d49c4ca8fac14fbf709684cc34f73f9a3",
343
- "date": "2026-06-22T01:24:08.207Z"
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="$p"
264
- case "$abs" in
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
- if ! try_trash "$p"; then
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
- if ! try_trash "$p"; then
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