@xdevops/issue-auto-finish 1.0.92 → 1.0.93

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 (41) hide show
  1. package/dist/{PtyRunner-NYASBTRP.js → PtyRunner-XMWDMH3L.js} +4 -2
  2. package/dist/ai-runner/DialogClassifier.d.ts +44 -0
  3. package/dist/ai-runner/DialogClassifier.d.ts.map +1 -0
  4. package/dist/ai-runner/PtyRunner.d.ts +17 -0
  5. package/dist/ai-runner/PtyRunner.d.ts.map +1 -1
  6. package/dist/{ai-runner-TOHVJJ76.js → ai-runner-S2ATTGWX.js} +2 -2
  7. package/dist/{analyze-DBH4K3J7.js → analyze-DAVYPBHK.js} +2 -2
  8. package/dist/{braindump-RYI4BGMG.js → braindump-A4R3A4QT.js} +2 -2
  9. package/dist/{chunk-ENF24C44.js → chunk-2XACBKPB.js} +2 -2
  10. package/dist/{chunk-6T7ZHAV2.js → chunk-BPVRMZU4.js} +9 -9
  11. package/dist/{chunk-4XMYOXGZ.js → chunk-HD6V7KPE.js} +878 -67
  12. package/dist/chunk-HD6V7KPE.js.map +1 -0
  13. package/dist/{chunk-WZGEYHCC.js → chunk-OPWP73PW.js} +271 -716
  14. package/dist/chunk-OPWP73PW.js.map +1 -0
  15. package/dist/{chunk-2WDVTLVF.js → chunk-SNSEW7DS.js} +1 -1
  16. package/dist/cli.js +5 -5
  17. package/dist/hooks/HookInjector.d.ts +14 -0
  18. package/dist/hooks/HookInjector.d.ts.map +1 -1
  19. package/dist/index.js +4 -4
  20. package/dist/{init-UKTP7LXS.js → init-OD7CLRWK.js} +2 -2
  21. package/dist/lib.js +2 -2
  22. package/dist/{restart-5D3ZDD5L.js → restart-JVVOYC6C.js} +2 -2
  23. package/dist/run.js +4 -4
  24. package/dist/{start-IQBNXLEI.js → start-INU24RRG.js} +2 -2
  25. package/package.json +1 -1
  26. package/src/web/frontend/dist/assets/index-BrvoaFSK.css +1 -0
  27. package/src/web/frontend/dist/assets/{index-BR0UoQER.js → index-CmyxgdS_.js} +54 -54
  28. package/src/web/frontend/dist/index.html +2 -2
  29. package/dist/chunk-4XMYOXGZ.js.map +0 -1
  30. package/dist/chunk-WZGEYHCC.js.map +0 -1
  31. package/src/web/frontend/dist/assets/index-DWOHf3bd.css +0 -1
  32. /package/dist/{PtyRunner-NYASBTRP.js.map → PtyRunner-XMWDMH3L.js.map} +0 -0
  33. /package/dist/{ai-runner-TOHVJJ76.js.map → ai-runner-S2ATTGWX.js.map} +0 -0
  34. /package/dist/{analyze-DBH4K3J7.js.map → analyze-DAVYPBHK.js.map} +0 -0
  35. /package/dist/{braindump-RYI4BGMG.js.map → braindump-A4R3A4QT.js.map} +0 -0
  36. /package/dist/{chunk-ENF24C44.js.map → chunk-2XACBKPB.js.map} +0 -0
  37. /package/dist/{chunk-6T7ZHAV2.js.map → chunk-BPVRMZU4.js.map} +0 -0
  38. /package/dist/{chunk-2WDVTLVF.js.map → chunk-SNSEW7DS.js.map} +0 -0
  39. /package/dist/{init-UKTP7LXS.js.map → init-OD7CLRWK.js.map} +0 -0
  40. /package/dist/{restart-5D3ZDD5L.js.map → restart-JVVOYC6C.js.map} +0 -0
  41. /package/dist/{start-IQBNXLEI.js.map → start-INU24RRG.js.map} +0 -0
@@ -18,6 +18,9 @@ import {
18
18
  rePlanPrompt,
19
19
  verifyPrompt
20
20
  } from "./chunk-GPZX4DSY.js";
21
+ import {
22
+ HookInjector
23
+ } from "./chunk-HD6V7KPE.js";
21
24
  import {
22
25
  getProjectKnowledge
23
26
  } from "./chunk-ACVOOHAR.js";
@@ -233,8 +236,8 @@ var GongfengClient = class {
233
236
  const encoded = encodeURIComponent(this.projectPath);
234
237
  return `${this.apiUrl}/api/v3/projects/${encoded}`;
235
238
  }
236
- async requestRaw(path13, options = {}) {
237
- const url = `${this.projectApiBase}${path13}`;
239
+ async requestRaw(path12, options = {}) {
240
+ const url = `${this.projectApiBase}${path12}`;
238
241
  logger4.debug("API request", { method: options.method || "GET", url });
239
242
  return this.circuitBreaker.execute(
240
243
  () => this.retryPolicy.execute(async () => {
@@ -251,11 +254,11 @@ var GongfengClient = class {
251
254
  throw new GongfengApiError(resp.status, `Gongfeng API error ${resp.status}: ${body}`, body);
252
255
  }
253
256
  return resp;
254
- }, `requestRaw ${options.method || "GET"} ${path13}`)
257
+ }, `requestRaw ${options.method || "GET"} ${path12}`)
255
258
  );
256
259
  }
257
- async request(path13, options = {}) {
258
- const resp = await this.requestRaw(path13, options);
260
+ async request(path12, options = {}) {
261
+ const resp = await this.requestRaw(path12, options);
259
262
  return resp.json();
260
263
  }
261
264
  async createIssue(title, description, labels) {
@@ -434,8 +437,8 @@ var GongfengClient = class {
434
437
  }
435
438
  return mr;
436
439
  }
437
- async requestGlobal(path13, options = {}) {
438
- const url = `${this.apiUrl}${path13}`;
440
+ async requestGlobal(path12, options = {}) {
441
+ const url = `${this.apiUrl}${path12}`;
439
442
  logger4.debug("API request (global)", { method: options.method || "GET", url });
440
443
  const resp = await this.circuitBreaker.execute(
441
444
  () => this.retryPolicy.execute(async () => {
@@ -452,7 +455,7 @@ var GongfengClient = class {
452
455
  throw new GongfengApiError(r.status, `Gongfeng API error ${r.status}: ${body}`, body);
453
456
  }
454
457
  return r;
455
- }, `requestGlobal ${options.method || "GET"} ${path13}`)
458
+ }, `requestGlobal ${options.method || "GET"} ${path12}`)
456
459
  );
457
460
  return resp.json();
458
461
  }
@@ -1646,7 +1649,7 @@ var PlanPersistence = class _PlanPersistence {
1646
1649
  };
1647
1650
 
1648
1651
  // src/phases/BasePhase.ts
1649
- import path5 from "path";
1652
+ import path4 from "path";
1650
1653
 
1651
1654
  // src/rules/RuleResolver.ts
1652
1655
  import { readdir, readFile } from "fs/promises";
