@dependfix/engine 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.d.mts +2 -184
- package/dist/auth.mjs +1 -1
- package/dist/{auth2.mjs → chunks/auth.mjs} +9 -14
- package/dist/chunks/auth.mjs.map +1 -0
- package/dist/chunks/index.d.mts +254 -0
- package/dist/index.d.mts +1168 -242
- package/dist/index.mjs +11372 -5222
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -9
- package/dist/auth-provider.d.mts +0 -82
- package/dist/auth2.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as FromAppParams, l as FromPatParams, o as AuthProvider, s as AuthProviderOptions } from "./chunks/index.mjs";
|
|
2
2
|
import { Octokit } from "@octokit/rest";
|
|
3
|
-
import { AlertClass, AlertSeverity, AlertSourceKind, AppError, FixAction, FixError, Logger, NormalizedSecurityAlert, RepositoryResult, RunResult, RunSummary, SeverityThreshold, createEmptyRunSummary } from "@dependfix/core";
|
|
3
|
+
import { AlertClass, AlertFixOutcome, AlertSeverity, AlertSourceKind, AlertsDisabledRecord, AppError, BaselineRedDelivery, CheckAttribution, CheckConclusion, CiAlignmentRecord, CiAlignmentStatus, CiDefaultBranchHealth, CiMirrorSkipped, CiWorkflowEvidence, DeliverySkipRecord, FixAction, FixError, Logger, NormalizedSecurityAlert, PrCheckFailureSummary, PrCheckWatchReport, PrCheckWatchState, RepeatedAttemptRecord, RepositoryResult, RunResult, RunSummary, SeverityThreshold, VerifyCommandCategory, createEmptyRunSummary } from "@dependfix/core";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
//#region src/github/client.d.ts
|
|
6
5
|
export interface RetryPolicyOptions {
|
|
7
6
|
/** 最大重试次数(默认 3;0 = 不重试) */
|
|
8
7
|
maxRetries?: number;
|
|
@@ -30,7 +29,7 @@ export interface OctokitClientOptions {
|
|
|
30
29
|
*
|
|
31
30
|
* 保留作为低层入口;`token` 路径与 `auth: fromPat(token)` 行为等价
|
|
32
31
|
* (共享同一 retry policy 与限流重试 hook)。
|
|
33
|
-
*
|
|
32
|
+
* 计划在后续阶段评估移除。
|
|
34
33
|
*/
|
|
35
34
|
token?: string;
|
|
36
35
|
/**
|
|
@@ -62,7 +61,7 @@ export interface OctokitClientOptions {
|
|
|
62
61
|
*
|
|
63
62
|
* @example
|
|
64
63
|
* ```typescript
|
|
65
|
-
* // 推荐:使用 auth
|
|
64
|
+
* // 推荐:使用 auth 抽象层(已实施)
|
|
66
65
|
* import { fromPat } from '@dependfix/engine/auth'
|
|
67
66
|
* const octokit = createGitHubClient({ auth: fromPat('ghp_xxxx') })
|
|
68
67
|
*
|
|
@@ -100,8 +99,277 @@ export declare function createGitHubClient(options: OctokitClientOptions): Octok
|
|
|
100
99
|
* - 其他状态码
|
|
101
100
|
*/
|
|
102
101
|
export declare function computeRetryDelayMs(error: unknown, attempt: number, baseDelayMs?: number, maxBackoffMs?: number): number | null;
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
/** 修复策略(尝试键的策略维度;策略变化即视为不同尝试)。 */
|
|
103
|
+
export type PlanStrategy = 'direct-upgrade' | 'override' | 'member-upgrade' | 'family-lockstep';
|
|
104
|
+
/** 尝试键输入。 */
|
|
105
|
+
export interface AttemptKeyInput {
|
|
106
|
+
/** 告警源(dependabot / pnpm-audit;Code Scanning / Code Quality 不参与尝试计数) */
|
|
107
|
+
source: string;
|
|
108
|
+
/** 包名(同一告警族的稳定标识) */
|
|
109
|
+
packageName: string;
|
|
110
|
+
/** 目标版本(本次修复计划的推荐版本) */
|
|
111
|
+
targetVersion: string;
|
|
112
|
+
/** 修复策略(见 PlanStrategy) */
|
|
113
|
+
planStrategy: PlanStrategy;
|
|
114
|
+
}
|
|
115
|
+
/** 尝试键长度(hex 字符数)。 */
|
|
116
|
+
export declare const ATTEMPT_KEY_LENGTH = 16;
|
|
117
|
+
/** 失败签名归一化输入上限(字符数;失败命令 + 错误文本各截断到该长度)。 */
|
|
118
|
+
export declare const FAILURE_SIGNATURE_INPUT_LIMIT = 2048;
|
|
119
|
+
/**
|
|
120
|
+
* 计算同告警尝试键。
|
|
121
|
+
*
|
|
122
|
+
* 同一输入恒等;目标版本或修复策略变化 → 键变化(自然失效,不继承尝试计数)。
|
|
123
|
+
*/
|
|
124
|
+
export declare function computeAttemptKey(input: AttemptKeyInput): string;
|
|
125
|
+
/**
|
|
126
|
+
* 计算 CI 失败签名(8 位 hex)。
|
|
127
|
+
*
|
|
128
|
+
* 归一化:命令与错误文本各自折叠空白 + 截断到 2KB,再取 sha256 前 8 位。
|
|
129
|
+
* 签名只增强证据(失败是否同因),**不改变尝试计数口径**。
|
|
130
|
+
*/
|
|
131
|
+
export declare function computeFailureSignature(command: string, error: string): string;
|
|
132
|
+
/** PR 正文里的尝试标记(一个 PR 可携带多条:一次修复通常覆盖多条告警)。 */
|
|
133
|
+
export interface AttemptMarker {
|
|
134
|
+
/** 尝试键(16 位 hex) */
|
|
135
|
+
key: string;
|
|
136
|
+
/** 尝试序号(1 起) */
|
|
137
|
+
n: number;
|
|
138
|
+
/** CI 失败签名(可选;仅回写阶段存在) */
|
|
139
|
+
failureSignature?: string;
|
|
140
|
+
/** CI 结果(`0` 成功 / `1` 失败;缺省 = 未知) */
|
|
141
|
+
failed?: 0 | 1;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* 生成尝试标记(HTML 注释,渲染后不可见;置于正文头部以避免尾部截断丢失)。
|
|
145
|
+
*
|
|
146
|
+
* `n` 由调用方按「同键已关闭 PR 数 + 1」给出;解析侧只接受 1-9999(查询窗口 50 条 ⇒ 实际上界 51),
|
|
147
|
+
* 超出会被丢弃(fail-open)。
|
|
148
|
+
*/
|
|
149
|
+
export declare function formatAttemptMarker(marker: AttemptMarker): string;
|
|
150
|
+
/**
|
|
151
|
+
* 解析 PR 正文中的尝试标记(支持多条)。
|
|
152
|
+
*
|
|
153
|
+
* 容错口径:键格式非法 / 序数非正整数(仅接受 1-9999 的十进制)/ 签名或结果格式非法 →
|
|
154
|
+
* 丢弃该条(fail-open)。同一标记内重复属性按 **last-wins**(后写覆盖)。
|
|
155
|
+
*/
|
|
156
|
+
export declare function parseAttemptMarkers(body: string | null | undefined): AttemptMarker[];
|
|
157
|
+
/**
|
|
158
|
+
* 把本次运行的尝试记录折算为 PR 标记。
|
|
159
|
+
*
|
|
160
|
+
* - 跳过(`skipped`)不写标记:该告警本次未进入修复,写入会虚增后续计数
|
|
161
|
+
* - 传入 `executed`(本次实际产出的动作)时,只写「确实执行过」的键:pristine 安装基线失败 /
|
|
162
|
+
* 验证门禁回滚 / 无交付物等分支下,计划阶段已记录的键不会被执行,写标记会白白消耗一次额度
|
|
163
|
+
* - 同键去重取最大序号(多仓 / 同包多 GHSA 会产出重复键)
|
|
164
|
+
*/
|
|
165
|
+
export declare function collectAttemptMarkers(records: readonly RepeatedAttemptRecord[], executed?: ReadonlyArray<Pick<FixAction, 'type' | 'repository' | 'target' | 'noOp'>>): AttemptMarker[];
|
|
166
|
+
/** 默认查询条数(设计稿 §6.2:最近 50 条关闭 PR)。 */
|
|
167
|
+
export declare const CLOSED_ATTEMPT_QUERY_LIMIT = 50;
|
|
168
|
+
/** 一条已关闭的 dependfix PR(仅保留尝试计数所需字段)。 */
|
|
169
|
+
export interface ClosedAttemptPR {
|
|
170
|
+
number: number;
|
|
171
|
+
/** PR 链接(证据 / 后续报告展示用) */
|
|
172
|
+
htmlUrl: string;
|
|
173
|
+
/** head 分支名(后续 PR 创建后 CI 回环按分支定位 PR 时使用) */
|
|
174
|
+
headRef: string;
|
|
175
|
+
markers: AttemptMarker[];
|
|
176
|
+
}
|
|
177
|
+
export interface ClosedAttemptIndexOptions {
|
|
178
|
+
/** 单仓库查询条数(默认 `CLOSED_ATTEMPT_QUERY_LIMIT`;仅用于测试与调优) */
|
|
179
|
+
limit?: number;
|
|
180
|
+
/** 失败告警输出(缺省静默;由调用方决定是否可见) */
|
|
181
|
+
logger?: Pick<Logger, 'warn'>;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 运行级「已关闭 PR 尝试索引」。
|
|
185
|
+
*
|
|
186
|
+
* 缓存按 `owner/repo` 存 **Promise**:同仓库并发告警共享同一次请求(也缓存失败结果,
|
|
187
|
+
* 避免一次限流把后续每条告警都变成一次重试)。
|
|
188
|
+
*/
|
|
189
|
+
export declare class ClosedAttemptIndex {
|
|
190
|
+
private readonly cache;
|
|
191
|
+
private readonly limit;
|
|
192
|
+
private readonly logger?;
|
|
193
|
+
constructor(options?: ClosedAttemptIndexOptions);
|
|
194
|
+
/** 读取仓库最近关闭的 dependfix PR(运行级缓存;失败返回空数组)。 */
|
|
195
|
+
closedPRs(octokit: Octokit, owner: string, repo: string): Promise<ClosedAttemptPR[]>;
|
|
196
|
+
/** 同键已关闭(未合并)PR 数。 */
|
|
197
|
+
closedAttemptCount(octokit: Octokit, owner: string, repo: string, key: string): Promise<number>;
|
|
198
|
+
private load;
|
|
199
|
+
}
|
|
200
|
+
/** 单次解析的文件数上限(防超大仓库 / 恶意仓库拖慢运行)。 */
|
|
201
|
+
export declare const MAX_WORKFLOW_FILES = 20;
|
|
202
|
+
/** 单文件字节上限(超出按「未能读取」降级,不解析半截 YAML)。 */
|
|
203
|
+
export declare const MAX_WORKFLOW_BYTES: number;
|
|
204
|
+
/** 默认分支健康预检的 workflow 数上限(每个一次 API 调用,控制配额)。 */
|
|
205
|
+
export declare const CI_HEALTH_MAX_WORKFLOWS = 3;
|
|
206
|
+
/** 单次健康预检的请求超时(限流重试也被 signal 约束,避免拖住交付)。 */
|
|
207
|
+
export declare const CI_HEALTH_TIMEOUT_MS = 5000;
|
|
208
|
+
/** 单个 workflow 保留的结构化命令片段上限(仅镜像计划需要;超出即整体降级,不截断执行源)。 */
|
|
209
|
+
export declare const MAX_RUN_FRAGMENTS = 2000;
|
|
210
|
+
type FragmentClassification = {
|
|
211
|
+
kind: 'category';
|
|
212
|
+
category: VerifyCommandCategory;
|
|
213
|
+
} | {
|
|
214
|
+
kind: 'install';
|
|
215
|
+
} | {
|
|
216
|
+
kind: 'ignore';
|
|
217
|
+
} | {
|
|
218
|
+
kind: 'unrecognized';
|
|
219
|
+
command: string;
|
|
220
|
+
};
|
|
221
|
+
/** 识别单个命令片段(导出以便单测锁定口径)。 */
|
|
222
|
+
export declare function classifyCommandFragment(fragment: string): FragmentClassification;
|
|
223
|
+
/** workflow 解析结果(失败时给出可渲染的原因,不抛错)。 */
|
|
224
|
+
export type WorkflowParseResult = {
|
|
225
|
+
ok: true;
|
|
226
|
+
evidence: CiWorkflowEvidence;
|
|
227
|
+
runFragments: CiRunFragment[];
|
|
228
|
+
/** 片段数超上限(仅在收集时可能出现):调用方须整体降级,不得用截断后的片段做执行计划 */
|
|
229
|
+
runFragmentsTruncated?: boolean;
|
|
230
|
+
} | {
|
|
231
|
+
ok: false;
|
|
232
|
+
reason: string;
|
|
233
|
+
};
|
|
234
|
+
/** 结构化命令片段的收集选项(默认不收集:口径比对不需要执行源,避免大幅工作流占用内存)。 */
|
|
235
|
+
export interface RunFragmentOptions {
|
|
236
|
+
collectRunFragments?: boolean;
|
|
237
|
+
maxRunFragments?: number;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 结构化命令片段(执行源,**原始命令未截断**)。
|
|
241
|
+
*
|
|
242
|
+
* 与 `CiWorkflowEvidence.unrecognized` 的分工:后者是 PR 正文展示用途(截断 120 字符、
|
|
243
|
+
* 反引号替换、每文件上限 5 条),不能作为执行源;本结构保留全部片段与所属 workflow。
|
|
244
|
+
*
|
|
245
|
+
* - `recognized`:默认链已覆盖的语义项(lint / build / typecheck / test)与 install
|
|
246
|
+
* - `unrecognized`:其余可执行片段(未知脚本、`docker` / `gh` / 任意 shell、包管理器非脚本子命令)
|
|
247
|
+
*/
|
|
248
|
+
export interface CiRunFragment {
|
|
249
|
+
command: string;
|
|
250
|
+
kind: 'recognized' | 'unrecognized';
|
|
251
|
+
workflow: string;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 解析单个 workflow 文件:只读 `jobs.*.steps[].run`,产出语义项与未识别命令。
|
|
255
|
+
*
|
|
256
|
+
* 非 GitHub Actions(缺少 `jobs` 映射)与非法 YAML 均返回失败结果,
|
|
257
|
+
* 由调用方降级为「未能读取 CI 配置」。
|
|
258
|
+
*/
|
|
259
|
+
export declare function parseWorkflowCommands(path: string, content: string, options?: RunFragmentOptions): WorkflowParseResult;
|
|
260
|
+
/** workflow 文件源(相对路径 + 文本)。 */
|
|
261
|
+
export interface WorkflowSource {
|
|
262
|
+
path: string;
|
|
263
|
+
content: string;
|
|
264
|
+
}
|
|
265
|
+
/** 读取结果:失败时给出可渲染原因(无目录 / 无文件 / 读取失败 / 超限)。 */
|
|
266
|
+
export type WorkflowSourceResult = {
|
|
267
|
+
ok: true;
|
|
268
|
+
sources: WorkflowSource[];
|
|
269
|
+
} | {
|
|
270
|
+
ok: false;
|
|
271
|
+
reason: string;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* 读取工作目录下 `.github/workflows/*.yml|yaml`(只读、有界)。
|
|
275
|
+
*
|
|
276
|
+
* 读取的是**工作区检出**的内容(引擎在默认分支检出上修复,修复链不改 workflow),
|
|
277
|
+
* 因此等价于「默认分支的 CI 配置」;多仓共享同一工作目录时的粒度局限见设计文档。
|
|
278
|
+
*/
|
|
279
|
+
export declare function readWorkflowSources(workDir: string): WorkflowSourceResult;
|
|
280
|
+
/** 单次运行最多镜像执行的脚本条数(执行成本受控;超限部分记 `over-limit` 披露)。 */
|
|
281
|
+
export declare const MAX_MIRROR_COMMANDS = 3;
|
|
282
|
+
/** CI 脚本镜像计划(纯计算,不执行)。 */
|
|
283
|
+
export interface CiMirrorPlan {
|
|
284
|
+
/** 可执行命令(规范化为 `<包管理器> run <script>`,按 workflow 顺序去重,≤ maxCommands) */
|
|
285
|
+
runnable: string[];
|
|
286
|
+
/** 被跳过的片段与原因(已按命令 + 原因去重) */
|
|
287
|
+
skipped: CiMirrorSkipped[];
|
|
288
|
+
/** workflow 无法读取 / 解析失败的原因(此时不做任何镜像) */
|
|
289
|
+
unreadableReason?: string;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* 计算 CI 脚本镜像计划:读取 workflow → 结构化片段 → 归一化 → 脚本存在性校验 → 去重 / 上限。
|
|
293
|
+
*
|
|
294
|
+
* 只消费 `kind === 'unrecognized'` 的片段(默认链已覆盖的语义项与 install 不重复执行);
|
|
295
|
+
* 不能归一化为受支持脚本形态的片段、脚本不存在的片段分别记 `unsupported-command` /
|
|
296
|
+
* `script-not-found`,超出上限的可执行候选记 `over-limit`——全部披露,不静默丢弃。
|
|
297
|
+
*
|
|
298
|
+
* 本函数不执行任何命令;执行、超时、取消与基线归因由验证链统一承担。
|
|
299
|
+
*/
|
|
300
|
+
export declare function planCiMirrorCommands(workDir: string, options?: {
|
|
301
|
+
maxCommands?: number;
|
|
302
|
+
}): CiMirrorPlan;
|
|
303
|
+
/** 比对结果(`CiAlignmentRecord` 的可计算子集)。 */
|
|
304
|
+
export interface CiChainComparison {
|
|
305
|
+
status: CiAlignmentStatus;
|
|
306
|
+
ciCategories: VerifyCommandCategory[];
|
|
307
|
+
extraInExecution: VerifyCommandCategory[];
|
|
308
|
+
missingInExecution: VerifyCommandCategory[];
|
|
309
|
+
comparisonNote?: string;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* 比对「本次实际执行的命令集」与「CI 可识别命令类别」。
|
|
313
|
+
*
|
|
314
|
+
* 判定口径:
|
|
315
|
+
* - CI 无可识别类别 → `inconclusive`(不能凭「没识别到」宣称一致);
|
|
316
|
+
* - 本次无可识别类别(自定义命令链)→ `inconclusive`(不按类别硬判不一致);
|
|
317
|
+
* - CI 有而本次无 → `differs`(口径缺口);
|
|
318
|
+
* - 本次有而 CI 无 → `aligned` + `extraInExecution`(本次更严格,披露不判不一致)。
|
|
319
|
+
*/
|
|
320
|
+
export declare function compareVerificationChains(executedCommands: readonly string[], workflows: readonly CiWorkflowEvidence[]): CiChainComparison;
|
|
321
|
+
/** 最小 logger 接口(引擎 Logger 与测试桩均满足)。 */
|
|
322
|
+
export interface CiAlignmentLogger {
|
|
323
|
+
warn(message: string): void;
|
|
324
|
+
}
|
|
325
|
+
export interface WorkflowHealthParams {
|
|
326
|
+
client: Pick<Octokit, 'rest'>;
|
|
327
|
+
owner: string;
|
|
328
|
+
repo: string;
|
|
329
|
+
defaultBranch: string;
|
|
330
|
+
timeoutMs?: number;
|
|
331
|
+
maxWorkflows?: number;
|
|
332
|
+
logger?: CiAlignmentLogger;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* 只读「口径比对所依据的 workflow」在默认分支的最近一次运行结论。
|
|
336
|
+
*
|
|
337
|
+
* 单次调用 + 请求级超时(限流重试同受 signal 约束);任一调用失败只记日志并返回
|
|
338
|
+
* `unavailableReason`,调用方不得据此标注「默认分支失败」。
|
|
339
|
+
*/
|
|
340
|
+
export declare function fetchDefaultBranchWorkflowHealth(workflowPaths: readonly string[], params: WorkflowHealthParams): Promise<{
|
|
341
|
+
health: CiDefaultBranchHealth[];
|
|
342
|
+
unavailableReason?: string;
|
|
343
|
+
}>;
|
|
344
|
+
export interface CiAlignmentInput {
|
|
345
|
+
repository: string;
|
|
346
|
+
workDir: string;
|
|
347
|
+
/** 本次实际执行的验证命令(跳过 `package.json` 中不存在的脚本;首失败短路时只含已执行前缀) */
|
|
348
|
+
commands: string[];
|
|
349
|
+
/** GitHub 客户端(pnpm-audit / 无 token 时为 null ⇒ 只做本地解析,不做健康预检) */
|
|
350
|
+
client: Pick<Octokit, 'rest'> | null;
|
|
351
|
+
/** 默认分支(未知时不发起健康预检) */
|
|
352
|
+
defaultBranch?: string;
|
|
353
|
+
logger?: CiAlignmentLogger;
|
|
354
|
+
healthTimeoutMs?: number;
|
|
355
|
+
/** 跳过默认分支健康预检(复用上一轮结果时使用) */
|
|
356
|
+
skipHealth?: boolean;
|
|
357
|
+
/**
|
|
358
|
+
* CI 脚本镜像记录(`--mirror-ci-scripts` 开启时提供)。
|
|
359
|
+
* `mirrored` 只含实际执行的命令;`skipped` 为计划期跳过项。两者均为「披露」,不参与比对判定。
|
|
360
|
+
*/
|
|
361
|
+
mirror?: {
|
|
362
|
+
mirrored: string[];
|
|
363
|
+
skipped: CiMirrorSkipped[];
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* 构建单仓库口径记录:本地解析 → 类别比对 → (可选)默认分支健康预检。
|
|
368
|
+
*
|
|
369
|
+
* 本函数不抛错:任何解析 / 网络问题都降级为 `unreadable` / `inconclusive` /
|
|
370
|
+
* `healthUnavailableReason`,调用方据此记录但不得阻断修复与交付。
|
|
371
|
+
*/
|
|
372
|
+
export declare function buildCiAlignmentRecord(input: CiAlignmentInput): Promise<CiAlignmentRecord>;
|
|
105
373
|
export interface FetchCodeQualityFindingsParams {
|
|
106
374
|
/** 仓库所属组织或用户 */
|
|
107
375
|
owner: string;
|
|
@@ -142,8 +410,6 @@ export declare function fetchCodeQualityFindings(client: Octokit, params: FetchC
|
|
|
142
410
|
* 映射口径与 `mapCodeScanningSeverity` 对齐(避免新源不一致)。
|
|
143
411
|
*/
|
|
144
412
|
export declare function mapCodeQualitySeverity(severity: string | null | undefined): AlertSeverity;
|
|
145
|
-
//#endregion
|
|
146
|
-
//#region src/github/code-scanning-fetcher.d.ts
|
|
147
413
|
export interface FetchCodeScanningAlertsParams {
|
|
148
414
|
/** 仓库所属组织或用户 */
|
|
149
415
|
owner: string;
|
|
@@ -174,8 +440,115 @@ export interface FetchCodeScanningAlertsParams {
|
|
|
174
440
|
* @returns 标准化告警列表
|
|
175
441
|
*/
|
|
176
442
|
export declare function fetchCodeScanningAlerts(client: Octokit, params: FetchCodeScanningAlertsParams): Promise<NormalizedSecurityAlert[]>;
|
|
177
|
-
|
|
178
|
-
|
|
443
|
+
/** 提交集合判定失败的两类信号(写入 `FixError.category`)。 */
|
|
444
|
+
export type CommitScopeErrorCode = 'UNEXPECTED_CHANGES' | 'NO_CHANGES';
|
|
445
|
+
export declare class CommitScopeError extends Error {
|
|
446
|
+
readonly category: CommitScopeErrorCode;
|
|
447
|
+
readonly paths: readonly string[];
|
|
448
|
+
constructor(category: CommitScopeErrorCode, message: string, paths?: readonly string[]);
|
|
449
|
+
}
|
|
450
|
+
/** 一条工作区改动(workDir 相对、POSIX 分隔符)。 */
|
|
451
|
+
export interface ChangedPath {
|
|
452
|
+
path: string;
|
|
453
|
+
untracked: boolean;
|
|
454
|
+
deleted: boolean;
|
|
455
|
+
/** 索引区已有改动(已暂存):`git commit` 会连带提交,必须纳入提交集合判定 */
|
|
456
|
+
staged: boolean;
|
|
457
|
+
/** 未合并冲突(`UU` / `AA` / `DD` 等):`git add` 会按工作树一侧静默「解决」,必须拒绝 */
|
|
458
|
+
conflicted: boolean;
|
|
459
|
+
/** 位于 workDir 之外(workDir 为仓库子目录时):索引区改动仍会被 commit 带入 */
|
|
460
|
+
outside: boolean;
|
|
461
|
+
}
|
|
462
|
+
/** 被拒绝的声明路径。 */
|
|
463
|
+
export interface PathRejection {
|
|
464
|
+
path: string;
|
|
465
|
+
reason: string;
|
|
466
|
+
}
|
|
467
|
+
/** 提交集合判定结果。 */
|
|
468
|
+
export interface CommitScope {
|
|
469
|
+
/** 需要暂存的路径(已排序,便于确定性提交) */
|
|
470
|
+
paths: string[];
|
|
471
|
+
/** 未声明的已跟踪改动(非空即拒绝提交) */
|
|
472
|
+
unexpected: string[];
|
|
473
|
+
/** 生成物 / 未声明的新文件(不提交;仅留痕) */
|
|
474
|
+
ignored: string[];
|
|
475
|
+
/** 声明路径不合法(拒绝提交) */
|
|
476
|
+
rejected: PathRejection[];
|
|
477
|
+
/** 声明了但工作区没有对应改动(仅留痕,不阻断) */
|
|
478
|
+
missing: string[];
|
|
479
|
+
/** 索引区已有的改动(已暂存) */
|
|
480
|
+
staged: string[];
|
|
481
|
+
/** 未合并冲突路径 */
|
|
482
|
+
conflicts: string[];
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* 路径是否在白名单内。
|
|
486
|
+
*
|
|
487
|
+
* `package.json` 允许任意层级(monorepo 成员 manifest 由成员级修复写盘);lockfile /
|
|
488
|
+
* workspace 配置 / `.npmrc` / `.gitignore` 只允许仓库根(引擎不会写嵌套位置的这些文件)。
|
|
489
|
+
*/
|
|
490
|
+
export declare function isCommitWhitelisted(path: string): boolean;
|
|
491
|
+
/** 是否为构建 / 安装生成物(一律不提交,也不触发未声明告警)。 */
|
|
492
|
+
export declare function isGeneratedPath(path: string): boolean;
|
|
493
|
+
/**
|
|
494
|
+
* 校验并归一化 fixer / AI patch 声明路径。
|
|
495
|
+
*
|
|
496
|
+
* 拒绝:绝对路径(含 Windows 盘符)、`..` 段、pathspec magic(`:(` 开头)、控制字符、空路径。
|
|
497
|
+
* 归一化:`\` → `/`、去掉 `./` 与重复分隔符(Windows 上 `path.relative` 产出 `\`)。
|
|
498
|
+
*/
|
|
499
|
+
export declare function normalizeCommitPath(raw: string): {
|
|
500
|
+
ok: true;
|
|
501
|
+
path: string;
|
|
502
|
+
} | {
|
|
503
|
+
ok: false;
|
|
504
|
+
reason: string;
|
|
505
|
+
};
|
|
506
|
+
/**
|
|
507
|
+
* 列出工作区改动(`git status` 单一事实源)。
|
|
508
|
+
*
|
|
509
|
+
* - `--untracked-files=all`:展开未跟踪目录,避免把整目录当一项
|
|
510
|
+
* - `--no-renames`:重命名拆成「删除 + 新增」,删除因此不会绕过未声明检测
|
|
511
|
+
* - 输出路径相对**仓库根**:按 `--show-prefix` 折算为 workDir 相对路径(workDir 可为子目录)
|
|
512
|
+
*/
|
|
513
|
+
export declare function listChangedPaths(workDir: string): Promise<ChangedPath[]>;
|
|
514
|
+
/** 从修复动作收集声明路径(仅成功且非 noOp 的动作)。 */
|
|
515
|
+
export declare function collectDeclaredPaths(actions: readonly FixAction[]): string[];
|
|
516
|
+
/** `stageAndCommit` 的可选声明路径。 */
|
|
517
|
+
export interface StageAndCommitOptions {
|
|
518
|
+
/** fixer / AI patch 声明的相对路径(与固定白名单取并集) */
|
|
519
|
+
declaredPaths?: readonly string[];
|
|
520
|
+
}
|
|
521
|
+
/** 暂存结果(留痕 / 断言用)。 */
|
|
522
|
+
export interface StageAndCommitResult {
|
|
523
|
+
/** 实际暂存的路径 */
|
|
524
|
+
staged: string[];
|
|
525
|
+
/** 因生成物 / 未跟踪而跳过的路径 */
|
|
526
|
+
ignored: string[];
|
|
527
|
+
/** 声明了但工作区没有对应改动 */
|
|
528
|
+
missing: string[];
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* 判定并暂存提交集合。
|
|
532
|
+
*
|
|
533
|
+
* 拒绝:非法声明路径 / 未声明的已跟踪改动(`UNEXPECTED_CHANGES`)、空集合(`NO_CHANGES`)、
|
|
534
|
+
* 索引区越界暂存内容(`UNEXPECTED_CHANGES`)。暂存用 `git add -- <paths>`(分批;`--` 阻断选项解析,
|
|
535
|
+
* 每条路径加 `:(literal)` 终止通配,文件名含 `*` / `?` / `[` 时也只暂存字面路径)。
|
|
536
|
+
*/
|
|
537
|
+
export declare function stageScopedChanges(workDir: string, declaredPaths?: readonly string[]): Promise<StageAndCommitResult>;
|
|
538
|
+
/**
|
|
539
|
+
* 提交已暂存内容(不动提交集合)。
|
|
540
|
+
*
|
|
541
|
+
* author / 签名 / hooks 三条隔离:显式 `-c user.name` / `-c user.email` 覆盖 host 全局,
|
|
542
|
+
* `-c commit.gpgsign=false` 阻断宿主签名,`--no-verify` 跳过目标仓库钩子(详见 ./git-signing.ts)。
|
|
543
|
+
*/
|
|
544
|
+
export declare function commitStaged(message: string, workDir: string, author: {
|
|
545
|
+
name: string;
|
|
546
|
+
email: string;
|
|
547
|
+
}): Promise<void>;
|
|
548
|
+
/** 判定本次提交集合(不写盘、不暂存)。 */
|
|
549
|
+
export declare function computeCommitScope(workDir: string, declaredPaths?: readonly string[]): Promise<CommitScope>;
|
|
550
|
+
/** 按固定大小切分路径(`git add` 的 argv 上限防护)。 */
|
|
551
|
+
export declare function chunkPaths(paths: readonly string[], size?: number): string[][];
|
|
179
552
|
export interface FetchDependabotAlertsParams {
|
|
180
553
|
/** 仓库所属组织或用户 */
|
|
181
554
|
owner: string;
|
|
@@ -203,7 +576,7 @@ export interface FetchDependabotAlertsParams {
|
|
|
203
576
|
*
|
|
204
577
|
* @example
|
|
205
578
|
* ```typescript
|
|
206
|
-
* // 推荐:使用 auth
|
|
579
|
+
* // 推荐:使用 auth 抽象层(已实施)
|
|
207
580
|
* import { fromPat } from '@dependfix/engine/auth'
|
|
208
581
|
* const octokit = createGitHubClient({ auth: fromPat('ghp_xxxx') })
|
|
209
582
|
* const alerts = await fetchDependabotAlerts(octokit, { owner: 'foo', repo: 'bar' })
|
|
@@ -213,8 +586,6 @@ export interface FetchDependabotAlertsParams {
|
|
|
213
586
|
* ```
|
|
214
587
|
*/
|
|
215
588
|
export declare function fetchDependabotAlerts(client: Octokit, params: FetchDependabotAlertsParams): Promise<NormalizedSecurityAlert[]>;
|
|
216
|
-
//#endregion
|
|
217
|
-
//#region src/github/errors.d.ts
|
|
218
589
|
/**
|
|
219
590
|
* 将 Octokit 请求错误映射为 `AppError`。
|
|
220
591
|
*
|
|
@@ -222,8 +593,200 @@ export declare function fetchDependabotAlerts(client: Octokit, params: FetchDepe
|
|
|
222
593
|
* @param context - 调用上下文描述(如 `'fetch repo info for foo/bar'`),会附加到错误消息中
|
|
223
594
|
*/
|
|
224
595
|
export declare function mapGitHubError(error: unknown, context: string): AppError;
|
|
225
|
-
|
|
226
|
-
|
|
596
|
+
/**
|
|
597
|
+
* git 执行语义隔离参数(单一事实源,engine 与平台侧共用)。
|
|
598
|
+
*
|
|
599
|
+
* 两类隔离:
|
|
600
|
+
* 1. **签名语义**:宿主 `commit.gpgsign=true` / `push.gpgSign=true` 会让 dependfix 的 commit 带上宿主个人签名
|
|
601
|
+
* (或直接失败)、push 带上 `--signed`(服务端 `receive-pack` 不支持时报
|
|
602
|
+
* `the receiving end does not support --signed push`)。以 `-c <key>=false` 形式仅作用于该次调用
|
|
603
|
+
* 即可隔离,且不写回任何配置文件;`-c` 的优先级高于 repo local / worktree / host global / system。
|
|
604
|
+
* 背景与取证口径见 docs/standards/git.md §3.8。
|
|
605
|
+
* 2. **hooks 语义**:被修复仓库若安装 husky / lint-staged(或自定义 `core.hooksPath`),其 `pre-commit` /
|
|
606
|
+
* `commit-msg` 钩子会在 dependfix 的自动 commit 时执行,`pre-push` 会在推送修复分支时执行。这类钩子依赖
|
|
607
|
+
* `npx` 与目标仓库完整 `node_modules`,在隔离执行环境下通常不可用——生产实证会以 `npx: not found`(exit 127)
|
|
608
|
+
* 中断 commit,进而触发 `COMMIT_FAILED` 与修复回滚(push 侧同类失效会触发 `push_failed`)。自动提交 / 推送
|
|
609
|
+
* 不应受目标仓库本地开发钩子约束,故在本次 commit / push 调用内分别跳过 commit 侧与 push 侧钩子。
|
|
610
|
+
*
|
|
611
|
+
* 策略:**不提供签名 / hooks opt-in**。
|
|
612
|
+
*/
|
|
613
|
+
/** commit 侧签名隔离参数。 */
|
|
614
|
+
export declare const GIT_COMMIT_SIGNING_ISOLATION_ARGS: readonly ["-c", "commit.gpgsign=false"];
|
|
615
|
+
/**
|
|
616
|
+
* commit 侧 hooks 隔离参数——须置于 `commit` 子命令**之后**(`--no-verify` 是 commit 的子命令选项,
|
|
617
|
+
* 而 `-c` 是 git 全局选项,二者位置不可互换)。
|
|
618
|
+
*
|
|
619
|
+
* 选型 `--no-verify` 而非 `-c core.hooksPath=<空目录>`:跨平台无需构造/保证目录存在,且同样覆盖
|
|
620
|
+
* husky 的 `core.hooksPath` 重定向场景(实测对 `pre-commit` 非 0 退出与 `core.hooksPath` 两者等效,
|
|
621
|
+
* 见 pr-creator.test.ts 的 hooks 隔离回归)。
|
|
622
|
+
*
|
|
623
|
+
* 边界:`--no-verify` 跳过 `pre-commit` / `commit-msg` / `prepare-commit-msg`,但**不跳过** `post-commit`
|
|
624
|
+
* (git 语义:`post-commit` 在 commit 完成后运行且不能改变结果,其失败不影响 commit 成败)。
|
|
625
|
+
*/
|
|
626
|
+
export declare const GIT_COMMIT_HOOKS_ISOLATION_ARGS: readonly ["--no-verify"];
|
|
627
|
+
/** push 侧签名隔离参数——覆盖 push / push --delete 等全部推送调用点。 */
|
|
628
|
+
export declare const GIT_PUSH_SIGNING_ISOLATION_ARGS: readonly ["-c", "push.gpgSign=false"];
|
|
629
|
+
/**
|
|
630
|
+
* push 侧 hooks 隔离参数——须置于 `push` 子命令**之后**(`--no-verify` 是 push 的子命令选项,
|
|
631
|
+
* 而 `-c` 是 git 全局选项,二者位置不可互换)。
|
|
632
|
+
*
|
|
633
|
+
* 覆盖 `pre-push`:被修复仓库的 `pre-push`(husky / 自定义 `core.hooksPath`)会在 dependfix 推送
|
|
634
|
+
* 修复分支时执行;隔离环境无 `npx` / 目标仓库 `node_modules` 不完整 → hook 非 0 退出 → `push_failed`
|
|
635
|
+
* → 交付链中断(与 commit 侧 `pre-commit` / `commit-msg` 同一类失效)。生产日志当前无 `pre-push`
|
|
636
|
+
* 实例,属预防性收口(口径见 docs/standards/git.md §3.8)。
|
|
637
|
+
*
|
|
638
|
+
* 边界:仅跳过 `pre-push`;同时适用于 `push --delete`(`cleanupRemoteBranch`)。
|
|
639
|
+
* 选型 `--no-verify` 与 commit 侧一致——无需构造/保证空 `core.hooksPath` 目录,且对
|
|
640
|
+
* `core.hooksPath` 重定向场景等效。
|
|
641
|
+
*/
|
|
642
|
+
export declare const GIT_PUSH_HOOKS_ISOLATION_ARGS: readonly ["--no-verify"];
|
|
643
|
+
/** 首次轮询间隔。 */
|
|
644
|
+
export declare const PR_CHECK_POLL_INITIAL_MS = 15000;
|
|
645
|
+
/** 轮询间隔退避上限。 */
|
|
646
|
+
export declare const PR_CHECK_POLL_MAX_MS = 60000;
|
|
647
|
+
/** 宽限期:创建后至少等这么久、且至少两轮轮询才允许判定 `no_ci_detected`。 */
|
|
648
|
+
export declare const PR_CHECK_GRACE_MS = 60000;
|
|
649
|
+
/** 单 PR 等待上限默认值(15 分钟)。 */
|
|
650
|
+
export declare const DEFAULT_PR_CHECK_TIMEOUT_MS = 900000;
|
|
651
|
+
/** 运行级等待总预算默认值(20 分钟)。 */
|
|
652
|
+
export declare const DEFAULT_PR_CHECK_RUN_BUDGET_MS = 1200000;
|
|
653
|
+
/** GitHub Actions job 预算基线(与 `security-auto-fix.yml` 的 `timeout-minutes: 25` 对齐)。 */
|
|
654
|
+
export declare const DEFAULT_JOB_BUDGET_MS: number;
|
|
655
|
+
/** 等待最多占用「剩余 job 预算」的比例(给 install / 验证 / 收尾留余量)。 */
|
|
656
|
+
export declare const JOB_BUDGET_MAX_SHARE = 0.7;
|
|
657
|
+
/** 报告与评论中保留的失败 job 数上限。 */
|
|
658
|
+
export declare const FAILED_CHECK_SUMMARY_LIMIT = 5;
|
|
659
|
+
/** 单 PR 轮询次数上限(按 15s→60s 退避,15 分钟预算约 20 轮;上限防注入时钟不前进导致空转)。 */
|
|
660
|
+
export declare const PR_CHECK_MAX_POLLS = 200;
|
|
661
|
+
/** 归一化观测到的一条 check(check run 或 commit status)。 */
|
|
662
|
+
export interface ObservedCheck {
|
|
663
|
+
/** 来源:check run / commit status(同名多轮组键的一部分) */
|
|
664
|
+
kind: 'check' | 'status';
|
|
665
|
+
/** provider 归因(check `app.slug` / status `context` 前缀;与平台同源) */
|
|
666
|
+
provider: string;
|
|
667
|
+
name: string;
|
|
668
|
+
conclusion: CheckConclusion;
|
|
669
|
+
/** 详情页 URL(check 用它提取 Actions run id 作为重跑血缘) */
|
|
670
|
+
url?: string;
|
|
671
|
+
/** 失败详情文本(用于 external_noise 文本签名) */
|
|
672
|
+
detail?: string;
|
|
673
|
+
/** 源侧 id(同名多轮收敛的确定性兜底,见 {@link dedupeObservedChecksByLatestRound}) */
|
|
674
|
+
id?: string | null;
|
|
675
|
+
/** 轮次时间戳(check `started_at ?? completed_at` / status `updated_at ?? created_at`) */
|
|
676
|
+
roundAt?: string | null;
|
|
677
|
+
}
|
|
678
|
+
export interface WatchPrChecksParams {
|
|
679
|
+
octokit: Octokit;
|
|
680
|
+
owner: string;
|
|
681
|
+
repo: string;
|
|
682
|
+
pr: {
|
|
683
|
+
number: number;
|
|
684
|
+
htmlUrl: string;
|
|
685
|
+
};
|
|
686
|
+
/** PR head 分支(作为 check 查询 ref 的兜底) */
|
|
687
|
+
headBranch: string;
|
|
688
|
+
/** PR head 提交 SHA(用于精确查询与父提交比对;缺省回退分支名) */
|
|
689
|
+
headSha?: string;
|
|
690
|
+
/** 本次 PR 携带的尝试标记(写进失败评论,便于后续计数追溯) */
|
|
691
|
+
attempts?: readonly AttemptMarker[];
|
|
692
|
+
/** 单 PR 等待上限(毫秒) */
|
|
693
|
+
timeoutMs: number;
|
|
694
|
+
/** 运行级等待总预算(毫秒) */
|
|
695
|
+
runBudgetMs: number;
|
|
696
|
+
/** 剩余 job 预算(毫秒);缺省不参与折算 */
|
|
697
|
+
jobBudgetRemainingMs?: number;
|
|
698
|
+
dryRun: boolean;
|
|
699
|
+
closeFailedPr: boolean;
|
|
700
|
+
logger: Pick<Logger, 'info' | 'warn' | 'error'>;
|
|
701
|
+
/** 注入时钟 / 休眠(测试用;缺省真实实现) */
|
|
702
|
+
sleep?: (ms: number) => Promise<void>;
|
|
703
|
+
now?: () => number;
|
|
704
|
+
}
|
|
705
|
+
export interface WatchPrChecksResult {
|
|
706
|
+
state: PrCheckWatchState;
|
|
707
|
+
attribution?: CheckAttribution;
|
|
708
|
+
closed: boolean;
|
|
709
|
+
commented: boolean;
|
|
710
|
+
polls: number;
|
|
711
|
+
durationMs: number;
|
|
712
|
+
failedChecks?: PrCheckFailureSummary[];
|
|
713
|
+
reason?: string;
|
|
714
|
+
commentError?: string;
|
|
715
|
+
closeError?: string;
|
|
716
|
+
/** `timeout` 时绑定到哪一层预算 */
|
|
717
|
+
budgetLimit?: BudgetLimit;
|
|
718
|
+
}
|
|
719
|
+
/** 预算绑定来源(超时时用于报告 / 评论归因)。 */
|
|
720
|
+
export type BudgetLimit = 'pr' | 'run' | 'job';
|
|
721
|
+
/**
|
|
722
|
+
* 有效等待上限 = min(per-PR 上限, per-run 预算, 剩余 job 预算 × 70%),并回传绑定来源。
|
|
723
|
+
*
|
|
724
|
+
* 剩余 job 预算为负 / 0 时立即超时(不再占用 job 时间)。非有限值(NaN / Infinity)按耗尽处理,
|
|
725
|
+
* 避免 `sleep(NaN)` 造成空转。
|
|
726
|
+
*/
|
|
727
|
+
export declare function resolveEffectiveTimeout(params: {
|
|
728
|
+
timeoutMs: number;
|
|
729
|
+
runBudgetMs: number;
|
|
730
|
+
jobBudgetRemainingMs?: number;
|
|
731
|
+
}): {
|
|
732
|
+
timeoutMs: number;
|
|
733
|
+
limit: BudgetLimit;
|
|
734
|
+
};
|
|
735
|
+
/** check run 结论 → 归一化结论(未完成统一 `pending`)。 */
|
|
736
|
+
export declare function normalizeCheckRunConclusion(status: string | null | undefined, conclusion: string | null | undefined): CheckConclusion;
|
|
737
|
+
/** commit status state → 归一化结论(`error` 归一为 `failure`)。 */
|
|
738
|
+
export declare function normalizeCommitStatusConclusion(state: string | null | undefined): CheckConclusion;
|
|
739
|
+
/**
|
|
740
|
+
* 清洗来自目标仓库的 check / status URL(不可信文本)。
|
|
741
|
+
*
|
|
742
|
+
* 只接受 `http(s)`;剥离控制字符与空白(防换行截断),并把括号与竖线百分号编码(防 Markdown 链接结构与表格单元格被劫持)。
|
|
743
|
+
*/
|
|
744
|
+
export declare function sanitizeCheckUrl(value: string | null | undefined): string | undefined;
|
|
745
|
+
/** 清洗来自目标仓库的 check / job 名(不可信文本):去控制字符与换行、压缩空白、截断。 */
|
|
746
|
+
export declare function sanitizeCheckName(value: string | null | undefined): string;
|
|
747
|
+
interface TerminalEvaluation {
|
|
748
|
+
state: PrCheckWatchState;
|
|
749
|
+
attribution?: CheckAttribution;
|
|
750
|
+
failedChecks?: PrCheckFailureSummary[];
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* 同名多轮收敛:同一「组键」只保留**最新一轮**(与平台 `dedupeSignalsByLatestRound` 同源,
|
|
754
|
+
* 组键与排序均由 `@dependfix/core` 的 `checkRoundKey` / `dedupeByLatestRound` 提供)。
|
|
755
|
+
*
|
|
756
|
+
* 触发场景:check run re-run(同一 workflow run 的同名新尝试)、同一 commit status context 的后发状态。
|
|
757
|
+
* 组键含 `kind` / `provider`:check run 与 commit status 同名、或同名 job 由不同 App 上报时**不合并**;
|
|
758
|
+
* check 还要求能证明同一条 workflow run(`details_url` 里的 run id),否则各自成组——
|
|
759
|
+
* 「push 触发」与「pull_request 触发」是同名不同 run,合并会掩蔽另一方的失败。
|
|
760
|
+
* 口径见 docs/design/governance/pr-build-deploy-signals.md §3.10。
|
|
761
|
+
*/
|
|
762
|
+
export declare function dedupeObservedChecksByLatestRound(checks: readonly ObservedCheck[]): ObservedCheck[];
|
|
763
|
+
/**
|
|
764
|
+
* 判定终态;未到终态返回 `undefined`(继续轮询)。
|
|
765
|
+
*
|
|
766
|
+
* 终态条件:已观测到至少一条 check,且全部 check 已完成(无 `pending`)。
|
|
767
|
+
* `completed + conclusion=null` 归一为 `unknown` 结论(`isFailedConclusion` 判失败,fail-closed),
|
|
768
|
+
* 与平台侧 `resolveCheckRunState` 同口径(docs/design/governance/pr-build-deploy-signals.md §3.10)。
|
|
769
|
+
* - 存在失败 → `failed`(逐条归因后聚合;混合归因 → `unknown`)
|
|
770
|
+
* - 无失败且有成功 → `passed`
|
|
771
|
+
* - 无失败且无成功(全是 cancelled / skipped / neutral)→ `cancelled`
|
|
772
|
+
*/
|
|
773
|
+
export declare function evaluateCheckTerminal(params: WatchPrChecksParams, observedChecks: readonly ObservedCheck[]): Promise<TerminalEvaluation | undefined>;
|
|
774
|
+
/** 构造失败评论正文(job 名 + URL + 归因 + 尝试标记)。 */
|
|
775
|
+
export declare function buildCheckFailureComment(params: {
|
|
776
|
+
prNumber: number;
|
|
777
|
+
state: PrCheckWatchState;
|
|
778
|
+
attribution?: CheckAttribution;
|
|
779
|
+
failedChecks?: readonly PrCheckFailureSummary[];
|
|
780
|
+
reason?: string;
|
|
781
|
+
attempts?: readonly AttemptMarker[];
|
|
782
|
+
closed?: boolean;
|
|
783
|
+
}): string;
|
|
784
|
+
/**
|
|
785
|
+
* 等待 PR check 终态并按归因处置。
|
|
786
|
+
*
|
|
787
|
+
* 任何 API / 评论 / 关闭失败都只降级记录,不抛错(调用方不因等待失败改变运行结论)。
|
|
788
|
+
*/
|
|
789
|
+
export declare function watchPullRequestChecks(params: WatchPrChecksParams): Promise<WatchPrChecksResult>;
|
|
227
790
|
export interface CreatePullRequestParams {
|
|
228
791
|
/** 已认证的 Octokit 实例 */
|
|
229
792
|
octokit: Octokit;
|
|
@@ -239,12 +802,21 @@ export interface CreatePullRequestParams {
|
|
|
239
802
|
title: string;
|
|
240
803
|
/** PR 内容(Markdown) */
|
|
241
804
|
body: string;
|
|
805
|
+
/**
|
|
806
|
+
* 创建为草稿 PR(基线红的交付降级 `draft` 档使用)。
|
|
807
|
+
*
|
|
808
|
+
* 草稿态让目标仓库 CI 仍会按既有失败为红,但不会触发人工 review 队列;
|
|
809
|
+
* 缺省 / `false` 时请求体不带 `draft`,与既有行为逐字一致。
|
|
810
|
+
*/
|
|
811
|
+
draft?: boolean;
|
|
242
812
|
}
|
|
243
813
|
export interface PullRequestResult {
|
|
244
814
|
/** PR 编号 */
|
|
245
815
|
number: number;
|
|
246
816
|
/** PR HTML URL */
|
|
247
817
|
htmlUrl: string;
|
|
818
|
+
/** PR head 提交 SHA(check 回环用它精确查询;响应缺省时 undefined) */
|
|
819
|
+
headSha?: string;
|
|
248
820
|
}
|
|
249
821
|
export interface FixBranchResult {
|
|
250
822
|
/** 分支名 */
|
|
@@ -261,6 +833,8 @@ export interface DependfixOpenPR {
|
|
|
261
833
|
/** PR head 分支名 */
|
|
262
834
|
headRef: string;
|
|
263
835
|
}
|
|
836
|
+
/** 自动修复分支统一前缀(分支名 = 前缀 + 内容指纹 8 位) */
|
|
837
|
+
export declare const DEPENDFIX_BRANCH_PREFIX = "dependfix/auto-fix-";
|
|
264
838
|
/**
|
|
265
839
|
* 计算修复内容指纹(sha256 前 8 位)。
|
|
266
840
|
*
|
|
@@ -306,27 +880,33 @@ export declare function computeFixAndPrPlan(existingPRs: DependfixOpenPR[], fing
|
|
|
306
880
|
*
|
|
307
881
|
* @returns 分支名和是否为新创建
|
|
308
882
|
*/
|
|
309
|
-
export declare function createFixBranch(branchName: string, workDir: string): FixBranchResult
|
|
883
|
+
export declare function createFixBranch(branchName: string, workDir: string): Promise<FixBranchResult>;
|
|
310
884
|
/**
|
|
311
|
-
*
|
|
312
|
-
* 自动设置 git user.name / user.email(如未设置)。
|
|
313
|
-
* 使用 `execFileSync` 参数数组形式(不经 shell),保证多行 commit message
|
|
314
|
-
* 与 UTF-8 字符(如 →)在 Windows/Linux 双平台传递一致。
|
|
315
|
-
*
|
|
316
|
-
* W3 修复(M18.4 audit round 2):显式传 `-c user.name=X -c user.email=Y` 强制 commit author
|
|
317
|
-
* 使用传入值,不受 host 全局 `user.name`(如 CaoMeiYouRen)污染——`git commit` 走 lookup order
|
|
318
|
-
* (env → `-c` config → local → global → system),显式 `-c` 在 lookup order 中最高优先。
|
|
885
|
+
* 暂存修复相关文件并提交。
|
|
319
886
|
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
887
|
+
* 提交集合由 [stageScopedChanges] 判定(固定白名单 ∪ fixer 声明路径,生成物剔除):
|
|
888
|
+
* 未声明的已跟踪改动抛 `UNEXPECTED_CHANGES`,空集合抛 `NO_CHANGES`——不再通配暂存,
|
|
889
|
+
* 避免把目标仓库的生成物与用户未提交改动带进 PR。author / 签名 / hooks 三条隔离见
|
|
890
|
+
* [commitStaged] 与 ./git-signing.ts。
|
|
322
891
|
*
|
|
323
|
-
* @
|
|
892
|
+
* @param author - 可选 commit author;不传时使用 PAT 默认值(GitHub App 路径传动态 author)
|
|
893
|
+
* @throws {CommitScopeError} 提交集合含未声明改动 / 非法声明路径 / 为空
|
|
894
|
+
* @see [M48.4 提交面白名单 §7](../../../../docs/design/governance/pr-delivery-closure.md#7-m484-提交面白名单与-yaml-定点编辑)
|
|
324
895
|
*/
|
|
325
896
|
export declare function stageAndCommit(message: string, workDir: string, author?: {
|
|
326
897
|
name: string;
|
|
327
898
|
email: string;
|
|
328
|
-
}):
|
|
329
|
-
|
|
899
|
+
}, options?: StageAndCommitOptions): Promise<StageAndCommitResult>;
|
|
900
|
+
/**
|
|
901
|
+
* 推送分支到 origin。
|
|
902
|
+
*
|
|
903
|
+
* 隔离(单一事实源见 ./git-signing.ts):
|
|
904
|
+
* - **签名**:显式传 `-c push.gpgSign=false`,避免宿主 `push.gpgSign=true` 让 push 带上
|
|
905
|
+
* `--signed`(服务端不支持时直接 `the receiving end does not support --signed push` 失败)
|
|
906
|
+
* - **hooks**:`push --no-verify` 跳过被修复仓库的 `pre-push`(隔离环境无 `npx` / 目标仓库
|
|
907
|
+
* `node_modules` 不完整时该 hook 会以非 0 退出,把交付链打断为 `push_failed`)
|
|
908
|
+
*/
|
|
909
|
+
export declare function pushBranch(branchName: string, workDir: string): Promise<void>;
|
|
330
910
|
/**
|
|
331
911
|
* 查找目标仓库中所有 open 状态的 dependfix 自动修复 PR。
|
|
332
912
|
*
|
|
@@ -358,7 +938,7 @@ export declare function commentOnPullRequest(octokit: Octokit, owner: string, re
|
|
|
358
938
|
*/
|
|
359
939
|
export declare function addLabelToPullRequest(octokit: Octokit, owner: string, repo: string, pullNumber: number, labels: string[]): Promise<void>;
|
|
360
940
|
/**
|
|
361
|
-
* 通过 GitHub API 创建 Pull Request
|
|
941
|
+
* 通过 GitHub API 创建 Pull Request(`draft: true` 创建草稿 PR:基线红的交付降级档)。
|
|
362
942
|
*/
|
|
363
943
|
export declare function createPullRequest(params: CreatePullRequestParams): Promise<PullRequestResult>;
|
|
364
944
|
/** 分支清理状态(用于 cleanup-branches 清单分类) */
|
|
@@ -398,10 +978,9 @@ export declare function isConfirmAnswer(answer: string): boolean;
|
|
|
398
978
|
* 明细表在尾部被截断),并附加截断说明——避免大仓库 PR 创建 422。
|
|
399
979
|
*
|
|
400
980
|
* @param supersededNumbers 被本 PR 取代并已关闭的旧 PR 编号列表(用于 Supersedes 声明)
|
|
981
|
+
* @param attemptMarkers 同告警尝试标记(HTML 注释;必须置于正文头部——正文超 64KB 时从尾部截断,尾置标记会丢失)
|
|
401
982
|
*/
|
|
402
|
-
export declare function generatePRBody(result: RunResult, supersededNumbers?: number[]): string;
|
|
403
|
-
//#endregion
|
|
404
|
-
//#region src/github/repo-policy.d.ts
|
|
983
|
+
export declare function generatePRBody(result: RunResult, supersededNumbers?: number[], attemptMarkers?: readonly AttemptMarker[]): string;
|
|
405
984
|
/** 单条 glob 模式长度上限(加固:防止超长模式引入匹配开销;受信配置 + 短输入) */
|
|
406
985
|
export declare const MAX_GLOB_PATTERN_LENGTH = 200;
|
|
407
986
|
/**
|
|
@@ -427,9 +1006,52 @@ export interface RepoPolicy {
|
|
|
427
1006
|
exclude?: string[];
|
|
428
1007
|
/** topic 黑名单(仅作用于发现结果:排除含任一指定 topic 的仓库) */
|
|
429
1008
|
topicsExclude?: string[];
|
|
1009
|
+
/**
|
|
1010
|
+
* overrides 保护名单(显式维护):仓库 glob → 不得自动写入 override 的包名列表。
|
|
1011
|
+
*
|
|
1012
|
+
* 命中时 dependfix 跳过该包的 override 写入并记审计(`OVERRIDE_PROTECTED`),
|
|
1013
|
+
* 防止历史上被人工移除的破坏性 override 复发(实证见
|
|
1014
|
+
* [override-protect-policy.md](../../../../docs/design/governance/override-protect-policy.md))。
|
|
1015
|
+
*
|
|
1016
|
+
* **必须按仓库粒度**:同一 override 对不同仓库的破坏性不同(如纯 ESM 依赖只破坏 CJS 消费方),
|
|
1017
|
+
* 全局包名黑名单会误伤真正需要该升级的仓库。键支持与 include / exclude 相同的 glob 语义
|
|
1018
|
+
* (`owner/*`、`owner/pkg-*`);全局兜底需写两段通配(owner 段与 repo 段各一个星号),因单星号不跨 `/`。
|
|
1019
|
+
*/
|
|
1020
|
+
overrideProtect?: Record<string, string[]>;
|
|
430
1021
|
}
|
|
431
1022
|
/** 是否命中任一 exclude 模式(黑名单)。 */
|
|
432
1023
|
export declare function matchesRepoExclude(policy: RepoPolicy, fullName: string): boolean;
|
|
1024
|
+
/**
|
|
1025
|
+
* 该仓库是否保护指定包的 override 写入。
|
|
1026
|
+
*
|
|
1027
|
+
* 命中条件:存在键 glob 匹配 `fullName` **且** 该键的包名列表包含 `packageName`。
|
|
1028
|
+
* 返回命中的模式(用于报告展示判定依据);未命中时 `protected=false`。
|
|
1029
|
+
*/
|
|
1030
|
+
export declare function matchesOverrideProtect(policy: RepoPolicy, fullName: string, packageName: string): {
|
|
1031
|
+
protected: boolean;
|
|
1032
|
+
matchedPattern?: string;
|
|
1033
|
+
};
|
|
1034
|
+
/**
|
|
1035
|
+
* 是否为可安全用作对象键的名称(非原型链风险键)。
|
|
1036
|
+
*
|
|
1037
|
+
* 原型链风险键(`__proto__` / `constructor` / `prototype`)在「以外部输入为键写入对象」时
|
|
1038
|
+
* 可能造成原型污染或语义歧义;overrideProtect 的两个入口(env / CLI 解析、目标仓库配置文件)
|
|
1039
|
+
* 共用本谓词,避免两处口径漂移。
|
|
1040
|
+
*/
|
|
1041
|
+
export declare function isSafePrototypeKey(key: string): boolean;
|
|
1042
|
+
/**
|
|
1043
|
+
* 解析 overrides 保护名单入口值(与 `--upgrade-groups` 同格式、同口径):
|
|
1044
|
+
* `name1:pkg1,pkg2;name2:pkg3`(`;` 分隔条目,`:` 分隔仓库 glob 与包列表,`,` 分隔包名)。
|
|
1045
|
+
*
|
|
1046
|
+
* 与 `normalizeUpgradeGroups` / `parseUpgradeGroupsFlag` 保持一致的 fail-fast 语义:
|
|
1047
|
+
* 空 entry 忽略;非空但缺冒号 / 仓库 glob 为空 / 包列表为空 → 抛错(不静默降级);
|
|
1048
|
+
* 原型链风险键名(`__proto__` / `constructor` / `prototype`)忽略。
|
|
1049
|
+
*
|
|
1050
|
+
* @param value - 原始入口值(CLI 单值 / env 单值)
|
|
1051
|
+
* @param errorFactory - 抛错工厂(config 侧抛 CONFIG_VALIDATION_ERROR、CLI 侧抛 ARGUMENT_PARSE_ERROR)
|
|
1052
|
+
* @param label - 报错中展示的入口名(如 `--override-protect` / `DEPENDFIX_OVERRIDE_PROTECT`)
|
|
1053
|
+
*/
|
|
1054
|
+
export declare function parseOverrideProtectEntries(value: string, errorFactory: (message: string) => Error, label: string): Record<string, string[]>;
|
|
433
1055
|
/** 是否通过 include 白名单(include 为空 = 不限制;非空 = 必须命中任一模式)。 */
|
|
434
1056
|
export declare function matchesRepoInclude(policy: RepoPolicy, fullName: string): boolean;
|
|
435
1057
|
/** topic 黑名单:仓库 topics 含任一指定 topic 即排除(大小写归一化后比较)。 */
|
|
@@ -439,8 +1061,6 @@ export declare function matchesTopicsExclude(policy: RepoPolicy, topics: string[
|
|
|
439
1061
|
* 设计要点:显式优先,用户显式指定的仓库不应被 include 静默剔除)。
|
|
440
1062
|
*/
|
|
441
1063
|
export declare function filterExplicitRepositories(policy: RepoPolicy, repositories: string[]): string[];
|
|
442
|
-
//#endregion
|
|
443
|
-
//#region src/github/repo-selector.d.ts
|
|
444
1064
|
/**
|
|
445
1065
|
* 从文件读取仓库列表(每行一个 `owner/repo`)。
|
|
446
1066
|
* 空行和 `#` 开头的注释行会被跳过。
|
|
@@ -450,8 +1070,6 @@ export declare function readReposFile(filePath: string): string[];
|
|
|
450
1070
|
* 合并 CLI 传入仓库列表与文件中的仓库列表,去重并校验。
|
|
451
1071
|
*/
|
|
452
1072
|
export declare function resolveRepoList(cliRepos: string[], reposFilePath?: string): string[];
|
|
453
|
-
//#endregion
|
|
454
|
-
//#region src/github/repository-discovery.d.ts
|
|
455
1073
|
export interface RepositoryDiscoveryOptions {
|
|
456
1074
|
/** 已认证的 Octokit 实例 */
|
|
457
1075
|
client: Octokit;
|
|
@@ -478,7 +1096,7 @@ export interface RepositoryDiscoveryOptions {
|
|
|
478
1096
|
probeConcurrency?: number;
|
|
479
1097
|
/**
|
|
480
1098
|
* 发现规模上限:最多保留的仓库数(按 fullName 字典序排序后截断)。
|
|
481
|
-
* 默认 100;设为 0
|
|
1099
|
+
* 默认 100;设为 0 表示不限制(负数会被拒绝)。
|
|
482
1100
|
* 大 org 场景下防止一次性全量发现导致 API 配额不可控消耗和超时。
|
|
483
1101
|
*/
|
|
484
1102
|
maxRepos?: number;
|
|
@@ -514,8 +1132,6 @@ export declare function discoverRepositories(options: RepositoryDiscoveryOptions
|
|
|
514
1132
|
* 显式 `Owner/Repo` 与发现 `owner/repo` 视为同一仓库)
|
|
515
1133
|
*/
|
|
516
1134
|
export declare function mergeRepositories(explicit: string[], discovered: string[]): string[];
|
|
517
|
-
//#endregion
|
|
518
|
-
//#region src/github/token-scope.d.ts
|
|
519
1135
|
/**
|
|
520
1136
|
* 凭据权限面启动检查(安全治理:超权限 token 启动即警告)。
|
|
521
1137
|
*
|
|
@@ -565,8 +1181,6 @@ export declare function analyzeTokenScope(scopeHeader: string | undefined, accep
|
|
|
565
1181
|
export declare function checkTokenPermissions(client: Octokit, options?: {
|
|
566
1182
|
codeScanningEnabled?: boolean;
|
|
567
1183
|
}): Promise<TokenScopeCheckResult>;
|
|
568
|
-
//#endregion
|
|
569
|
-
//#region src/code-scanning/rule-classifier.d.ts
|
|
570
1184
|
/**
|
|
571
1185
|
* A 类自动修复白名单默认集合(默认值常量;测试 disjointness 不变量用)。
|
|
572
1186
|
*
|
|
@@ -618,8 +1232,6 @@ export declare function classifyRule(ruleId: string | null | undefined): AlertCl
|
|
|
618
1232
|
* 读取自当前生效配置(`getActiveRulesConfig().suggested`);未收录规则返回通用建议(C 类兜底,不静默)。
|
|
619
1233
|
*/
|
|
620
1234
|
export declare function suggestionFor(ruleId: string | null | undefined): string;
|
|
621
|
-
//#endregion
|
|
622
|
-
//#region src/code-scanning/rule-config.d.ts
|
|
623
1235
|
export type RuleClass = 'auto-fixable' | 'suggested' | 'report-only';
|
|
624
1236
|
export interface RuleConfigEntry {
|
|
625
1237
|
/** 规则 id(如 `js/sql-injection`,trim 后用于匹配;空串非法) */
|
|
@@ -677,8 +1289,6 @@ export declare function getActiveRulesConfig(): CompiledRulesConfig;
|
|
|
677
1289
|
export declare function setActiveRulesConfig(config: CompiledRulesConfig): void;
|
|
678
1290
|
/** 重置为默认配置(测试 cleanup + 运行时 fallback) */
|
|
679
1291
|
export declare function resetActiveRulesConfig(): void;
|
|
680
|
-
//#endregion
|
|
681
|
-
//#region src/code-scanning/templates.d.ts
|
|
682
1292
|
export interface TemplateApplyResult {
|
|
683
1293
|
/** 修改后的文件内容 */
|
|
684
1294
|
content: string;
|
|
@@ -699,8 +1309,155 @@ export interface CodeScanningFixTemplate {
|
|
|
699
1309
|
}
|
|
700
1310
|
/** 获取规则对应的修复模板;无模板返回 undefined(调用方回退建议模式)。 */
|
|
701
1311
|
export declare function getCodeScanningFixTemplate(ruleId: string): CodeScanningFixTemplate | undefined;
|
|
702
|
-
|
|
703
|
-
|
|
1312
|
+
/** `package.json` 的最小结构视图(只声明本模块读写的字段)。 */
|
|
1313
|
+
interface PackageJson {
|
|
1314
|
+
name?: string;
|
|
1315
|
+
dependencies?: Record<string, string>;
|
|
1316
|
+
devDependencies?: Record<string, string>;
|
|
1317
|
+
optionalDependencies?: Record<string, string>;
|
|
1318
|
+
peerDependencies?: Record<string, string>;
|
|
1319
|
+
pnpm?: {
|
|
1320
|
+
overrides?: Record<string, string>;
|
|
1321
|
+
[key: string]: unknown;
|
|
1322
|
+
};
|
|
1323
|
+
[key: string]: unknown;
|
|
1324
|
+
}
|
|
1325
|
+
/** 依赖所在的安装组与原始声明。 */
|
|
1326
|
+
interface DependencyInfo {
|
|
1327
|
+
group: 'dependencies' | 'devDependencies' | 'optionalDependencies';
|
|
1328
|
+
version: string;
|
|
1329
|
+
}
|
|
1330
|
+
/**
|
|
1331
|
+
* 在 `package.json` 的 `dependencies` / `devDependencies` / `optionalDependencies` 中按顺序查找包。
|
|
1332
|
+
*/
|
|
1333
|
+
export declare function findDependencyVersion(pkg: PackageJson, packageName: string): DependencyInfo | null;
|
|
1334
|
+
/**
|
|
1335
|
+
* 从版本声明中提取前缀(^ / ~ / 空)。
|
|
1336
|
+
*
|
|
1337
|
+
* @example
|
|
1338
|
+
* extractPrefix('^4.17.20') // '^'
|
|
1339
|
+
* extractPrefix('~4.17.0') // '~'
|
|
1340
|
+
* extractPrefix('4.17.20') // ''
|
|
1341
|
+
* extractPrefix('*') // '^' (默认)
|
|
1342
|
+
*/
|
|
1343
|
+
export declare function extractPrefix(version: string): string;
|
|
1344
|
+
/**
|
|
1345
|
+
* 确保 `package.json` 中存在 `pnpm.overrides` 对象,若不存在则创建。
|
|
1346
|
+
* 返回 `overrides` 对象的引用,调用方可直接写入。
|
|
1347
|
+
*/
|
|
1348
|
+
export declare function ensurePnpmOverrides(pkg: PackageJson): Record<string, string>;
|
|
1349
|
+
/** 版本化 overrides 批量应用条目(一条 = 一个包的多 key overrides)。 */
|
|
1350
|
+
interface VersionedOverridesPlan {
|
|
1351
|
+
packageName: string;
|
|
1352
|
+
overrides: Record<string, string>;
|
|
1353
|
+
}
|
|
1354
|
+
/** 批量应用结果(不抛错:失败经 `error` 文本暴露,成功可带 `warning`)。 */
|
|
1355
|
+
interface VersionedOverridesApplyResult {
|
|
1356
|
+
success: boolean;
|
|
1357
|
+
warning?: string;
|
|
1358
|
+
error?: string;
|
|
1359
|
+
/**
|
|
1360
|
+
* 失败阶段:`precheck`(未写盘)/ `install`(已写盘且安装失败)/
|
|
1361
|
+
* `verify`(安装成功但回读 lockfile 仍有低于目标的实例,已回滚)——供单包包装保持既有 `toVersion` 口径。
|
|
1362
|
+
*/
|
|
1363
|
+
failurePhase?: 'precheck' | 'install' | 'verify';
|
|
1364
|
+
/** 安装失败是否由安装环境问题导致(信号终止 / 超时 / 无 stderr 诊断);调用方据此停止逐包重试 */
|
|
1365
|
+
environmental?: boolean;
|
|
1366
|
+
}
|
|
1367
|
+
/** 单条写盘结果(版本声明保留原前缀)。 */
|
|
1368
|
+
interface ManifestUpgradeApplied {
|
|
1369
|
+
packageName: string;
|
|
1370
|
+
fromVersion: string;
|
|
1371
|
+
toVersion: string;
|
|
1372
|
+
isMajor: boolean;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* 归一化单个 selector。
|
|
1376
|
+
*
|
|
1377
|
+
* 等价类:`1` / `^1` / `1.x` / `1.*` / `^1.x` → `major:1`。
|
|
1378
|
+
* 其余(`~1`、`^1.2`、`1.1.21`、`>=1 <2` 等)原样返回(trim 后)。
|
|
1379
|
+
*/
|
|
1380
|
+
export declare function normalizeOverrideSelector(selector: string): string;
|
|
1381
|
+
/** 归一化整条 override key(含 scoped 包名与 `parent>child` 路径)。 */
|
|
1382
|
+
export declare function normalizeOverrideKey(key: string): string;
|
|
1383
|
+
/** upsert 结果:实际写入的 key(优先复用已有等价写法)与写入前旧值。 */
|
|
1384
|
+
interface OverrideUpsert {
|
|
1385
|
+
/** 实际写入的 key;命中已有语义等价 key 时为其原写法 */
|
|
1386
|
+
key: string;
|
|
1387
|
+
/** 写入前的旧值(`undefined` = 新增) */
|
|
1388
|
+
oldValue: string | undefined;
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* 写入 / 更新一条 override。命中已有语义等价 key(如已有 `pkg@^1` 而写入 `pkg@1`)
|
|
1392
|
+
* 时复用已有写法,保证同一 selector 只保留一种写法。
|
|
1393
|
+
*/
|
|
1394
|
+
export declare function upsertOverride(overrides: Record<string, string | undefined>, key: string, value: string): OverrideUpsert;
|
|
1395
|
+
/**
|
|
1396
|
+
* 从版本声明中提取主版本号(major)。
|
|
1397
|
+
* 去除前缀后匹配第一个 semver 段。
|
|
1398
|
+
*
|
|
1399
|
+
* @example
|
|
1400
|
+
* parseMajorVersion('^4.17.20') // 4
|
|
1401
|
+
* parseMajorVersion('~2.0.0') // 2
|
|
1402
|
+
* parseMajorVersion('1.2.3') // 1
|
|
1403
|
+
* parseMajorVersion('*') // -1
|
|
1404
|
+
*/
|
|
1405
|
+
export declare function parseMajorVersion(version: string): number;
|
|
1406
|
+
/**
|
|
1407
|
+
* 比较两个语义化版本(`x.y.z`,可选 pre-release 后缀)。
|
|
1408
|
+
*
|
|
1409
|
+
* `a > b` 返回正数,`a < b` 返回负数,相等返回 0;非 semver 字符串按 0 处理
|
|
1410
|
+
* (保守:不参与大小比较)。pre-release 后缀忽略(如 `1.0.0-beta` 视为 `1.0.0`)。
|
|
1411
|
+
*
|
|
1412
|
+
* @example
|
|
1413
|
+
* compareSemver('4.18.0', '4.17.21') // 1
|
|
1414
|
+
* compareSemver('5.4.20', '6.4.3') // -1
|
|
1415
|
+
* compareSemver('1.2.3', '1.2.3') // 0
|
|
1416
|
+
*/
|
|
1417
|
+
export declare function compareSemver(a: string, b: string): number;
|
|
1418
|
+
/**
|
|
1419
|
+
* 检测版本声明是否包含包管理器协议前缀
|
|
1420
|
+
* (`workspace:` / `catalog:` / `link:` / `file:` / `npm:` / `github:` /
|
|
1421
|
+
* `gitlab:` / `bitbucket:` / `gist:` / `git:` / `git+ssh:` / `git+https:` /
|
|
1422
|
+
* `git+http:` / `git+file:` / `https:` / `ssh:` 等)。
|
|
1423
|
+
*
|
|
1424
|
+
* 这类声明不是 semver range,`extractPrefix` 会将其误归为 `^` 导致声明被
|
|
1425
|
+
* 不可逆改写(如 `catalog:` → `^x.y.z`、`git+ssh:` 来源从 fork/私有源静默
|
|
1426
|
+
* 切回 registry),升级前必须拒绝。
|
|
1427
|
+
*
|
|
1428
|
+
* @example
|
|
1429
|
+
* isNonSemverDeclaration('^4.17.20') // false
|
|
1430
|
+
* isNonSemverDeclaration('workspace:*') // true
|
|
1431
|
+
* isNonSemverDeclaration('catalog:') // true
|
|
1432
|
+
* isNonSemverDeclaration('link:../pkg') // true
|
|
1433
|
+
* isNonSemverDeclaration('git+ssh://...') // true
|
|
1434
|
+
* isNonSemverDeclaration('gitlab:...') // true
|
|
1435
|
+
* isNonSemverDeclaration('https://...tgz') // true
|
|
1436
|
+
*/
|
|
1437
|
+
export declare function isNonSemverDeclaration(version: string): boolean;
|
|
1438
|
+
/**
|
|
1439
|
+
* 从 `pnpm-lock.yaml` 中读取指定包的**所有**锁定版本实例。
|
|
1440
|
+
*
|
|
1441
|
+
* 支持两种 lockfile 键格式:
|
|
1442
|
+
* 1. v9 早期格式(lockfileVersion 9.0 起):`/package-name/version:`
|
|
1443
|
+
* 2. pnpm v10+/v11 snapshot 格式:`package-name@version:` 或
|
|
1444
|
+
* `package-name@version(peer@x)(peer2@y):`(peer 后缀条目)
|
|
1445
|
+
*
|
|
1446
|
+
* 同一包在 lockfile 中可能共存多个版本(如 vite@5.4.14 与 vite@8.2.0),
|
|
1447
|
+
* 多版本共存是「版本化 overrides(pkg@version: ^target)」修复策略的前提。
|
|
1448
|
+
*
|
|
1449
|
+
* @returns 去重后的版本列表(如 `['5.4.14', '8.2.0']`),未找到返回 `[]`
|
|
1450
|
+
*/
|
|
1451
|
+
export declare function readLockfileVersions(lockfilePath: string, packageName: string): string[];
|
|
1452
|
+
/**
|
|
1453
|
+
* 从 `pnpm-lock.yaml` 中读取指定包的当前锁定版本。
|
|
1454
|
+
*
|
|
1455
|
+
* 多版本并存时(如同一包同时被根与子目录 manifest 引用),取**最高版本**
|
|
1456
|
+
* (保守:不降级保护依赖此语义,如根 vite@8.2.0 与 docs vite@5.4.14 并存)。
|
|
1457
|
+
*
|
|
1458
|
+
* @returns 锁定版本字符串(如 `'5.0.0'`),未找到返回 `null`
|
|
1459
|
+
*/
|
|
1460
|
+
export declare function readLockfileVersion(lockfilePath: string, packageName: string): string | null;
|
|
704
1461
|
export interface UpgradeDependencyParams {
|
|
705
1462
|
/** 包名(如 `'lodash'`, `'@babel/traverse'`) */
|
|
706
1463
|
packageName: string;
|
|
@@ -730,22 +1487,18 @@ export interface DependencyFixResult {
|
|
|
730
1487
|
error?: string;
|
|
731
1488
|
/** 成功但存在需要用户注意的附加信息(如 overrides 写入位置可能被 pnpm 忽略) */
|
|
732
1489
|
warning?: string;
|
|
1490
|
+
/**
|
|
1491
|
+
* 失败是否由安装环境问题导致(信号终止 / 超时 / 无 stderr 诊断)。
|
|
1492
|
+
* 调用方据此停止后续安装尝试——同一环境下逐包重试只会重复失败并耗尽运行预算。
|
|
1493
|
+
*/
|
|
1494
|
+
environmental?: boolean;
|
|
733
1495
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
pnpm?: {
|
|
741
|
-
overrides?: Record<string, string>;
|
|
742
|
-
[key: string]: unknown;
|
|
743
|
-
};
|
|
744
|
-
[key: string]: unknown;
|
|
745
|
-
}
|
|
746
|
-
interface DependencyInfo {
|
|
747
|
-
group: 'dependencies' | 'devDependencies' | 'optionalDependencies';
|
|
748
|
-
version: string;
|
|
1496
|
+
/** 家族锁步升级结果:`updates` 在安装失败时也保留已尝试的声明,便于报告展示。 */
|
|
1497
|
+
export interface FamilyUpgradeDependenciesResult {
|
|
1498
|
+
success: boolean;
|
|
1499
|
+
updates: ManifestUpgradeApplied[];
|
|
1500
|
+
error?: string;
|
|
1501
|
+
environmental?: boolean;
|
|
749
1502
|
}
|
|
750
1503
|
/**
|
|
751
1504
|
* 升级单个依赖到指定版本。
|
|
@@ -763,6 +1516,23 @@ interface DependencyInfo {
|
|
|
763
1516
|
* @returns 修复结果
|
|
764
1517
|
*/
|
|
765
1518
|
export declare function upgradeDependency(params: UpgradeDependencyParams): Promise<DependencyFixResult>;
|
|
1519
|
+
/**
|
|
1520
|
+
* 家族锁步升级:一次写盘 + 一次安装,失败整体回滚(含 lockfile)。
|
|
1521
|
+
*
|
|
1522
|
+
* 与 [upgradeDependency] 的区别只有写盘条数:族成员的 manifest 声明全部改完再执行
|
|
1523
|
+
* 一次 `pnpm install`,任一成员校验失败 / 安装失败 / 回滚失败都按「整族失败」返回,
|
|
1524
|
+
* 不产生半族状态。成员清单由 [planFamilyUpgrade] 决定(含触发包)。
|
|
1525
|
+
*
|
|
1526
|
+
* @param params - 工作目录、可选成员目录、待写盘成员(包名 + 目标版本)
|
|
1527
|
+
*/
|
|
1528
|
+
export declare function upgradeFamilyDependencies(params: {
|
|
1529
|
+
workDir: string;
|
|
1530
|
+
manifestDir?: string;
|
|
1531
|
+
updates: ReadonlyArray<{
|
|
1532
|
+
packageName: string;
|
|
1533
|
+
targetVersion: string;
|
|
1534
|
+
}>;
|
|
1535
|
+
}): Promise<FamilyUpgradeDependenciesResult>;
|
|
766
1536
|
/**
|
|
767
1537
|
* 通过 pnpm `overrides` 升级间接(transitive)依赖。
|
|
768
1538
|
*
|
|
@@ -800,97 +1570,25 @@ export declare function overrideTransitiveDependency(params: UpgradeDependencyPa
|
|
|
800
1570
|
* @param params - 包名、overrides 映射(`pkg@major` 或 `pkg` → `^target`)、工作目录
|
|
801
1571
|
* @returns 修复结果(fromVersion 为空字符串,表示多实例无单一来源版本)
|
|
802
1572
|
*/
|
|
1573
|
+
/**
|
|
1574
|
+
* 批量应用版本化 overrides:**一次写盘 + 一次安装**,失败整体回滚(含 lockfile)。
|
|
1575
|
+
* 动机:逐包应用使单仓安装次数 = 可修包数(实测大仓 7–8 次),是资源受限主机 OOM 的放大器之一;
|
|
1576
|
+
* [applyVersionedOverrides] 为单包薄包装,与本函数共用实现。调用方应过滤 `overrides` 为空的条目。
|
|
1577
|
+
*/
|
|
1578
|
+
export declare function applyVersionedOverridesBatch(params: {
|
|
1579
|
+
workDir: string;
|
|
1580
|
+
plans: VersionedOverridesPlan[];
|
|
1581
|
+
}): Promise<VersionedOverridesApplyResult>;
|
|
1582
|
+
/**
|
|
1583
|
+
* 应用单个包的版本化 overrides(内部委托 [applyVersionedOverridesBatch])。
|
|
1584
|
+
* 写入位置:有 `pnpm-workspace.yaml` 时写其 `overrides`,否则写 `package.json#pnpm.overrides`;
|
|
1585
|
+
* 失败自动回滚(含 lockfile),不执行验证(由上层负责)。
|
|
1586
|
+
*/
|
|
803
1587
|
export declare function applyVersionedOverrides(params: {
|
|
804
1588
|
packageName: string;
|
|
805
1589
|
versionedOverrides: Record<string, string>;
|
|
806
1590
|
workDir: string;
|
|
807
1591
|
}): Promise<DependencyFixResult>;
|
|
808
|
-
/**
|
|
809
|
-
* 从版本声明中提取前缀(^ / ~ / 空)。
|
|
810
|
-
*
|
|
811
|
-
* @example
|
|
812
|
-
* extractPrefix('^4.17.20') // '^'
|
|
813
|
-
* extractPrefix('~4.17.0') // '~'
|
|
814
|
-
* extractPrefix('4.17.20') // ''
|
|
815
|
-
* extractPrefix('*') // '^' (默认)
|
|
816
|
-
*/
|
|
817
|
-
export declare function extractPrefix(version: string): string;
|
|
818
|
-
/**
|
|
819
|
-
* 检测版本声明是否包含包管理器协议前缀
|
|
820
|
-
* (`workspace:` / `catalog:` / `link:` / `file:` / `npm:` / `github:` /
|
|
821
|
-
* `gitlab:` / `bitbucket:` / `gist:` / `git:` / `git+ssh:` / `git+https:` /
|
|
822
|
-
* `git+http:` / `git+file:` / `https:` / `ssh:` 等)。
|
|
823
|
-
*
|
|
824
|
-
* 这类声明不是 semver range,`extractPrefix` 会将其误归为 `^` 导致声明被
|
|
825
|
-
* 不可逆改写(如 `catalog:` → `^x.y.z`、`git+ssh:` 来源从 fork/私有源静默
|
|
826
|
-
* 切回 registry),升级前必须拒绝。
|
|
827
|
-
*
|
|
828
|
-
* @example
|
|
829
|
-
* isNonSemverDeclaration('^4.17.20') // false
|
|
830
|
-
* isNonSemverDeclaration('workspace:*') // true
|
|
831
|
-
* isNonSemverDeclaration('catalog:') // true
|
|
832
|
-
* isNonSemverDeclaration('link:../pkg') // true
|
|
833
|
-
* isNonSemverDeclaration('git+ssh://...') // true
|
|
834
|
-
* isNonSemverDeclaration('gitlab:...') // true
|
|
835
|
-
* isNonSemverDeclaration('https://...tgz') // true
|
|
836
|
-
*/
|
|
837
|
-
export declare function isNonSemverDeclaration(version: string): boolean;
|
|
838
|
-
/**
|
|
839
|
-
* 从版本声明中提取主版本号(major)。
|
|
840
|
-
* 去除前缀后匹配第一个 semver 段。
|
|
841
|
-
*
|
|
842
|
-
* @example
|
|
843
|
-
* parseMajorVersion('^4.17.20') // 4
|
|
844
|
-
* parseMajorVersion('~2.0.0') // 2
|
|
845
|
-
* parseMajorVersion('1.2.3') // 1
|
|
846
|
-
* parseMajorVersion('*') // -1
|
|
847
|
-
*/
|
|
848
|
-
export declare function parseMajorVersion(version: string): number;
|
|
849
|
-
/**
|
|
850
|
-
* 比较两个语义化版本(`x.y.z`,可选 pre-release 后缀)。
|
|
851
|
-
*
|
|
852
|
-
* - `a > b` 返回正数,`a < b` 返回负数,相等返回 0
|
|
853
|
-
* - 非 semver 字符串按 0 处理(保守:不参与大小比较)
|
|
854
|
-
* - 仅比较主/次/补丁段,pre-release 后缀忽略(如 `1.0.0-beta` 视为 `1.0.0`)
|
|
855
|
-
*
|
|
856
|
-
* @example
|
|
857
|
-
* compareSemver('4.18.0', '4.17.21') // 1
|
|
858
|
-
* compareSemver('5.4.20', '6.4.3') // -1
|
|
859
|
-
* compareSemver('1.2.3', '1.2.3') // 0
|
|
860
|
-
*/
|
|
861
|
-
export declare function compareSemver(a: string, b: string): number;
|
|
862
|
-
/**
|
|
863
|
-
* 在 `package.json` 的 `dependencies` / `devDependencies` / `optionalDependencies` 中按顺序查找包。
|
|
864
|
-
*/
|
|
865
|
-
export declare function findDependencyVersion(pkg: PackageJson, packageName: string): DependencyInfo | null;
|
|
866
|
-
/**
|
|
867
|
-
* 确保 `package.json` 中存在 `pnpm.overrides` 对象,若不存在则创建。
|
|
868
|
-
* 返回 `overrides` 对象的引用,调用方可直接写入。
|
|
869
|
-
*/
|
|
870
|
-
export declare function ensurePnpmOverrides(pkg: PackageJson): Record<string, string>;
|
|
871
|
-
/**
|
|
872
|
-
* 从 `pnpm-lock.yaml` 中读取指定包的**所有**锁定版本实例。
|
|
873
|
-
*
|
|
874
|
-
* 支持两种 lockfile 键格式:
|
|
875
|
-
* 1. v9 早期格式(lockfileVersion 9.0 起):`/package-name/version:`
|
|
876
|
-
* 2. pnpm v10+/v11 snapshot 格式:`package-name@version:` 或
|
|
877
|
-
* `package-name@version(peer@x)(peer2@y):`(peer 后缀条目)
|
|
878
|
-
*
|
|
879
|
-
* 同一包在 lockfile 中可能共存多个版本(如 vite@5.4.14 与 vite@8.2.0),
|
|
880
|
-
* 多版本共存是「版本化 overrides(pkg@version: ^target)」修复策略的前提。
|
|
881
|
-
*
|
|
882
|
-
* @returns 去重后的版本列表(如 `['5.4.14', '8.2.0']`),未找到返回 `[]`
|
|
883
|
-
*/
|
|
884
|
-
export declare function readLockfileVersions(lockfilePath: string, packageName: string): string[];
|
|
885
|
-
/**
|
|
886
|
-
* 从 `pnpm-lock.yaml` 中读取指定包的当前锁定版本。
|
|
887
|
-
*
|
|
888
|
-
* 多版本并存时(如同一包同时被根与子目录 manifest 引用),取**最高版本**
|
|
889
|
-
* (保守:不降级保护依赖此语义,如根 vite@8.2.0 与 docs vite@5.4.14 并存)。
|
|
890
|
-
*
|
|
891
|
-
* @returns 锁定版本字符串(如 `'5.0.0'`),未找到返回 `null`
|
|
892
|
-
*/
|
|
893
|
-
export declare function readLockfileVersion(lockfilePath: string, packageName: string): string | null;
|
|
894
1592
|
/**
|
|
895
1593
|
* 读取当前已生效的 pnpm overrides 映射(与写入位置保持一致):
|
|
896
1594
|
* - 存在 `pnpm-workspace.yaml` → 读取其中 `overrides` 字段(pnpm v10+ 推荐位置)
|
|
@@ -900,7 +1598,7 @@ export declare function readLockfileVersion(lockfilePath: string, packageName: s
|
|
|
900
1598
|
* 条目取 max 合并,不丢不改写已有条目(2026-08-09 复盘:此前生成侧不感知
|
|
901
1599
|
* 已有条目,导致 `pkg: ^x` 与 `pkg@major: ^y` 并存分裂)。
|
|
902
1600
|
*
|
|
903
|
-
* @returns 已有 overrides 映射(key →
|
|
1601
|
+
* @returns 已有 overrides 映射(key → 版本声明);无配置、解析失败或 `overrides` 形态非法返回 {}
|
|
904
1602
|
*/
|
|
905
1603
|
export declare function readExistingOverrides(workDir: string): Record<string, string>;
|
|
906
1604
|
/**
|
|
@@ -923,9 +1621,7 @@ export declare function detectPnpmMajor(workDir: string): number | null;
|
|
|
923
1621
|
* partitionSubmanifestAlerts 的常规跳过逻辑处理,避免重复计数。
|
|
924
1622
|
*/
|
|
925
1623
|
export declare function isCrossMajorFixRequired(lockfilePath: string, alert: NormalizedSecurityAlert): boolean;
|
|
926
|
-
|
|
927
|
-
//#region src/fixers/pnpm/index.d.ts
|
|
928
|
-
export type LockfileFailureCategory = 'LOCKFILE_NOT_FOUND' | 'MANIFEST_MISMATCH' | 'LOCKFILE_VERSION_MISMATCH' | 'CORRUPTED_LOCKFILE' | 'CREDENTIAL_ERROR' | 'RESOLVE_ERROR' | 'MINIMUM_RELEASE_AGE' | 'UNKNOWN';
|
|
1624
|
+
export type LockfileFailureCategory = 'LOCKFILE_NOT_FOUND' | 'MANIFEST_MISMATCH' | 'LOCKFILE_VERSION_MISMATCH' | 'CORRUPTED_LOCKFILE' | 'CREDENTIAL_ERROR' | 'RESOLVE_ERROR' | 'MINIMUM_RELEASE_AGE' | 'ENVIRONMENT_ERROR' | 'ABORTED' | 'UNKNOWN';
|
|
929
1625
|
export type RepairStrategy = 'REGENERATE' | 'FIX_ENTRIES' | 'PIN_TOOLCHAIN' | 'REINSTALL' | 'SKIP';
|
|
930
1626
|
export interface RepairLockfileParams {
|
|
931
1627
|
/** 工作目录(必须包含 package.json 和 pnpm-lock.yaml) */
|
|
@@ -949,6 +1645,10 @@ export interface RepairAttempt {
|
|
|
949
1645
|
success: boolean;
|
|
950
1646
|
error?: string;
|
|
951
1647
|
durationMs: number;
|
|
1648
|
+
/** 进程退出码(非零退出时;被信号杀死 / spawn 失败时为 null) */
|
|
1649
|
+
exitCode?: number | null;
|
|
1650
|
+
/** 终止进程的信号(如 `SIGKILL` / `SIGTERM`);非信号终止时为 null */
|
|
1651
|
+
signal?: string | null;
|
|
952
1652
|
}
|
|
953
1653
|
export interface LockfileRepairResult {
|
|
954
1654
|
success: boolean;
|
|
@@ -956,22 +1656,50 @@ export interface LockfileRepairResult {
|
|
|
956
1656
|
failureDetail?: string;
|
|
957
1657
|
strategy?: RepairStrategy;
|
|
958
1658
|
diff?: LockfileDiff | null;
|
|
1659
|
+
/** 修复后 lockfile **内容**是否实际改变(不同于行数 / 包数摘要;已合规时为 false)。 */
|
|
1660
|
+
changed?: boolean;
|
|
959
1661
|
attemptHistory: RepairAttempt[];
|
|
960
1662
|
/** 修复后 lockfile 的 lockfileVersion(提取自 pnpm-lock.yaml) */
|
|
961
1663
|
lockfileVersion?: string;
|
|
962
1664
|
/** 修复前后 lockfileVersion 是否变化(格式漂移检测,wisdom: pnpm v11 overrides 迁移教训) */
|
|
963
1665
|
lockfileVersionChanged?: boolean;
|
|
1666
|
+
/**
|
|
1667
|
+
* 环境性安装失败(诊断步 `pnpm install --frozen-lockfile` 无 stderr 诊断 / 被信号杀死 / 超时)。
|
|
1668
|
+
* 调用方据此**不归因目标仓库**(不计入「本次改动引入的失败」,与既有失败基线同族口径)。
|
|
1669
|
+
*/
|
|
1670
|
+
environmental?: boolean;
|
|
964
1671
|
}
|
|
965
1672
|
interface ClassificationResult {
|
|
966
1673
|
ok: boolean;
|
|
967
1674
|
category?: LockfileFailureCategory;
|
|
1675
|
+
/** 原始 stderr(保留供测试 / 来源区分;生产证据统一走 `diagnostics`) */
|
|
968
1676
|
stderr?: string;
|
|
1677
|
+
/** 原始 stdout(pnpm 11 的安装脚本错误常写在这里;生产证据统一走 `diagnostics`) */
|
|
1678
|
+
stdout?: string;
|
|
1679
|
+
/** stderr + stdout 的合并诊断文本(分类与失败详情使用) */
|
|
1680
|
+
diagnostics?: string;
|
|
1681
|
+
/** 进程退出码(非零退出时;被信号杀死 / spawn 失败时为 null) */
|
|
1682
|
+
exitCode: number | null;
|
|
1683
|
+
/** 终止进程的信号;非信号终止时为 null */
|
|
1684
|
+
signal: string | null;
|
|
1685
|
+
/** 是否因超时被终止(execFileSync timeout) */
|
|
1686
|
+
timedOut: boolean;
|
|
1687
|
+
/** spawn 级 errno(如 `ENOENT`——工具链缺失);无时为 null */
|
|
1688
|
+
errno: string | null;
|
|
1689
|
+
/** 合并诊断是否为空(无任何可用诊断信息) */
|
|
1690
|
+
noDiagnostics: boolean;
|
|
1691
|
+
/** 是否环境性失败(信号 / 超时 / 无 stderr 诊断) */
|
|
1692
|
+
environmental: boolean;
|
|
969
1693
|
}
|
|
970
1694
|
/**
|
|
971
1695
|
* 执行 `pnpm i --frozen-lockfile` 并解析失败分类。
|
|
972
|
-
* 成功时返回 { ok: true }
|
|
1696
|
+
* 成功时返回 `{ ok: true }`。
|
|
1697
|
+
*
|
|
1698
|
+
* 失败时保留进程级信号(退出码 / 信号 / 超时 / spawn errno):无 stderr 诊断(被信号杀死 /
|
|
1699
|
+
* 超时 / 静默非零退出)时归 `ENVIRONMENT_ERROR` + `environmental: true`——外部不再只看到
|
|
1700
|
+
* `Command failed: pnpm install --no-frozen-lockfile` 这类无定位信息的结果。
|
|
973
1701
|
*/
|
|
974
|
-
export declare function classifyLockfileFailure(workDir: string): ClassificationResult
|
|
1702
|
+
export declare function classifyLockfileFailure(workDir: string): Promise<ClassificationResult>;
|
|
975
1703
|
/** 从 lockfile 内容提取 `lockfileVersion` 字段值(如 `9.0`);缺失返回 null。 */
|
|
976
1704
|
export declare function extractLockfileVersion(content: string): string | null;
|
|
977
1705
|
/**
|
|
@@ -1000,10 +1728,12 @@ export declare function resolvePnpmVersion(workDir: string, toolchain?: {
|
|
|
1000
1728
|
* - 验证通过 → 记录 diff、返回 success
|
|
1001
1729
|
* - 验证失败 → 继续下一个策略
|
|
1002
1730
|
* 5. 所有策略失败 → 回滚 lockfile、返回失败结果
|
|
1731
|
+
*
|
|
1732
|
+
* 2026-10-17:本函数为**异步**(诊断 / frozen 校验 / 策略执行改为受管异步 `spawn`,
|
|
1733
|
+
* 见 `runners/process-control.ts`)——同步实现会阻塞事件循环(引擎与平台同进程),
|
|
1734
|
+
* 使平台的执行超时定时器一起停摆,且无法在取消时终止子进程树。
|
|
1003
1735
|
*/
|
|
1004
|
-
export declare function repairLockfile(params: RepairLockfileParams): LockfileRepairResult
|
|
1005
|
-
//#endregion
|
|
1006
|
-
//#region src/fixers/code-scanning/index.d.ts
|
|
1736
|
+
export declare function repairLockfile(params: RepairLockfileParams): Promise<LockfileRepairResult>;
|
|
1007
1737
|
export interface ApplyCodeScanningFixParams {
|
|
1008
1738
|
/** 工作目录(告警 manifestPath 为相对路径,resolve 后读取) */
|
|
1009
1739
|
workDir: string;
|
|
@@ -1047,11 +1777,24 @@ export declare function restoreSourceFile(workDir: string, snapshot: SourceFileS
|
|
|
1047
1777
|
* 返回**真实路径**(后续读写走真实路径,避免再次经过 symlink)。
|
|
1048
1778
|
*/
|
|
1049
1779
|
export declare function resolveWithinWorkDir(workDir: string, relativePath: string): string | null;
|
|
1050
|
-
//#endregion
|
|
1051
|
-
//#region src/config/index.d.ts
|
|
1052
1780
|
export declare const RUNTIME_MODES: readonly ["report-only", "fix", "fix-and-pr", "cleanup-branches"];
|
|
1053
1781
|
export declare const SEVERITY_THRESHOLDS: readonly ["critical", "high", "medium", "all"];
|
|
1054
1782
|
export declare const ALERT_SOURCES: readonly AlertSourceKind[];
|
|
1783
|
+
/**
|
|
1784
|
+
* GitHub App 认证配置。
|
|
1785
|
+
* 通过 GitHub App installation token 认证时使用,用于生成真实 bot 身份的 commit author。
|
|
1786
|
+
* 仅在 fix / fix-and-pr 模式下创建 commit 时生效;PAT 路径保持不变。
|
|
1787
|
+
*/
|
|
1788
|
+
export interface GitHubAppConfig {
|
|
1789
|
+
/** GitHub App ID */
|
|
1790
|
+
appId: string;
|
|
1791
|
+
/** PEM 格式私钥 */
|
|
1792
|
+
privateKey: string;
|
|
1793
|
+
/** Installation ID */
|
|
1794
|
+
installationId: string;
|
|
1795
|
+
/** Bot 用户名(用于 commit author 动态生成;缺省 fallback `dependfix[bot]`) */
|
|
1796
|
+
botLogin?: string;
|
|
1797
|
+
}
|
|
1055
1798
|
/**
|
|
1056
1799
|
* 环境变量统一前缀(v0.2 起替代旧项目名遗留的 `AUTO_FIX_GITHUB_SECURITY_`)。
|
|
1057
1800
|
* 所有环境变量读取必须经由 {@link readEnv},禁止散落硬编码,防止改名漏网。
|
|
@@ -1064,6 +1807,7 @@ export declare const ENV_PREFIX = "DEPENDFIX_";
|
|
|
1064
1807
|
*/
|
|
1065
1808
|
export declare function readEnv(env: NodeJS.ProcessEnv, name: string): string | undefined;
|
|
1066
1809
|
export type RuntimeMode = typeof RUNTIME_MODES[number];
|
|
1810
|
+
export type RollbackGranularity = 'unit' | 'repo';
|
|
1067
1811
|
export interface RuntimeConfig {
|
|
1068
1812
|
mode: RuntimeMode;
|
|
1069
1813
|
severityThreshold: SeverityThreshold;
|
|
@@ -1094,6 +1838,12 @@ export interface RuntimeConfig {
|
|
|
1094
1838
|
* 排除含任一指定 topic 的仓库。仅作用于发现结果(显式列表无 topics 元数据)。
|
|
1095
1839
|
*/
|
|
1096
1840
|
repoTopicsExclude?: string[];
|
|
1841
|
+
/**
|
|
1842
|
+
* overrides 保护名单(`--override-protect` / `DEPENDFIX_OVERRIDE_PROTECT`):
|
|
1843
|
+
* 仓库 glob(`owner/*` / `owner/pkg-*`;全局兜底需写两段通配,因单星号不跨斜杠)→ 不得自动写入 override 的包名列表。
|
|
1844
|
+
* 命中时跳过该包的 override 写入并记 `OVERRIDE_PROTECTED` 审计(防历史上被人工移除的破坏性 override 复发)。
|
|
1845
|
+
*/
|
|
1846
|
+
overrideProtect?: Record<string, string[]>;
|
|
1097
1847
|
dryRun: boolean;
|
|
1098
1848
|
createPullRequest: boolean;
|
|
1099
1849
|
/** 修复完成后是否在本地当前分支直接提交(不推送、不创建 PR) */
|
|
@@ -1103,6 +1853,11 @@ export interface RuntimeConfig {
|
|
|
1103
1853
|
/** fix-and-pr 模式下结束后是否自动删除已合并/已关闭的 dependfix 分支(非交互) */
|
|
1104
1854
|
cleanupBranchesAuto: boolean;
|
|
1105
1855
|
githubToken: string;
|
|
1856
|
+
/**
|
|
1857
|
+
* GitHub App 认证配置(用于 commit author 真实 bot 身份)。
|
|
1858
|
+
* 仅 fix-and-pr / fix 模式下创建 commit 时使用;PAT 路径保持不变。
|
|
1859
|
+
*/
|
|
1860
|
+
githubApp?: GitHubAppConfig;
|
|
1106
1861
|
/**
|
|
1107
1862
|
* 告警数据源。默认 `github-dependabot`(GitHub Dependabot alerts API);
|
|
1108
1863
|
* `pnpm-audit` 为本地无 token 回退(`pnpm audit --json`),repository 解析
|
|
@@ -1132,10 +1887,60 @@ export interface RuntimeConfig {
|
|
|
1132
1887
|
*
|
|
1133
1888
|
* 开启后仅对「根 package.json 直接依赖(workspace 成员独占声明维持人工)
|
|
1134
1889
|
* + lockfile 单版本」的跨线告警自动升级,升级后复核脆弱实例消除、
|
|
1135
|
-
* 强制完整验证(install + lint + build),失败自动回滚;
|
|
1890
|
+
* 强制完整验证(install + lint + build + typecheck + test),失败自动回滚;
|
|
1136
1891
|
* 间接依赖 / 多版本共存跨线告警维持人工处理(skipped + warn)。
|
|
1137
1892
|
*/
|
|
1138
1893
|
allowMajorUpgrade: boolean;
|
|
1894
|
+
/**
|
|
1895
|
+
* 验证失败回滚粒度:`unit`(默认)回退最近一个已通过 probe 的变更单元并重验一次;
|
|
1896
|
+
* `repo` 保持既有整仓 `git reset --hard` 逃生语义。
|
|
1897
|
+
*/
|
|
1898
|
+
rollbackGranularity?: RollbackGranularity;
|
|
1899
|
+
/**
|
|
1900
|
+
* 把目标仓库 CI 独有的 `pnpm/npm/yarn run` 脚本追加到验证链(`--mirror-ci-scripts` /
|
|
1901
|
+
* `DEPENDFIX_MIRROR_CI_SCRIPTS`,默认 `false`)。
|
|
1902
|
+
*
|
|
1903
|
+
* 开启后在默认链**之后**执行(≤3 条、首失败即停),与默认链共用同一超时 / 取消面,
|
|
1904
|
+
* 并同样纳入修复前基线采样(基线已红 → `preExisting`,不回滚、不改 exit code)。
|
|
1905
|
+
* `docker` / `gh` / 任意 shell 与非脚本片段只记 `mirrorSkipped`,不执行。
|
|
1906
|
+
* 显式自定义链(`--commands` / Action `commands` / 平台 `verifyCommands`)整链替换默认链,
|
|
1907
|
+
* **不与 mirror 叠加**。
|
|
1908
|
+
*/
|
|
1909
|
+
mirrorCiScripts?: boolean;
|
|
1910
|
+
/**
|
|
1911
|
+
* 忽略同告警尝试上限,强制再试一次(`--retry-failed` / `DEPENDFIX_RETRY_FAILED`,默认 `false`)。
|
|
1912
|
+
*
|
|
1913
|
+
* 仅 fix-and-pr 生效:同一告警 / 目标版本 / 修复策略连续两次关闭后,第 3 次起默认跳过
|
|
1914
|
+
* (`alertsSkippedByReason['repeated-failure']`);开启后仍执行并在报告标注「人工强制」。
|
|
1915
|
+
* 尝试计数载体为 PR 正文 HTML 注释,计数口径见
|
|
1916
|
+
* [pr-delivery-closure.md §6](../../../../docs/design/governance/pr-delivery-closure.md)。
|
|
1917
|
+
*/
|
|
1918
|
+
retryFailed?: boolean;
|
|
1919
|
+
/**
|
|
1920
|
+
* 基线红(修复后安装仍既有失败)时的交付降级档位(`DEPENDFIX_ON_BASELINE_RED`,默认 `skip`):
|
|
1921
|
+
* `skip` 回滚并留痕 / `issue` 按失败指纹开 issue / `draft` 不回滚、创建**草稿** PR(仅 fix-and-pr;
|
|
1922
|
+
* 平台只记录 summary)。口径见 [§16](../../../../docs/design/governance/pr-delivery-closure.md)。
|
|
1923
|
+
*/
|
|
1924
|
+
onBaselineRed?: BaselineRedDelivery;
|
|
1925
|
+
/** PR 创建后等待 check 终态(`--wait-pr-checks` / `DEPENDFIX_WAIT_PR_CHECKS`,默认 false;仅 fix-and-pr,口径见 [§8](../../../../docs/design/governance/pr-delivery-closure.md)) */
|
|
1926
|
+
waitPrChecks?: boolean;
|
|
1927
|
+
/** check 失败且归因 self_caused 时关闭 PR 并删分支(`--close-failed-pr`,默认 false;需同时等待,其余归因只评论) */
|
|
1928
|
+
closeFailedPr?: boolean;
|
|
1929
|
+
/** 单个 PR 的 check 等待上限(毫秒;默认 900000,60000-1800000) */
|
|
1930
|
+
prCheckTimeoutMs?: number;
|
|
1931
|
+
/** 运行内 check 等待总预算(毫秒;默认 1200000,60000-1800000,且 ≤ 剩余 job 预算 70%) */
|
|
1932
|
+
prCheckRunBudgetMs?: number;
|
|
1933
|
+
/** job 总预算基线(毫秒;`DEPENDFIX_JOB_BUDGET_MS`)。缺省仅在 `GITHUB_ACTIONS=true` 按 25 分钟套用 */
|
|
1934
|
+
jobBudgetMs?: number;
|
|
1935
|
+
/** 运行截止时间(epoch ms;平台计算、引擎消费):预算不足时停止启动新工作并写 `BUDGET_EXHAUSTED` 审计。 */
|
|
1936
|
+
deadlineAt?: number;
|
|
1937
|
+
/** 执行宿主的构建版本回执(平台注入;缺省回退引擎包版本,最终 `unknown`;与 `/api/health` 同源)。 */
|
|
1938
|
+
buildVersion?: string;
|
|
1939
|
+
/**
|
|
1940
|
+
* 执行宿主的构建 commit(平台容器注入)。只有宿主构建期能提供;
|
|
1941
|
+
* 本地执行场景固定回退 `unknown`,不参与任何判定。
|
|
1942
|
+
*/
|
|
1943
|
+
buildCommit?: string;
|
|
1139
1944
|
/**
|
|
1140
1945
|
* Dependabot alerts 专用 token(可选)。
|
|
1141
1946
|
* 提供时仅用于拉取 Dependabot alerts(GITHUB_TOKEN 无法读取该 API,
|
|
@@ -1176,7 +1981,7 @@ export interface RuntimeConfig {
|
|
|
1176
1981
|
toolchainPnpmVersion?: string;
|
|
1177
1982
|
/**
|
|
1178
1983
|
* 发现规模上限(`--max-repos` / `DEPENDFIX_MAX_REPOS`):最多保留的仓库数。
|
|
1179
|
-
* 默认 100;设为 0
|
|
1984
|
+
* 默认 100;设为 0 表示不限制(负数会被拒绝)。大 org 场景下防止一次性全量发现。
|
|
1180
1985
|
*/
|
|
1181
1986
|
maxRepos: number;
|
|
1182
1987
|
/**
|
|
@@ -1234,6 +2039,8 @@ export interface CliConfigOverrides {
|
|
|
1234
2039
|
repoExclude?: string[];
|
|
1235
2040
|
/** 发现结果 topic 黑名单(排除含任一指定 topic 的仓库) */
|
|
1236
2041
|
repoTopicsExclude?: string[];
|
|
2042
|
+
/** overrides 保护名单(仓库 glob → 包名列表;命中则跳过 override 写入) */
|
|
2043
|
+
overrideProtect?: Record<string, string[]>;
|
|
1237
2044
|
dryRun?: boolean;
|
|
1238
2045
|
createPullRequest?: boolean;
|
|
1239
2046
|
/** 修复完成后是否在本地当前分支直接提交 */
|
|
@@ -1254,6 +2061,24 @@ export interface CliConfigOverrides {
|
|
|
1254
2061
|
* 无 env 通道;Action 不支持)。详见 RuntimeConfig.allowMajorUpgrade。
|
|
1255
2062
|
*/
|
|
1256
2063
|
allowMajorUpgrade?: boolean;
|
|
2064
|
+
/** 验证失败回滚粒度(unit / repo;默认 unit) */
|
|
2065
|
+
rollbackGranularity?: RollbackGranularity;
|
|
2066
|
+
/** 把目标仓库 CI 独有的包管理器脚本追加到验证链(`--mirror-ci-scripts`;默认关闭) */
|
|
2067
|
+
mirrorCiScripts?: boolean;
|
|
2068
|
+
/** 忽略同告警尝试上限并强制再试(`--retry-failed`;默认关闭,仅 fix-and-pr 生效) */
|
|
2069
|
+
retryFailed?: boolean;
|
|
2070
|
+
/** 基线红的交付降级档位(`DEPENDFIX_ON_BASELINE_RED`;默认 `skip`,仅 fix-and-pr 生效) */
|
|
2071
|
+
onBaselineRed?: BaselineRedDelivery;
|
|
2072
|
+
/** 等待本次 PR 的 check 终态(`--wait-pr-checks`;默认关闭,仅 fix-and-pr 生效) */
|
|
2073
|
+
waitPrChecks?: boolean;
|
|
2074
|
+
/** check 失败且归因 self_caused 时关闭 PR(`--close-failed-pr`;默认关闭,需同时等待) */
|
|
2075
|
+
closeFailedPr?: boolean;
|
|
2076
|
+
/** 单 PR check 等待上限(毫秒) */
|
|
2077
|
+
prCheckTimeoutMs?: number;
|
|
2078
|
+
/** 运行级 check 等待总预算(毫秒) */
|
|
2079
|
+
prCheckRunBudgetMs?: number;
|
|
2080
|
+
/** job 总预算基线(毫秒;缺省按 Actions 25 分钟兜底) */
|
|
2081
|
+
jobBudgetMs?: number;
|
|
1257
2082
|
/** Dependabot alerts 专用 token(可选,最小权限;缺省回退 githubToken) */
|
|
1258
2083
|
alertsToken?: string;
|
|
1259
2084
|
maxAlertsPerRepository?: number;
|
|
@@ -1269,7 +2094,7 @@ export interface CliConfigOverrides {
|
|
|
1269
2094
|
toolchainPnpmVersion?: string;
|
|
1270
2095
|
/**
|
|
1271
2096
|
* 发现规模上限(`--max-repos` / `DEPENDFIX_MAX_REPOS`):最多保留的仓库数。
|
|
1272
|
-
* 默认 100;设为 0
|
|
2097
|
+
* 默认 100;设为 0 表示不限制(负数会被拒绝)。大 org 场景下防止一次性全量发现。
|
|
1273
2098
|
*/
|
|
1274
2099
|
maxRepos?: number;
|
|
1275
2100
|
/** AI 研判总开关(`--ai`) */
|
|
@@ -1282,19 +2107,24 @@ export interface CliConfigOverrides {
|
|
|
1282
2107
|
aiBaseUrl?: string;
|
|
1283
2108
|
/** AI Anthropic 兼容端点(`--ai-api-url`,仅 provider=anthropic 生效) */
|
|
1284
2109
|
aiApiUrl?: string;
|
|
1285
|
-
/** AI API Key(`--ai-api-key
|
|
2110
|
+
/** AI API Key(`--ai-api-key`;CLI 参数优先,DEPENDFIX_AI_API_KEY 环境变量兜底) */
|
|
1286
2111
|
aiApiKey?: string;
|
|
1287
2112
|
/** AI 触发范围(`--ai-trigger`:failure / major / both) */
|
|
1288
2113
|
aiTrigger?: AiTriggerKind;
|
|
1289
2114
|
/** 是否输出详细日志 */
|
|
1290
2115
|
verbose?: boolean;
|
|
1291
|
-
/** 自定义验证命令(覆盖默认的 `pnpm install --frozen-lockfile` / `pnpm lint` / `pnpm build`) */
|
|
2116
|
+
/** 自定义验证命令(覆盖默认的 `pnpm install --frozen-lockfile` / `pnpm lint` / `pnpm build` / `pnpm typecheck` / `pnpm test`) */
|
|
1292
2117
|
commands?: string[];
|
|
1293
2118
|
/**
|
|
1294
2119
|
* 历史查询(仅 CLI `--history`):读取归档索引列出仓库历史运行摘要,
|
|
1295
2120
|
* 不进入运行配置(resolveRuntimeConfig 不消费),由 CLI 层直接处理。
|
|
1296
2121
|
*/
|
|
1297
2122
|
history?: string;
|
|
2123
|
+
/**
|
|
2124
|
+
* GitHub App 认证配置(用于 commit author 真实 bot 身份)。
|
|
2125
|
+
* 仅 fix / fix-and-pr 模式下创建 commit 时使用;PAT 路径保持不变。
|
|
2126
|
+
*/
|
|
2127
|
+
githubApp?: GitHubAppConfig;
|
|
1298
2128
|
}
|
|
1299
2129
|
export interface ResolveRuntimeConfigOptions {
|
|
1300
2130
|
env?: NodeJS.ProcessEnv;
|
|
@@ -1316,8 +2146,6 @@ export declare function resolveRuntimeConfig(options?: ResolveRuntimeConfigOptio
|
|
|
1316
2146
|
* @returns `owner/repo` 或 `null`(非 GitHub / 无 origin)
|
|
1317
2147
|
*/
|
|
1318
2148
|
export declare function inferRepoFromGitRemote(workDir: string): string | null;
|
|
1319
|
-
//#endregion
|
|
1320
|
-
//#region src/report/archiver.d.ts
|
|
1321
2149
|
export interface ArchiveRepoStats {
|
|
1322
2150
|
repository: string;
|
|
1323
2151
|
alertsCount: number;
|
|
@@ -1369,8 +2197,6 @@ export declare function readArchiveIndex(outputDir?: string): ArchiveIndex;
|
|
|
1369
2197
|
* 仅返回包含该仓库的运行;无结果返回 []。
|
|
1370
2198
|
*/
|
|
1371
2199
|
export declare function queryRepoHistory(repo: string, outputDir?: string): ArchiveRunEntry[];
|
|
1372
|
-
//#endregion
|
|
1373
|
-
//#region src/report/history.d.ts
|
|
1374
2200
|
/**
|
|
1375
2201
|
* 将某仓库的历史运行摘要格式化为多行文本(倒序时间:最新在前)。
|
|
1376
2202
|
*
|
|
@@ -1381,8 +2207,6 @@ export declare function queryRepoHistory(repo: string, outputDir?: string): Arch
|
|
|
1381
2207
|
* 无历史时返回提示行(非空,调用方直接打印)。
|
|
1382
2208
|
*/
|
|
1383
2209
|
export declare function formatHistory(entries: ArchiveRunEntry[], repo: string): string;
|
|
1384
|
-
//#endregion
|
|
1385
|
-
//#region src/multirepo/scheduler.d.ts
|
|
1386
2210
|
/** 并发上限(1-16,配置校验范围) */
|
|
1387
2211
|
export declare const MAX_CONCURRENCY_LIMIT = 16;
|
|
1388
2212
|
/** 默认并发(保守:行为与现状一致,逐仓库串行) */
|
|
@@ -1412,15 +2236,11 @@ export interface ConcurrencySchedulerOptions<T> {
|
|
|
1412
2236
|
export declare function runWithConcurrency<T>(options: ConcurrencySchedulerOptions<T>): Promise<void>;
|
|
1413
2237
|
/** 校验并发值是否在 1-16 范围内(config 层调用,抛 AppError)。 */
|
|
1414
2238
|
export declare function isValidConcurrency(value: number): boolean;
|
|
1415
|
-
//#endregion
|
|
1416
|
-
//#region src/app/branch-cleanup.d.ts
|
|
1417
2239
|
/**
|
|
1418
2240
|
* 关闭被取代的旧 PR 并回收其 head 分支(supersede 流程)。
|
|
1419
2241
|
* 关闭失败记录错误;分支删除失败仅 warn(家务活 best-effort,不触发非零退出)。
|
|
1420
2242
|
*/
|
|
1421
2243
|
export declare function closeSupersededPRs(ctx: Pick<AppContext, 'logger' | 'allErrors'>, client: Octokit, owner: string, repo: string, supersedePRs: DependfixOpenPR[]): Promise<void>;
|
|
1422
|
-
//#endregion
|
|
1423
|
-
//#region src/ai/usage.d.ts
|
|
1424
2244
|
interface AiUsage {
|
|
1425
2245
|
/** 调用次数 */
|
|
1426
2246
|
calls: number;
|
|
@@ -1451,8 +2271,6 @@ export declare class AiUsageTracker {
|
|
|
1451
2271
|
record(inputTokens: number, outputTokens: number): void;
|
|
1452
2272
|
snapshot(): AiUsage;
|
|
1453
2273
|
}
|
|
1454
|
-
//#endregion
|
|
1455
|
-
//#region src/app/helpers.d.ts
|
|
1456
2274
|
/** DependfixApp 提供给辅助方法的最小状态切片。 */
|
|
1457
2275
|
interface AppContext {
|
|
1458
2276
|
config: RuntimeConfig;
|
|
@@ -1463,10 +2281,61 @@ interface AppContext {
|
|
|
1463
2281
|
allAlerts: NormalizedSecurityAlert[];
|
|
1464
2282
|
allActions: FixAction[];
|
|
1465
2283
|
allErrors: FixError[];
|
|
2284
|
+
/** alerts 功能未启用记录(方案 A:未启用 ≠ 失败,不计入 allErrors) */
|
|
2285
|
+
alertsDisabled: AlertsDisabledRecord[];
|
|
1466
2286
|
repoResults: RepositoryResult[];
|
|
1467
2287
|
summary: RunSummary;
|
|
1468
2288
|
startedAt: string;
|
|
1469
2289
|
finishedAt: string;
|
|
2290
|
+
/** GitHub App 认证提供者(用于 commit author 真实 bot 身份) */
|
|
2291
|
+
authProvider?: AuthProvider;
|
|
2292
|
+
/**
|
|
2293
|
+
* 验证链口径记录(run 级累积;`verifyProject` 写入,报告与 PR 正文消费)。
|
|
2294
|
+
*
|
|
2295
|
+
* 缺省(测试直接构造 ctx)⇒ 不记录;同一仓库多次验证取命令并集(按首次出现顺序),
|
|
2296
|
+
* 并集未增长时复用既有记录与首轮健康预检结果,避免重复发起 API 调用。
|
|
2297
|
+
*/
|
|
2298
|
+
ciAlignment?: CiAlignmentRecord[];
|
|
2299
|
+
/**
|
|
2300
|
+
* 同告警尝试记录(run 级累积;`repo-fix` 的计划阶段写入,报告与 PR 正文标记消费)。
|
|
2301
|
+
* 缺省(测试直接构造 ctx)⇒ 不记录。
|
|
2302
|
+
*/
|
|
2303
|
+
attemptTracking?: RepeatedAttemptRecord[];
|
|
2304
|
+
/**
|
|
2305
|
+
* 最近关闭 dependfix PR 的尝试索引(运行级缓存;仅 fix-and-pr 模式注入)。
|
|
2306
|
+
* 缺省 ⇒ 不做同告警尝试判定(行为与引入前一致)。
|
|
2307
|
+
*/
|
|
2308
|
+
attemptIndex?: ClosedAttemptIndex;
|
|
2309
|
+
/**
|
|
2310
|
+
* PR 落点仓库(`owner/repo`,= 本次运行的第一个仓库)。
|
|
2311
|
+
*
|
|
2312
|
+
* 尝试标记只能写进该仓库的 PR,故只有该仓库的告警参与尝试计数;多仓运行其余仓库
|
|
2313
|
+
* 不做跳过判定(避免「在 A 仓计 B 仓的尝试」造成永久跳过)。
|
|
2314
|
+
*/
|
|
2315
|
+
attemptRepo?: string;
|
|
2316
|
+
/**
|
|
2317
|
+
* 告警级修复结果收集器(run 级;修复管线在无法由 actions 反推的判定点写入,
|
|
2318
|
+
* 报告 `alertOutcomes` 与平台 `ScanResult.fixStatus` 回写消费)。
|
|
2319
|
+
* 缺省(测试直接构造 ctx)⇒ 报告只按 actions 与告警属性推导,不含收敛 / 跳过等显式判定。
|
|
2320
|
+
*/
|
|
2321
|
+
alertOutcomes?: Map<string, AlertFixOutcome>;
|
|
2322
|
+
/**
|
|
2323
|
+
* PR check 回环结果(仅 `--wait-pr-checks` 且实际创建 PR 时存在)。
|
|
2324
|
+
* 缺省 ⇒ 不等待(行为与引入前一致)。
|
|
2325
|
+
*/
|
|
2326
|
+
prCheckWatch?: PrCheckWatchReport;
|
|
2327
|
+
/**
|
|
2328
|
+
* 交付跳过记录(修复后安装仍为既有失败 → 有修复但不交付)。
|
|
2329
|
+
* 缺省(测试直接构造 ctx)⇒ 不记录,summary 计数保持 0。
|
|
2330
|
+
*/
|
|
2331
|
+
deliverySkips?: DeliverySkipRecord[];
|
|
2332
|
+
/**
|
|
2333
|
+
* 运行截止时间(epoch ms;来自 `RuntimeConfig.deadlineAt`)。
|
|
2334
|
+
* 缺省 ⇒ 不限预算(CLI 本地运行),所有预算检查放行。
|
|
2335
|
+
*/
|
|
2336
|
+
deadlineAt?: number;
|
|
2337
|
+
/** 已记录的预算跳过(`stage:work`;避免同一跳过来回刷审计)。缺省 ⇒ 不去重。 */
|
|
2338
|
+
budgetSkips?: Set<string>;
|
|
1470
2339
|
}
|
|
1471
2340
|
/**
|
|
1472
2341
|
* 按动作构成生成 PR 标题(收尾审查遗留修复:cs-only 修复不再误标 "N upgrades",
|
|
@@ -1476,8 +2345,6 @@ interface AppContext {
|
|
|
1476
2345
|
* codeFixes 过滤条件一致(均 success && !noOp);任一侧口径变更必须同步。
|
|
1477
2346
|
*/
|
|
1478
2347
|
export declare function buildPrTitle(summary: Pick<RunSummary, 'alertsFixed'>, actions: FixAction[]): string;
|
|
1479
|
-
//#endregion
|
|
1480
|
-
//#region src/helpers/index.d.ts
|
|
1481
2348
|
/**
|
|
1482
2349
|
* 对可修复告警按包名去重(同包收敛)。
|
|
1483
2350
|
*
|
|
@@ -1505,7 +2372,7 @@ export declare function restoreTrackedFiles(workDir: string, snapshot: Record<st
|
|
|
1505
2372
|
/**
|
|
1506
2373
|
* 快速验证(逐包):运行验证命令序列。
|
|
1507
2374
|
*
|
|
1508
|
-
*
|
|
2375
|
+
* 有自定义命令时执行完整序列(命令以自定义链为准,典型形态含 install + setup + lint + build + typecheck + test),
|
|
1509
2376
|
* 否则仅运行 `pnpm lint`(脚本存在时)。
|
|
1510
2377
|
*
|
|
1511
2378
|
* 设计决策(run 33946113272 复盘):旧版仅跑 `pnpm lint`,但 Nuxt 等框架
|
|
@@ -1567,8 +2434,6 @@ export declare function partitionSubmanifestAlerts(alerts: NormalizedSecurityAle
|
|
|
1567
2434
|
* 进入跨线链路必然失败,维持人工处理。
|
|
1568
2435
|
*/
|
|
1569
2436
|
export declare function isRootDirectDependency(workDir: string, packageName: string): boolean;
|
|
1570
|
-
//#endregion
|
|
1571
|
-
//#region src/grouping/index.d.ts
|
|
1572
2437
|
/** 分组来源(决定分组优先级与命名语义) */
|
|
1573
2438
|
export type GroupSource = 'explicit' | 'dependabot' | 'types' | 'scope' | 'prefix' | 'single';
|
|
1574
2439
|
export interface DependencyGroup {
|
|
@@ -1659,8 +2524,6 @@ export declare function isMainPackagePresent(pkg: PackageJsonLike, lockfilePath:
|
|
|
1659
2524
|
* 5. @types 归并(主包有告警并入其组)/ 独立组 / 清理候选(主包已不存在)
|
|
1660
2525
|
*/
|
|
1661
2526
|
export declare function buildUpgradeGroups(alerts: NormalizedSecurityAlert[], options: GroupingOptions): GroupingResult;
|
|
1662
|
-
//#endregion
|
|
1663
|
-
//#region src/runners/network-audit.d.ts
|
|
1664
2527
|
/**
|
|
1665
2528
|
* 执行期网络外联审计 + 出站白名单拦截(安全治理:恶意脚本外联回传/下载 payload 的事故溯源与阻断)。
|
|
1666
2529
|
*
|
|
@@ -1690,8 +2553,8 @@ interface NetworkAuditEntry {
|
|
|
1690
2553
|
/** deny-by-default 拦截的违规外联标记(白名单校验失败的外联为 true) */
|
|
1691
2554
|
violation?: boolean;
|
|
1692
2555
|
}
|
|
1693
|
-
|
|
1694
|
-
|
|
2556
|
+
/** 对子进程输出做敏感信息脱敏(可安全写入日志 / 报告)。 */
|
|
2557
|
+
export declare function sanitizeOutput(output: string): string;
|
|
1695
2558
|
/**
|
|
1696
2559
|
* 单条命令的执行结果
|
|
1697
2560
|
*/
|
|
@@ -1704,6 +2567,8 @@ export interface CommandResult {
|
|
|
1704
2567
|
durationMs: number;
|
|
1705
2568
|
/** 是否因超时被中止(默认 false) */
|
|
1706
2569
|
timedOut?: boolean;
|
|
2570
|
+
/** 超时兜底落定时是否未能确认直接子进程已退出 */
|
|
2571
|
+
terminationUnconfirmed?: boolean;
|
|
1707
2572
|
/** stdout 摘要(截断到 200 行,已脱敏) */
|
|
1708
2573
|
stdout: string;
|
|
1709
2574
|
/** stderr 摘要(截断到 200 行,已脱敏) */
|
|
@@ -1717,12 +2582,13 @@ export interface VerificationParams {
|
|
|
1717
2582
|
workDir: string;
|
|
1718
2583
|
/**
|
|
1719
2584
|
* 要执行的命令序列。
|
|
1720
|
-
* 默认: `pnpm install --frozen-lockfile` → `pnpm lint` → `pnpm build`
|
|
2585
|
+
* 默认: `pnpm install --frozen-lockfile` → `pnpm lint` → `pnpm build` → `pnpm typecheck` → `pnpm test`
|
|
1721
2586
|
*/
|
|
1722
2587
|
commands?: string[];
|
|
1723
2588
|
/**
|
|
1724
2589
|
* 单命令超时(毫秒),超时中止该命令并终止其进程树。
|
|
1725
|
-
* 默认 10
|
|
2590
|
+
* 默认 10 分钟(恶意死循环脚本超时中止,防长时间占用);
|
|
2591
|
+
* 未显式提供时读取 `DEPENDFIX_VERIFY_TIMEOUT_MS`(10s-30min,越界回退默认)。
|
|
1726
2592
|
*/
|
|
1727
2593
|
commandTimeoutMs?: number;
|
|
1728
2594
|
/**
|
|
@@ -1731,6 +2597,12 @@ export interface VerificationParams {
|
|
|
1731
2597
|
* 仅当环境无既有代理时注入(覆盖用户代理会破坏其网络行为)。
|
|
1732
2598
|
*/
|
|
1733
2599
|
networkAuditDisabled?: boolean;
|
|
2600
|
+
/**
|
|
2601
|
+
* 遇首个失败命令后是否立即停止(默认 true,保持修复后验证的短路语义)。
|
|
2602
|
+
* 修复前基线采样传 false:完整执行整条链并逐段记录,避免 install 失败遮蔽
|
|
2603
|
+
* test 的既有失败(nest-template 形态)。
|
|
2604
|
+
*/
|
|
2605
|
+
stopOnFailure?: boolean;
|
|
1734
2606
|
}
|
|
1735
2607
|
/**
|
|
1736
2608
|
* 验证执行结果
|
|
@@ -1749,6 +2621,59 @@ export interface VerificationResult {
|
|
|
1749
2621
|
/** 非白名单外联违规(deny-by-default 拦截记录;空数组 = 无违规或审计关闭) */
|
|
1750
2622
|
networkViolations?: NetworkAuditEntry[];
|
|
1751
2623
|
}
|
|
2624
|
+
/**
|
|
2625
|
+
* 默认验证命令链(**唯一事实源**——app 层经此导入,消除此前的双副本漂移)。
|
|
2626
|
+
*
|
|
2627
|
+
* **顺序** install → lint → build → typecheck → test:
|
|
2628
|
+
* - 便宜且失败信息明确的命令靠前,先失败可快速短路;test 置于最后(通常是链中最慢一步)。
|
|
2629
|
+
* - typecheck 必须排在 build 之后:workspace 包的 `tsc` 依赖前置包已发射的 `dist` 声明
|
|
2630
|
+
* (实测移出 `packages/{core,engine,cli}/dist` 后 `pnpm --filter @dependfix/platform typecheck`
|
|
2631
|
+
* 报大量 `TS2307 Cannot find module`)。
|
|
2632
|
+
* - typecheck 排在 test 之前:类型错误优先于测试运行短路;修复前基线使用
|
|
2633
|
+
* 完整链(`stopOnFailure:false`),不再受首失败前缀覆盖。
|
|
2634
|
+
*
|
|
2635
|
+
* **为何纳入 typecheck**:改动前的四条命令互不重叠地都不做类型检查——lint 只跑规则
|
|
2636
|
+
* (类型解析失败通常降级为规则告警而非错误)、tsdown 的 `dts` 只发射声明、vitest 走 esbuild
|
|
2637
|
+
* 转译。实证:消费方 `nodemailer.Transporter` 在依赖升到 10.x 后不再存在(TS2503),
|
|
2638
|
+
* 而 install / lint / build / test 四条全绿——类型面破坏被判 `verificationPassed = true`
|
|
2639
|
+
* 并交付成 PR,直到目标仓库 CI 才红。**边界**:`"build": "tsc"` 形态的仓库 build 本身即
|
|
2640
|
+
* 类型检查,此时本命令为冗余(只增耗时,无害),并非新增防线。
|
|
2641
|
+
*
|
|
2642
|
+
* **为何纳入 test**:仅 install/lint/build 的矩阵无法捕获「lint/build 通过但测试无法运行或失败」
|
|
2643
|
+
* 的破坏。实证:目标仓库把 `decode-uri-component` 升到纯 ESM 版本后,CJS 消费方
|
|
2644
|
+
* `query-string@7.1.3` 在 Jest 下无法加载该模块(`SyntaxError: Unexpected token 'export'`),
|
|
2645
|
+
* 而 install / lint / build 三条全绿——坏修复被交付成 PR。
|
|
2646
|
+
*
|
|
2647
|
+
* 无 `typecheck` / `test` 脚本的仓库由 `validateVerifyCommands` 跳过并记 `SCRIPT_NOT_FOUND` 审计,
|
|
2648
|
+
* 不会误伤未配置对应脚本的仓库。
|
|
2649
|
+
*
|
|
2650
|
+
* **已知边界**:脚本语义不实(如 `"typecheck": "tsc --noEmit || true"`)无法机检;
|
|
2651
|
+
* 「typecheck / test 长期为红」的仓库由命令级既有失败基线豁免;基线完整链采样全部命令
|
|
2652
|
+
* (`sampleVerificationBaseline` 传 `stopOnFailure:false`),修复后验证仍首失败即停;
|
|
2653
|
+
* 需 `nuxt prepare` 之类前置步骤的仓库默认链不成立,走 `--commands` / 平台 `verifyCommands` /
|
|
2654
|
+
* action `commands` 逃生舱。
|
|
2655
|
+
*/
|
|
2656
|
+
export declare const DEFAULT_VERIFY_COMMANDS: string[];
|
|
2657
|
+
/**
|
|
2658
|
+
* 单命令超时(10 分钟):与纳入 test 前保持一致,不因命令数增加而调整。
|
|
2659
|
+
* 注意:test 通常是链中最慢一步,大型测试套件超 10 分钟会被判超时 → 该命令计为失败。
|
|
2660
|
+
* 修复前即红的既有失败不归因本次改动(命令级基线判定,见 `sampleVerificationBaseline`),
|
|
2661
|
+
* 但超时本身仍按失败记录(不作独立超时豁免)。
|
|
2662
|
+
*
|
|
2663
|
+
* CI 镜像脚本(`--mirror-ci-scripts`)与默认链共用本超时——镜像不引入第二个计时器。
|
|
2664
|
+
*/
|
|
2665
|
+
export declare const DEFAULT_COMMAND_TIMEOUT_MS: number;
|
|
2666
|
+
/** 验证命令超时覆盖 env(运维面;默认链与 CI 镜像脚本同源)。 */
|
|
2667
|
+
export declare const VERIFY_TIMEOUT_ENV = "DEPENDFIX_VERIFY_TIMEOUT_MS";
|
|
2668
|
+
/** 允许的最小单命令超时(低于 10s 无实际意义,按配置错误回退默认)。 */
|
|
2669
|
+
export declare const MIN_COMMAND_TIMEOUT_MS = 10000;
|
|
2670
|
+
/** 允许的最大单命令超时(30 分钟,与平台单仓执行上限同量级)。 */
|
|
2671
|
+
export declare const MAX_COMMAND_TIMEOUT_MS: number;
|
|
2672
|
+
/**
|
|
2673
|
+
* 解析单命令超时(毫秒):合法正整数且落在 [10s, 30min] 内才采纳,否则回退默认。
|
|
2674
|
+
* 与安装类超时(`fixers/install-timeouts.ts`)同族口径,但两者刻意不同源、互不覆盖。
|
|
2675
|
+
*/
|
|
2676
|
+
export declare function resolveCommandTimeoutMs(env?: NodeJS.ProcessEnv, fallback?: number): number;
|
|
1752
2677
|
/**
|
|
1753
2678
|
* 压缩验证命令输出为报告可读的摘要(首尾各取若干行,超长中间省略)。
|
|
1754
2679
|
* 完整输出由日志承载;报告保持紧凑,避免 error 字段失控膨胀。
|
|
@@ -1772,12 +2697,6 @@ export declare function formatVerificationError(cr: CommandResult): string;
|
|
|
1772
2697
|
* ```
|
|
1773
2698
|
*/
|
|
1774
2699
|
export declare function runVerification(params: VerificationParams): Promise<VerificationResult>;
|
|
1775
|
-
/**
|
|
1776
|
-
* 对外暴露以支持单独测试
|
|
1777
|
-
*/
|
|
1778
|
-
export declare function sanitizeOutput(output: string): string;
|
|
1779
|
-
//#endregion
|
|
1780
|
-
//#region src/alerts/pnpm-audit-fetcher.d.ts
|
|
1781
2700
|
/**
|
|
1782
2701
|
* pnpm audit 本地回退数据源(无 GitHub token 场景)。
|
|
1783
2702
|
*
|
|
@@ -1811,6 +2730,8 @@ interface RiskRecord {
|
|
|
1811
2730
|
ghsaId?: string;
|
|
1812
2731
|
/** CVE ID 列表(pnpm audit `advisory.cves[]` 字符串数组) */
|
|
1813
2732
|
cveIds?: string[];
|
|
2733
|
+
/** 依赖链路径(`advisories[].findings[].paths[]` 合并去重,每项一条完整链) */
|
|
2734
|
+
dependencyPaths?: string[];
|
|
1814
2735
|
}
|
|
1815
2736
|
/**
|
|
1816
2737
|
* 解析 pnpm audit 报告(legacy + modern 双格式),按
|
|
@@ -1818,17 +2739,15 @@ interface RiskRecord {
|
|
|
1818
2739
|
*/
|
|
1819
2740
|
export declare function parseAuditReport(report: unknown): RiskRecord[];
|
|
1820
2741
|
/**
|
|
1821
|
-
* advisoryId
|
|
2742
|
+
* advisoryId 的稳定数字哈希(保留以维持向后兼容 `NormalizedSecurityAlert.id: number`)。
|
|
1822
2743
|
*
|
|
1823
2744
|
* 取 sha256 前 4 字节完整 uint32(非设计稿的 `% 2^31`:uint32 语义更自然,
|
|
1824
2745
|
* 碰撞概率 ~2^-32/对,12 条告警场景生日界 ~1.6e-8,可忽略)。
|
|
1825
2746
|
*
|
|
1826
|
-
*
|
|
2747
|
+
* 已弃用:唯一去重键改为 `upstreamId`,详见 [`normalizeUpstreamId`](../../../core/src/alerts/upstream-id.ts)。
|
|
1827
2748
|
* 本函数保留仅为兼容现有 `NormalizedSecurityAlert.id: number` 字段,**不是**平台去重键。
|
|
1828
2749
|
*/
|
|
1829
2750
|
export declare function hashAdvisoryId(packageName: string, advisoryId: string): number;
|
|
1830
|
-
//#endregion
|
|
1831
|
-
//#region src/ai/provider.d.ts
|
|
1832
2751
|
interface AiConfig {
|
|
1833
2752
|
/** 提供商类型:openai-compatible(默认)/ anthropic */
|
|
1834
2753
|
provider: 'openai-compatible' | 'anthropic';
|
|
@@ -1863,8 +2782,6 @@ interface AiChatResult {
|
|
|
1863
2782
|
text: string;
|
|
1864
2783
|
usage: AiChatUsage;
|
|
1865
2784
|
}
|
|
1866
|
-
//#endregion
|
|
1867
|
-
//#region src/ai/schema.d.ts
|
|
1868
2785
|
declare const replaceBlockSchema: z.ZodObject<{
|
|
1869
2786
|
search: z.ZodString;
|
|
1870
2787
|
replace: z.ZodString;
|
|
@@ -1897,8 +2814,6 @@ declare const assessmentSchema: z.ZodObject<{
|
|
|
1897
2814
|
type AiAssessment = z.infer<typeof assessmentSchema>;
|
|
1898
2815
|
type AiFileChange = z.infer<typeof fileChangeSchema>;
|
|
1899
2816
|
type AiReplaceBlock = z.infer<typeof replaceBlockSchema>;
|
|
1900
|
-
//#endregion
|
|
1901
|
-
//#region src/ai/changelog-fetcher.d.ts
|
|
1902
2817
|
interface ChangelogEntry {
|
|
1903
2818
|
/** release 版本号(tag_name 原样保留,可能为 `v1.2.3` 形态) */
|
|
1904
2819
|
version: string;
|
|
@@ -1909,8 +2824,6 @@ interface ChangelogEntry {
|
|
|
1909
2824
|
/** release 页面地址 */
|
|
1910
2825
|
htmlUrl: string;
|
|
1911
2826
|
}
|
|
1912
|
-
//#endregion
|
|
1913
|
-
//#region src/ai/prompt.d.ts
|
|
1914
2827
|
interface AssessmentContextInput {
|
|
1915
2828
|
packageName: string;
|
|
1916
2829
|
fromVersion: string;
|
|
@@ -1922,8 +2835,6 @@ interface AssessmentContextInput {
|
|
|
1922
2835
|
/** 受影响文件路径列表(可选) */
|
|
1923
2836
|
affectedFiles?: string[];
|
|
1924
2837
|
}
|
|
1925
|
-
//#endregion
|
|
1926
|
-
//#region src/ai/secrets.d.ts
|
|
1927
2838
|
/**
|
|
1928
2839
|
* 对文本中的敏感值做脱敏替换(保留首 4 尾 4 字符便于定位)。
|
|
1929
2840
|
*
|
|
@@ -1935,8 +2846,6 @@ interface AssessmentContextInput {
|
|
|
1935
2846
|
* // → 'call failed with key sk-a****yz'
|
|
1936
2847
|
*/
|
|
1937
2848
|
export declare function maskSecrets(text: string, secrets: string[]): string;
|
|
1938
|
-
//#endregion
|
|
1939
|
-
//#region src/ai/index.d.ts
|
|
1940
2849
|
export interface AssessResult {
|
|
1941
2850
|
/** 结构化研判(降级时为 null,走建议模式) */
|
|
1942
2851
|
assessment: AiAssessment | null;
|
|
@@ -1970,16 +2879,25 @@ export interface AssessOptions {
|
|
|
1970
2879
|
* 降级语义:调用方走建议模式(报告输出人工建议),不静默、可审计。
|
|
1971
2880
|
*/
|
|
1972
2881
|
export declare function assessBreakingChange(options: AssessOptions): Promise<AssessResult>;
|
|
1973
|
-
//#endregion
|
|
1974
|
-
//#region src/app/repo-alerts.d.ts
|
|
1975
2882
|
/**
|
|
1976
2883
|
* 获取仓库的默认分支。
|
|
1977
2884
|
* pnpm-audit 模式 client 为 null → 返回 ''(报告显示 local)。
|
|
1978
2885
|
* 失败时返回 `'unknown'`(不阻塞主流程)。
|
|
1979
2886
|
*/
|
|
1980
2887
|
export declare function fetchDefaultBranch(client: Octokit | null, owner: string, repo: string): Promise<string>;
|
|
1981
|
-
|
|
1982
|
-
|
|
2888
|
+
/**
|
|
2889
|
+
* 输出「部分源拉取失败」汇总(per-source 错误隔离:单源失败不阻断其余源的结果)。
|
|
2890
|
+
*
|
|
2891
|
+
* 触发条件(必须全部满足,避免与"仓库失败"(无任何成功源)语义重叠):
|
|
2892
|
+
* 1. allErrors 至少包含一个 `stage='fetch' + category='FETCH_FAILED'` 错误(per-source 失败)
|
|
2893
|
+
* 2. **至少一个仓库成功拉取了部分告警**(isAnyRepoSuccessful = true)——
|
|
2894
|
+
* 否则该仓库已按失败处理(无任何成功源),由 processRepoForReport catch + logger.error 单独处理,
|
|
2895
|
+
* 本函数聚焦"warn + 保留成功源"场景的汇总输出,避免重复提示。
|
|
2896
|
+
*
|
|
2897
|
+
* 汇总按 source 分组('dependabot' / 'code-scanning' / 'code-quality' / 'pnpm-audit'),
|
|
2898
|
+
* 列出每个源失败的仓库数 + 示例错误消息,便于用户快速定位是 token 权限还是网络问题。
|
|
2899
|
+
*/
|
|
2900
|
+
export declare function logPartialSourceFailureSummary(allErrors: FixError[], logger: Logger, isAnyRepoSuccessful: boolean): void;
|
|
1983
2901
|
export interface DependfixAppOptions {
|
|
1984
2902
|
/** 已解析的运行时配置 */
|
|
1985
2903
|
config: RuntimeConfig;
|
|
@@ -2009,20 +2927,8 @@ export interface DependfixRunResult {
|
|
|
2009
2927
|
/** 进程退出码:0=全部成功, 1=部分失败, 2=全部失败 */
|
|
2010
2928
|
exitCode: number;
|
|
2011
2929
|
}
|
|
2012
|
-
/**
|
|
2013
|
-
* 输出"部分源拉取失败"汇总(todo.md §M19.5 C8 per-source 错误隔离)。
|
|
2014
|
-
*
|
|
2015
|
-
* 触发条件(必须全部满足,避免与"全部源失败"语义重叠):
|
|
2016
|
-
* 1. allErrors 至少包含一个 `stage='fetch' + category='FETCH_FAILED'` 错误(per-source 失败)
|
|
2017
|
-
* 2. **至少一个仓库成功拉取了部分告警**(isAnyRepoSuccessful = true)——
|
|
2018
|
-
* 否则就是"全部源失败"语义,已由 processRepoForReport catch + logger.error 单独处理,
|
|
2019
|
-
* 本函数聚焦"warn + 保留成功源"场景的汇总输出,避免重复提示。
|
|
2020
|
-
*
|
|
2021
|
-
* 汇总按 source 分组('dependabot' / 'code-scanning' / 'code-quality' / 'pnpm-audit'),
|
|
2022
|
-
* 列出每个源失败的仓库数 + 示例错误消息,便于用户快速定位是 token 权限还是网络问题。
|
|
2023
|
-
*/
|
|
2024
|
-
export declare function logPartialSourceFailureSummary(allErrors: FixError[], logger: Logger, isAnyRepoSuccessful: boolean): void;
|
|
2025
2930
|
export declare class DependfixApp {
|
|
2931
|
+
/** 运行时配置;构造期按「中央配置优先」合并目标仓库专属配置后单次赋值(见 applyRepoConfig) */
|
|
2026
2932
|
private readonly config;
|
|
2027
2933
|
private readonly workDir;
|
|
2028
2934
|
private readonly reportOutputDir;
|
|
@@ -2031,9 +2937,15 @@ export declare class DependfixApp {
|
|
|
2031
2937
|
private readonly customCommands?;
|
|
2032
2938
|
private readonly executionEnvironment;
|
|
2033
2939
|
private readonly runId;
|
|
2940
|
+
/** GitHub App 认证提供者(用于 commit author 真实 bot 身份;仅 fix/fix-and-pr 模式生效) */
|
|
2941
|
+
private readonly githubAppAuth?;
|
|
2942
|
+
/** 运行构建版本回执(`[build]` 启动行;平台注入优先,CLI 回退包版本) */
|
|
2943
|
+
private readonly buildInfo;
|
|
2034
2944
|
private readonly allAlerts;
|
|
2035
2945
|
private readonly allActions;
|
|
2036
2946
|
private readonly allErrors;
|
|
2947
|
+
/** alerts 功能未启用记录(未启用 ≠ 失败,不计入 allErrors / exitCode) */
|
|
2948
|
+
private readonly alertsDisabled;
|
|
2037
2949
|
private readonly repoResults;
|
|
2038
2950
|
private readonly summary;
|
|
2039
2951
|
/** run 级 AI 用量聚合(--ai 实际调用时填充;报告 aiUsage 段数据源;由 repo-fix 管线步骤回写) */
|
|
@@ -2042,7 +2954,36 @@ export declare class DependfixApp {
|
|
|
2042
2954
|
private finishedAt;
|
|
2043
2955
|
/** 运行前工作区是否已有未提交改动(验证门禁回滚保护:避免销毁用户本地工作) */
|
|
2044
2956
|
private preExistingDirty;
|
|
2957
|
+
/** 运行级修复前基线(跨仓库复用;惰性首采,零告警不采样)。 */
|
|
2958
|
+
private verificationBaseline;
|
|
2959
|
+
/** 单元回滚 checkpoint(单元 probe 开始前记录,跨仓库传递)。 */
|
|
2960
|
+
private readonly verificationCheckpoints;
|
|
2961
|
+
/** 验证链口径记录(run 级;`verifyProject` 写入,报告与 PR 正文消费) */
|
|
2962
|
+
private readonly ciAlignment;
|
|
2963
|
+
/** 最近关闭 PR 的尝试索引(run 级缓存;仅 fix-and-pr 模式参与判定) */
|
|
2964
|
+
private readonly attemptIndex;
|
|
2965
|
+
/** 同告警尝试记录(run 级;报告与 PR 正文标记数据源) */
|
|
2966
|
+
private readonly attemptTracking;
|
|
2967
|
+
/** PR 落点仓库(第一个仓库;尝试标记只能写进该仓库的 PR) */
|
|
2968
|
+
private attemptRepo;
|
|
2969
|
+
/** PR check 回环结果(run 级;仅在 `--wait-pr-checks` 且创建 PR 时递增) */
|
|
2970
|
+
private readonly prCheckWatchReport;
|
|
2971
|
+
/** 交付跳过记录(基线红;`computeSummary` 据此派生 summary 计数) */
|
|
2972
|
+
private readonly deliverySkips;
|
|
2973
|
+
/** 已记录的预算跳过(`stage:work`;逐包命中不刷审计) */
|
|
2974
|
+
private readonly budgetSkips;
|
|
2975
|
+
/** `draft` 档的跳过记录(sanity: PR 创建后回填载体编号) */
|
|
2976
|
+
private baselineRedDraft?;
|
|
2977
|
+
private readonly alertOutcomes;
|
|
2045
2978
|
constructor(options: DependfixAppOptions);
|
|
2979
|
+
/**
|
|
2980
|
+
* 请求中止本次运行(平台执行超时 / 运维中止的接入点;协作式、可重复调用)。
|
|
2981
|
+
*
|
|
2982
|
+
* 语义与留痕口径见 [app/abort.ts](./abort.ts) 的 `recordRunAbort`;核心三步:
|
|
2983
|
+
* ① 立即终止在跑子进程树;② 不再启动新工作(仓库边界 / 验证链 / 安装命令三重短路);
|
|
2984
|
+
* ③ 放弃交付(半成品不落地)。不抛错、不中断调用栈。
|
|
2985
|
+
*/
|
|
2986
|
+
abort(reason?: string): void;
|
|
2046
2987
|
/** 供辅助方法使用的状态切片。 */
|
|
2047
2988
|
private get ctx();
|
|
2048
2989
|
/** 执行完整的编排流程,返回结构化结果和退出码。 */
|
|
@@ -2057,7 +2998,6 @@ export declare class DependfixApp {
|
|
|
2057
2998
|
private runStartupSecurityChecks;
|
|
2058
2999
|
private executeMode;
|
|
2059
3000
|
private executeReportMode;
|
|
2060
|
-
private processRepoForReport;
|
|
2061
3001
|
private executeFixMode;
|
|
2062
3002
|
private processRepoForFix;
|
|
2063
3003
|
/**
|
|
@@ -2078,16 +3018,6 @@ export declare class DependfixApp {
|
|
|
2078
3018
|
* - dry-run 模式仅列清单并打印 "would delete",不执行删除
|
|
2079
3019
|
*/
|
|
2080
3020
|
private executeCleanupBranchesMode;
|
|
2081
|
-
/**
|
|
2082
|
-
* 重复 PR 处理:在新 PR 上添加评论指向被取代的旧 PR + 添加 `duplicate` label。
|
|
2083
|
-
*
|
|
2084
|
-
* 失败仅记录 warning(家务活 best-effort),不阻断主流程:
|
|
2085
|
-
* - 新 PR 已创建成功,用户已可访问
|
|
2086
|
-
* - 评论失败不影响 PR 本身的可用性
|
|
2087
|
-
* - 但需要 `issues: write` token scope(比 `pull-requests: write` 宽);
|
|
2088
|
-
* 若 token 权限不足,error 会被记录但不阻塞
|
|
2089
|
-
*/
|
|
2090
|
-
private handleDuplicatePRs;
|
|
2091
3021
|
/**
|
|
2092
3022
|
* 多仓库并发执行管线。
|
|
2093
3023
|
*
|
|
@@ -2108,10 +3038,6 @@ export declare class DependfixApp {
|
|
|
2108
3038
|
* - 未配置 `--owner`:沿用现有 resolveAlertRepositories 语义
|
|
2109
3039
|
*/
|
|
2110
3040
|
private resolveRepositories;
|
|
2111
|
-
/** pnpm-audit 模式不创建 GitHub client(无 token);github-dependabot 模式返回主 token client。 */
|
|
2112
|
-
private githubClientOrNull;
|
|
2113
|
-
private createClient;
|
|
2114
3041
|
}
|
|
2115
|
-
|
|
2116
|
-
export type { AiAssessment, AiChatResult, AiConfig, AiFileChange, AiReplaceBlock, AiUsage, AlertClass, AlertSourceKind, AssessmentContextInput, AuthProvider, AuthProviderOptions, FromAppParams, FromPatParams, SeverityThreshold };
|
|
3042
|
+
export type { AiAssessment, AiChatResult, AiConfig, AiFileChange, AiReplaceBlock, AiUsage, AlertClass, AlertSourceKind, AssessmentContextInput, AuthProvider, AuthProviderOptions, FromAppParams, FromPatParams, ManifestUpgradeApplied, OverrideUpsert, PackageJson, SeverityThreshold, VersionedOverridesApplyResult, VersionedOverridesPlan };
|
|
2117
3043
|
//# sourceMappingURL=index.d.mts.map
|