@wuyanbin/ai-code-review-cli-remote 1.2.0 → 1.4.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.
Files changed (75) hide show
  1. package/README.md +73 -0
  2. package/dist/core/agent-runtime.d.ts +81 -0
  3. package/dist/core/agent-runtime.d.ts.map +1 -0
  4. package/dist/core/agent-runtime.js +186 -0
  5. package/dist/core/agent-runtime.js.map +1 -0
  6. package/dist/core/confidence.d.ts +40 -0
  7. package/dist/core/confidence.d.ts.map +1 -0
  8. package/dist/core/confidence.js +74 -0
  9. package/dist/core/confidence.js.map +1 -0
  10. package/dist/core/context.js +1 -1
  11. package/dist/core/context.js.map +1 -1
  12. package/dist/core/cursor-rules.d.ts +20 -2
  13. package/dist/core/cursor-rules.d.ts.map +1 -1
  14. package/dist/core/cursor-rules.js +67 -26
  15. package/dist/core/cursor-rules.js.map +1 -1
  16. package/dist/core/default-ignore.d.ts +4 -11
  17. package/dist/core/default-ignore.d.ts.map +1 -1
  18. package/dist/core/default-ignore.js +34 -8
  19. package/dist/core/default-ignore.js.map +1 -1
  20. package/dist/core/diff.d.ts +5 -0
  21. package/dist/core/diff.d.ts.map +1 -1
  22. package/dist/core/diff.js +24 -0
  23. package/dist/core/diff.js.map +1 -1
  24. package/dist/core/incremental.d.ts +15 -4
  25. package/dist/core/incremental.d.ts.map +1 -1
  26. package/dist/core/incremental.js +66 -2
  27. package/dist/core/incremental.js.map +1 -1
  28. package/dist/core/model.d.ts +8 -0
  29. package/dist/core/model.d.ts.map +1 -1
  30. package/dist/core/model.js +19 -1
  31. package/dist/core/model.js.map +1 -1
  32. package/dist/core/prompt.d.ts.map +1 -1
  33. package/dist/core/prompt.js +11 -7
  34. package/dist/core/prompt.js.map +1 -1
  35. package/dist/core/reviewer.d.ts.map +1 -1
  36. package/dist/core/reviewer.js +25 -5
  37. package/dist/core/reviewer.js.map +1 -1
  38. package/dist/core/symbol-context.d.ts +4 -0
  39. package/dist/core/symbol-context.d.ts.map +1 -1
  40. package/dist/core/symbol-context.js +36 -12
  41. package/dist/core/symbol-context.js.map +1 -1
  42. package/dist/core/verdict.d.ts +18 -1
  43. package/dist/core/verdict.d.ts.map +1 -1
  44. package/dist/core/verdict.js +49 -2
  45. package/dist/core/verdict.js.map +1 -1
  46. package/dist/core/verification.d.ts +96 -0
  47. package/dist/core/verification.d.ts.map +1 -0
  48. package/dist/core/verification.js +363 -0
  49. package/dist/core/verification.js.map +1 -0
  50. package/dist/core/verify-tools.d.ts +67 -0
  51. package/dist/core/verify-tools.d.ts.map +1 -0
  52. package/dist/core/verify-tools.js +396 -0
  53. package/dist/core/verify-tools.js.map +1 -0
  54. package/dist/gitlab/api.d.ts +6 -3
  55. package/dist/gitlab/api.d.ts.map +1 -1
  56. package/dist/gitlab/api.js +21 -7
  57. package/dist/gitlab/api.js.map +1 -1
  58. package/dist/platform/findings.d.ts +1 -1
  59. package/dist/platform/findings.d.ts.map +1 -1
  60. package/dist/platform/findings.js +15 -2
  61. package/dist/platform/findings.js.map +1 -1
  62. package/dist/runner.d.ts.map +1 -1
  63. package/dist/runner.js +38 -11
  64. package/dist/runner.js.map +1 -1
  65. package/dist/shared/identity.d.ts +8 -0
  66. package/dist/shared/identity.d.ts.map +1 -1
  67. package/dist/shared/identity.js +21 -0
  68. package/dist/shared/identity.js.map +1 -1
  69. package/dist/shared/run-budget.d.ts +20 -0
  70. package/dist/shared/run-budget.d.ts.map +1 -0
  71. package/dist/shared/run-budget.js +53 -0
  72. package/dist/shared/run-budget.js.map +1 -0
  73. package/dist/types.d.ts +37 -3
  74. package/dist/types.d.ts.map +1 -1
  75. package/package.json +2 -1
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @wuyanbin/ai-code-review-cli-remote
2
+
3
+ Mico Devhub 的 AI Code Review 远程客户端。由 GitLab CI 的 `ai_code_review` job 调用(模板见仓库 `ci-templates/remote.yml`),
4
+ 在 Runner 本地完成模型调用与 MR 评论,平台只负责配置下发、模型网关与结果持久化。
5
+
6
+ ## 一次运行做什么
7
+
8
+ ```
9
+ stdin: git diff <merge-base>..HEAD
10
+ │
11
+ ├─ 1. 拉配置 GET /api/modules/code-review/ci/config 模型、规则、GitLab 评论 token
12
+ ├─ 2. 预检 GitLab MR:Draft / 已合并 / 陈旧流水线 直接退出,不花模型成本
13
+ ├─ 3. 已知 findings GET /api/modules/code-review/ci/findings?mrIid= OPEN / WONT_FIX / SUPPRESSED + lastReviewedSha
14
+ ├─ 4. 主评审 分片 + 注解 diff + 符号级上下文;首轮 baseline 两趟取并集,增量运行一趟
15
+ ├─ 5. 对账 保活 / 收口 / 人工 dismiss / 增量准入;已知 OPEN 交复核 agent,新报交语义判重
16
+ ├─ 6. 取证验证 只对本次新建的 P0:带只读工具的 agent 读仓库核实,CONFIRMED 才发布
17
+ ├─ 7. 发布 行内评论 = 经验证的 P0;P1 / P2 只在摘要汇总(封顶 10 条);摘要 = 结论 + 验证说明 + AI 概述
18
+ ├─ 8. 回写 PUT /api/modules/code-review/ci/findings 全量 finding 状态(含验证结论、resolve 时间)
19
+ └─ 9. 上报 POST /api/modules/code-review/ci/runs 状态、用量、verdict、分项计数、Top 问题
20
+ ```
21
+
22
+ ### 发布策略(1.4.0 起)
23
+
24
+ | severity | 取证验证 | 行内评论 | 参与准入 | 入库对账 |
25
+ | --- | --- | --- | --- | --- |
26
+ | P0 | 是,只有 `CONFIRMED` 发布 | 是 | 是(任一 OPEN 且 blocking 的 P0 → `ACTION_REQUIRED`) | 是 |
27
+ | P1 / P2 | 否 | 否,摘要「P1 提示(未验证)」段按文件 / 行号列出,封顶 10 条 | 否 | 是 |
28
+
29
+ 验证结论为 `REFUTED` / `UNSURE` / `SKIPPED` 的 finding 以 `SUPPRESSED` 入库:`REFUTED` / `UNSURE` 对同一指纹粘性,
30
+ 后续 push 不重验;`SKIPPED`(预算、候选上限、时限没排上)不粘性,下次再报重新验证。
31
+
32
+ ### 取证验证 agent
33
+
34
+ - 运行时:`@anthropic-ai/sdk` 的 Tool Runner(`src/core/agent-runtime.ts`),非流式,经平台网关调用项目配置的 Claude 模型;
35
+ `apiFormat` 不是 `claude` 的项目跳过验证、照旧发布。
36
+ - 工具(`src/core/verify-tools.ts`,只读):`read_file`(行范围,≤ 200 行 / 16KB)、`search_code`(`git grep -E`,≤ 50 条)、
37
+ `list_files`(`git ls-files`,≤ 200)、`get_symbol`(tree-sitter 声明定位)。路径限定检出根内;构建产物、锁文件、二进制不可读;
38
+ 测试与文档可读(它们是佐证);项目 `review.ignore` 不限制读取。
39
+ - 结论经 strict 工具 `submit_verdict` 收口;`CONFIRMED` 必须带 `file:line` 证据且该行包含 `snippet`,否则降 `UNSURE`。
40
+ - 预算:每条候选 8 轮 / 90s,每 run 最多 10 条(P0 > P1、再按文件 / 行号),整 run 10 分钟;网关按 run 硬限 60 次调用 /
41
+ 200 万 prompt token,超限 403 `run_budget_exceeded`,CLI 不重试、停止派发、剩余记 `SKIPPED`,已确认照发。
42
+
43
+ ## 环境变量与请求头
44
+
45
+ | 名称 | 来源 | 说明 |
46
+ | --- | --- | --- |
47
+ | `AICR_PLATFORM_URL` / `AICR_PROJECT_TOKEN` | CI 变量(接入时平台写入) | 平台地址与项目 token |
48
+ | `AICR_CLI_VERSION` | CI 模板变量,默认 `latest` | 锁版本即回滚手段;无 per-feature 行为开关 |
49
+ | `CI_MERGE_REQUEST_IID` / `CI_COMMIT_SHA` / `CI_MERGE_REQUEST_SOURCE_BRANCH_SHA` | GitLab CI | MR 定位与 head 校验 |
50
+ | `CI_MERGE_REQUEST_DIFF_BASE_SHA` / `CI_MERGE_REQUEST_TARGET_BRANCH_NAME` | GitLab CI | 仓库 `.cursor/rules` 从 merge-base 的 git 树读取;取不到就跳过,不读工作树 |
51
+ | `CI_JOB_ID` | GitLab CI | run id;缺失时生成 uuid |
52
+ | `AICR_INCREMENTAL_CONTEXT` / `AICR_MAX_PAGINATION_PAGES` | 可选 | 增量上下文半径 / GitLab 翻页上限 |
53
+
54
+ 每次模型调用带 `x-aicr-purpose`(`review` / `summary` / `revalidate` / `semantic` / `verify`)与 `x-aicr-run-id`,
55
+ 平台网关据此在 `ai_call_log` 归因并做按 run 的硬限。
56
+
57
+ ## 模型调用的请求形态
58
+
59
+ - 主评审、复核、判重、摘要:`core/model.ts` 的适配器,非流式,system 稳定块打 prompt cache 断点。
60
+ - 取证验证:Tool Runner,`max_tokens` 8000、`output_config.effort = medium`,不传 `thinking`(Claude Opus 5 / 5.5 默认自适应思考),
61
+ 不依赖任何 `anthropic-beta` 头或 beta 字段(网关不转发)。
62
+
63
+ ## 开发
64
+
65
+ ```bash
66
+ npm run typecheck -w @wuyanbin/ai-code-review-cli-remote
67
+ npm test -w @wuyanbin/ai-code-review-cli-remote # 编译到 .tmp-test-build 再 node --test;含 FakeWorld 端到端集成测试
68
+ npm run build:aicr-cli-remote # 仓库根目录;同时把 tree-sitter wasm 复制进 dist/
69
+ ```
70
+
71
+ - `test/helpers/fake-world.ts`:有状态的假平台 + 假 GitLab + 假模型(含 Tool Runner 回放),跑真实 CLI 进程多轮。
72
+ - `eval/`:验证 agent 评测集与门槛(误杀 ≤ 10%、放过 ≤ 30%),脚本见 `scripts/eval-*.mjs`,说明见 `eval/README.md`。
73
+ - 发布:`npm publish`(`files` 只含 `dist` 与本 README);平台先部署、CLI 后发;回滚锁 `AICR_CLI_VERSION`。
@@ -0,0 +1,81 @@
1
+ import type { z } from "zod";
2
+ import { type RunBudgetSignal } from "../shared/run-budget";
3
+ import { type ParsedUsage } from "./model";
4
+ /**
5
+ * 带只读工具的 agent 运行时底座。
6
+ *
7
+ * 验证 agent(以及后续的主评审 agent 化)只依赖 `AgentRuntime` 接口;唯一实现
8
+ * `ToolRunnerRuntime` 基于 `@anthropic-ai/sdk` 的 Tool Runner(beta 命名空间,
9
+ * package.json 精确锁版本),经平台网关 `<origin>/api/ai/anthropic` 非流式调用:
10
+ * - baseURL = 平台下发的 endpoint 去掉 `/v1/messages`,SDK 自己拼路径;
11
+ * - 项目 token 作 `x-api-key`;`x-aicr-purpose` / `x-aicr-run-id` 供网关归因与按 run 限额;
12
+ * - 网关不转发 `anthropic-beta`,本期不依赖任何 beta 请求字段或头;
13
+ * - 不传 `thinking`(各代模型默认即可),`effort` 显式 medium,避免模型切换时成本跳变。
14
+ * 结论只能经「收口工具」(strict schema)提交:模型调用它即视为提交并结束,不再发起下一轮。
15
+ */
16
+ export type AgentStopReason = "submitted" | "max_turns" | "deadline" | "budget_exceeded" | "error";
17
+ /** 工具执行结果:字符串回给模型;`{ error }` 以 is_error tool_result 回给模型,绝不抛出 */
18
+ export type ToolRunOutcome = string | {
19
+ error: string;
20
+ };
21
+ export interface AgentTool<Schema extends z.ZodType = z.ZodType> {
22
+ name: string;
23
+ description: string;
24
+ inputSchema: Schema;
25
+ run: (input: z.infer<Schema>) => Promise<ToolRunOutcome> | ToolRunOutcome;
26
+ /** 收口工具:schema strict,模型调用它即为提交结论并结束运行(不执行 run) */
27
+ submit?: boolean;
28
+ }
29
+ /** 让各工具以各自的 zod schema 定义,又能放进同一个数组 */
30
+ export declare function defineAgentTool<Schema extends z.ZodType>(tool: AgentTool<Schema>): AgentTool;
31
+ export interface AgentRunInput {
32
+ /** run 内稳定、可缓存的指令 */
33
+ system: string;
34
+ user: string;
35
+ tools: AgentTool[];
36
+ /** 最多发起的 API 请求数(Tool Runner 的 max_iterations) */
37
+ maxTurns: number;
38
+ /** 绝对时间戳(ms):到点中断进行中的请求并结束 */
39
+ deadlineAt: number;
40
+ /** 用途标签:网关归因与 run 级用量汇总 */
41
+ purpose: string;
42
+ }
43
+ export interface AgentRunResult {
44
+ /** 收口工具的输入(已通过 schema 校验);未提交为 null */
45
+ output: unknown | null;
46
+ stopReason: AgentStopReason;
47
+ /** 实际发起的 API 请求数 */
48
+ turns: number;
49
+ usage: ParsedUsage;
50
+ /** 诊断信息(错误消息、未提交原因等),只用于日志 */
51
+ detail?: string;
52
+ }
53
+ export interface AgentRuntime {
54
+ runAgent(input: AgentRunInput): Promise<AgentRunResult>;
55
+ }
56
+ export interface ToolRunnerRuntimeOptions {
57
+ /** 平台下发的 Claude 端点(`<origin>/api/ai/anthropic/v1/messages`) */
58
+ endpoint: string;
59
+ apiKey: string;
60
+ model: string;
61
+ /** 缺省取 resolveRunId() */
62
+ runId?: string;
63
+ /** 测试注入 */
64
+ fetch?: typeof fetch;
65
+ /** 缺省为进程级单例 */
66
+ budget?: RunBudgetSignal;
67
+ maxTokens?: number;
68
+ timeoutMs?: number;
69
+ maxRetries?: number;
70
+ }
71
+ /** endpoint 去掉 `/v1/messages` 后缀(与尾部斜杠),得到 SDK 的 baseURL */
72
+ export declare function toBaseUrl(endpoint: string): string;
73
+ export declare class ToolRunnerRuntime implements AgentRuntime {
74
+ private readonly client;
75
+ private readonly model;
76
+ private readonly budget;
77
+ private readonly maxTokens;
78
+ constructor(options: ToolRunnerRuntimeOptions);
79
+ runAgent(input: AgentRunInput): Promise<AgentRunResult>;
80
+ }
81
+ //# sourceMappingURL=agent-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runtime.d.ts","sourceRoot":"","sources":["../../src/core/agent-runtime.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,WAAW,GACX,UAAU,GACV,iBAAiB,GACjB,OAAO,CAAC;AAEZ,kEAAkE;AAClE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC;IAC1E,mDAAmD;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,uCAAuC;AACvC,wBAAgB,eAAe,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO,EACtD,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GACtB,SAAS,CAEX;AAED,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,eAAe,CAAC;IAC5B,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;IACnB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,wBAAwB;IACvC,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW;IACX,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,eAAe;IACf,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElD;AAwED,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,wBAAwB;IAcvC,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;CAoG9D"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ToolRunnerRuntime = void 0;
7
+ exports.defineAgentTool = defineAgentTool;
8
+ exports.toBaseUrl = toBaseUrl;
9
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
10
+ const zod_1 = require("@anthropic-ai/sdk/helpers/beta/zod");
11
+ const ToolError_1 = require("@anthropic-ai/sdk/lib/tools/ToolError");
12
+ const identity_1 = require("../shared/identity");
13
+ const run_budget_1 = require("../shared/run-budget");
14
+ const model_1 = require("./model");
15
+ /** 让各工具以各自的 zod schema 定义,又能放进同一个数组 */
16
+ function defineAgentTool(tool) {
17
+ return tool;
18
+ }
19
+ const DEFAULT_MAX_TOKENS = 8000;
20
+ const DEFAULT_TIMEOUT_MS = 120000;
21
+ const DEFAULT_MAX_RETRIES = 1;
22
+ const EFFORT = "medium";
23
+ const NUDGE_MESSAGE = "你尚未提交结论。请在完成必要的取证后调用 submit_verdict 工具提交结论;这是结束本次验证的唯一方式。";
24
+ /** endpoint 去掉 `/v1/messages` 后缀(与尾部斜杠),得到 SDK 的 baseURL */
25
+ function toBaseUrl(endpoint) {
26
+ return endpoint.replace(/\/+$/, "").replace(/\/v1\/messages$/, "");
27
+ }
28
+ function emptyUsage() {
29
+ return { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 };
30
+ }
31
+ function toCount(value) {
32
+ return typeof value === "number" && Number.isFinite(value) && value > 0
33
+ ? Math.floor(value)
34
+ : 0;
35
+ }
36
+ /** 与 ClaudeAdapter 同一口径:input_tokens 不含缓存读写,归一化为总 prompt token */
37
+ function parseMessageUsage(usage) {
38
+ if (!usage)
39
+ return emptyUsage();
40
+ const cacheRead = toCount(usage.cache_read_input_tokens);
41
+ const cacheWrite = toCount(usage.cache_creation_input_tokens);
42
+ return {
43
+ inputTokens: toCount(usage.input_tokens) + cacheRead + cacheWrite,
44
+ outputTokens: toCount(usage.output_tokens),
45
+ cacheReadTokens: cacheRead,
46
+ cacheWriteTokens: cacheWrite,
47
+ };
48
+ }
49
+ function addUsage(total, part) {
50
+ total.inputTokens += part.inputTokens;
51
+ total.outputTokens += part.outputTokens;
52
+ total.cacheReadTokens += part.cacheReadTokens;
53
+ total.cacheWriteTokens += part.cacheWriteTokens;
54
+ }
55
+ function errorMessage(error) {
56
+ return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
57
+ }
58
+ /** 把 AgentTool 映射为 Tool Runner 的可运行工具;`{ error }` 结果转成 is_error tool_result */
59
+ function toRunnableTool(tool) {
60
+ const runnable = (0, zod_1.betaZodTool)({
61
+ name: tool.name,
62
+ description: tool.description,
63
+ inputSchema: tool.inputSchema,
64
+ run: async (input) => {
65
+ if (tool.submit)
66
+ return "结论已收到。";
67
+ const outcome = await tool.run(input);
68
+ if (typeof outcome === "string")
69
+ return outcome;
70
+ throw new ToolError_1.ToolError(outcome.error);
71
+ },
72
+ });
73
+ return tool.submit ? { ...runnable, strict: true } : runnable;
74
+ }
75
+ /** 在一条 assistant 消息里找收口工具调用;首个通过 schema 校验的即为提交 */
76
+ function findSubmission(message, submitTool) {
77
+ let invalid = null;
78
+ for (const block of message.content) {
79
+ if (block.type !== "tool_use" || block.name !== submitTool.name)
80
+ continue;
81
+ const parsed = submitTool.inputSchema.safeParse(block.input);
82
+ if (parsed.success)
83
+ return { kind: "valid", output: parsed.data };
84
+ invalid = { kind: "invalid", detail: parsed.error.message };
85
+ }
86
+ return invalid;
87
+ }
88
+ class ToolRunnerRuntime {
89
+ constructor(options) {
90
+ this.model = options.model;
91
+ this.budget = options.budget ?? run_budget_1.runBudget;
92
+ this.maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
93
+ this.client = new sdk_1.default({
94
+ apiKey: options.apiKey,
95
+ baseURL: toBaseUrl(options.endpoint),
96
+ defaultHeaders: { "x-aicr-run-id": options.runId ?? (0, identity_1.resolveRunId)() },
97
+ maxRetries: options.maxRetries ?? DEFAULT_MAX_RETRIES,
98
+ timeout: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
99
+ ...(options.fetch ? { fetch: options.fetch } : {}),
100
+ });
101
+ }
102
+ async runAgent(input) {
103
+ const usage = emptyUsage();
104
+ let turns = 0;
105
+ const finish = (stopReason, output = null, detail) => ({
106
+ output,
107
+ stopReason,
108
+ turns,
109
+ usage,
110
+ ...(detail ? { detail } : {}),
111
+ });
112
+ if (this.budget.exhausted)
113
+ return finish("budget_exceeded");
114
+ const remainingMs = input.deadlineAt - Date.now();
115
+ if (remainingMs <= 0)
116
+ return finish("deadline");
117
+ const submitTool = input.tools.find((tool) => tool.submit) ?? null;
118
+ const controller = new AbortController();
119
+ const timer = setTimeout(() => controller.abort(), remainingMs);
120
+ let nudged = false;
121
+ try {
122
+ const runner = this.client.beta.messages.toolRunner({
123
+ model: this.model,
124
+ max_tokens: this.maxTokens,
125
+ // system 稳定块打缓存断点:同一 run 内各候选共用 system 与工具定义
126
+ system: [
127
+ {
128
+ type: "text",
129
+ text: input.system,
130
+ cache_control: { type: "ephemeral" },
131
+ },
132
+ ],
133
+ messages: [{ role: "user", content: input.user }],
134
+ tools: input.tools.map(toRunnableTool),
135
+ max_iterations: input.maxTurns,
136
+ output_config: { effort: EFFORT },
137
+ }, {
138
+ headers: { "x-aicr-purpose": input.purpose },
139
+ signal: controller.signal,
140
+ });
141
+ for await (const message of runner) {
142
+ turns += 1;
143
+ const turnUsage = parseMessageUsage(message.usage);
144
+ addUsage(usage, turnUsage);
145
+ (0, model_1.recordUsage)(input.purpose, turnUsage);
146
+ if (submitTool) {
147
+ const submission = findSubmission(message, submitTool);
148
+ // 提交即结束:跳出迭代,Tool Runner 不再执行工具、不再发起下一轮
149
+ if (submission?.kind === "valid") {
150
+ return finish("submitted", submission.output);
151
+ }
152
+ // 收口输入不合法:交回 Tool Runner,其 parse 失败会以 is_error 告知模型重试
153
+ if (submission?.kind === "invalid")
154
+ continue;
155
+ }
156
+ if (message.stop_reason !== "tool_use") {
157
+ // 模型没经收口工具就结束了:提醒一次,再不提交按 error 收场
158
+ if (!nudged && turns < input.maxTurns) {
159
+ nudged = true;
160
+ runner.pushMessages({ role: "user", content: NUDGE_MESSAGE });
161
+ continue;
162
+ }
163
+ return finish("error", null, `ended without submitting (stop_reason=${message.stop_reason})`);
164
+ }
165
+ }
166
+ // 迭代自然结束:只剩 max_iterations 耗尽这一种情形(其余均在循环内返回)
167
+ return finish(turns >= input.maxTurns ? "max_turns" : "error", null, turns >= input.maxTurns ? undefined : "runner ended without a final turn");
168
+ }
169
+ catch (error) {
170
+ if (controller.signal.aborted || error instanceof sdk_1.default.APIUserAbortError) {
171
+ return finish("deadline", null, errorMessage(error));
172
+ }
173
+ if (error instanceof sdk_1.default.APIError &&
174
+ (0, run_budget_1.isRunBudgetExceeded)(error.status ?? 0, error.error)) {
175
+ this.budget.markExhausted(input.purpose);
176
+ return finish("budget_exceeded", null, errorMessage(error));
177
+ }
178
+ return finish("error", null, errorMessage(error));
179
+ }
180
+ finally {
181
+ clearTimeout(timer);
182
+ }
183
+ }
184
+ }
185
+ exports.ToolRunnerRuntime = ToolRunnerRuntime;
186
+ //# sourceMappingURL=agent-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runtime.js","sourceRoot":"","sources":["../../src/core/agent-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { AIComment, Confidence } from "../types";
2
+ /**
3
+ * 审查意见置信度:模型自报 high / medium / low,并给出依据行号(evidence)。
4
+ * 这里只做两件事——校验 evidence 是否落在模型真正看得到的行上、据此下调 confidence;
5
+ * confidence 之后只用于 MR 评论标注与平台度量,不参与发布集、准入与 fingerprint。
6
+ */
7
+ export declare const CONFIDENCE_LEVELS: readonly Confidence[];
8
+ export declare function isConfidence(value: unknown): value is Confidence;
9
+ export declare function downgradeConfidence(confidence: Confidence): Confidence;
10
+ export interface EvidenceCheck {
11
+ confidence: Confidence | undefined;
12
+ /** 模型没给 evidence(缺失或空数组):不降级,只计数 */
13
+ evidenceMissing: boolean;
14
+ /** 因不可见行占半数以上而被下调 */
15
+ downgraded: boolean;
16
+ }
17
+ /** 解析阶段的评论:比 AIComment 多一个只在 CLI 内部存在的 evidence */
18
+ export interface ParsedComment extends AIComment {
19
+ evidence?: number[];
20
+ }
21
+ /**
22
+ * 可见行集合 = 注解 diff 的 [ADD] / [CTX] 行 ∪ 变更源码上下文渲染的行(按新文件侧行号、
23
+ * 归一化路径)。evidence 非空且其中不可见的行号占半数以上 → confidence 降一级。
24
+ */
25
+ export declare function checkEvidence(comment: {
26
+ file: string;
27
+ confidence?: Confidence;
28
+ evidence?: number[];
29
+ }, visible: Map<string, Set<number>>): EvidenceCheck;
30
+ export interface ConfidenceCheckStats {
31
+ evidenceMissing: number;
32
+ confidenceDowngraded: number;
33
+ }
34
+ /** 对整批解析结果做校验,并剥掉 evidence——它不进入对齐、发布与对账 */
35
+ export declare function applyConfidenceChecks(comments: ParsedComment[], visible: Map<string, Set<number>>): {
36
+ comments: AIComment[];
37
+ stats: ConfidenceCheckStats;
38
+ };
39
+ export declare function mergeVisibleLines(...sources: Array<Map<string, Set<number>>>): Map<string, Set<number>>;
40
+ //# sourceMappingURL=confidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.d.ts","sourceRoot":"","sources":["../../src/core/confidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,UAAU,EAA8B,CAAC;AAElF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAGtE;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC;IACnC,oCAAoC;IACpC,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,mDAAmD;AACnD,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EACvE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAChC,aAAa,CAYf;AAED,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,4CAA4C;AAC5C,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAChC;IAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAAC,KAAK,EAAE,oBAAoB,CAAA;CAAE,CAaxD;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAC1C,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAc1B"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONFIDENCE_LEVELS = void 0;
4
+ exports.isConfidence = isConfidence;
5
+ exports.downgradeConfidence = downgradeConfidence;
6
+ exports.checkEvidence = checkEvidence;
7
+ exports.applyConfidenceChecks = applyConfidenceChecks;
8
+ exports.mergeVisibleLines = mergeVisibleLines;
9
+ const diff_1 = require("./diff");
10
+ /**
11
+ * 审查意见置信度:模型自报 high / medium / low,并给出依据行号(evidence)。
12
+ * 这里只做两件事——校验 evidence 是否落在模型真正看得到的行上、据此下调 confidence;
13
+ * confidence 之后只用于 MR 评论标注与平台度量,不参与发布集、准入与 fingerprint。
14
+ */
15
+ exports.CONFIDENCE_LEVELS = ["high", "medium", "low"];
16
+ function isConfidence(value) {
17
+ return value === "high" || value === "medium" || value === "low";
18
+ }
19
+ function downgradeConfidence(confidence) {
20
+ if (confidence === "high")
21
+ return "medium";
22
+ return "low";
23
+ }
24
+ /**
25
+ * 可见行集合 = 注解 diff 的 [ADD] / [CTX] 行 ∪ 变更源码上下文渲染的行(按新文件侧行号、
26
+ * 归一化路径)。evidence 非空且其中不可见的行号占半数以上 → confidence 降一级。
27
+ */
28
+ function checkEvidence(comment, visible) {
29
+ const evidence = comment.evidence ?? [];
30
+ if (evidence.length === 0) {
31
+ return { confidence: comment.confidence, evidenceMissing: true, downgraded: false };
32
+ }
33
+ const lines = visible.get((0, diff_1.normalizePath)(comment.file));
34
+ const invalid = evidence.filter((line) => !lines?.has(line)).length;
35
+ if (invalid * 2 < evidence.length || comment.confidence === undefined) {
36
+ return { confidence: comment.confidence, evidenceMissing: false, downgraded: false };
37
+ }
38
+ const next = downgradeConfidence(comment.confidence);
39
+ return { confidence: next, evidenceMissing: false, downgraded: next !== comment.confidence };
40
+ }
41
+ /** 对整批解析结果做校验,并剥掉 evidence——它不进入对齐、发布与对账 */
42
+ function applyConfidenceChecks(comments, visible) {
43
+ const stats = { evidenceMissing: 0, confidenceDowngraded: 0 };
44
+ const out = [];
45
+ for (const comment of comments) {
46
+ const check = checkEvidence(comment, visible);
47
+ if (check.evidenceMissing)
48
+ stats.evidenceMissing += 1;
49
+ if (check.downgraded)
50
+ stats.confidenceDowngraded += 1;
51
+ const { evidence: _evidence, confidence: _confidence, ...rest } = comment;
52
+ void _evidence;
53
+ void _confidence;
54
+ out.push(check.confidence ? { ...rest, confidence: check.confidence } : rest);
55
+ }
56
+ return { comments: out, stats };
57
+ }
58
+ function mergeVisibleLines(...sources) {
59
+ const merged = new Map();
60
+ for (const source of sources) {
61
+ for (const [file, lines] of source) {
62
+ const key = (0, diff_1.normalizePath)(file);
63
+ let target = merged.get(key);
64
+ if (!target) {
65
+ target = new Set();
66
+ merged.set(key, target);
67
+ }
68
+ for (const line of lines)
69
+ target.add(line);
70
+ }
71
+ }
72
+ return merged;
73
+ }
74
+ //# sourceMappingURL=confidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/core/confidence.ts"],"names":[],"mappings":"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"}
@@ -128,7 +128,7 @@ async function collectShardSourceContextDetailed(diff, options = {}) {
128
128
  });
