deepseeker-code 1.0.65 → 1.0.66

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +60 -12
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -1353,6 +1353,7 @@ sync\uFF08\u591A\u5165\u53E3\u6D41\u6C34\u7EBF\uFF0C\u628A GitHub/GitLab label i
1353
1353
  baselineProbePass: "\u{1F9EA} \u57FA\u7EBF\u63A2\u6D4B\u901A\u8FC7\uFF0C\u6062\u590D\u5E72\u51C0\u6811\u540E\u8FDB agent \u9636\u6BB5",
1354
1354
  testFilesH: "## \u89E6\u78B0\u7684\u6D4B\u8BD5\u6587\u4EF6\uFF08\u4FE1\u606F\u6807\u6CE8\uFF09",
1355
1355
  testFilesNote: (n) => `\u672C\u6B21 diff \u89E6\u78B0 ${n} \u4E2A\u6D4B\u8BD5\u8DEF\u5F84\uFF08P1 \u4EC5\u4FE1\u606F\u6807\u6CE8\uFF0C\u4E0D\u53C2\u4E0E\u72B6\u6001\u5224\u5B9A\uFF09\uFF1A`,
1356
+ changedMore: (n) => `\u2026\uFF08\u5176\u4F59 ${n} \u4E2A\u7565\uFF09`,
1356
1357
  artifactLine: (p, branch) => ` \u4EA7\u7269\uFF1A${p}\uFF08\u5206\u652F ${branch}\uFF0C\u5DF2\u63D0\u4EA4\uFF0C\u4FDD\u7559\u5F85\u4EBA\u5DE5\u5904\u7F6E\uFF09`,
1357
1358
  inWindowNow: (hhmm) => `\u23F0 \u5F53\u524D ${hhmm} \u5DF2\u5728\u7A97\u53E3\u5185\uFF0C\u7ACB\u5373\u5F00\u8DD1\u3002`,
1358
1359
  waitWindowWait: (h, m) => `\u23F0 --wait-window\uFF1A${h} \u5C0F\u65F6 ${m} \u5206\u540E\uFF08\u7A97\u53E3\u8D77\u70B9\uFF09\u5F00\u8DD1\u3002\u6302\u673A\u7B49\u5F85\u4E2D\uFF0CCtrl+C \u53EF\u53D6\u6D88\u3002`,