@@ -1743,454 +1746,6 @@ ${rule.content}`;
1743
1746
  }
1744
1747
  };
1745
1748
 
1746
- // src/hooks/HookInjector.ts
1747
- import fs3 from "fs";
1748
- import path4 from "path";
1749
- var logger7 = logger.child("HookInjector");
1750
- var HOOKS_DIR = ".claude-plan/.hooks";
1751
- var EVENTS_FILE_NAME = ".hook-events.jsonl";
1752
- var MANIFEST_FILE_NAME = ".artifact-manifest.jsonl";
1753
- var CONTEXT_FILE_NAME = ".hook-context.json";
1754
- var HookInjector = class {
1755
- inject(ctx) {
1756
- this.writeHookScripts(ctx);
1757
- this.writeContextFile(ctx);
1758
- this.writeSettingsLocal(ctx);
1759
- this.initEventsFile(ctx);
1760
- logger7.info("Hooks injected", {
1761
- workDir: ctx.workDir,
1762
- issueIid: ctx.issueIid,
1763
- phase: ctx.phaseName,
1764
- artifacts: ctx.expectedArtifacts
1765
- });
1766
- }
1767
- /**
1768
- * 阶段切换时更新 hooks 配置(重写脚本 + settings.local.json)。
1769
- * 保留 events/manifest 文件(不截断),仅更新脚本和配置。
1770
- */
1771
- updateForPhase(ctx) {
1772
- this.writeHookScripts(ctx);
1773
- this.writeContextFile(ctx);
1774
- this.writeSettingsLocal(ctx);
1775
- logger7.info("Hooks updated for phase", {
1776
- workDir: ctx.workDir,
1777
- issueIid: ctx.issueIid,
1778
- phase: ctx.phaseName
1779
- });
1780
- }
1781
- readManifest(workDir) {
1782
- const manifestPath = path4.join(workDir, ".claude-plan", MANIFEST_FILE_NAME);
1783
- return readJsonl(manifestPath);
1784
- }
1785
- readEvents(workDir) {
1786
- const eventsPath = path4.join(workDir, ".claude-plan", EVENTS_FILE_NAME);
1787
- return readJsonl(eventsPath);
1788
- }
1789
- getEventsFilePath(workDir) {
1790
- return path4.join(workDir, ".claude-plan", EVENTS_FILE_NAME);
1791
- }
1792
- getManifestFilePath(workDir) {
1793
- return path4.join(workDir, ".claude-plan", MANIFEST_FILE_NAME);
1794
- }
1795
- cleanup(workDir) {
1796
- const hooksDir = path4.join(workDir, HOOKS_DIR);
1797
- try {
1798
- if (fs3.existsSync(hooksDir)) {
1799
- fs3.rmSync(hooksDir, { recursive: true });
1800
- }
1801
- } catch (err) {
1802
- logger7.warn("Failed to cleanup hooks", { error: err.message });
1803
- }
1804
- }
1805
- // ---------------------------------------------------------------------------
1806
- // Private
1807
- // ---------------------------------------------------------------------------
1808
- writeHookScripts(ctx) {
1809
- const hooksDir = path4.join(ctx.workDir, HOOKS_DIR);
1810
- fs3.mkdirSync(hooksDir, { recursive: true });
1811
- const eventsFile = path4.join(ctx.workDir, ".claude-plan", EVENTS_FILE_NAME);
1812
- const manifestFile = path4.join(ctx.workDir, ".claude-plan", MANIFEST_FILE_NAME);
1813
- const contextFile = path4.join(ctx.workDir, ".claude-plan", CONTEXT_FILE_NAME);
1814
- const expected = ctx.expectedArtifacts.join(",");
1815
- const phaseExpected = (ctx.phaseExpectedArtifacts ?? ctx.expectedArtifacts).join(",");
1816
- const scripts = [
1817
- { name: "session-start.sh", content: buildSessionStartScript(eventsFile) },
1818
- { name: "compact-restore.sh", content: buildCompactRestoreScript(eventsFile, contextFile) },
1819
- { name: "post-tool-use.sh", content: buildPostToolUseScript(eventsFile, manifestFile, expected) },
1820
- { name: "post-artifact.sh", content: buildPostArtifactScript(manifestFile, expected) },
1821
- { name: "exit-plan-mode.sh", content: buildExitPlanModeScript(eventsFile) },
1822
- { name: "permission.sh", content: buildPermissionScript(eventsFile) },
1823
- { name: "protect-files.sh", content: buildProtectFilesScript(eventsFile, ctx.phaseName, ctx.planDir) },
1824
- { name: "stop.sh", content: buildStopScript(eventsFile, ctx.planDir, phaseExpected) }
1825
- ];
1826
- for (const { name, content } of scripts) {
1827
- const scriptPath = path4.join(hooksDir, name);
1828
- fs3.writeFileSync(scriptPath, content, { mode: 493 });
1829
- }
1830
- }
1831
- writeContextFile(ctx) {
1832
- const contextPath = path4.join(ctx.workDir, ".claude-plan", CONTEXT_FILE_NAME);
1833
- const context = {
1834
- issueIid: ctx.issueIid,
1835
- issueTitle: ctx.issueTitle ?? "",
1836
- issueDescription: ctx.issueDescription ?? "",
1837
- phaseName: ctx.phaseName ?? "",
1838
- expectedArtifacts: ctx.expectedArtifacts,
1839
- planDir: ctx.planDir
1840
- };
1841
- fs3.writeFileSync(contextPath, JSON.stringify(context, null, 2), "utf-8");
1842
- }
1843
- writeSettingsLocal(ctx) {
1844
- const claudeDir = path4.join(ctx.workDir, ".claude");
1845
- fs3.mkdirSync(claudeDir, { recursive: true });
1846
- const settingsPath = path4.join(claudeDir, "settings.local.json");
1847
- let existing = {};
1848
- if (fs3.existsSync(settingsPath)) {
1849
- try {
1850
- existing = JSON.parse(fs3.readFileSync(settingsPath, "utf-8"));
1851
- } catch {
1852
- logger7.warn("Failed to parse existing settings.local.json, overwriting");
1853
- }
1854
- }
1855
- const hooksDir = path4.join(ctx.workDir, HOOKS_DIR);
1856
- const hooks = buildHooksConfig(hooksDir, ctx);
1857
- const merged = { ...existing, hooks };
1858
- fs3.writeFileSync(settingsPath, JSON.stringify(merged, null, 2), "utf-8");
1859
- }
1860
- initEventsFile(ctx) {
1861
- const eventsPath = path4.join(ctx.workDir, ".claude-plan", EVENTS_FILE_NAME);
1862
- const manifestPath = path4.join(ctx.workDir, ".claude-plan", MANIFEST_FILE_NAME);
1863
- fs3.writeFileSync(eventsPath, "", "utf-8");
1864
- fs3.writeFileSync(manifestPath, "", "utf-8");
1865
- }
1866
- };
1867
- function buildHooksConfig(hooksDir, ctx) {
1868
- const isPlanPhase = ctx.phaseName === "plan";
1869
- const artifactIfPatterns = buildArtifactIfPatterns(ctx.expectedArtifacts);
1870
- const config = {
1871
- SessionStart: [
1872
- {
1873
- hooks: [{
1874
- type: "command",
1875
- command: path4.join(hooksDir, "session-start.sh"),
1876
- timeout: 5
1877
- }]
1878
- },
1879
- {
1880
- matcher: "compact",
1881
- hooks: [{
1882
- type: "command",
1883
- command: path4.join(hooksDir, "compact-restore.sh"),
1884
- timeout: 5
1885
- }]
1886
- }
1887
- ],
1888
- PreToolUse: [
1889
- {
1890
- matcher: "Edit|Write",
1891
- hooks: [{
1892
- type: "command",
1893
- command: path4.join(hooksDir, "protect-files.sh"),
1894
- timeout: 5,
1895
- ...buildProtectIfClause(ctx.phaseName)
1896
- }]
1897
- }
1898
- ],
1899
- PostToolUse: buildPostToolUseConfig(hooksDir, artifactIfPatterns),
1900
- PermissionRequest: buildPermissionRequestConfig(hooksDir, isPlanPhase),
1901
- Stop: [{
1902
- hooks: [{
1903
- type: "command",
1904
- command: path4.join(hooksDir, "stop.sh"),
1905
- timeout: 15
1906
- }]
1907
- }]
1908
- };
1909
- return config;
1910
- }
1911
- function buildPermissionRequestConfig(hooksDir, isPlanPhase) {
1912
- const groups = [];
1913
- if (isPlanPhase) {
1914
- groups.push({
1915
- matcher: "ExitPlanMode",
1916
- hooks: [{
1917
- type: "command",
1918
- command: path4.join(hooksDir, "exit-plan-mode.sh"),
1919
- timeout: 5
1920
- }]
1921
- });
1922
- }
1923
- groups.push({
1924
- matcher: "Bash|Edit|Write|Read|Glob|Grep|WebFetch|WebSearch|mcp__.*",
1925
- hooks: [{
1926
- type: "command",
1927
- command: path4.join(hooksDir, "permission.sh"),
1928
- timeout: 5
1929
- }]
1930
- });
1931
- return groups;
1932
- }
1933
- function buildPostToolUseConfig(hooksDir, artifactIfPatterns) {
1934
- const groups = [];
1935
- if (artifactIfPatterns) {
1936
- groups.push({
1937
- matcher: "Write|Edit",
1938
- hooks: [{
1939
- type: "command",
1940
- command: path4.join(hooksDir, "post-artifact.sh"),
1941
- timeout: 10,
1942
- if: artifactIfPatterns
1943
- }]
1944
- });
1945
- }
1946
- groups.push({
1947
- matcher: "Write|Edit",
1948
- hooks: [{
1949
- type: "command",
1950
- command: path4.join(hooksDir, "post-tool-use.sh"),
1951
- timeout: 10
1952
- }]
1953
- });
1954
- return groups;
1955
- }
1956
- function buildArtifactIfPatterns(artifacts) {
1957
- if (artifacts.length === 0) return void 0;
1958
- return artifacts.flatMap((f) => [`Write(*${f})`, `Edit(*${f})`]).join("|");
1959
- }
1960
- function buildProtectIfClause(phaseName) {
1961
- const alwaysProtected = [".env", ".env.*", "package-lock.json", "pnpm-lock.yaml"];
1962
- const patterns = [...alwaysProtected];
1963
- if (phaseName === "build") {
1964
- patterns.push("01-plan.md");
1965
- }
1966
- if (phaseName === "verify") {
1967
- patterns.push("01-plan.md");
1968
- }
1969
- const ifValue = patterns.flatMap((f) => [`Edit(*${f})`, `Write(*${f})`]).join("|");
1970
- return { if: ifValue };
1971
- }
1972
- function buildSessionStartScript(eventsFile) {
1973
- return `#!/bin/bash
1974
- set -euo pipefail
1975
- INPUT=$(cat)
1976
- SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
1977
- printf '{"ts":"%s","event":"session_start","session_id":"%s"}\\n' \\
1978
- "$(date -u +%FT%TZ)" "$SESSION_ID" >> ${quote(eventsFile)}
1979
- exit 0
1980
- `;
1981
- }
1982
- function buildCompactRestoreScript(eventsFile, contextFile) {
1983
- return `#!/bin/bash
1984
- set -euo pipefail
1985
-
1986
- CONTEXT_FILE=${quote(contextFile)}
1987
- if [ ! -f "$CONTEXT_FILE" ]; then
1988
- exit 0
1989
- fi
1990
-
1991
- ISSUE_IID=$(jq -r '.issueIid // empty' < "$CONTEXT_FILE")
1992
- ISSUE_TITLE=$(jq -r '.issueTitle // empty' < "$CONTEXT_FILE")
1993
- ISSUE_DESC=$(jq -r '.issueDescription // empty' < "$CONTEXT_FILE")
1994
- PHASE=$(jq -r '.phaseName // empty' < "$CONTEXT_FILE")
1995
- PLAN_DIR=$(jq -r '.planDir // empty' < "$CONTEXT_FILE")
1996
- ARTIFACTS=$(jq -r '.expectedArtifacts | join(", ") // empty' < "$CONTEXT_FILE")
1997
-
1998
- READY=""
1999
- MISSING=""
2000
- for f in $(jq -r '.expectedArtifacts[]' < "$CONTEXT_FILE" 2>/dev/null); do
2001
- FPATH="$PLAN_DIR/$f"
2002
- if [ -f "$FPATH" ] && [ "$(wc -c < "$FPATH")" -ge 50 ]; then
2003
- READY="$READY $f"
2004
- else
2005
- MISSING="$MISSING $f"
2006
- fi
2007
- done
2008
- READY=$(echo "$READY" | xargs)
2009
- MISSING=$(echo "$MISSING" | xargs)
2010
-
2011
- printf '{"ts":"%s","event":"compact_restore"}\\n' "$(date -u +%FT%TZ)" >> ${quote(eventsFile)}
2012
-
2013
- cat <<CONTEXT
2014
- [\u4E0A\u4E0B\u6587\u6062\u590D \u2014 compaction \u540E\u81EA\u52A8\u6CE8\u5165]
2015
- Issue #$ISSUE_IID: $ISSUE_TITLE
2016
- \u5F53\u524D\u9636\u6BB5: $PHASE
2017
- \u9884\u671F\u4EA7\u7269: $ARTIFACTS
2018
- \u5DF2\u5C31\u7EEA: \${READY:-\u65E0}
2019
- \u672A\u5B8C\u6210: \${MISSING:-\u65E0}
2020
-
2021
- \u9700\u6C42\u63CF\u8FF0:
2022
- $ISSUE_DESC
2023
- CONTEXT
2024
- exit 0
2025
- `;
2026
- }
2027
- function buildPostToolUseScript(eventsFile, manifestFile, expected) {
2028
- return `#!/bin/bash
2029
- set -euo pipefail
2030
- INPUT=$(cat)
2031
- FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
2032
- [ -z "$FILE_PATH" ] && exit 0
2033
-
2034
- EXPECTED=${quote(expected)}
2035
- BASENAME=$(basename "$FILE_PATH")
2036
-
2037
- if echo "$EXPECTED" | tr ',' '\\n' | grep -qx "$BASENAME"; then
2038
- BYTES=$(wc -c < "$FILE_PATH" 2>/dev/null || echo 0)
2039
- printf '{"ts":"%s","event":"artifact_write","file":"%s","path":"%s","bytes":%s}\\n' \\
2040
- "$(date -u +%FT%TZ)" "$BASENAME" "$FILE_PATH" "$BYTES" >> ${quote(manifestFile)}
2041
- fi
2042
-
2043
- printf '{"ts":"%s","event":"artifact_write","file":"%s","path":"%s","bytes":0}\\n' \\
2044
- "$(date -u +%FT%TZ)" "$BASENAME" "$FILE_PATH" >> ${quote(eventsFile)}
2045
- exit 0
2046
- `;
2047
- }
2048
- function buildPostArtifactScript(manifestFile, expected) {
2049
- return `#!/bin/bash
2050
- set -euo pipefail
2051
- INPUT=$(cat)
2052
- FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
2053
- [ -z "$FILE_PATH" ] && exit 0
2054
-
2055
- EXPECTED=${quote(expected)}
2056
- BASENAME=$(basename "$FILE_PATH")
2057
-
2058
- if echo "$EXPECTED" | tr ',' '\\n' | grep -qx "$BASENAME"; then
2059
- BYTES=$(wc -c < "$FILE_PATH" 2>/dev/null || echo 0)
2060
- printf '{"ts":"%s","event":"write","file":"%s","path":"%s","bytes":%s}\\n' \\
2061
- "$(date -u +%FT%TZ)" "$BASENAME" "$FILE_PATH" "$BYTES" >> ${quote(manifestFile)}
2062
- fi
2063
- exit 0
2064
- `;
2065
- }
2066
- function buildExitPlanModeScript(eventsFile) {
2067
- return `#!/bin/bash
2068
- set -euo pipefail
2069
- INPUT=$(cat)
2070
-
2071
- printf '{"ts":"%s","event":"exit_plan_mode"}\\n' "$(date -u +%FT%TZ)" >> ${quote(eventsFile)}
2072
-
2073
- echo '{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow"}}}'
2074
- exit 0
2075
- `;
2076
- }
2077
- function buildPermissionScript(eventsFile) {
2078
- return `#!/bin/bash
2079
- set -euo pipefail
2080
- INPUT=$(cat)
2081
- TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
2082
- printf '{"ts":"%s","event":"permission_request","tool":"%s"}\\n' \\
2083
- "$(date -u +%FT%TZ)" "$TOOL" >> ${quote(eventsFile)}
2084
- echo '{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow"}}}'
2085
- exit 0
2086
- `;
2087
- }
2088
- function buildProtectFilesScript(eventsFile, phaseName, planDir) {
2089
- return `#!/bin/bash
2090
- set -euo pipefail
2091
- INPUT=$(cat)
2092
- TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
2093
- FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
2094
- [ -z "$FILE_PATH" ] && exit 0
2095
-
2096
- BASENAME=$(basename "$FILE_PATH")
2097
- PHASE=${quote(phaseName ?? "")}
2098
-
2099
- blocked_reason() {
2100
- printf '{"ts":"%s","event":"protect_blocked","tool":"%s","file":"%s"}\\n' \\
2101
- "$(date -u +%FT%TZ)" "$TOOL" "$BASENAME" >> ${quote(eventsFile)}
2102
- echo "$1" >&2
2103
- exit 2
2104
- }
2105
-
2106
- case "$BASENAME" in
2107
- .env|.env.*)
2108
- blocked_reason "\u7981\u6B62\u4FEE\u6539\u73AF\u5883\u914D\u7F6E\u6587\u4EF6 $BASENAME\uFF0C\u8BF7\u901A\u8FC7 .env.example \u6216\u6587\u6863\u8BF4\u660E\u914D\u7F6E\u53D8\u66F4\u3002"
2109
- ;;
2110
- package-lock.json|pnpm-lock.yaml)
2111
- blocked_reason "\u7981\u6B62\u76F4\u63A5\u4FEE\u6539\u9501\u6587\u4EF6 $BASENAME\uFF0C\u8BF7\u901A\u8FC7 npm install / pnpm install \u66F4\u65B0\u4F9D\u8D56\u3002"
2112
- ;;
2113
- esac
2114
-
2115
- if [ "$PHASE" = "build" ] || [ "$PHASE" = "verify" ]; then
2116
- case "$BASENAME" in
2117
- 01-plan.md)
2118
- blocked_reason "\u5728 $PHASE \u9636\u6BB5\u7981\u6B62\u4FEE\u6539\u89C4\u5212\u6587\u6863 01-plan.md\uFF0C\u8BE5\u6587\u4EF6\u5728 plan \u9636\u6BB5\u5DF2\u786E\u5B9A\u3002"
2119
- ;;
2120
- esac
2121
- fi
2122
-
2123
- exit 0
2124
- `;
2125
- }
2126
- function buildStopScript(eventsFile, planDir, phaseExpected) {
2127
- return `#!/bin/bash
2128
- set -euo pipefail
2129
- INPUT=$(cat)
2130
- STOP_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false')
2131
-
2132
- PLAN_DIR=${quote(planDir)}
2133
- MIN_BYTES=50
2134
- PHASE_EXPECTED=${quote(phaseExpected)}
2135
-
2136
- MISSING=""
2137
- READY=""
2138
- for f in $(echo "$PHASE_EXPECTED" | tr ',' ' '); do
2139
- [ -z "$f" ] && continue
2140
- FPATH="$PLAN_DIR/$f"
2141
- if [ -f "$FPATH" ] && [ "$(wc -c < "$FPATH")" -ge "$MIN_BYTES" ]; then
2142
- BYTES=$(wc -c < "$FPATH")
2143
- READY="$READY $f(\${BYTES} bytes)"
2144
- else
2145
- MISSING="$MISSING $f"
2146
- fi
2147
- done
2148
-
2149
- MISSING=$(echo "$MISSING" | xargs)
2150
- READY=$(echo "$READY" | xargs)
2151
-
2152
- if [ -n "$MISSING" ] && [ "$STOP_ACTIVE" != "true" ]; then
2153
- printf '{"ts":"%s","event":"stop","blocked":true,"missing":"%s"}\\n' \\
2154
- "$(date -u +%FT%TZ)" "$MISSING" >> ${quote(eventsFile)}
2155
-
2156
- REASON="\u4EA7\u7269\u672A\u5C31\u7EEA: $MISSING\u3002\u8BF7\u5199\u5165 $PLAN_DIR/ \u4E0B\u7684\u5BF9\u5E94\u6587\u4EF6\u3002\u5DF2\u5C31\u7EEA: \${READY:-\u65E0}"
2157
-
2158
- printf '{"decision":"block","reason":"%s"}' "$REASON"
2159
- exit 0
2160
- fi
2161
-
2162
- printf '{"ts":"%s","event":"stop","blocked":false,"missing":"%s"}\\n' \\
2163
- "$(date -u +%FT%TZ)" "\${MISSING:-none}" >> ${quote(eventsFile)}
2164
- exit 0
2165
- `;
2166
- }
2167
- function quote(s) {
2168
- return `"${s.replace(/"/g, '\\"')}"`;
2169
- }
2170
- function readJsonl(filePath) {
2171
- if (!fs3.existsSync(filePath)) return [];
2172
- try {
2173
- const content = fs3.readFileSync(filePath, "utf-8").trim();
2174
- if (!content) return [];
2175
- return content.split("\n").reduce((acc, line) => {
2176
- const trimmed = line.trim();
2177
- if (!trimmed) return acc;
2178
- try {
2179
- acc.push(JSON.parse(trimmed));
2180
- } catch {
2181
- logger7.debug("Skipping malformed JSONL line", { line: trimmed });
2182
- }
2183
- return acc;
2184
- }, []);
2185
- } catch {
2186
- return [];
2187
- }
2188
- }
2189
-
2190
- // src/hooks/HookEventWatcher.ts
2191
- import fs4 from "fs";
2192
- var logger8 = logger.child("HookEventWatcher");
2193
-
2194
1749
  // src/phases/BasePhase.ts