129
129
  return result.text
130
130
  ? result
131
- : { text: "(无源码上下文)", stats: result.stats };
131
+ : { text: "(无源码上下文)", stats: result.stats, renderedLines: result.renderedLines };
132
132
  }
133
133
  /** 兼容旧调用方:只要文本 */
134
134
  async function collectShardSourceContext(diff, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":";;AAuHA,gEAWC;AAMD,8EAYC;AAGD,8DAKC;AA5JD,qCAA4D;AAC5D,+CAA4C;AAC5C,yCAAoC;AACpC,qDAG0B;AAC1B,+CAAgD;AAEhD,sDAAsD;AACtD,+BAA+B;AAC/B,MAAM,UAAU,GAAG;IACjB,iBAAiB;IACjB,WAAW;IACX,gBAAgB;IAChB,kBAAkB;IAClB,sBAAsB;CACvB,CAAC;AAEF,MAAM,cAAc,GAAG,KAAM,CAAC;AAC9B;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG,KAAM,CAAC;AAChC,0BAA0B;AAC1B,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAYrC,SAAS,cAAc,CAAC,GAAsB;IAC5C,MAAM,IAAI,GAAG;QACX,CAAC,OAAO,EAAE,GAAG,CAAC,sBAAsB,CAAC;QACrC,CAAC,OAAO,EAAE,GAAG,CAAC,4BAA4B,CAAC;QAC3C,CAAC,OAAO,EAAE,GAAG,CAAC,uBAAuB,CAAC;QACtC,CAAC,KAAK,EAAE,GAAG,CAAC,mCAAmC,CAAC;QAChD,CAAC,MAAM,EAAE,GAAG,CAAC,mCAAmC,CAAC;QACjD,CAAC,QAAQ,EAAE,GAAG,CAAC,aAAa,CAAC;KAC9B,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAEvD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO;QACL,WAAW;QACX,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,KAA2B;IAC5D,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,yBAAyB,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IACzC,OAAO;QACL,iCAAiC;QACjC,+CAA+C;YAC7C,wDAAwD;QAC1D,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,OAAO,GAA2C,EAAE,CAAC;IAC3D,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAA,mBAAO,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,IAAA,oBAAU,EAAC,IAAI,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAA,kBAAQ,EAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;gBACnE,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBACxC,OAAO,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,GAAG,IAAI,IAAI,KAAK,EAAE;wBACzB,IAAI,EAAE,IAAA,mBAAO,EAAC,IAAI,EAAE,KAAK,CAAC;qBAC3B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW;IACxC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,IAAI,SAAS,IAAI,cAAc;YAAE,MAAM;QACvC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC7C,MAAM,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAA,6BAAe,EAAC,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;YACxD,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACrC,QAAQ,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,0BAA0B,CAC9C,UAAgC,EAAE;IAElC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,QAAQ,GAAG;QACf,GAAG,cAAc,CAAC,GAAG,CAAC;QACtB,GAAG,yBAAyB,CAAC,OAAO,CAAC,aAAa,CAAC;QACnD,GAAG,CAAC,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;KAChC,CAAC;IACF,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,iCAAiC,CACrD,IAAY,EACZ,UAAgC,EAAE;IAElC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,IAAA,wCAAuB,EAAC,IAAI,EAAE;QACjD,GAAG;QACH,WAAW,EAAE,gBAAgB;KAC9B,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,IAAI;QAChB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC;AACrF,CAAC;AAED,kBAAkB;AACX,KAAK,UAAU,yBAAyB,CAC7C,IAAY,EACZ,UAAgC,EAAE;IAElC,OAAO,CAAC,MAAM,iCAAiC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC"}
@@ -13,10 +13,28 @@ export interface CollectCursorRulesOptions {
13
13
  changedFiles: string[];
14
14
  /** 纳入规则正文的总字节预算 */
15
15
  maxBytes?: number;
16
+ /**
17
+ * 规则来源提交。缺省按 env 解析:`CI_MERGE_REQUEST_DIFF_BASE_SHA`,否则
18
+ * `git merge-base origin/<CI_MERGE_REQUEST_TARGET_BRANCH_NAME> HEAD`。
19
+ */
20
+ base?: string;
21
+ env?: NodeJS.ProcessEnv;
16
22
  }
23
+ export interface RulesBase {
24
+ sha: string;
25
+ source: "CI_MERGE_REQUEST_DIFF_BASE_SHA" | "merge-base";
26
+ }
27
+ /**
28
+ * 解析仓库规则的来源提交:MR 的 merge-base。优先 `CI_MERGE_REQUEST_DIFF_BASE_SHA`
29
+ * (须在本地可达),否则 `git merge-base origin/<目标分支> HEAD`;都取不到返回 null。
30
+ * 从 merge-base 读而不是工作树:MR 自身对 .cursor/rules 的改动合入前不得生效,
31
+ * 否则被审分支可以通过改规则影响对自己的审查。
32
+ */
33
+ export declare function resolveRulesBase(cwd: string, env?: NodeJS.ProcessEnv): RulesBase | null;
17
34
  /**
18
- * 读取仓库 .cursor/rules 目录,解析并按 frontmatter 语义筛选出应纳入本次审查的规则。
19
- * alwaysApply 规则优先,超出字节预算时截断。任何单文件异常均跳过(fail-open)。
35
+ * 从 MR merge-base 的 git 树读取 .cursor/rules,解析并按 frontmatter 语义筛选出应纳入
36
+ * 本次审查的规则。alwaysApply 规则优先,超出字节预算时截断。任何单文件异常均跳过
37
+ * (fail-open);merge-base 取不到则跳过仓库规则并记日志,**不**回退到工作树。
20
38
  */
21
39
  export declare function collectCursorRules(options: CollectCursorRulesOptions): CursorRule[];
22
40
  /** 将结构化规则渲染为「项目规范」条目字符串(带来源/描述标注)。 */
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-rules.d.ts","sourceRoot":"","sources":["../../src/core/cursor-rules.ts"],"names":[],"mappings":"AAGA,iCAAiC;AACjC,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,yBAAyB,GACjC,UAAU,EAAE,CAyDd;AAED,sCAAsC;AACtC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAO/D"}
1
+ {"version":3,"file":"cursor-rules.d.ts","sourceRoot":"","sources":["../../src/core/cursor-rules.ts"],"names":[],"mappings":"AAEA,iCAAiC;AACjC,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AA4KD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,gCAAgC,GAAG,YAAY,CAAC;CACzD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,SAAS,GAAG,IAAI,CAgBlB;AAaD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,yBAAyB,GACjC,UAAU,EAAE,CA2Dd;AAED,sCAAsC;AACtC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAO/D"}