@@ -1523,6 +1524,7 @@ sync (multi-entry pipeline \u2014 pull labeled GitHub/GitLab issues into local t
1523
1524
  baselineProbePass: "\u{1F9EA} baseline probe passed; restoring the clean tree, entering the agent phase",
1524
1525
  testFilesH: "## Touched test files (informational)",
1525
1526
  testFilesNote: (n) => `This diff touches ${n} test paths (P1: informational only, not part of status judgment):`,
1527
+ changedMore: (n) => `...(and ${n} more)`,
1526
1528
  artifactLine: (p, branch) => ` Artifact: ${p} (branch ${branch}, committed, kept for manual handling)`,
1527
1529
  inWindowNow: (hhmm) => `\u23F0 It's ${hhmm}, already inside the window \u2014 starting now.`,
1528
1530
  waitWindowWait: (h, m) => `\u23F0 --wait-window: starting in ${h}h ${m}m (at the window start). Waiting \u2014 Ctrl+C to cancel.`,
@@ -1617,6 +1619,7 @@ var init_config2 = __esm({
1617
1619
  badTokenEnv: (v) => `gitlab.tokenEnv \u975E\u6CD5\uFF08"${v}"\uFF09\uFF1A\u987B\u662F\u73AF\u5883\u53D8\u91CF\u540D\uFF08\u5927\u5199\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF\uFF09\u2014\u2014\u4E0D\u8981\u628A token \u672C\u4F53\u5199\u8FDB\u6587\u4EF6\uFF08sync.json \u8BBE\u8BA1\u4E3A\u53EF\u63D0\u4EA4\uFF0C\xA73.2\uFF09\u3002`,
1618
1620
  tokenLooksReal: "gitlab.tokenEnv \u7684\u503C\u50CF token \u672C\u4F53\uFF08glpat-/ghp_/github_pat_ \u524D\u7F00\uFF09\uFF1A\u8FD9\u91CC\u53EA\u6536\u73AF\u5883\u53D8\u91CF\u3010\u540D\u3011\uFF0Ctoken \u653E\u73AF\u5883\u53D8\u91CF\u91CC\u3002",
1619
1621
  badDefaultAccept: (v) => `defaultAccept \u975E\u6CD5\uFF08${v}\uFF09\uFF1A\u987B\u4E3A\u975E\u7A7A\u5355\u884C shell \u547D\u4EE4\u5B57\u7B26\u4E32\u3002`,
1622
+ badDefaultSetup: (v) => `defaultSetup \u975E\u6CD5\uFF08${v}\uFF09\uFF1A\u987B\u4E3A\u975E\u7A7A\u5355\u884C shell \u547D\u4EE4\u5B57\u7B26\u4E32\u3002`,
1620
1623
  badBudget: (v) => `defaultBudgetYuan \u975E\u6CD5\uFF08${v}\uFF09\uFF1A\u987B\u4E3A\u6B63\u6570\uFF08\u5143\uFF09\u3002`,
1621
1624
  badMaxPerDay: (v) => `maxTicketsPerDay \u975E\u6CD5\uFF08${v}\uFF09\uFF1A\u987B\u4E3A\u6B63\u6574\u6570\u3002`,
1622
1625
  badBool: (k, v) => `${k} \u975E\u6CD5\uFF08${v}\uFF09\uFF1A\u987B\u4E3A true \u6216 false\u3002`,
@@ -1638,6 +1641,7 @@ var init_config2 = __esm({
1638
1641
  badTokenEnv: (v) => `Invalid gitlab.tokenEnv ("${v}"): must be an environment variable NAME (A-Z/0-9/_) \u2014 never the token itself (sync.json is designed to be committable).`,
1639
1642
  tokenLooksReal: "gitlab.tokenEnv looks like a real token (glpat-/ghp_/github_pat_ prefix): only the env var NAME goes here; the token lives in the environment.",
1640
1643
  badDefaultAccept: (v) => `Invalid defaultAccept (${v}): must be a non-empty single-line shell command string.`,
1644
+ badDefaultSetup: (v) => `Invalid defaultSetup (${v}): must be a non-empty single-line shell command string.`,
1641
1645
  badBudget: (v) => `Invalid defaultBudgetYuan (${v}): must be a positive number (yuan).`,
1642
1646
  badMaxPerDay: (v) => `Invalid maxTicketsPerDay (${v}): must be a positive integer.`,
1643
1647
  badBool: (k, v) => `Invalid ${k} (${v}): must be true or false.`,
@@ -1652,7 +1656,7 @@ var init_config2 = __esm({
1652
1656
  return typeof v === "function" ? v(...args) : v;
1653
1657
  };
1654
1658
  SYNC_CONFIG_PATH = () => path7.join(batchQueueRoot(), "sync.json");
1655
- ALLOWED_KEYS = ["github", "gitlab", "defaultAccept", "defaultBudgetYuan", "maxTicketsPerDay", "allowExternalAccept", "authorAllowlist", "blockedKeywords", "maxBodyLength", "testPathPatterns"].join(", ");
1659
+ ALLOWED_KEYS = ["github", "gitlab", "defaultAccept", "defaultSetup", "defaultBudgetYuan", "maxTicketsPerDay", "allowExternalAccept", "authorAllowlist", "blockedKeywords", "maxBodyLength", "testPathPatterns"].join(", ");
1656
1660
  REPO_SHAPE = /^[\w.-]+\/[\w.-]+$/;
1657
1661
  ENV_NAME_SHAPE = /^[A-Z_][A-Z0-9_]*$/i;
1658
1662
  TOKEN_SHAPE = /glpat-|ghp_|github_pat_|gho_/;
@@ -1703,7 +1707,7 @@ var init_config2 = __esm({
1703
1707
  if (TOKEN_SHAPE.test(gl.tokenEnv)) return { ok: false, error: cfgMsg(locale2, "tokenLooksReal") };
1704
1708
  config.gitlab = { baseUrl: gl.baseUrl, projects: gl.projects, label: gl.label, tokenEnv: gl.tokenEnv };
1705
1709
  }
1706
- if (config.github === void 0 && config.gitlab === void 0) {
1710
+ if (config.github === void 0 && config.gitlab === void 0 && !opts?.allowNoSource) {
1707
1711
  return { ok: false, error: cfgMsg(locale2, "noSource") };
1708
1712
  }
1709
1713
  if (obj.defaultAccept !== void 0) {
@@ -1712,6 +1716,12 @@ var init_config2 = __esm({
1712
1716
  }
1713
1717
  config.defaultAccept = obj.defaultAccept.trim();
1714
1718
  }
1719
+ if (obj.defaultSetup !== void 0) {
1720
+ if (!isStr(obj.defaultSetup) || !obj.defaultSetup.trim() || /\r|\n/.test(obj.defaultSetup)) {
1721
+ return { ok: false, error: cfgMsg(locale2, "badDefaultSetup", JSON.stringify(obj.defaultSetup)) };
1722
+ }
1723
+ config.defaultSetup = obj.defaultSetup.trim();
1724
+ }
1715
1725
  if (obj.defaultBudgetYuan !== void 0) {
1716
1726
  const n = Number(obj.defaultBudgetYuan);
1717
1727
  if (!Number.isFinite(n) || n <= 0) return { ok: false, error: cfgMsg(locale2, "badBudget", String(obj.defaultBudgetYuan)) };
@@ -2033,6 +2043,8 @@ var init_strings2 = __esm({
2033
2043
  chkCfgOk: "\u914D\u7F6E\u5408\u6CD5\uFF08sync.json\uFF09",
2034
2044
  chkCfgFail: (e) => `\u914D\u7F6E\u975E\u6CD5\uFF1A${e}`,
2035
2045
  fixCfg: "\u628A sync.json.example \u590D\u5236\u4E3A <\u9879\u76EE>/.deepseeker-code/batch/sync.json \u5E76\u6309\u9700\u4FEE\u6539\uFF08GitHub \u6E90\u4E24\u884C\u5373\u53EF\uFF09",
2046
+ chkSetupMissing: "defaultSetup \u672A\u914D\u7F6E\uFF08\u975E\u963B\u65AD\uFF09\u2014\u2014\u9700\u88C5\u4F9D\u8D56\u7684\u4ED3\u5E93\u5EFA\u8BAE\u914D\u7F6E\uFF0C\u5426\u5219\u5EFA\u51FA\u7684\u7968\u4F1A\u56E0\u73AF\u5883\u7F3A\u5931\u88AB\u7F13\u5B58\u6210 baseline-broken\uFF08\u5F53\u665A\u7A7A\u8F6C\uFF09",
2047
+ fixSetup: '\u5728 sync.json \u52A0 "defaultSetup": "pnpm install"\uFF08\u6216\u8BE5\u4ED3\u5E93\u7684\u5B9E\u9645\u73AF\u5883\u51C6\u5907\u547D\u4EE4\uFF09',
2036
2048
  chkGhAuthOk: "gh \u5DF2\u5B89\u88C5\u4E14\u5DF2\u767B\u5F55",
2037
2049
  chkGhAuthFail: (why) => `gh \u4E0D\u53EF\u7528\u6216\u672A\u767B\u5F55\uFF08${why}\uFF09`,
2038
2050
  fixGhAuth: "\u5B89\u88C5 gh\uFF08https://cli.github.com\uFF09\u540E\u6267\u884C gh auth login\uFF1B\u6216\u8BBE GH_TOKEN \u73AF\u5883\u53D8\u91CF",
@@ -2092,6 +2104,8 @@ var init_strings2 = __esm({
2092
2104
  chkCfgOk: "Config valid (sync.json)",
2093
2105
  chkCfgFail: (e) => `Config invalid: ${e}`,
2094
2106
  fixCfg: "Copy sync.json.example to <project>/.deepseeker-code/batch/sync.json and adjust (two lines for a GitHub source)",
2107
+ chkSetupMissing: "defaultSetup not configured (non-blocking) \u2014 recommended for repos that need dependency setup, otherwise tickets fail the baseline probe and get cached as baseline-broken (idle all night)",
2108
+ fixSetup: `Add "defaultSetup": "pnpm install" to sync.json (or the repo's actual setup command)`,
2095
2109
  chkGhAuthOk: "gh installed and logged in",
2096
2110
  chkGhAuthFail: (why) => `gh unavailable or not logged in (${why})`,
2097
2111
  fixGhAuth: "Install gh (https://cli.github.com), run gh auth login; or set the GH_TOKEN environment variable",
@@ -2153,6 +2167,9 @@ var init_doctor = __esm({
2153
2167
  } else {
2154
2168
  items.push({ ok: true, text: M("chkCfgOk") });
2155
2169
  const config = cfg.config;
2170
+ if (config.defaultSetup === void 0) {
2171
+ items.push({ ok: true, text: M("chkSetupMissing"), warn: true, fix: M("fixSetup") });
2172
+ }
2156
2173
  if (config.github) {
2157
2174
  const auth = await exec2("gh", ["auth", "status"]).catch((e) => ({ code: -1, stdout: "", stderr: String(e?.message ?? e) }));
2158
2175
  if (auth.code === 0) {
@@ -2228,11 +2245,12 @@ var init_doctor = __esm({
2228
2245
  }
2229
2246
  }
2230
2247
  for (const it of items) {
2231
- out(`${it.ok ? "\u2713" : "\u2717"} ${it.text}`);
2232
- if (!it.ok && it.fix) out(M("chkFixLine", it.fix));
2248
+ out(`${it.warn ? "\u26A0" : it.ok ? "\u2713" : "\u2717"} ${it.text}`);
2249
+ if ((!it.ok || it.warn) && it.fix) out(M("chkFixLine", it.fix));
2233
2250
  }
2234
2251
  const fails = items.filter((i) => !i.ok).length;
2235
- out(fails === 0 ? M("chkPass", items.length) : M("chkFail", fails, items.length));
2252
+ const hard = items.filter((i) => !i.warn).length;
2253
+ out(fails === 0 ? M("chkPass", hard) : M("chkFail", fails, hard));
2236
2254
  return { ok: fails === 0, items };
2237
2255
  };
2238
2256
  }
@@ -2263,7 +2281,7 @@ ${inner.map(quoteLine).join("\n")}`;
2263
2281
  // ../core/src/batch/continuation.ts
2264
2282
  import fs8 from "fs/promises";
2265
2283
  import path9 from "path";
2266
- var doneTicketPath, findDoneTicketIdBySourceId, continuationBaseBranch, extractPrevReportSummary, buildContinuationTicketSource;
2284
+ var doneTicketPath, findDoneTicketIdBySourceId, continuationBaseBranch, CHANGED_FILE_CAP, CHANGED_MORE_NOTE, extractPrevReportSummary, buildContinuationTicketSource;
2267
2285
  var init_continuation = __esm({
2268
2286
  "../core/src/batch/continuation.ts"() {
2269
2287
  "use strict";
@@ -2292,6 +2310,8 @@ var init_continuation = __esm({
2292
2310
  const branch = m?.[1];
2293
2311
  return branch && /^[\w][\w./-]*$/.test(branch) ? branch : null;
2294
2312
  };
2313
+ CHANGED_FILE_CAP = 30;
2314
+ CHANGED_MORE_NOTE = (n) => `\u2026\uFF08\u5176\u4F59 ${n} \u4E2A\u7565\uFF09`;
2295
2315
  extractPrevReportSummary = (report, locale2 = "zh", maxChars = 1200) => {
2296
2316
  if (!report) return locale2 === "zh" ? "\uFF08\u524D\u6B21\u62A5\u544A\u5DF2\u4E0D\u5B58\u5728\u2014\u2014\u5B58\u6863\u53EF\u80FD\u88AB clean \u6E05\u7406\uFF09" : "(previous report unavailable \u2014 archive may have been cleaned)";
2297
2317
  const fm = (key) => {
@@ -2303,6 +2323,12 @@ var init_continuation = __esm({
2303
2323
  `- \u82B1\u8D39 / cost: ${fm("cost-yuan") || "?"} \u5143`,
2304
2324
  `- \u4EA7\u7269\u5206\u652F / branch: ${fm("branch") || "?"}`
2305
2325
  ];
2326
+ const changedAll = [...report.matchAll(/^changed-file:\s*(.+)$/gm)].map((m) => m[1].trim());
2327
+ if (changedAll.length > 0) {
2328
+ const shown = changedAll.slice(0, CHANGED_FILE_CAP);
2329
+ if (changedAll.length > CHANGED_FILE_CAP) shown.push(CHANGED_MORE_NOTE(changedAll.length - CHANGED_FILE_CAP));
2330
+ lines.push("", "\u3010\u524D\u6B21\u6539\u52A8\u6587\u4EF6 / previous changed files\u3011", "", ...shown.map((f) => `- ${f}`));
2331
+ }
2306
2332
  const sec = /^## (?:模型收尾汇报|Model final report)\s*$/m.exec(report);
2307
2333
  if (sec) {
2308
2334
  const rest = report.slice(sec.index + sec[0].length);
@@ -2903,6 +2929,8 @@ ${head}\uFF1A${note}
2903
2929
  "---",
2904
2930
  `title: ${sanitizeTitle(candidate.title)}`,
2905
2931
  `accept: ${acc.accept}`,
2932
+ // defaultSetup(定时时代真缺口):配置了才写 setup 行(未配置不写,手工票/老行为零变化);续修票不走此处(本来继承前票 setup)。
2933
+ config.defaultSetup ? `setup: ${config.defaultSetup}` : null,
2906
2934
  `source: ${candidate.sourceId.split(":")[0]}`,
2907
2935
  candidate.url ? `source-url: ${candidate.url}` : null,
2908
2936
  `source-id: ${candidate.sourceId}`,
@@ -3210,12 +3238,13 @@ var pr_exports = {};
3210
3238
  __export(pr_exports, {
3211
3239
  buildPrBody: () => buildPrBody,
3212
3240
  defaultPrFetch: () => defaultPrFetch,
3241
+ nameStatusToPaths: () => nameStatusToPaths,
3213
3242
  runBatchPr: () => runBatchPr
3214
3243
  });
3215
3244
  import fs13 from "fs/promises";
3216
3245
  import os5 from "os";
3217
3246
  import path14 from "path";
3218
- var defaultPrFetch, PR_MSG, msg3, BRANCH_RE, FILE_LIST_CAP, buildPrBody, runBatchPr;
3247
+ var defaultPrFetch, PR_MSG, msg3, BRANCH_RE, FILE_LIST_CAP, nameStatusToPaths, buildPrBody, runBatchPr;
3219
3248
  var init_pr = __esm({
3220
3249
  "../core/src/batch/pr.ts"() {
3221
3250
  "use strict";
@@ -3316,6 +3345,7 @@ You can open the MR on the web: branch agent/<ticket-id> is on the remote.`,
3316
3345
  };
3317
3346
  BRANCH_RE = /^[\w][\w./-]*$/;
3318
3347
  FILE_LIST_CAP = 20;
3348
+ nameStatusToPaths = (rows) => rows.map((line) => line.split(/\t/).pop() ?? line).filter(Boolean);
3319
3349
  buildPrBody = (args) => {
3320
3350
  const lines = [
3321
3351
  `## ${args.title}`,
@@ -3452,13 +3482,14 @@ ${mt.stderr}`.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.includes("CONF
3452
3482
  out(M("conflictBlock", conflicts.join("\n")));
3453
3483
  return fail(M("conflictShort"));
3454
3484
  }
3455
- const nst = await g(["diff", "--name-status", `${mergeBase}..${branch}`]);
3485
+ const nst = await g(["-c", "core.quotepath=false", "diff", "--name-status", `${mergeBase}..${branch}`]);
3456
3486
  const shortstat = await g(["diff", "--shortstat", `${mergeBase}..${branch}`]);
3457
3487
  const files = nst.code === 0 ? nst.stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean) : [];
3458
3488
  out(M("reviewHeader", files.length));
3459
3489
  for (const f of files.slice(0, FILE_LIST_CAP)) out(` ${f}`);
3460
3490
  if (files.length > FILE_LIST_CAP) out(` ${M("moreFiles", files.length - FILE_LIST_CAP)}`);
3461
3491
  if (shortstat.code === 0 && shortstat.stdout.trim()) out(` ${shortstat.stdout.trim()}`);
3492
+ const filePaths = nameStatusToPaths(files);
3462
3493
  const bodyTmp = path14.join(os5.tmpdir(), `dsc-pr-body-${process.pid}-${Math.random().toString(36).slice(2, 8)}.md`);
3463
3494
  try {
3464
3495
  await fs13.writeFile(bodyTmp, buildPrBody({
@@ -3466,7 +3497,7 @@ ${mt.stderr}`.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.includes("CONF
3466
3497
  title: ticket.title,
3467
3498
  status,
3468
3499
  costYuan: fm("cost-yuan") || "0",
3469
- files,
3500
+ files: filePaths,
3470
3501
  issueNumber: gh ? Number(gh[2]) : void 0
3471
3502
  }), "utf-8");
3472
3503
  const pushBranch = `agent/${ticketId}`;
@@ -22833,13 +22864,14 @@ ${args.trajectory}`;
22833
22864
  var batchRunner_exports = {};
22834
22865
  __export(batchRunner_exports, {
22835
22866
  buildReport: () => buildReport,
22867
+ numstatToChangedFiles: () => numstatToChangedFiles,
22836
22868
  parseWaitWindow: () => parseWaitWindow,
22837
22869
  runBatchQueue: () => runBatchQueue
22838
22870
  });
22839
22871
  import fs60 from "fs";
22840
22872
  import path60 from "path";
22841
22873
  import { spawn as spawn8 } from "child_process";
22842
- var BATCH_EDIT_TOOLS, BATCH_DEFAULT_DENYLIST, ACCEPT_TIMEOUT_MIN, ACCEPT_TAIL_LINES, emit2, ts, runAcceptCommand, extraTestPatterns, gitSimple, mainRepoRootOf, touchedTestFiles, collectSessionCost, commitText, buildWatchdogLines, buildReport, runOneTask, parseWaitWindow, nowMinutes, sleep, waitUntilWindow, runBatchQueue;
22874
+ var BATCH_EDIT_TOOLS, BATCH_DEFAULT_DENYLIST, ACCEPT_TIMEOUT_MIN, ACCEPT_TAIL_LINES, emit2, ts, runAcceptCommand, extraTestPatterns, gitSimple, mainRepoRootOf, touchedTestFiles, CHANGED_FILE_CAP2, numstatToChangedFiles, collectSessionCost, commitText, buildWatchdogLines, buildReport, runOneTask, parseWaitWindow, nowMinutes, sleep, waitUntilWindow, runBatchQueue;
22843
22875
  var init_batchRunner = __esm({
22844
22876
  "src/batchRunner.ts"() {
22845
22877
  "use strict";
@@ -22931,6 +22963,15 @@ ${lines.slice(-ACCEPT_TAIL_LINES).join("\n")}` : text;
22931
22963
  if (!out) return [];
22932
22964
  return out.split("\n").map((s) => s.trim()).filter(Boolean).filter((f) => isTestPath(f, extraTestPatterns));
22933
22965
  };
22966
+ CHANGED_FILE_CAP2 = 30;
22967
+ numstatToChangedFiles = (raw) => raw.split("\n").map((l) => l.trim()).filter(Boolean).map((line) => {
22968
+ const cols = line.split(" ");
22969
+ const file = cols.pop() ?? "?";
22970
+ const added = cols[0] ?? "-";
22971
+ const removed = cols[1] ?? "-";
22972
+ const counts = added === "-" && removed === "-" ? "(binary)" : `(+${added}/-${removed})`;
22973
+ return `${file} ${counts}`;
22974
+ });
22934
22975
  collectSessionCost = async (sessionId) => {
22935
22976
  const recs = (await readUsageRecords(2)).filter((r) => r.sessionId === sessionId || r.sessionId.startsWith(sessionId + "__sub__"));
22936
22977
  const c = { rounds: 0, mainRounds: 0, subRuns: 0, promptTokens: 0, completionTokens: 0, cachedTokens: 0, costYuan: null, toolCostYuan: 0, auxCostYuan: 0, partialPrice: false, durationMs: 0 };
@@ -22995,6 +23036,10 @@ ${T.testFilesH}
22995
23036
  ${T.testFilesNote(args.touchedTestFiles.length)}
22996
23037
  ${args.touchedTestFiles.map((f) => `- \`${f}\``).join("\n")}
22997
23038
  ` : "";
23039
+ const changed = args.changedFiles ?? [];
23040
+ const changedFm = changed.length === 0 ? "" : changed.slice(0, CHANGED_FILE_CAP2).map((f) => `changed-file: ${f}
23041
+ `).join("") + (changed.length > CHANGED_FILE_CAP2 ? `changed-file: ${T.changedMore(changed.length - CHANGED_FILE_CAP2)}
23042
+ ` : "");
22998
23043
  return `---
22999
23044
  id: ${id}
23000
23045
  title: ${ticket.title}
@@ -23006,7 +23051,7 @@ ${ticket.needsReview ? "needs-review: true\n" : ""}session: batch-${id}
23006
23051
  worktree: ${wt?.path ?? T.notCreated}
23007
23052
  branch: ${wt?.branch ?? T.notCreated}
23008
23053
  ${ticket.continues ? `continues: ${ticket.continues}
23009
- ` : ""}---
23054
+ ` : ""}${changedFm}---
23010
23055
 
23011
23056
  ${T.reportTitle(ticket.title)}
23012
23057
 
@@ -23407,6 +23452,8 @@ ${s.output}
23407
23452
  else if (commit.error) emit2(T.commitFail(commit.error));
23408
23453
  const diff = await harvestDiff(wt);
23409
23454
  const touched = await touchedTestFiles(wt.path, wt.baseSha);
23455
+ const changedNumstat = await gitSimple(["-c", "core.quotepath=false", "diff", "--cached", "--numstat", wt.baseSha], wt.path);
23456
+ const changedFiles = changedNumstat ? numstatToChangedFiles(changedNumstat) : void 0;
23410
23457
  let downgraded = false;
23411
23458
  if (status === "passed" && touched.length > 0 && !t.needsReview) {
23412
23459
  t.needsReview = true;
@@ -23429,7 +23476,8 @@ ${s.output}
23429
23476
  errorMessage: agentError,
23430
23477
  watchdogLines: buildWatchdogLines(wdSnapshots, cost.costYuan) ?? void 0,
23431
23478
  touchedTestFiles: touched.length > 0 ? touched : void 0,
23432
- imagesRead
23479
+ imagesRead,
23480
+ changedFiles
23433
23481
  }));
23434
23482
  if (downgraded) {
23435
23483
  await markTicketNeedsReview(doneTicketPath(task.id)).catch(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepseeker-code",
3
- "version": "1.0.65",
3
+ "version": "1.0.66",
4
4
  "description": "DeepSeeker-Code 终端客户端(React Ink,in-process 直驱 runAgent)",
5
5
  "homepage": "https://github.com/xknk/deepSeekCode#readme",
6
6
  "repository": {