2195
1750
  var BasePhase = class _BasePhase {
2196
1751
  static MIN_ARTIFACT_BYTES = 50;
@@ -2335,7 +1890,7 @@ ${t("basePhase.rulesSection", { rules })}`;
2335
1890
  const resultFiles = this.getResultFiles(ctx);
2336
1891
  const snapshotFilenames = resultFiles.map((f) => f.filename);
2337
1892
  const artifactCheck = snapshotFilenames.length > 0 ? () => snapshotFilenames.every((fn) => this.plan.isArtifactReady(fn, _BasePhase.MIN_ARTIFACT_BYTES)) : void 0;
2338
- const artifactPaths = snapshotFilenames.length > 0 ? snapshotFilenames.map((fn) => path5.join(this.plan.planDir, fn)) : void 0;
1893
+ const artifactPaths = snapshotFilenames.length > 0 ? snapshotFilenames.map((fn) => path4.join(this.plan.planDir, fn)) : void 0;
2339
1894
  let capturedSessionId;
2340
1895
  const result = await this.aiRunner.run({
2341
1896
  prompt,
@@ -2432,14 +1987,14 @@ ${t("basePhase.rulesSection", { rules })}`;
2432
1987
  const context = `${ctx.demand.title} ${ctx.demand.description} ${ctx.demand.supplement ? JSON.stringify(ctx.demand.supplement) : ""}`;
2433
1988
  if (ctx.workspace && ctx.workspace.repos.length > 1) {
2434
1989
  for (const repo of ctx.workspace.repos) {
2435
- const rulesDir = path5.join(repo.gitRootDir, ".cursor", "rules");
1990
+ const rulesDir = path4.join(repo.gitRootDir, ".cursor", "rules");
2436
1991
  try {
2437
1992
  await resolver.loadRules(rulesDir);
2438
1993
  } catch {
2439
1994
  }
2440
1995
  }
2441
1996
  } else {
2442
- const rulesDir = path5.join(this.plan.baseDir, ".cursor", "rules");
1997
+ const rulesDir = path4.join(this.plan.baseDir, ".cursor", "rules");
2443
1998
  await resolver.loadRules(rulesDir);
2444
1999
  }
2445
2000
  const matched = resolver.matchRules(context);
@@ -2713,20 +2268,20 @@ var BuildPhase = class extends BasePhase {
2713
2268
  };
2714
2269
 
2715
2270
  // src/release/ReleaseDetectCache.ts
2716
- import fs5 from "fs";
2717
- import path6 from "path";
2271
+ import fs3 from "fs";
2272
+ import path5 from "path";
2718
2273
  import { createHash } from "crypto";
2719
- var logger9 = logger.child("ReleaseDetectCache");
2274
+ var logger7 = logger.child("ReleaseDetectCache");
2720
2275
  function hashProjectPath(projectPath) {
2721
2276
  return createHash("sha256").update(projectPath).digest("hex").slice(0, 16);
2722
2277
  }
2723
2278
  var ReleaseDetectCache = class {
2724
2279
  cacheDir;
2725
2280
  constructor(dataDir) {
2726
- this.cacheDir = path6.join(dataDir, "release-detect");
2281
+ this.cacheDir = path5.join(dataDir, "release-detect");
2727
2282
  }
2728
2283
  filePath(projectPath) {
2729
- return path6.join(this.cacheDir, `${hashProjectPath(projectPath)}.json`);
2284
+ return path5.join(this.cacheDir, `${hashProjectPath(projectPath)}.json`);
2730
2285
  }
2731
2286
  /**
2732
2287
  * 读取缓存。返回 null 如果不存在、已过期或校验失败。
@@ -2734,21 +2289,21 @@ var ReleaseDetectCache = class {
2734
2289
  get(projectPath, ttlMs) {
2735
2290
  const fp = this.filePath(projectPath);
2736
2291
  try {
2737
- if (!fs5.existsSync(fp)) return null;
2738
- const raw = fs5.readFileSync(fp, "utf-8");
2292
+ if (!fs3.existsSync(fp)) return null;
2293
+ const raw = fs3.readFileSync(fp, "utf-8");
2739
2294
  const data = JSON.parse(raw);
2740
2295
  if (data.projectPath !== projectPath) {
2741
- logger9.warn("Cache projectPath mismatch, ignoring", { expected: projectPath, got: data.projectPath });
2296
+ logger7.warn("Cache projectPath mismatch, ignoring", { expected: projectPath, got: data.projectPath });
2742
2297
  return null;
2743
2298
  }
2744
2299
  const age = Date.now() - new Date(data.detectedAt).getTime();
2745
2300
  if (age > ttlMs) {
2746
- logger9.debug("Cache expired", { projectPath, ageMs: age, ttlMs });
2301
+ logger7.debug("Cache expired", { projectPath, ageMs: age, ttlMs });
2747
2302
  return null;
2748
2303
  }
2749
2304
  return data;
2750
2305
  } catch (err) {
2751
- logger9.warn("Failed to read release detect cache", { path: fp, error: err.message });
2306
+ logger7.warn("Failed to read release detect cache", { path: fp, error: err.message });
2752
2307
  return null;
2753
2308
  }
2754
2309
  }
@@ -2758,13 +2313,13 @@ var ReleaseDetectCache = class {
2758
2313
  set(result) {
2759
2314
  const fp = this.filePath(result.projectPath);
2760
2315
  try {
2761
- if (!fs5.existsSync(this.cacheDir)) {
2762
- fs5.mkdirSync(this.cacheDir, { recursive: true });
2316
+ if (!fs3.existsSync(this.cacheDir)) {
2317
+ fs3.mkdirSync(this.cacheDir, { recursive: true });
2763
2318
  }
2764
- fs5.writeFileSync(fp, JSON.stringify(result, null, 2), "utf-8");
2765
- logger9.debug("Release detect cache written", { projectPath: result.projectPath, path: fp });
2319
+ fs3.writeFileSync(fp, JSON.stringify(result, null, 2), "utf-8");
2320
+ logger7.debug("Release detect cache written", { projectPath: result.projectPath, path: fp });
2766
2321
  } catch (err) {
2767
- logger9.warn("Failed to write release detect cache", { path: fp, error: err.message });
2322
+ logger7.warn("Failed to write release detect cache", { path: fp, error: err.message });
2768
2323
  }
2769
2324
  }
2770
2325
  /**
@@ -2773,14 +2328,14 @@ var ReleaseDetectCache = class {
2773
2328
  invalidate(projectPath) {
2774
2329
  const fp = this.filePath(projectPath);
2775
2330
  try {
2776
- if (fs5.existsSync(fp)) {
2777
- fs5.unlinkSync(fp);
2778
- logger9.info("Release detect cache invalidated", { projectPath });
2331
+ if (fs3.existsSync(fp)) {
2332
+ fs3.unlinkSync(fp);
2333
+ logger7.info("Release detect cache invalidated", { projectPath });
2779
2334
  return true;
2780
2335
  }
2781
2336
  return false;
2782
2337
  } catch (err) {
2783
- logger9.warn("Failed to invalidate release detect cache", { path: fp, error: err.message });
2338
+ logger7.warn("Failed to invalidate release detect cache", { path: fp, error: err.message });
2784
2339
  return false;
2785
2340
  }
2786
2341
  }
@@ -3231,9 +2786,9 @@ function createLifecycleManager(def) {
3231
2786
 
3232
2787
  // src/workspace/WorkspaceConfig.ts
3233
2788
  import { z } from "zod";
3234
- import fs6 from "fs";
3235
- import path7 from "path";
3236
- var logger10 = logger.child("WorkspaceConfig");
2789
+ import fs4 from "fs";
2790
+ import path6 from "path";
2791
+ var logger8 = logger.child("WorkspaceConfig");
3237
2792
  var repoConfigSchema = z.object({
3238
2793
  name: z.string().min(1, "Repo name is required"),
3239
2794
  projectPath: z.string().min(1, "Gongfeng project path is required"),
@@ -3249,29 +2804,29 @@ var workspaceConfigSchema = z.object({
3249
2804
  });
3250
2805
  function loadWorkspaceConfig(configPath) {
3251
2806
  if (!configPath) return null;
3252
- if (!fs6.existsSync(configPath)) {
3253
- logger10.warn("Workspace config file not found, falling back to single-repo mode", {
2807
+ if (!fs4.existsSync(configPath)) {
2808
+ logger8.warn("Workspace config file not found, falling back to single-repo mode", {
3254
2809
  path: configPath
3255
2810
  });
3256
2811
  return null;
3257
2812
  }
3258
2813
  try {
3259
- const raw = fs6.readFileSync(configPath, "utf-8");
2814
+ const raw = fs4.readFileSync(configPath, "utf-8");
3260
2815
  const json = JSON.parse(raw);
3261
2816
  const result = workspaceConfigSchema.safeParse(json);
3262
2817
  if (!result.success) {
3263
2818
  const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
3264
- logger10.error(`Workspace config validation failed:
2819
+ logger8.error(`Workspace config validation failed:
3265
2820
  ${issues}`);
3266
2821
  return null;
3267
2822
  }
3268
- logger10.info("Workspace config loaded", {
2823
+ logger8.info("Workspace config loaded", {
3269
2824
  primary: result.data.primary.name,
3270
2825
  associates: result.data.associates.map((a) => a.name)
3271
2826
  });
3272
2827
  return result.data;
3273
2828
  } catch (err) {
3274
- logger10.error("Failed to parse workspace config", {
2829
+ logger8.error("Failed to parse workspace config", {
3275
2830
  path: configPath,
3276
2831
  error: err.message
3277
2832
  });
@@ -3297,14 +2852,14 @@ function isMultiRepo(ws) {
3297
2852
  }
3298
2853
  function persistWorkspaceConfig(ws, filePath) {
3299
2854
  try {
3300
- const dir = path7.dirname(filePath);
3301
- if (!fs6.existsSync(dir)) {
3302
- fs6.mkdirSync(dir, { recursive: true });
2855
+ const dir = path6.dirname(filePath);
2856
+ if (!fs4.existsSync(dir)) {
2857
+ fs4.mkdirSync(dir, { recursive: true });
3303
2858
  }
3304
- fs6.writeFileSync(filePath, JSON.stringify(ws, null, 2) + "\n", "utf-8");
3305
- logger10.info("Workspace config auto-generated from .env", { path: filePath });
2859
+ fs4.writeFileSync(filePath, JSON.stringify(ws, null, 2) + "\n", "utf-8");
2860
+ logger8.info("Workspace config auto-generated from .env", { path: filePath });
3306
2861
  } catch (err) {
3307
- logger10.warn("Failed to persist workspace config", {
2862
+ logger8.warn("Failed to persist workspace config", {
3308
2863
  path: filePath,
3309
2864
  error: err.message
3310
2865
  });
@@ -3312,12 +2867,12 @@ function persistWorkspaceConfig(ws, filePath) {
3312
2867
  }
3313
2868
 
3314
2869
  // src/workspace/WorkspaceManager.ts
3315
- import path8 from "path";
3316
- import fs7 from "fs/promises";
2870
+ import path7 from "path";
2871
+ import fs5 from "fs/promises";
3317
2872
  import { execFile } from "child_process";
3318
2873
  import { promisify } from "util";
3319
2874
  var execFileAsync = promisify(execFile);
3320
- var logger11 = logger.child("WorkspaceManager");
2875
+ var logger9 = logger.child("WorkspaceManager");
3321
2876
  var WorkspaceManager = class {
3322
2877
  wsConfig;
3323
2878
  worktreeBaseDir;
@@ -3346,7 +2901,7 @@ var WorkspaceManager = class {
3346
2901
  */
3347
2902
  async prepareWorkspace(issueIid, branchName, globalBaseBranch, globalBranchPrefix) {
3348
2903
  const wsRoot = this.getWorkspaceRoot(issueIid);
3349
- await fs7.mkdir(wsRoot, { recursive: true });
2904
+ await fs5.mkdir(wsRoot, { recursive: true });
3350
2905
  const primaryCtx = await this.preparePrimaryRepo(
3351
2906
  issueIid,
3352
2907
  branchName,
@@ -3365,7 +2920,7 @@ var WorkspaceManager = class {
3365
2920
  );
3366
2921
  associateCtxs.push(ctx);
3367
2922
  }
3368
- logger11.info("Workspace prepared", {
2923
+ logger9.info("Workspace prepared", {
3369
2924
  issueIid,
3370
2925
  wsRoot,
3371
2926
  repos: [primaryCtx.name, ...associateCtxs.map((a) => a.name)]
@@ -3390,7 +2945,7 @@ var WorkspaceManager = class {
3390
2945
  await git.commit(message);
3391
2946
  await git.push(wsCtx.branchName);
3392
2947
  committed.push(repo.name);
3393
- logger11.info("Committed and pushed changes", {
2948
+ logger9.info("Committed and pushed changes", {
3394
2949
  repo: repo.name,
3395
2950
  branch: wsCtx.branchName
3396
2951
  });
@@ -3404,19 +2959,19 @@ var WorkspaceManager = class {
3404
2959
  async cleanupWorkspace(wsCtx) {
3405
2960
  try {
3406
2961
  await this.mainGit.worktreeRemove(wsCtx.primary.gitRootDir, true);
3407
- logger11.info("Primary worktree removed", { dir: wsCtx.primary.gitRootDir });
2962
+ logger9.info("Primary worktree removed", { dir: wsCtx.primary.gitRootDir });
3408
2963
  } catch (err) {
3409
- logger11.warn("Failed to remove primary worktree", {
2964
+ logger9.warn("Failed to remove primary worktree", {
3410
2965
  dir: wsCtx.primary.gitRootDir,
3411
2966
  error: err.message
3412
2967
  });
3413
2968
  }
3414
2969
  for (const assoc of wsCtx.associates) {
3415
2970
  try {
3416
- await fs7.rm(assoc.gitRootDir, { recursive: true, force: true });
3417
- logger11.info("Associate repo dir removed", { name: assoc.name, dir: assoc.gitRootDir });
2971
+ await fs5.rm(assoc.gitRootDir, { recursive: true, force: true });
2972
+ logger9.info("Associate repo dir removed", { name: assoc.name, dir: assoc.gitRootDir });
3418
2973
  } catch (err) {
3419
- logger11.warn("Failed to remove associate repo dir", {
2974
+ logger9.warn("Failed to remove associate repo dir", {
3420
2975
  name: assoc.name,
3421
2976
  dir: assoc.gitRootDir,
3422
2977
  error: err.message
@@ -3424,9 +2979,9 @@ var WorkspaceManager = class {
3424
2979
  }
3425
2980
  }
3426
2981
  try {
3427
- const entries = await fs7.readdir(wsCtx.workspaceRoot);
2982
+ const entries = await fs5.readdir(wsCtx.workspaceRoot);
3428
2983
  if (entries.length === 0) {
3429
- await fs7.rmdir(wsCtx.workspaceRoot);
2984
+ await fs5.rmdir(wsCtx.workspaceRoot);
3430
2985
  }
3431
2986
  } catch {
3432
2987
  }
@@ -3438,13 +2993,13 @@ var WorkspaceManager = class {
3438
2993
  const wsRoot = this.getWorkspaceRoot(issueIid);
3439
2994
  const primary = this.wsConfig.primary;
3440
2995
  const defaultPrefix = globalBranchPrefix ?? primary.branchPrefix ?? "feat/issue";
3441
- const primaryDir = path8.join(wsRoot, primary.name);
2996
+ const primaryDir = path7.join(wsRoot, primary.name);
3442
2997
  const repos = [{
3443
2998
  name: primary.name,
3444
2999
  projectPath: primary.projectPath,
3445
3000
  role: primary.role ?? "",
3446
3001
  gitRootDir: primaryDir,
3447
- workDir: path8.join(primaryDir, primary.projectSubDir ?? ""),
3002
+ workDir: path7.join(primaryDir, primary.projectSubDir ?? ""),
3448
3003
  baseBranch: primary.baseBranch ?? globalBaseBranch,
3449
3004
  branchPrefix: primary.branchPrefix ?? defaultPrefix,
3450
3005
  isPrimary: true
@@ -3454,8 +3009,8 @@ var WorkspaceManager = class {
3454
3009
  name: assoc.name,
3455
3010
  projectPath: assoc.projectPath,
3456
3011
  role: assoc.role ?? "",
3457
- gitRootDir: path8.join(wsRoot, assoc.name),
3458
- workDir: path8.join(wsRoot, assoc.name, assoc.projectSubDir ?? ""),
3012
+ gitRootDir: path7.join(wsRoot, assoc.name),
3013
+ workDir: path7.join(wsRoot, assoc.name, assoc.projectSubDir ?? ""),
3459
3014
  baseBranch: assoc.baseBranch ?? globalBaseBranch,
3460
3015
  branchPrefix: assoc.branchPrefix ?? defaultPrefix,
3461
3016
  isPrimary: false
@@ -3464,12 +3019,12 @@ var WorkspaceManager = class {
3464
3019
  return repos;
3465
3020
  }
3466
3021
  getWorkspaceRoot(issueIid) {
3467
- return path8.join(this.worktreeBaseDir, `issue-${issueIid}`);
3022
+ return path7.join(this.worktreeBaseDir, `issue-${issueIid}`);
3468
3023
  }
3469
3024
  // ── Internal helpers ──
3470
3025
  async preparePrimaryRepo(issueIid, branchName, wsRoot, globalBaseBranch) {
3471
3026
  const primary = this.wsConfig.primary;
3472
- const repoDir = path8.join(wsRoot, primary.name);
3027
+ const repoDir = path7.join(wsRoot, primary.name);
3473
3028
  const baseBranch = primary.baseBranch ?? globalBaseBranch;
3474
3029
  await this.ensurePrimaryWorktree(repoDir, branchName, baseBranch);
3475
3030
  return {
@@ -3477,18 +3032,18 @@ var WorkspaceManager = class {
3477
3032
  projectPath: primary.projectPath,
3478
3033
  role: primary.role ?? "",
3479
3034
  gitRootDir: repoDir,
3480
- workDir: path8.join(repoDir, primary.projectSubDir ?? ""),
3035
+ workDir: path7.join(repoDir, primary.projectSubDir ?? ""),
3481
3036
  baseBranch,
3482
3037
  branchPrefix: primary.branchPrefix ?? "feat/issue",
3483
3038
  isPrimary: true
3484
3039
  };
3485
3040
  }
3486
3041
  async ensurePrimaryWorktree(repoDir, branchName, baseBranch) {
3487
- const wsRoot = path8.dirname(repoDir);
3042
+ const wsRoot = path7.dirname(repoDir);
3488
3043
  if (wsRoot !== repoDir) {
3489
3044
  try {
3490
- await fs7.access(path8.join(wsRoot, ".git"));
3491
- logger11.info("Migrating legacy worktree to primary subdir", { from: wsRoot, to: repoDir });
3045
+ await fs5.access(path7.join(wsRoot, ".git"));
3046
+ logger9.info("Migrating legacy worktree to primary subdir", { from: wsRoot, to: repoDir });
3492
3047
  await this.mainGit.worktreeRemove(wsRoot, true);
3493
3048
  await this.mainGit.worktreePrune();
3494
3049
  await this.cleanStaleDir(wsRoot);
@@ -3498,11 +3053,11 @@ var WorkspaceManager = class {
3498
3053
  const worktrees = await this.mainGit.worktreeList();
3499
3054
  if (worktrees.includes(repoDir)) {
3500
3055
  try {
3501
- await fs7.access(path8.join(repoDir, ".git"));
3502
- logger11.info("Reusing existing primary worktree", { dir: repoDir });
3056
+ await fs5.access(path7.join(repoDir, ".git"));
3057
+ logger9.info("Reusing existing primary worktree", { dir: repoDir });
3503
3058
  return;
3504
3059
  } catch {
3505
- logger11.warn("Primary worktree registered but .git missing, recreating", { dir: repoDir });
3060
+ logger9.warn("Primary worktree registered but .git missing, recreating", { dir: repoDir });
3506
3061
  await this.mainGit.worktreeRemove(repoDir, true);
3507
3062
  await this.mainGit.worktreePrune();
3508
3063
  }
@@ -3521,19 +3076,19 @@ var WorkspaceManager = class {
3521
3076
  await this.mainGit.worktreeAdd(repoDir, branchName, `origin/${baseBranch}`);
3522
3077
  }
3523
3078
  async prepareAssociateRepo(assoc, _issueIid, branchName, wsRoot, globalBaseBranch, globalBranchPrefix) {
3524
- const repoDir = path8.join(wsRoot, assoc.name);
3079
+ const repoDir = path7.join(wsRoot, assoc.name);
3525
3080
  const baseBranch = assoc.baseBranch ?? globalBaseBranch;
3526
3081
  const cloneUrl = `${this.gongfengApiUrl}/${assoc.projectPath}.git`;
3527
- const gitDirExists = await this.dirExists(path8.join(repoDir, ".git"));
3082
+ const gitDirExists = await this.dirExists(path7.join(repoDir, ".git"));
3528
3083
  if (!gitDirExists) {
3529
3084
  await this.cleanStaleDir(repoDir);
3530
- logger11.info("Cloning associate repo", { name: assoc.name, url: cloneUrl });
3085
+ logger9.info("Cloning associate repo", { name: assoc.name, url: cloneUrl });
3531
3086
  await execFileAsync("git", ["clone", "--depth", "50", cloneUrl, repoDir], {
3532
3087
  timeout: 3e5,
3533
3088
  maxBuffer: 10 * 1024 * 1024
3534
3089
  });
3535
3090
  } else {
3536
- logger11.info("Reusing existing associate clone", { name: assoc.name, dir: repoDir });
3091
+ logger9.info("Reusing existing associate clone", { name: assoc.name, dir: repoDir });
3537
3092
  }
3538
3093
  const assocGit = new GitOperations(repoDir);
3539
3094
  await assocGit.fetch();
@@ -3556,7 +3111,7 @@ var WorkspaceManager = class {
3556
3111
  projectPath: assoc.projectPath,
3557
3112
  role: assoc.role ?? "",
3558
3113
  gitRootDir: repoDir,
3559
- workDir: path8.join(repoDir, assoc.projectSubDir ?? ""),
3114
+ workDir: path7.join(repoDir, assoc.projectSubDir ?? ""),
3560
3115
  baseBranch,
3561
3116
  branchPrefix: assoc.branchPrefix ?? globalBranchPrefix,
3562
3117
  isPrimary: false
@@ -3564,13 +3119,13 @@ var WorkspaceManager = class {
3564
3119
  }
3565
3120
  async cleanStaleDir(dir) {
3566
3121
  if (await this.dirExists(dir)) {
3567
- logger11.warn("Removing stale directory", { dir });
3568
- await fs7.rm(dir, { recursive: true, force: true });
3122
+ logger9.warn("Removing stale directory", { dir });
3123
+ await fs5.rm(dir, { recursive: true, force: true });
3569
3124
  }
3570
3125
  }
3571
3126
  async dirExists(dir) {
3572
3127
  try {
3573
- await fs7.access(dir);
3128
+ await fs5.access(dir);
3574
3129
  return true;
3575
3130
  } catch {
3576
3131
  return false;
@@ -3579,8 +3134,8 @@ var WorkspaceManager = class {
3579
3134
  };
3580
3135
 
3581
3136
  // src/orchestrator/PipelineOrchestrator.ts
3582
- import path12 from "path";
3583
- import fs11 from "fs/promises";
3137
+ import path11 from "path";
3138
+ import fs9 from "fs/promises";
3584
3139
  import fsSync from "fs";
3585
3140
  import { execFile as execFile2 } from "child_process";
3586
3141
  import { promisify as promisify2 } from "util";
@@ -3613,8 +3168,8 @@ function mapSupplement(s) {
3613
3168
  }
3614
3169
 
3615
3170
  // src/utils/MergeRequestHelper.ts
3616
- import fs8 from "fs";
3617
- import path9 from "path";
3171
+ import fs6 from "fs";
3172
+ import path8 from "path";
3618
3173
  var TAPD_PATTERNS = [
3619
3174
  /--story=(\d+)/i,
3620
3175
  /--bug=(\d+)/i,
@@ -3658,9 +3213,9 @@ function generateMRDescription(options) {
3658
3213
  ];
3659
3214
  const planSections = [];
3660
3215
  for (const { filename, label } of summaryFiles) {
3661
- const filePath = path9.join(planDir, ".claude-plan", `issue-${issueIid}`, filename);
3662
- if (fs8.existsSync(filePath)) {
3663
- const content = fs8.readFileSync(filePath, "utf-8");
3216
+ const filePath = path8.join(planDir, ".claude-plan", `issue-${issueIid}`, filename);
3217
+ if (fs6.existsSync(filePath)) {
3218
+ const content = fs6.readFileSync(filePath, "utf-8");
3664
3219
  const summary = extractSummary(content);
3665
3220
  if (summary) {
3666
3221
  planSections.push(`### ${label}
@@ -3684,7 +3239,7 @@ function extractSummary(content, maxLines = 20) {
3684
3239
 
3685
3240
  // src/deploy/PortAllocator.ts
3686
3241
  import net from "net";
3687
- var logger12 = logger.child("PortAllocator");
3242
+ var logger10 = logger.child("PortAllocator");
3688
3243
  var DEFAULT_OPTIONS = {
3689
3244
  backendPortBase: 4e3,
3690
3245
  frontendPortBase: 9e3,
@@ -3709,7 +3264,7 @@ var PortAllocator = class {
3709
3264
  async allocate(issueIid) {
3710
3265
  const existing = this.allocated.get(issueIid);
3711
3266
  if (existing) {
3712
- logger12.info("Returning already allocated ports", { issueIid, ports: existing });
3267
+ logger10.info("Returning already allocated ports", { issueIid, ports: existing });
3713
3268
  return existing;
3714
3269
  }
3715
3270
  const usedBackend = new Set([...this.allocated.values()].map((p) => p.backendPort));
@@ -3727,10 +3282,10 @@ var PortAllocator = class {
3727
3282
  if (beOk && feOk) {
3728
3283
  const pair = { backendPort, frontendPort };
3729
3284
  this.allocated.set(issueIid, pair);
3730
- logger12.info("Ports allocated", { issueIid, ...pair });
3285
+ logger10.info("Ports allocated", { issueIid, ...pair });
3731
3286
  return pair;
3732
3287
  }
3733
- logger12.debug("Port pair unavailable, trying next", {
3288
+ logger10.debug("Port pair unavailable, trying next", {
3734
3289
  backendPort,
3735
3290
  frontendPort,
3736
3291
  beOk,
@@ -3745,7 +3300,7 @@ var PortAllocator = class {
3745
3300
  const pair = this.allocated.get(issueIid);
3746
3301
  if (pair) {
3747
3302
  this.allocated.delete(issueIid);
3748
- logger12.info("Ports released", { issueIid, ...pair });
3303
+ logger10.info("Ports released", { issueIid, ...pair });
3749
3304
  }
3750
3305
  }
3751
3306
  getPortsForIssue(issueIid) {
@@ -3756,15 +3311,15 @@ var PortAllocator = class {
3756
3311
  }
3757
3312
  restore(issueIid, ports) {
3758
3313
  this.allocated.set(issueIid, ports);
3759
- logger12.info("Ports restored from persistence", { issueIid, ...ports });
3314
+ logger10.info("Ports restored from persistence", { issueIid, ...ports });
3760
3315
  }
3761
3316
  };
3762
3317
 
3763
3318
  // src/deploy/DevServerManager.ts
3764
3319
  import { spawn } from "child_process";
3765
- import fs9 from "fs";
3766
- import path10 from "path";
3767
- var logger13 = logger.child("DevServerManager");
3320
+ import fs7 from "fs";
3321
+ import path9 from "path";
3322
+ var logger11 = logger.child("DevServerManager");
3768
3323
  var DEFAULT_OPTIONS2 = {};
3769
3324
  var DevServerManager = class {
3770
3325
  servers = /* @__PURE__ */ new Map();
@@ -3772,25 +3327,25 @@ var DevServerManager = class {
3772
3327
  logDir;
3773
3328
  constructor(options) {
3774
3329
  this.options = { ...DEFAULT_OPTIONS2, ...options };
3775
- this.logDir = path10.join(resolveDataDir(), "preview-logs");
3776
- if (!fs9.existsSync(this.logDir)) {
3777
- fs9.mkdirSync(this.logDir, { recursive: true });
3330
+ this.logDir = path9.join(resolveDataDir(), "preview-logs");
3331
+ if (!fs7.existsSync(this.logDir)) {
3332
+ fs7.mkdirSync(this.logDir, { recursive: true });
3778
3333
  }
3779
3334
  }
3780
3335
  getLogPath(issueIid, type) {
3781
- const filePath = path10.join(this.logDir, `${issueIid}-${type}.log`);
3782
- return fs9.existsSync(filePath) ? filePath : null;
3336
+ const filePath = path9.join(this.logDir, `${issueIid}-${type}.log`);
3337
+ return fs7.existsSync(filePath) ? filePath : null;
3783
3338
  }
3784
3339
  async startServers(wtCtx, ports) {
3785
3340
  if (this.servers.has(wtCtx.issueIid)) {
3786
- logger13.info("Servers already running for issue", { issueIid: wtCtx.issueIid });
3341
+ logger11.info("Servers already running for issue", { issueIid: wtCtx.issueIid });
3787
3342
  return;
3788
3343
  }
3789
- logger13.info("Starting dev servers", { issueIid: wtCtx.issueIid, ...ports });
3790
- const backendLogPath = path10.join(this.logDir, `${wtCtx.issueIid}-backend.log`);
3791
- const frontendLogPath = path10.join(this.logDir, `${wtCtx.issueIid}-frontend.log`);
3792
- const backendLog = fs9.createWriteStream(backendLogPath, { flags: "a" });
3793
- const frontendLog = fs9.createWriteStream(frontendLogPath, { flags: "a" });
3344
+ logger11.info("Starting dev servers", { issueIid: wtCtx.issueIid, ...ports });
3345
+ const backendLogPath = path9.join(this.logDir, `${wtCtx.issueIid}-backend.log`);
3346
+ const frontendLogPath = path9.join(this.logDir, `${wtCtx.issueIid}-frontend.log`);
3347
+ const backendLog = fs7.createWriteStream(backendLogPath, { flags: "a" });
3348
+ const frontendLog = fs7.createWriteStream(frontendLogPath, { flags: "a" });
3794
3349
  const tsLine = (stream, data) => `[${(/* @__PURE__ */ new Date()).toISOString()}] [${stream}] ${data.toString().trimEnd()}
3795
3350
  `;
3796
3351
  const backendEnv = {
@@ -3814,9 +3369,9 @@ var DevServerManager = class {
3814
3369
  backendLog.write(tsLine("stderr", data));
3815
3370
  });
3816
3371
  backend.on("exit", (code) => {
3817
- logger13.info("Backend process exited", { issueIid: wtCtx.issueIid, code });
3372
+ logger11.info("Backend process exited", { issueIid: wtCtx.issueIid, code });
3818
3373
  });
3819
- const frontendDir = path10.join(wtCtx.workDir, "frontend");
3374
+ const frontendDir = path9.join(wtCtx.workDir, "frontend");
3820
3375
  const frontendEnv = {
3821
3376
  ...process.env,
3822
3377
  BACKEND_PORT: String(ports.backendPort),
@@ -3838,7 +3393,7 @@ var DevServerManager = class {
3838
3393
  frontendLog.write(tsLine("stderr", data));
3839
3394
  });
3840
3395
  frontend.on("exit", (code) => {
3841
- logger13.info("Frontend process exited", { issueIid: wtCtx.issueIid, code });
3396
+ logger11.info("Frontend process exited", { issueIid: wtCtx.issueIid, code });
3842
3397
  });
3843
3398
  const serverSet = {
3844
3399
  backend,
@@ -3850,14 +3405,14 @@ var DevServerManager = class {
3850
3405
  frontendLog
3851
3406
  };
3852
3407
  this.servers.set(wtCtx.issueIid, serverSet);
3853
- logger13.info("Dev servers spawned, waiting for startup", { issueIid: wtCtx.issueIid, ...ports });
3408
+ logger11.info("Dev servers spawned, waiting for startup", { issueIid: wtCtx.issueIid, ...ports });
3854
3409
  await new Promise((r) => setTimeout(r, 1e4));
3855
- logger13.info("Dev servers startup grace period done", { issueIid: wtCtx.issueIid });
3410
+ logger11.info("Dev servers startup grace period done", { issueIid: wtCtx.issueIid });
3856
3411
  }
3857
3412
  stopServers(issueIid) {
3858
3413
  const set = this.servers.get(issueIid);
3859
3414
  if (!set) return;
3860
- logger13.info("Stopping dev servers", { issueIid, ports: set.ports });
3415
+ logger11.info("Stopping dev servers", { issueIid, ports: set.ports });
3861
3416
  killProcess(set.backend, `backend #${issueIid}`);
3862
3417
  killProcess(set.frontend, `frontend #${issueIid}`);
3863
3418
  set.backendLog.end();
@@ -3894,7 +3449,7 @@ function killProcess(proc, label) {
3894
3449
  }
3895
3450
  setTimeout(() => {
3896
3451
  if (!proc.killed && proc.exitCode === null) {
3897
- logger13.warn(`Force killing ${label}`);
3452
+ logger11.warn(`Force killing ${label}`);
3898
3453
  try {
3899
3454
  process.kill(-pid, "SIGKILL");
3900
3455
  } catch {
@@ -3903,7 +3458,7 @@ function killProcess(proc, label) {
3903
3458
  }
3904
3459
  }, 5e3);
3905
3460
  } catch (err) {
3906
- logger13.warn(`Failed to kill ${label}`, { error: err.message });
3461
+ logger11.warn(`Failed to kill ${label}`, { error: err.message });
3907
3462
  }
3908
3463
  }
3909
3464
 
@@ -3922,13 +3477,13 @@ function isE2eEnabledForIssue(issueIid, tracker, cfg) {
3922
3477
  }
3923
3478
 
3924
3479
  // src/e2e/ScreenshotCollector.ts
3925
- import fs10 from "fs";
3926
- import path11 from "path";
3927
- var logger14 = logger.child("ScreenshotCollector");
3480
+ import fs8 from "fs";
3481
+ import path10 from "path";
3482
+ var logger12 = logger.child("ScreenshotCollector");
3928
3483
  var MAX_SCREENSHOTS = 20;
3929
3484
  function walkDir(dir, files = []) {
3930
- for (const entry of fs10.readdirSync(dir, { withFileTypes: true })) {
3931
- const full = path11.join(dir, entry.name);
3485
+ for (const entry of fs8.readdirSync(dir, { withFileTypes: true })) {
3486
+ const full = path10.join(dir, entry.name);
3932
3487
  if (entry.isDirectory()) {
3933
3488
  walkDir(full, files);
3934
3489
  } else if (entry.isFile() && entry.name.endsWith(".png")) {
@@ -3938,34 +3493,34 @@ function walkDir(dir, files = []) {
3938
3493
  return files;
3939
3494
  }
3940
3495
  function collectScreenshots(workDir) {
3941
- const testResultsDir = path11.join(workDir, "frontend", "test-results");
3942
- if (!fs10.existsSync(testResultsDir)) {
3943
- logger14.debug("test-results directory not found", { dir: testResultsDir });
3496
+ const testResultsDir = path10.join(workDir, "frontend", "test-results");
3497
+ if (!fs8.existsSync(testResultsDir)) {
3498
+ logger12.debug("test-results directory not found", { dir: testResultsDir });
3944
3499
  return [];
3945
3500
  }
3946
3501
  const pngFiles = walkDir(testResultsDir);
3947
3502
  if (pngFiles.length === 0) {
3948
- logger14.debug("No screenshots found");
3503
+ logger12.debug("No screenshots found");
3949
3504
  return [];
3950
3505
  }
3951
3506
  const screenshots = pngFiles.map((filePath) => {
3952
- const relative = path11.relative(testResultsDir, filePath);
3953
- const testName = relative.split(path11.sep)[0] || path11.basename(filePath, ".png");
3507
+ const relative = path10.relative(testResultsDir, filePath);
3508
+ const testName = relative.split(path10.sep)[0] || path10.basename(filePath, ".png");
3954
3509
  return { filePath, testName };
3955
3510
  });
3956
3511
  if (screenshots.length > MAX_SCREENSHOTS) {
3957
- logger14.warn("Too many screenshots, truncating", {
3512
+ logger12.warn("Too many screenshots, truncating", {
3958
3513
  total: screenshots.length,
3959
3514
  max: MAX_SCREENSHOTS
3960
3515
  });
3961
3516
  return screenshots.slice(0, MAX_SCREENSHOTS);
3962
3517
  }
3963
- logger14.info("Screenshots collected", { count: screenshots.length });
3518
+ logger12.info("Screenshots collected", { count: screenshots.length });
3964
3519
  return screenshots;
3965
3520
  }
3966
3521
 
3967
3522
  // src/e2e/ScreenshotPublisher.ts
3968
- var logger15 = logger.child("ScreenshotPublisher");
3523
+ var logger13 = logger.child("ScreenshotPublisher");
3969
3524
  function buildComment(uploaded, truncated) {
3970
3525
  const lines = [t("screenshot.title"), ""];
3971
3526
  for (const item of uploaded) {
@@ -3984,12 +3539,12 @@ var ScreenshotPublisher = class {
3984
3539
  const { workDir, issueIid, issueId, mrIid } = options;
3985
3540
  const screenshots = collectScreenshots(workDir);
3986
3541
  if (screenshots.length === 0) {
3987
- logger15.info("No E2E screenshots to publish", { issueIid });
3542
+ logger13.info("No E2E screenshots to publish", { issueIid });
3988
3543
  return;
3989
3544
  }
3990
3545
  const uploaded = await this.uploadAll(screenshots);
3991
3546
  if (uploaded.length === 0) {
3992
- logger15.warn("All screenshot uploads failed", { issueIid });
3547
+ logger13.warn("All screenshot uploads failed", { issueIid });
3993
3548
  return;
3994
3549
  }
3995
3550
  const truncated = screenshots.length >= 20;
@@ -3998,7 +3553,7 @@ var ScreenshotPublisher = class {
3998
3553
  if (mrIid) {
3999
3554
  await this.postToMergeRequest(mrIid, comment);
4000
3555
  }
4001
- logger15.info("E2E screenshots published", {
3556
+ logger13.info("E2E screenshots published", {
4002
3557
  issueIid,
4003
3558
  mrIid,
4004
3559
  count: uploaded.length
@@ -4014,7 +3569,7 @@ var ScreenshotPublisher = class {
4014
3569
  markdown: result.markdown
4015
3570
  });
4016
3571
  } catch (err) {
4017
- logger15.warn("Failed to upload screenshot", {
3572
+ logger13.warn("Failed to upload screenshot", {
4018
3573
  filePath: screenshot.filePath,
4019
3574
  error: err.message
4020
3575
  });
@@ -4026,7 +3581,7 @@ var ScreenshotPublisher = class {
4026
3581
  try {
4027
3582
  await this.gongfeng.createIssueNote(issueId, comment);
4028
3583
  } catch (err) {
4029
- logger15.warn("Failed to post screenshots to issue", {
3584
+ logger13.warn("Failed to post screenshots to issue", {
4030
3585
  issueId,
4031
3586
  error: err.message
4032
3587
  });
@@ -4036,7 +3591,7 @@ var ScreenshotPublisher = class {
4036
3591
  try {
4037
3592
  await this.gongfeng.createMergeRequestNote(mrIid, comment);
4038
3593
  } catch (err) {
4039
- logger15.warn("Failed to post screenshots to merge request", {
3594
+ logger13.warn("Failed to post screenshots to merge request", {
4040
3595
  mrIid,
4041
3596
  error: err.message
4042
3597
  });
@@ -4219,7 +3774,7 @@ metrics.registerCounter("iaf_braindump_batches_total", "Total braindump batches"
4219
3774
  metrics.registerCounter("iaf_braindump_tasks_total", "Total braindump tasks");
4220
3775
 
4221
3776
  // src/orchestrator/steps/SetupStep.ts
4222
- var logger16 = logger.child("SetupStep");
3777
+ var logger14 = logger.child("SetupStep");
4223
3778
  async function executeSetup(ctx, deps) {
4224
3779
  const { issue, wtCtx, record, pipelineDef, branchName } = ctx;
4225
3780
  try {
@@ -4228,7 +3783,7 @@ async function executeSetup(ctx, deps) {
4228
3783
  "auto-finish:processing"
4229
3784
  ]);
4230
3785
  } catch (err) {
4231
- logger16.warn("Failed to update issue labels", { error: err.message });
3786
+ logger14.warn("Failed to update issue labels", { error: err.message });
4232
3787
  }
4233
3788
  await deps.mainGitMutex.runExclusive(async () => {
4234
3789
  deps.emitProgress(issue.iid, "fetch", t("orchestrator.fetchProgress"));
@@ -4287,7 +3842,7 @@ async function executeSetup(ctx, deps) {
4287
3842
  issueDescription: issue.description
4288
3843
  });
4289
3844
  } catch (err) {
4290
- logger16.warn("Failed to inject Claude Code hooks (non-blocking)", {
3845
+ logger14.warn("Failed to inject Claude Code hooks (non-blocking)", {
4291
3846
  error: err.message
4292
3847
  });
4293
3848
  }
@@ -4399,7 +3954,7 @@ function clearPendingDialog(issueIid) {
4399
3954
  }
4400
3955
 
4401
3956
  // src/orchestrator/steps/PhaseHelpers.ts
4402
- var logger17 = logger.child("PhaseHelpers");
3957
+ var logger15 = logger.child("PhaseHelpers");
4403
3958
  async function safeComment(deps, issueId, message) {
4404
3959
  try {
4405
3960
  await deps.gongfeng.createIssueNote(issueId, message);
@@ -4421,7 +3976,7 @@ async function commitPlanFiles(ctx, wtGit, wtGitMap, phaseName, displayId) {
4421
3976
  for (const repo of ctx.workspace.repos) {
4422
3977
  const repoGit = wtGitMap?.get(repo.name);
4423
3978
  if (!repoGit) {
4424
- logger17.warn("Missing GitOperations for repo, skipping commit", { repo: repo.name });
3979
+ logger15.warn("Missing GitOperations for repo, skipping commit", { repo: repo.name });
4425
3980
  continue;
4426
3981
  }
4427
3982
  const branch = repo.branchPrefix ? `${repo.branchPrefix}-${displayId}` : ctx.branchName;
@@ -4430,10 +3985,10 @@ async function commitPlanFiles(ctx, wtGit, wtGitMap, phaseName, displayId) {
4430
3985
  await repoGit.add(["."]);
4431
3986
  await repoGit.commit(commitMsg);
4432
3987
  await repoGit.push(branch);
4433
- logger17.info("Committed changes for repo", { repo: repo.name, branch });
3988
+ logger15.info("Committed changes for repo", { repo: repo.name, branch });
4434
3989
  }
4435
3990
  } catch (err) {
4436
- logger17.warn("Failed to commit/push for repo", {
3991
+ logger15.warn("Failed to commit/push for repo", {
4437
3992
  repo: repo.name,
4438
3993
  error: err.message
4439
3994
  });
@@ -4471,15 +4026,15 @@ async function syncResultToIssue(phase, ctx, displayId, phaseName, deps, issueId
4471
4026
  summary
4472
4027
  );
4473
4028
  await safeComment(deps, issueId, comment);
4474
- logger17.info("Result synced to issue", { issueIid: displayId, file: file.filename });
4029
+ logger15.info("Result synced to issue", { issueIid: displayId, file: file.filename });
4475
4030
  }
4476
4031
  } catch (err) {
4477
- logger17.warn("Failed to sync result to issue", { error: err.message });
4032
+ logger15.warn("Failed to sync result to issue", { error: err.message });
4478
4033
  await safeComment(deps, issueId, issueProgressComment(phaseName, "completed"));
4479
4034
  }
4480
4035
  }
4481
4036
  function handlePlanApproval(displayId, phaseName, deps) {
4482
- logger17.info("ACP plan-approval requested, delegating to review gate", {
4037
+ logger15.info("ACP plan-approval requested, delegating to review gate", {
4483
4038
  issueIid: displayId,
4484
4039
  phase: phaseName
4485
4040
  });
@@ -4489,14 +4044,14 @@ function handlePlanApproval(displayId, phaseName, deps) {
4489
4044
  const data = payload.data;
4490
4045
  if (data.issueIid !== displayId) return;
4491
4046
  cleanup();
4492
- logger17.info("ACP plan-approval approved via review gate", { issueIid: displayId });
4047
+ logger15.info("ACP plan-approval approved via review gate", { issueIid: displayId });
4493
4048
  resolve("allow");
4494
4049
  };
4495
4050
  const onRejected = (payload) => {
4496
4051
  const data = payload.data;
4497
4052
  if (data.issueIid !== displayId) return;
4498
4053
  cleanup();
4499
- logger17.info("ACP plan-approval rejected via review gate", { issueIid: displayId });
4054
+ logger15.info("ACP plan-approval rejected via review gate", { issueIid: displayId });
4500
4055
  resolve("reject");
4501
4056
  };
4502
4057
  const cleanup = () => {
@@ -4508,7 +4063,7 @@ function handlePlanApproval(displayId, phaseName, deps) {
4508
4063
  });
4509
4064
  }
4510
4065
  function handleInteractiveDialog(displayId, phaseName, deps, request) {
4511
- logger17.info("Interactive dialog forwarded to frontend", {
4066
+ logger15.info("Interactive dialog forwarded to frontend", {
4512
4067
  issueIid: displayId,
4513
4068
  phase: phaseName,
4514
4069
  question: request.content.slice(0, 80),
@@ -4538,7 +4093,7 @@ function handleInteractiveDialog(displayId, phaseName, deps, request) {
4538
4093
  if (data.issueIid !== displayId) return;
4539
4094
  cleanup();
4540
4095
  clearPendingDialog(displayId);
4541
- logger17.info("Interactive dialog response received from frontend", {
4096
+ logger15.info("Interactive dialog response received from frontend", {
4542
4097
  issueIid: displayId,
4543
4098
  response: data.response
4544
4099
  });
@@ -4548,7 +4103,7 @@ function handleInteractiveDialog(displayId, phaseName, deps, request) {
4548
4103
  const data = payload.data;
4549
4104
  if (data.issueIid !== displayId) return;
4550
4105
  cleanup();
4551
- logger17.info("Interactive dialog dismissed by user (false positive)", { issueIid: displayId });
4106
+ logger15.info("Interactive dialog dismissed by user (false positive)", { issueIid: displayId });
4552
4107
  resolve("");
4553
4108
  };
4554
4109
  deps.eventBus.on("agent:inputResponse", onResponse);
@@ -4572,7 +4127,7 @@ function updateHooksForPhase(spec, pipelineDef, ctx, wtPlan) {
4572
4127
  issueDescription: ctx.issue.description
4573
4128
  });
4574
4129
  } catch (err) {
4575
- logger17.warn("Failed to update hooks for phase (non-blocking)", {
4130
+ logger15.warn("Failed to update hooks for phase (non-blocking)", {
4576
4131
  phase: spec.name,
4577
4132
  error: err.message
4578
4133
  });
@@ -4580,7 +4135,7 @@ function updateHooksForPhase(spec, pipelineDef, ctx, wtPlan) {
4580
4135
  }
4581
4136
 
4582
4137
  // src/lifecycle/DefaultLifecycleHook.ts
4583
- var logger18 = logger.child("DefaultLifecycleHook");
4138
+ var logger16 = logger.child("DefaultLifecycleHook");
4584
4139
  var DefaultLifecycleHook = class {
4585
4140
  async beforePhase(ctx) {
4586
4141
  const { spec, issueCtx, deps, wtPlan } = ctx;
@@ -4680,7 +4235,7 @@ function createCallbacksFromHook(hook, ctx) {
4680
4235
  }
4681
4236
 
4682
4237
  // src/orchestrator/strategies/GateStrategy.ts
4683
- var logger19 = logger.child("GateStrategy");
4238
+ var logger17 = logger.child("GateStrategy");
4684
4239
  var GateStrategy = class {
4685
4240
  name = "gate";
4686
4241
  shouldSkip() {
@@ -4690,7 +4245,7 @@ var GateStrategy = class {
4690
4245
  const { spec, issueCtx, deps, wtPlan } = ctx;
4691
4246
  const { issue } = issueCtx;
4692
4247
  if (deps.shouldAutoApprove(issue.labels)) {
4693
- logger19.info("Auto-approving review gate (matched autoApproveLabels)", {
4248
+ logger17.info("Auto-approving review gate (matched autoApproveLabels)", {
4694
4249
  iid: issue.iid,
4695
4250
  labels: issue.labels,
4696
4251
  autoApproveLabels: deps.config.review.autoApproveLabels
@@ -4716,19 +4271,19 @@ var GateStrategy = class {
4716
4271
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
4717
4272
  });
4718
4273
  deps.eventBus.emitTyped("review:requested", { issueIid: issue.iid });
4719
- logger19.info("Review gate reached, pausing", { iid: issue.iid });
4274
+ logger17.info("Review gate reached, pausing", { iid: issue.iid });
4720
4275
  return { paused: true };
4721
4276
  }
4722
4277
  };
4723
4278
 
4724
4279
  // src/orchestrator/strategies/AiPhaseStrategy.ts
4725
- var logger20 = logger.child("AiPhaseStrategy");
4280
+ var logger18 = logger.child("AiPhaseStrategy");
4726
4281
  var AiPhaseStrategy = class {
4727
4282
  name = "ai";
4728
4283
  shouldSkip(ctx) {
4729
4284
  const { spec, issueCtx, deps } = ctx;
4730
4285
  if (spec.name === "uat" && !isE2eEnabledForIssue(issueCtx.issue.iid, deps.tracker, deps.config)) {
4731
- logger20.info("UAT phase skipped (E2E not enabled for this issue)", { iid: issueCtx.issue.iid });
4286
+ logger18.info("UAT phase skipped (E2E not enabled for this issue)", { iid: issueCtx.issue.iid });
4732
4287
  return true;
4733
4288
  }
4734
4289
  return false;
@@ -4749,7 +4304,7 @@ var AiPhaseStrategy = class {
4749
4304
  const runner = this.resolveRunner(ctx);
4750
4305
  if (spec.name === "uat") {
4751
4306
  const runnerName = runner === deps.e2eAiRunner ? "e2eAiRunner (CodeBuddy)" : "mainRunner";
4752
- logger20.info("UAT phase starting", { iid: issue.iid, runner: runnerName });
4307
+ logger18.info("UAT phase starting", { iid: issue.iid, runner: runnerName });
4753
4308
  }
4754
4309
  const phase = createPhase(spec.name, runner, wtGit, wtPlan, deps.config);
4755
4310
  if (wtGitMap) phase.setWtGitMap(wtGitMap);
@@ -4783,7 +4338,7 @@ var AiPhaseStrategy = class {
4783
4338
  const { spec, issueCtx, deps, wtGit, wtPlan, wtGitMap } = ctx;
4784
4339
  const { issue, phaseCtx } = issueCtx;
4785
4340
  if (outcome.awaitCompletion) {
4786
- logger20.info("Async phase running, awaiting completion", { iid: issue.iid, phase: spec.name });
4341
+ logger18.info("Async phase running, awaiting completion", { iid: issue.iid, phase: spec.name });
4787
4342
  const finalOutcome = await outcome.awaitCompletion;
4788
4343
  if (finalOutcome.sessionId) {
4789
4344
  wtPlan.updatePhaseSessionId(spec.name, finalOutcome.sessionId);
@@ -4799,7 +4354,7 @@ var AiPhaseStrategy = class {
4799
4354
  const runner = this.resolveRunner(ctx);
4800
4355
  const phase = createPhase(spec.name, runner, wtGit, wtPlan, deps.config);
4801
4356
  await syncResultToIssue(phase, phaseCtx, issue.iid, spec.name, deps, issue.id, wtPlan);
4802
- logger20.info("Async phase completed successfully", { iid: issue.iid, phase: spec.name });
4357
+ logger18.info("Async phase completed successfully", { iid: issue.iid, phase: spec.name });
4803
4358
  return { paused: false };
4804
4359
  }
4805
4360
  const errMsg = finalOutcome.error?.message ?? "Unknown error";
@@ -4825,7 +4380,7 @@ var AiPhaseStrategy = class {
4825
4380
  deps.tracker.updatePhaseProgress(issue.iid, spec.name, { status: "gate_waiting" });
4826
4381
  const gateEvent = spec.name === "uat" ? "uat:gateRequested" : "release:gateRequested";
4827
4382
  deps.eventBus.emitTyped(gateEvent, { issueIid: issue.iid });
4828
- logger20.info("Async phase running (no awaitCompletion), pausing pipeline", {
4383
+ logger18.info("Async phase running (no awaitCompletion), pausing pipeline", {
4829
4384
  iid: issue.iid,
4830
4385
  phase: spec.name
4831
4386
  });
@@ -4838,13 +4393,13 @@ var AiPhaseStrategy = class {
4838
4393
  wtPlan.updatePhaseProgress(spec.name, "gate_waiting");
4839
4394
  deps.tracker.updatePhaseProgress(issue.iid, spec.name, { status: "gate_waiting" });
4840
4395
  deps.eventBus.emitTyped("release:gateRequested", { issueIid: issue.iid });
4841
- logger20.info("Phase requested gate, pausing", { iid: issue.iid, phase: spec.name });
4396
+ logger18.info("Phase requested gate, pausing", { iid: issue.iid, phase: spec.name });
4842
4397
  return { paused: true };
4843
4398
  }
4844
4399
  };
4845
4400
 
4846
4401
  // src/orchestrator/strategies/VerifyFixStrategy.ts
4847
- var logger21 = logger.child("VerifyFixStrategy");
4402
+ var logger19 = logger.child("VerifyFixStrategy");
4848
4403
  var VerifyFixStrategy = class {
4849
4404
  name = "verify-fix";
4850
4405
  shouldSkip() {
@@ -4861,14 +4416,14 @@ var VerifyFixStrategy = class {
4861
4416
  issueIid: issue.iid,
4862
4417
  maxIterations
4863
4418
  });
4864
- logger21.info("Verify-fix loop started", {
4419
+ logger19.info("Verify-fix loop started", {
4865
4420
  iid: issue.iid,
4866
4421
  maxIterations,
4867
4422
  buildPhaseIdx
4868
4423
  });
4869
4424
  for (let iteration = 1; iteration <= maxIterations; iteration++) {
4870
4425
  if (isShuttingDown()) throw new ServiceShutdownError();
4871
- logger21.info("Verify-fix loop iteration", { iteration, maxIterations, iid: issue.iid });
4426
+ logger19.info("Verify-fix loop iteration", { iteration, maxIterations, iid: issue.iid });
4872
4427
  updateHooksForPhase(verifySpec, pipelineDef, issueCtx, wtPlan);
4873
4428
  const verifyRunner = resolveVerifyRunner(deps);
4874
4429
  const verifyPhase = createPhase("verify", verifyRunner, wtGit, wtPlan, deps.config);
@@ -4887,7 +4442,7 @@ var VerifyFixStrategy = class {
4887
4442
  hooks
4888
4443
  );
4889
4444
  } catch (err) {
4890
- logger21.warn("Verify phase execution failed", {
4445
+ logger19.warn("Verify phase execution failed", {
4891
4446
  iteration,
4892
4447
  iid: issue.iid,
4893
4448
  error: err.message
@@ -4917,10 +4472,10 @@ var VerifyFixStrategy = class {
4917
4472
  failures: report?.failureReasons
4918
4473
  });
4919
4474
  if (passed) {
4920
- logger21.info("Verify-fix loop passed", { iteration, iid: issue.iid });
4475
+ logger19.info("Verify-fix loop passed", { iteration, iid: issue.iid });
4921
4476
  return { paused: false };
4922
4477
  }
4923
- logger21.info("Verify failed, issues found", {
4478
+ logger19.info("Verify failed, issues found", {
4924
4479
  iteration,
4925
4480
  iid: issue.iid,
4926
4481
  failures: report?.failureReasons,
@@ -4933,7 +4488,7 @@ var VerifyFixStrategy = class {
4933
4488
  failures: report?.failureReasons ?? []
4934
4489
  });
4935
4490
  const failMsg = `Verify-fix loop exhausted after ${maxIterations} iterations. Remaining issues: ${report?.failureReasons?.join("; ") ?? "unknown"}`;
4936
- logger21.warn(failMsg, { iid: issue.iid });
4491
+ logger19.warn(failMsg, { iid: issue.iid });
4937
4492
  throw new AIExecutionError("verify", failMsg, {
4938
4493
  output: report?.rawReport ?? "",
4939
4494
  exitCode: 0
@@ -4952,7 +4507,7 @@ var VerifyFixStrategy = class {
4952
4507
  async executeBuildFix(ctx, deps, wtGit, wtPlan, buildPhaseIdx, fixContext, wtGitMap, hooks) {
4953
4508
  const { issue, phaseCtx, pipelineDef } = ctx;
4954
4509
  const buildSpec = pipelineDef.phases[buildPhaseIdx];
4955
- logger21.info("Looping back to build for fix", {
4510
+ logger19.info("Looping back to build for fix", {
4956
4511
  iteration: fixContext.iteration,
4957
4512
  iid: issue.iid,
4958
4513
  failures: fixContext.verifyFailures
@@ -5000,7 +4555,7 @@ function resolveStrategy(spec, config) {
5000
4555
  }
5001
4556
 
5002
4557
  // src/orchestrator/steps/PhaseLoopStep.ts
5003
- var logger22 = logger.child("PhaseLoopStep");
4558
+ var logger20 = logger.child("PhaseLoopStep");
5004
4559
  async function runPhaseWithLifecycle(phase, phaseCtx, spec, ctx, deps, wtGit, wtPlan, wtGitMap, hook) {
5005
4560
  const lifecycleHook = hook ?? new DefaultLifecycleHook();
5006
4561
  const execCtx = {
@@ -5065,15 +4620,15 @@ async function executePhaseLoop(ctx, deps, wtGit, wtPlan, wtGitMap) {
5065
4620
  if (skippedDeployPhase && !phaseCtx.ports) {
5066
4621
  const existingPorts = deps.getPortsForIssue(issue.iid);
5067
4622
  if (existingPorts && deps.isPreviewRunning(issue.iid)) {
5068
- logger22.info("Restored preview ports from allocator", { iid: issue.iid, ...existingPorts });
4623
+ logger20.info("Restored preview ports from allocator", { iid: issue.iid, ...existingPorts });
5069
4624
  phaseCtx.ports = existingPorts;
5070
4625
  ctx.wtCtx.ports = existingPorts;
5071
4626
  serversStarted = true;
5072
4627
  } else {
5073
4628
  if (existingPorts) {
5074
- logger22.info("Ports allocated but servers not running, restarting", { iid: issue.iid });
4629
+ logger20.info("Ports allocated but servers not running, restarting", { iid: issue.iid });
5075
4630
  } else {
5076
- logger22.info("Restarting preview servers for resumed pipeline", { iid: issue.iid });
4631
+ logger20.info("Restarting preview servers for resumed pipeline", { iid: issue.iid });
5077
4632
  }
5078
4633
  const ports = await deps.startPreviewServers(ctx.wtCtx, issue);
5079
4634
  if (ports) {
@@ -5139,7 +4694,7 @@ function healStaleProgress(ctx, deps, wtPlan, startIdx) {
5139
4694
  const prevSpec = pipelineDef.phases[i];
5140
4695
  const pp = currentProgress.phases[prevSpec.name];
5141
4696
  if (pp && pp.status !== "completed") {
5142
- logger22.warn("Fixing stale phase progress", {
4697
+ logger20.warn("Fixing stale phase progress", {
5143
4698
  iid: issue.iid,
5144
4699
  phase: prevSpec.name,
5145
4700
  was: pp.status,
@@ -5171,7 +4726,7 @@ function healStaleProgress(ctx, deps, wtPlan, startIdx) {
5171
4726
  }
5172
4727
 
5173
4728
  // src/orchestrator/steps/CompletionStep.ts
5174
- var logger23 = logger.child("CompletionStep");
4729
+ var logger21 = logger.child("CompletionStep");
5175
4730
  async function executeCompletion(ctx, deps, phaseResult, _wtGitMap) {
5176
4731
  const { issue, branchName, wtCtx } = ctx;
5177
4732
  deps.emitProgress(issue.iid, "create_mr", t("orchestrator.createMrProgress"));
@@ -5203,7 +4758,7 @@ async function executeCompletion(ctx, deps, phaseResult, _wtGitMap) {
5203
4758
  mrIid: void 0
5204
4759
  });
5205
4760
  } catch (err) {
5206
- logger23.warn("Failed to publish E2E screenshots", {
4761
+ logger21.warn("Failed to publish E2E screenshots", {
5207
4762
  iid: issue.iid,
5208
4763
  error: err.message
5209
4764
  });
@@ -5223,19 +4778,19 @@ async function executeCompletion(ctx, deps, phaseResult, _wtGitMap) {
5223
4778
  await deps.claimer.releaseClaim(issue.id, issue.iid, "completed");
5224
4779
  }
5225
4780
  if (phaseResult.serversStarted && deps.config.preview.keepAfterComplete) {
5226
- logger23.info("Preview servers kept running after completion", { iid: issue.iid });
4781
+ logger21.info("Preview servers kept running after completion", { iid: issue.iid });
5227
4782
  } else {
5228
4783
  deps.stopPreviewServers(issue.iid);
5229
4784
  await deps.mainGitMutex.runExclusive(async () => {
5230
4785
  if (wtCtx.workspace) {
5231
4786
  await deps.workspaceManager.cleanupWorkspace(wtCtx.workspace);
5232
- logger23.info("Workspace cleaned up", { dir: wtCtx.workspace.workspaceRoot });
4787
+ logger21.info("Workspace cleaned up", { dir: wtCtx.workspace.workspaceRoot });
5233
4788
  } else {
5234
4789
  try {
5235
4790
  await deps.mainGit.worktreeRemove(wtCtx.gitRootDir, true);
5236
- logger23.info("Worktree cleaned up", { dir: wtCtx.gitRootDir });
4791
+ logger21.info("Worktree cleaned up", { dir: wtCtx.gitRootDir });
5237
4792
  } catch (err) {
5238
- logger23.warn("Failed to cleanup worktree", {
4793
+ logger21.warn("Failed to cleanup worktree", {
5239
4794
  dir: wtCtx.gitRootDir,
5240
4795
  error: err.message
5241
4796
  });
@@ -5243,16 +4798,16 @@ async function executeCompletion(ctx, deps, phaseResult, _wtGitMap) {
5243
4798
  }
5244
4799
  });
5245
4800
  }
5246
- logger23.info("Issue processing completed", { iid: issue.iid });
4801
+ logger21.info("Issue processing completed", { iid: issue.iid });
5247
4802
  }
5248
4803
 
5249
4804
  // src/orchestrator/steps/FailureHandler.ts
5250
- var logger24 = logger.child("FailureHandler");
4805
+ var logger22 = logger.child("FailureHandler");
5251
4806
  async function handleFailure(err, issue, wtCtx, deps) {
5252
4807
  const errorMsg = err.message;
5253
4808
  const isRetryable = err instanceof AIExecutionError ? err.isRetryable : true;
5254
4809
  const wasActiveAtTimeout = err instanceof AIExecutionError && err.wasActiveAtTimeout;
5255
- logger24.error("Issue processing failed", { iid: issue.iid, error: errorMsg, isRetryable, wasActiveAtTimeout });
4810
+ logger22.error("Issue processing failed", { iid: issue.iid, error: errorMsg, isRetryable, wasActiveAtTimeout });
5256
4811
  metrics.incCounter("iaf_issues_failed_total");
5257
4812
  const currentRecord = deps.tracker.get(issue.iid);
5258
4813
  const failedAtState = currentRecord?.state || "pending" /* Pending */;
@@ -5265,11 +4820,11 @@ async function handleFailure(err, issue, wtCtx, deps) {
5265
4820
  }
5266
4821
  }
5267
4822
  if (wasReset) {
5268
- logger24.info("Issue was reset during processing, skipping failure marking", { iid: issue.iid });
4823
+ logger22.info("Issue was reset during processing, skipping failure marking", { iid: issue.iid });
5269
4824
  throw err;
5270
4825
  }
5271
4826
  if (failedAtState === "paused" /* Paused */) {
5272
- logger24.info("Issue was paused during processing, skipping failure handling", { iid: issue.iid });
4827
+ logger22.info("Issue was paused during processing, skipping failure handling", { iid: issue.iid });
5273
4828
  throw err;
5274
4829
  }
5275
4830
  try {
@@ -5291,7 +4846,7 @@ async function handleFailure(err, issue, wtCtx, deps) {
5291
4846
  try {
5292
4847
  await deps.claimer.releaseClaim(issue.id, issue.iid, "failed");
5293
4848
  } catch (releaseErr) {
5294
- logger24.warn("Failed to release lock on failure", {
4849
+ logger22.warn("Failed to release lock on failure", {
5295
4850
  iid: issue.iid,
5296
4851
  error: releaseErr.message
5297
4852
  });
@@ -5299,7 +4854,7 @@ async function handleFailure(err, issue, wtCtx, deps) {
5299
4854
  }
5300
4855
  deps.stopPreviewServers(issue.iid);
5301
4856
  const preservedDirs = wtCtx.workspace ? [wtCtx.workspace.primary.gitRootDir, ...wtCtx.workspace.associates.map((a) => a.gitRootDir)] : [wtCtx.gitRootDir];
5302
- logger24.info("Worktree(s) preserved for debugging", {
4857
+ logger22.info("Worktree(s) preserved for debugging", {
5303
4858
  primary: wtCtx.gitRootDir,
5304
4859
  all: preservedDirs
5305
4860
  });
@@ -5308,7 +4863,7 @@ async function handleFailure(err, issue, wtCtx, deps) {
5308
4863
 
5309
4864
  // src/orchestrator/PipelineOrchestrator.ts
5310
4865
  var execFileAsync2 = promisify2(execFile2);
5311
- var logger25 = logger.child("PipelineOrchestrator");
4866
+ var logger23 = logger.child("PipelineOrchestrator");
5312
4867
  var PipelineOrchestrator = class {
5313
4868
  config;
5314
4869
  gongfeng;
@@ -5338,7 +4893,7 @@ var PipelineOrchestrator = class {
5338
4893
  setAIRunner(runner) {
5339
4894
  this.aiRunner = runner;
5340
4895
  this.conflictResolver = new ConflictResolver(runner);
5341
- logger25.info("AIRunner replaced via hot-reload");
4896
+ logger23.info("AIRunner replaced via hot-reload");
5342
4897
  }
5343
4898
  constructor(config, gongfeng, git, aiRunner, tracker, supplementStore, mainGitMutex, eventBusInstance, wsConfig, tenantId, e2eAiRunner) {
5344
4899
  this.config = config;
@@ -5356,14 +4911,14 @@ var PipelineOrchestrator = class {
5356
4911
  this.pipelineDef = mode === "plan-mode" ? buildPlanModePipeline({ releaseEnabled: config.release.enabled, e2eEnabled: config.e2e.enabled }) : getPipelineDef(mode);
5357
4912
  registerPipeline(this.pipelineDef);
5358
4913
  this.lifecycleManager = createLifecycleManager(this.pipelineDef);
5359
- logger25.info("Pipeline mode resolved", { tenantId: this.tenantId, mode: this.pipelineDef.mode, aiMode: config.ai.mode });
4914
+ logger23.info("Pipeline mode resolved", { tenantId: this.tenantId, mode: this.pipelineDef.mode, aiMode: config.ai.mode });
5360
4915
  this.portAllocator = new PortAllocator({
5361
4916
  backendPortBase: config.e2e.backendPortBase,
5362
4917
  frontendPortBase: config.e2e.frontendPortBase
5363
4918
  });
5364
4919
  this.devServerManager = new DevServerManager();
5365
4920
  this.screenshotPublisher = new ScreenshotPublisher(gongfeng);
5366
- this.effectiveWorktreeBaseDir = this.tenantId === "default" ? config.project.worktreeBaseDir : path12.join(config.project.worktreeBaseDir, this.tenantId);
4921
+ this.effectiveWorktreeBaseDir = this.tenantId === "default" ? config.project.worktreeBaseDir : path11.join(config.project.worktreeBaseDir, this.tenantId);
5367
4922
  const effectiveWsConfig = wsConfig ?? buildSingleRepoWorkspace(config.project, config.gongfeng.projectPath);
5368
4923
  this.workspaceManager = new WorkspaceManager({
5369
4924
  wsConfig: effectiveWsConfig,
@@ -5372,7 +4927,7 @@ var PipelineOrchestrator = class {
5372
4927
  mainGitMutex: this.mainGitMutex,
5373
4928
  gongfengApiUrl: config.gongfeng.apiUrl
5374
4929
  });
5375
- logger25.info("WorkspaceManager initialized", {
4930
+ logger23.info("WorkspaceManager initialized", {
5376
4931
  tenantId: this.tenantId,
5377
4932
  primary: effectiveWsConfig.primary.name,
5378
4933
  associates: effectiveWsConfig.associates.map((a) => a.name)
@@ -5393,7 +4948,7 @@ var PipelineOrchestrator = class {
5393
4948
  this.claimer = claimer;
5394
4949
  }
5395
4950
  async cleanupStaleState() {
5396
- logger25.info("Cleaning up stale worktree state...");
4951
+ logger23.info("Cleaning up stale worktree state...");
5397
4952
  let cleaned = 0;
5398
4953
  const repoGitRoot = this.config.project.gitRootDir;
5399
4954
  try {
@@ -5402,11 +4957,11 @@ var PipelineOrchestrator = class {
5402
4957
  if (wtDir === repoGitRoot) continue;
5403
4958
  if (!wtDir.includes("/issue-")) continue;
5404
4959
  try {
5405
- const gitFile = path12.join(wtDir, ".git");
4960
+ const gitFile = path11.join(wtDir, ".git");
5406
4961
  try {
5407
- await fs11.access(gitFile);
4962
+ await fs9.access(gitFile);
5408
4963
  } catch {
5409
- logger25.warn("Worktree corrupted (.git missing), force removing", { dir: wtDir });
4964
+ logger23.warn("Worktree corrupted (.git missing), force removing", { dir: wtDir });
5410
4965
  await this.mainGit.worktreeRemove(wtDir, true).catch(() => {
5411
4966
  });
5412
4967
  await this.mainGit.worktreePrune();
@@ -5415,32 +4970,32 @@ var PipelineOrchestrator = class {
5415
4970
  }
5416
4971
  const wtGit = new GitOperations(wtDir);
5417
4972
  if (await wtGit.isRebaseInProgress()) {
5418
- logger25.warn("Aborting residual rebase in worktree", { dir: wtDir });
4973
+ logger23.warn("Aborting residual rebase in worktree", { dir: wtDir });
5419
4974
  await wtGit.rebaseAbort();
5420
4975
  cleaned++;
5421
4976
  }
5422
- const indexLock = path12.join(wtDir, ".git", "index.lock");
4977
+ const indexLock = path11.join(wtDir, ".git", "index.lock");
5423
4978
  try {
5424
- await fs11.unlink(indexLock);
5425
- logger25.warn("Removed stale index.lock", { path: indexLock });
4979
+ await fs9.unlink(indexLock);
4980
+ logger23.warn("Removed stale index.lock", { path: indexLock });
5426
4981
  cleaned++;
5427
4982
  } catch {
5428
4983
  }
5429
4984
  } catch (err) {
5430
- logger25.warn("Failed to clean worktree state", { dir: wtDir, error: err.message });
4985
+ logger23.warn("Failed to clean worktree state", { dir: wtDir, error: err.message });
5431
4986
  }
5432
4987
  }
5433
4988
  } catch (err) {
5434
- logger25.warn("Failed to list worktrees for cleanup", { error: err.message });
4989
+ logger23.warn("Failed to list worktrees for cleanup", { error: err.message });
5435
4990
  }
5436
- const mainIndexLock = path12.join(repoGitRoot, ".git", "index.lock");
4991
+ const mainIndexLock = path11.join(repoGitRoot, ".git", "index.lock");
5437
4992
  try {
5438
- await fs11.unlink(mainIndexLock);
5439
- logger25.warn("Removed stale main repo index.lock", { path: mainIndexLock });
4993
+ await fs9.unlink(mainIndexLock);
4994
+ logger23.warn("Removed stale main repo index.lock", { path: mainIndexLock });
5440
4995
  cleaned++;
5441
4996
  } catch {
5442
4997
  }
5443
- logger25.info("Stale state cleanup complete", { cleaned });
4998
+ logger23.info("Stale state cleanup complete", { cleaned });
5444
4999
  }
5445
5000
  /**
5446
5001
  * 重启后清理幽灵端口分配。
@@ -5453,7 +5008,7 @@ var PipelineOrchestrator = class {
5453
5008
  for (const record of this.tracker.getAll()) {
5454
5009
  if (record.ports) {
5455
5010
  const iid = getIid(record);
5456
- logger25.info("Clearing stale port allocation after restart", { iid, ports: record.ports });
5011
+ logger23.info("Clearing stale port allocation after restart", { iid, ports: record.ports });
5457
5012
  this.tracker.updateState(iid, record.state, {
5458
5013
  ports: void 0,
5459
5014
  previewStartedAt: void 0
@@ -5498,20 +5053,20 @@ var PipelineOrchestrator = class {
5498
5053
  }
5499
5054
  try {
5500
5055
  await this.mainGit.worktreeRemove(wtCtx.gitRootDir, true);
5501
- logger25.info("Worktree cleaned up", { dir: wtCtx.gitRootDir });
5056
+ logger23.info("Worktree cleaned up", { dir: wtCtx.gitRootDir });
5502
5057
  } catch (err) {
5503
- logger25.warn("Failed to cleanup worktree", { dir: wtCtx.gitRootDir, error: err.message });
5058
+ logger23.warn("Failed to cleanup worktree", { dir: wtCtx.gitRootDir, error: err.message });
5504
5059
  }
5505
5060
  }
5506
5061
  async installDependencies(workDir) {
5507
- logger25.info("Installing dependencies in worktree", { workDir });
5062
+ logger23.info("Installing dependencies in worktree", { workDir });
5508
5063
  const knowledge = getProjectKnowledge() ?? KNOWLEDGE_DEFAULTS;
5509
5064
  const pkgMgr = knowledge.toolchain.packageManager.toLowerCase();
5510
5065
  const isNodeProject = ["npm", "pnpm", "yarn", "bun"].some((m) => pkgMgr.includes(m));
5511
5066
  if (isNodeProject) {
5512
5067
  const ready = await this.ensureNodeModules(workDir);
5513
5068
  if (ready) {
5514
- logger25.info("node_modules ready \u2014 skipping install");
5069
+ logger23.info("node_modules ready \u2014 skipping install");
5515
5070
  return;
5516
5071
  }
5517
5072
  }
@@ -5524,10 +5079,10 @@ var PipelineOrchestrator = class {
5524
5079
  maxBuffer: 10 * 1024 * 1024,
5525
5080
  timeout: 3e5
5526
5081
  });
5527
- logger25.info("Dependencies installed");
5082
+ logger23.info("Dependencies installed");
5528
5083
  } catch (err) {
5529
5084
  if (fallbackCmd) {
5530
- logger25.warn(`${installCmd} failed, retrying with fallback command`, {
5085
+ logger23.warn(`${installCmd} failed, retrying with fallback command`, {
5531
5086
  error: err.message
5532
5087
  });
5533
5088
  const [fallbackBin, ...fallbackArgs] = fallbackCmd.split(/\s+/);
@@ -5537,45 +5092,45 @@ var PipelineOrchestrator = class {
5537
5092
  maxBuffer: 10 * 1024 * 1024,
5538
5093
  timeout: 3e5
5539
5094
  });
5540
- logger25.info("Dependencies installed (fallback)");
5095
+ logger23.info("Dependencies installed (fallback)");
5541
5096
  } catch (retryErr) {
5542
- logger25.warn("Fallback install also failed", {
5097
+ logger23.warn("Fallback install also failed", {
5543
5098
  error: retryErr.message
5544
5099
  });
5545
5100
  }
5546
5101
  } else {
5547
- logger25.warn("Install failed, no fallback configured", {
5102
+ logger23.warn("Install failed, no fallback configured", {
5548
5103
  error: err.message
5549
5104
  });
5550
5105
  }
5551
5106
  }
5552
5107
  }
5553
5108
  async ensureNodeModules(workDir) {
5554
- const targetBin = path12.join(workDir, "node_modules", ".bin");
5109
+ const targetBin = path11.join(workDir, "node_modules", ".bin");
5555
5110
  try {
5556
- await fs11.access(targetBin);
5557
- logger25.info("node_modules already complete (has .bin/)");
5111
+ await fs9.access(targetBin);
5112
+ logger23.info("node_modules already complete (has .bin/)");
5558
5113
  return true;
5559
5114
  } catch {
5560
5115
  }
5561
- const sourceNM = path12.join(this.config.project.workDir, "node_modules");
5562
- const targetNM = path12.join(workDir, "node_modules");
5116
+ const sourceNM = path11.join(this.config.project.workDir, "node_modules");
5117
+ const targetNM = path11.join(workDir, "node_modules");
5563
5118
  try {
5564
- await fs11.access(sourceNM);
5119
+ await fs9.access(sourceNM);
5565
5120
  } catch {
5566
- logger25.warn("Main repo node_modules not found, skipping seed", { sourceNM });
5121
+ logger23.warn("Main repo node_modules not found, skipping seed", { sourceNM });
5567
5122
  return false;
5568
5123
  }
5569
- logger25.info("Seeding node_modules from main repo via reflink copy", { sourceNM, targetNM });
5124
+ logger23.info("Seeding node_modules from main repo via reflink copy", { sourceNM, targetNM });
5570
5125
  try {
5571
5126
  await execFileAsync2("rm", ["-rf", targetNM], { timeout: 6e4 });
5572
5127
  await execFileAsync2("cp", ["-a", "--reflink=auto", sourceNM, targetNM], {
5573
5128
  timeout: 12e4
5574
5129
  });
5575
- logger25.info("node_modules seeded from main repo");
5130
+ logger23.info("node_modules seeded from main repo");
5576
5131
  return true;
5577
5132
  } catch (err) {
5578
- logger25.warn("Failed to seed node_modules from main repo", {
5133
+ logger23.warn("Failed to seed node_modules from main repo", {
5579
5134
  error: err.message
5580
5135
  });
5581
5136
  return false;
@@ -5585,16 +5140,16 @@ var PipelineOrchestrator = class {
5585
5140
  const record = this.tracker.get(issueIid);
5586
5141
  if (!record) throw new IssueNotFoundError(issueIid);
5587
5142
  const wtCtx = this.computeWorktreeContext(issueIid, record.branchName);
5588
- logger25.info("Restarting issue \u2014 cleaning context", { issueIid, branchName: record.branchName });
5143
+ logger23.info("Restarting issue \u2014 cleaning context", { issueIid, branchName: record.branchName });
5589
5144
  this.pendingActions.set(issueIid, "restart");
5590
5145
  this.aiRunner.killByWorkDir(wtCtx.workDir);
5591
5146
  this.e2eAiRunner?.killByWorkDir(wtCtx.workDir);
5592
5147
  this.stopPreviewServers(issueIid);
5593
5148
  try {
5594
5149
  const deleted = await this.gongfeng.cleanupAgentNotes(getExternalId(record));
5595
- logger25.info("Agent notes cleaned up", { issueIid, deleted });
5150
+ logger23.info("Agent notes cleaned up", { issueIid, deleted });
5596
5151
  } catch (err) {
5597
- logger25.warn("Failed to cleanup agent notes", { issueIid, error: err.message });
5152
+ logger23.warn("Failed to cleanup agent notes", { issueIid, error: err.message });
5598
5153
  }
5599
5154
  await this.mainGitMutex.runExclusive(async () => {
5600
5155
  await this.cleanupWorktree(wtCtx);
@@ -5611,19 +5166,19 @@ var PipelineOrchestrator = class {
5611
5166
  await this.cleanupE2eOutputs(issueIid);
5612
5167
  this.tracker.resetFull(issueIid);
5613
5168
  this.pendingActions.delete(issueIid);
5614
- logger25.info("Issue restarted", { issueIid });
5169
+ logger23.info("Issue restarted", { issueIid });
5615
5170
  }
5616
5171
  async cancelIssue(issueIid) {
5617
5172
  const record = this.tracker.get(issueIid);
5618
5173
  if (!record) throw new IssueNotFoundError(issueIid);
5619
5174
  const wtCtx = this.computeWorktreeContext(issueIid, record.branchName);
5620
- logger25.info("Cancelling issue \u2014 cleaning all resources", { issueIid, branchName: record.branchName });
5175
+ logger23.info("Cancelling issue \u2014 cleaning all resources", { issueIid, branchName: record.branchName });
5621
5176
  this.aiRunner.killByWorkDir(wtCtx.workDir);
5622
5177
  this.stopPreviewServers(issueIid);
5623
5178
  try {
5624
5179
  await this.gongfeng.removeLabelsWithPrefix(getExternalId(record), "auto-finish");
5625
5180
  } catch (err) {
5626
- logger25.warn("Failed to remove labels on cancel", { issueIid, error: err.message });
5181
+ logger23.warn("Failed to remove labels on cancel", { issueIid, error: err.message });
5627
5182
  }
5628
5183
  await this.mainGitMutex.runExclusive(async () => {
5629
5184
  await this.cleanupWorktree(wtCtx);
@@ -5640,7 +5195,7 @@ var PipelineOrchestrator = class {
5640
5195
  this.tracker.clearProcessingLock(issueIid);
5641
5196
  this.tracker.updateState(issueIid, "skipped" /* Skipped */);
5642
5197
  await this.cleanupE2eOutputs(issueIid);
5643
- logger25.info("Issue cancelled", { issueIid });
5198
+ logger23.info("Issue cancelled", { issueIid });
5644
5199
  }
5645
5200
  /**
5646
5201
  * Remove the E2E output directory for an issue: {uatVendorDir}/outputs/issue-{iid}
@@ -5648,13 +5203,13 @@ var PipelineOrchestrator = class {
5648
5203
  async cleanupE2eOutputs(issueIid) {
5649
5204
  const vendorDir = this.config.e2e.uatVendorDir;
5650
5205
  if (!vendorDir) return;
5651
- const abs = path12.isAbsolute(vendorDir) ? vendorDir : path12.resolve(this.config.project.workDir, vendorDir);
5652
- const outputDir = path12.join(abs, "outputs", `issue-${issueIid}`);
5206
+ const abs = path11.isAbsolute(vendorDir) ? vendorDir : path11.resolve(this.config.project.workDir, vendorDir);
5207
+ const outputDir = path11.join(abs, "outputs", `issue-${issueIid}`);
5653
5208
  try {
5654
- await fs11.rm(outputDir, { recursive: true, force: true });
5655
- logger25.info("E2E outputs cleaned up", { issueIid, dir: outputDir });
5209
+ await fs9.rm(outputDir, { recursive: true, force: true });
5210
+ logger23.info("E2E outputs cleaned up", { issueIid, dir: outputDir });
5656
5211
  } catch (err) {
5657
- logger25.warn("Failed to cleanup E2E outputs", { issueIid, dir: outputDir, error: err.message });
5212
+ logger23.warn("Failed to cleanup E2E outputs", { issueIid, dir: outputDir, error: err.message });
5658
5213
  }
5659
5214
  }
5660
5215
  /**
@@ -5666,10 +5221,10 @@ var PipelineOrchestrator = class {
5666
5221
  if (!this.workspaceManager) return;
5667
5222
  const wsRoot = this.workspaceManager.getWorkspaceRoot(issueIid);
5668
5223
  try {
5669
- await fs11.rm(wsRoot, { recursive: true, force: true });
5670
- logger25.info("Workspace root cleaned up", { issueIid, dir: wsRoot });
5224
+ await fs9.rm(wsRoot, { recursive: true, force: true });
5225
+ logger23.info("Workspace root cleaned up", { issueIid, dir: wsRoot });
5671
5226
  } catch (err) {
5672
- logger25.warn("Failed to cleanup workspace root", { issueIid, dir: wsRoot, error: err.message });
5227
+ logger23.warn("Failed to cleanup workspace root", { issueIid, dir: wsRoot, error: err.message });
5673
5228
  }
5674
5229
  }
5675
5230
  retryFromPhase(issueIid, phase) {
@@ -5685,7 +5240,7 @@ var PipelineOrchestrator = class {
5685
5240
  this.aiRunner.killByWorkDir(wtCtx.workDir);
5686
5241
  }
5687
5242
  this.e2eAiRunner?.killByWorkDir(wtCtx.workDir);
5688
- logger25.info("Retrying issue from phase", { issueIid, phase });
5243
+ logger23.info("Retrying issue from phase", { issueIid, phase });
5689
5244
  const ok = this.tracker.resetToPhase(issueIid, phase, issueDef);
5690
5245
  if (!ok) {
5691
5246
  throw new InvalidPhaseError(phase);
@@ -5712,7 +5267,7 @@ var PipelineOrchestrator = class {
5712
5267
  } else {
5713
5268
  this.tracker.pauseIssue(issueIid, record.currentPhase ?? "");
5714
5269
  }
5715
- logger25.info("Issue abort requested", { issueIid, state: record.state });
5270
+ logger23.info("Issue abort requested", { issueIid, state: record.state });
5716
5271
  }
5717
5272
  continueIssue(issueIid) {
5718
5273
  const record = this.tracker.get(issueIid);
@@ -5722,7 +5277,7 @@ var PipelineOrchestrator = class {
5722
5277
  }
5723
5278
  const issueDef = this.getIssueSpecificPipelineDef(record);
5724
5279
  this.tracker.resumeFromPause(issueIid, issueDef, false);
5725
- logger25.info("Issue continued from pause", { issueIid });
5280
+ logger23.info("Issue continued from pause", { issueIid });
5726
5281
  }
5727
5282
  redoPhase(issueIid) {
5728
5283
  const record = this.tracker.get(issueIid);
@@ -5766,7 +5321,7 @@ var PipelineOrchestrator = class {
5766
5321
  }
5767
5322
  this.eventBus.emitTyped("issue:redone", { issueIid });
5768
5323
  }
5769
- logger25.info("Issue redo requested", { issueIid, state: record.state });
5324
+ logger23.info("Issue redo requested", { issueIid, state: record.state });
5770
5325
  }
5771
5326
  /**
5772
5327
  * 处理中止/重做的共享逻辑:
@@ -5839,7 +5394,7 @@ var PipelineOrchestrator = class {
5839
5394
  async _processIssueImpl(issue) {
5840
5395
  const branchName = `${this.config.project.branchPrefix}-${issue.iid}`;
5841
5396
  const wtCtx = this.computeWorktreeContext(issue.iid, branchName);
5842
- logger25.info("Processing issue", {
5397
+ logger23.info("Processing issue", {
5843
5398
  iid: issue.iid,
5844
5399
  title: issue.title,
5845
5400
  branchName,
@@ -5946,7 +5501,7 @@ var PipelineOrchestrator = class {
5946
5501
  title,
5947
5502
  description
5948
5503
  });
5949
- logger25.info("Merge request created successfully", {
5504
+ logger23.info("Merge request created successfully", {
5950
5505
  iid: issue.iid,
5951
5506
  mrIid: mr.iid,
5952
5507
  mrUrl: mr.web_url
@@ -5954,7 +5509,7 @@ var PipelineOrchestrator = class {
5954
5509
  return { url: mr.web_url, iid: mr.iid };
5955
5510
  } catch (err) {
5956
5511
  const errorMsg = err.message;
5957
- logger25.warn("Failed to create merge request, trying to find existing one", {
5512
+ logger23.warn("Failed to create merge request, trying to find existing one", {
5958
5513
  iid: issue.iid,
5959
5514
  error: errorMsg
5960
5515
  });
@@ -5971,7 +5526,7 @@ var PipelineOrchestrator = class {
5971
5526
  this.config.project.baseBranch
5972
5527
  );
5973
5528
  if (existing) {
5974
- logger25.info("Found existing merge request", {
5529
+ logger23.info("Found existing merge request", {
5975
5530
  iid: issueIid,
5976
5531
  mrIid: existing.iid,
5977
5532
  mrUrl: existing.web_url
@@ -5979,7 +5534,7 @@ var PipelineOrchestrator = class {
5979
5534
  return { url: existing.web_url, iid: existing.iid };
5980
5535
  }
5981
5536
  } catch (findErr) {
5982
- logger25.warn("Failed to find existing merge request", {
5537
+ logger23.warn("Failed to find existing merge request", {
5983
5538
  iid: issueIid,
5984
5539
  error: findErr.message
5985
5540
  });
@@ -6024,7 +5579,7 @@ var PipelineOrchestrator = class {
6024
5579
  });
6025
5580
  return ports;
6026
5581
  } catch (err) {
6027
- logger25.error("Failed to start preview servers", {
5582
+ logger23.error("Failed to start preview servers", {
6028
5583
  iid: issue.iid,
6029
5584
  error: err.message
6030
5585
  });
@@ -6059,7 +5614,7 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6059
5614
  await this.mainGitMutex.runExclusive(async () => {
6060
5615
  await this.cleanupWorktree(wtCtx);
6061
5616
  });
6062
- logger25.info("Preview stopped and worktree cleaned", { iid: issueIid });
5617
+ logger23.info("Preview stopped and worktree cleaned", { iid: issueIid });
6063
5618
  }
6064
5619
  async markDeployed(issueIid) {
6065
5620
  const record = this.tracker.get(issueIid);
@@ -6076,7 +5631,7 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6076
5631
  try {
6077
5632
  await this.gongfeng.closeIssue(externalId);
6078
5633
  } catch (err) {
6079
- logger25.warn("Failed to close issue on Gongfeng", { iid: issueIid, error: err.message });
5634
+ logger23.warn("Failed to close issue on Gongfeng", { iid: issueIid, error: err.message });
6080
5635
  }
6081
5636
  try {
6082
5637
  const issue = await this.gongfeng.getIssueDetail(externalId);
@@ -6084,10 +5639,10 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6084
5639
  labels.push("auto-finish:deployed");
6085
5640
  await this.gongfeng.updateIssueLabels(externalId, labels);
6086
5641
  } catch (err) {
6087
- logger25.warn("Failed to update labels", { iid: issueIid, error: err.message });
5642
+ logger23.warn("Failed to update labels", { iid: issueIid, error: err.message });
6088
5643
  }
6089
5644
  this.tracker.updateState(issueIid, "deployed" /* Deployed */);
6090
- logger25.info("Issue marked as deployed", { iid: issueIid });
5645
+ logger23.info("Issue marked as deployed", { iid: issueIid });
6091
5646
  }
6092
5647
  async restartPreview(issueIid) {
6093
5648
  const record = this.tracker.get(issueIid);
@@ -6114,7 +5669,7 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6114
5669
  throw err;
6115
5670
  }
6116
5671
  const url = this.buildPreviewUrl(issueIid);
6117
- logger25.info("Preview restarted", { iid: issueIid, url });
5672
+ logger23.info("Preview restarted", { iid: issueIid, url });
6118
5673
  return url;
6119
5674
  }
6120
5675
  getPreviewHost() {
@@ -6147,7 +5702,7 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6147
5702
  if (!record) throw new IssueNotFoundError(issueIid);
6148
5703
  const baseBranch = this.config.project.baseBranch;
6149
5704
  const branchName = record.branchName;
6150
- logger25.info("Starting conflict resolution", { issueIid, branchName, baseBranch });
5705
+ logger23.info("Starting conflict resolution", { issueIid, branchName, baseBranch });
6151
5706
  this.tracker.updateState(issueIid, "resolving_conflict" /* ResolvingConflict */);
6152
5707
  this.eventBus.emitTyped("conflict:started", { issueIid });
6153
5708
  try {
@@ -6180,7 +5735,7 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6180
5735
  });
6181
5736
  }
6182
5737
  });
6183
- logger25.info("Running verification after conflict resolution", { issueIid });
5738
+ logger23.info("Running verification after conflict resolution", { issueIid });
6184
5739
  const wtPlan = new PlanPersistence(wtCtx.workDir, issueIid);
6185
5740
  wtPlan.ensureDir();
6186
5741
  const verifyPhase = createPhase("verify", this.aiRunner, wtGit, wtPlan, this.config);
@@ -6218,10 +5773,10 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6218
5773
  } catch {
6219
5774
  }
6220
5775
  await this.commentOnMr(record.mrUrl, t("conflict.mrResolvedComment"));
6221
- logger25.info("Conflict resolution completed", { issueIid });
5776
+ logger23.info("Conflict resolution completed", { issueIid });
6222
5777
  } catch (err) {
6223
5778
  const errorMsg = err.message;
6224
- logger25.error("Conflict resolution failed", { issueIid, error: errorMsg });
5779
+ logger23.error("Conflict resolution failed", { issueIid, error: errorMsg });
6225
5780
  try {
6226
5781
  const wtGit = new GitOperations(wtCtx.gitRootDir);
6227
5782
  if (await wtGit.isRebaseInProgress()) {
@@ -6251,7 +5806,7 @@ E2E \u6D4B\u8BD5\u5C06\u5C1D\u8BD5\u4F7F\u7528 config.json \u4E2D\u7684\u9ED8\u8
6251
5806
  try {
6252
5807
  await this.gongfeng.createMergeRequestNote(mrIid, body);
6253
5808
  } catch (err) {
6254
- logger25.warn("Failed to comment on MR", { mrIid, error: err.message });
5809
+ logger23.warn("Failed to comment on MR", { mrIid, error: err.message });
6255
5810
  }
6256
5811
  }
6257
5812
  };
@@ -6327,7 +5882,7 @@ ${questions}
6327
5882
  }
6328
5883
 
6329
5884
  // src/services/BrainstormService.ts
6330
- var logger26 = logger.child("Brainstorm");
5885
+ var logger24 = logger.child("Brainstorm");
6331
5886
  function agentConfigToAIConfig(agentCfg, timeoutMs) {
6332
5887
  return {
6333
5888
  mode: agentCfg.mode,
@@ -6363,7 +5918,7 @@ var BrainstormService = class {
6363
5918
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
6364
5919
  };
6365
5920
  this.sessions.set(session.id, session);
6366
- logger26.info("Created brainstorm session", { sessionId: session.id });
5921
+ logger24.info("Created brainstorm session", { sessionId: session.id });
6367
5922
  return session;
6368
5923
  }
6369
5924
  getSession(id) {
@@ -6372,7 +5927,7 @@ var BrainstormService = class {
6372
5927
  async generate(sessionId, onEvent) {
6373
5928
  const session = this.requireSession(sessionId);
6374
5929
  session.status = "generating";
6375
- logger26.info("Generating SDD", { sessionId });
5930
+ logger24.info("Generating SDD", { sessionId });
6376
5931
  const prompt = buildGeneratePrompt(session.transcript);
6377
5932
  const result = await this.generatorRunner.run({
6378
5933
  prompt,
@@ -6398,7 +5953,7 @@ var BrainstormService = class {
6398
5953
  const session = this.requireSession(sessionId);
6399
5954
  const roundNum = session.rounds.length + 1;
6400
5955
  session.status = "reviewing";
6401
- logger26.info("Reviewing SDD", { sessionId, round: roundNum });
5956
+ logger24.info("Reviewing SDD", { sessionId, round: roundNum });
6402
5957
  onEvent?.({ type: "round:start", data: { round: roundNum, phase: "review" }, round: roundNum });
6403
5958
  const prompt = buildReviewPrompt(session.currentSdd, roundNum);
6404
5959
  const result = await this.reviewerRunner.run({
@@ -6431,7 +5986,7 @@ var BrainstormService = class {
6431
5986
  throw new Error("No review round to refine from");
6432
5987
  }
6433
5988
  session.status = "refining";
6434
- logger26.info("Refining SDD", { sessionId, round: currentRound.round });
5989
+ logger24.info("Refining SDD", { sessionId, round: currentRound.round });
6435
5990
  const prompt = buildRefinePrompt(currentRound.questions);
6436
5991
  const result = await this.generatorRunner.run({
6437
5992
  prompt,
@@ -6518,4 +6073,4 @@ export {
6518
6073
  PipelineOrchestrator,
6519
6074
  BrainstormService
6520
6075
  };
6521
- //# sourceMappingURL=chunk-WZGEYHCC.js.map
6076
+ //# sourceMappingURL=chunk-OPWP73PW.js.map