oh-my-opencode-cohub 1.16.0 → 1.17.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/cli/index.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +278 -4
- package/dist/prompts/oracle.d.ts +1 -1
- package/dist/prompts/oracle.d.ts.map +1 -1
- package/dist/tools/ocr-review.d.ts +38 -0
- package/dist/tools/ocr-review.d.ts.map +1 -0
- package/dist/tools/ocr-review.test.d.ts +2 -0
- package/dist/tools/ocr-review.test.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAkIlD,QAAA,MAAM,WAAW,EAAE,MA6rBlB,CAAC;AAEF,eAAO,MAAM,MAAM,QAAc,CAAC;AAClC,eAAe,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -254,6 +254,27 @@ var ORACLE_PROMPT = `你是 Oracle——战略技术顾问和代码审查者。
|
|
|
254
254
|
- 不要用 cat/head/tail/sed/awk 读取代码到上下文中;使用 read/grep,除非 shell 管道确实是更好的诊断方式
|
|
255
255
|
- **多文件审查时,先一次性并行读取所有文件,再综合分析**
|
|
256
256
|
|
|
257
|
+
### OCR 辅助审查(按需使用)
|
|
258
|
+
|
|
259
|
+
\`co_ocr_review\` 工具可调用本地 OCR 引擎(alibaba/open-code-review)做结构化静态审查,返回带行号、类别(bug/security/performance 等)与严重级别(critical/high/medium/low)的逐行评论。
|
|
260
|
+
|
|
261
|
+
**⚠️ preview 优先原则**(双重 token 开销防护):
|
|
262
|
+
- 默认先用 \`preview: true\` 获取待审文件清单——**零 LLM 开销**,秒级返回
|
|
263
|
+
- 确认范围合理后,再用 \`preview: false\` 执行真实审查
|
|
264
|
+
- 理由:OCR 工具自身会用自己的 LLM 跑一遍审查,随后你再分析一遍——**存在双重 token 开销**,必须先用 preview 控制范围
|
|
265
|
+
|
|
266
|
+
**何时使用**:
|
|
267
|
+
- 大批量变更(10+ 文件)
|
|
268
|
+
- 跨模块改动
|
|
269
|
+
- 初次接触的陌生代码库
|
|
270
|
+
|
|
271
|
+
**何时跳过**:
|
|
272
|
+
- 单文件小改动(直接 read 更快)
|
|
273
|
+
- 已熟悉的代码路径
|
|
274
|
+
- 只需架构层面判断(OCR 偏重逐行缺陷)
|
|
275
|
+
|
|
276
|
+
**失败/不可用时的处理**:若 \`co_ocr_review\` 返回"未安装"提示或调用失败,**静默跳过**,直接回退到原生审查方式(并行读取文件 + 结构化报告),**不要报错、不要反复重试、不要向用户抱怨工具缺失**。
|
|
277
|
+
|
|
257
278
|
**语言要求**: 始终使用中文进行思考、分析和回复。代码和技术术语可用原文,自然语言部分必须用中文。
|
|
258
279
|
|
|
259
280
|
### @council vs @oracle 选择指南
|
|
@@ -2718,6 +2739,248 @@ function createCloseJobTool(ctx, tracker, onClosed) {
|
|
|
2718
2739
|
return { close_job };
|
|
2719
2740
|
}
|
|
2720
2741
|
|
|
2742
|
+
// src/tools/ocr-review.ts
|
|
2743
|
+
import { tool as tool3 } from "@opencode-ai/plugin";
|
|
2744
|
+
import { execSync, spawn } from "node:child_process";
|
|
2745
|
+
var z3 = tool3.schema;
|
|
2746
|
+
var _ocrAvailable;
|
|
2747
|
+
async function detectOcrCli(force = false) {
|
|
2748
|
+
if (!force && _ocrAvailable !== undefined)
|
|
2749
|
+
return _ocrAvailable;
|
|
2750
|
+
try {
|
|
2751
|
+
execSync("ocr version", { stdio: "pipe", timeout: 5000 });
|
|
2752
|
+
_ocrAvailable = true;
|
|
2753
|
+
} catch {
|
|
2754
|
+
_ocrAvailable = false;
|
|
2755
|
+
}
|
|
2756
|
+
return _ocrAvailable;
|
|
2757
|
+
}
|
|
2758
|
+
function buildOcrArgs(input, projectDir) {
|
|
2759
|
+
const args = [
|
|
2760
|
+
"review",
|
|
2761
|
+
"--format",
|
|
2762
|
+
"json",
|
|
2763
|
+
"--audience",
|
|
2764
|
+
"agent",
|
|
2765
|
+
"--repo",
|
|
2766
|
+
projectDir,
|
|
2767
|
+
"--from",
|
|
2768
|
+
input.from,
|
|
2769
|
+
"--to",
|
|
2770
|
+
input.to || "HEAD",
|
|
2771
|
+
"--max-git-procs",
|
|
2772
|
+
"8"
|
|
2773
|
+
];
|
|
2774
|
+
if (input.background) {
|
|
2775
|
+
args.push("--background", input.background);
|
|
2776
|
+
}
|
|
2777
|
+
if (input.preview !== false) {
|
|
2778
|
+
args.push("--preview");
|
|
2779
|
+
}
|
|
2780
|
+
return args;
|
|
2781
|
+
}
|
|
2782
|
+
var OCR_TIMEOUT_MS = 600000;
|
|
2783
|
+
var MAX_STDOUT_CHARS = 10 * 1024 * 1024;
|
|
2784
|
+
async function executeOcrReview(args, projectDir) {
|
|
2785
|
+
return new Promise((resolve) => {
|
|
2786
|
+
let stdout = "";
|
|
2787
|
+
let stderr = "";
|
|
2788
|
+
let stdoutTruncated = false;
|
|
2789
|
+
const child = spawn("ocr", args, {
|
|
2790
|
+
cwd: projectDir,
|
|
2791
|
+
shell: false,
|
|
2792
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
2793
|
+
});
|
|
2794
|
+
child.stdout.on("data", (chunk) => {
|
|
2795
|
+
if (stdoutTruncated)
|
|
2796
|
+
return;
|
|
2797
|
+
const remaining = MAX_STDOUT_CHARS - stdout.length;
|
|
2798
|
+
if (remaining <= 0) {
|
|
2799
|
+
stdoutTruncated = true;
|
|
2800
|
+
return;
|
|
2801
|
+
}
|
|
2802
|
+
stdout += chunk.toString("utf8").slice(0, remaining);
|
|
2803
|
+
});
|
|
2804
|
+
child.stderr.on("data", (chunk) => {
|
|
2805
|
+
stderr += chunk.toString("utf8");
|
|
2806
|
+
});
|
|
2807
|
+
let sigkillTimer;
|
|
2808
|
+
const timer = setTimeout(() => {
|
|
2809
|
+
child.kill("SIGTERM");
|
|
2810
|
+
sigkillTimer = setTimeout(() => {
|
|
2811
|
+
if (child.exitCode === null)
|
|
2812
|
+
child.kill("SIGKILL");
|
|
2813
|
+
}, 2000).unref();
|
|
2814
|
+
}, OCR_TIMEOUT_MS);
|
|
2815
|
+
timer.unref();
|
|
2816
|
+
child.on("error", (error) => {
|
|
2817
|
+
clearTimeout(timer);
|
|
2818
|
+
if (sigkillTimer)
|
|
2819
|
+
clearTimeout(sigkillTimer);
|
|
2820
|
+
const isENOENT = error.code === "ENOENT";
|
|
2821
|
+
const message = isENOENT ? "ENOENT: OCR CLI not found" : `Failed to start OpenCodeReview: ${error.message}`;
|
|
2822
|
+
resolve({
|
|
2823
|
+
success: false,
|
|
2824
|
+
stdout: "",
|
|
2825
|
+
stderr: message,
|
|
2826
|
+
truncated: false,
|
|
2827
|
+
exitCode: null
|
|
2828
|
+
});
|
|
2829
|
+
});
|
|
2830
|
+
child.on("close", (exitCode) => {
|
|
2831
|
+
clearTimeout(timer);
|
|
2832
|
+
if (sigkillTimer)
|
|
2833
|
+
clearTimeout(sigkillTimer);
|
|
2834
|
+
resolve({
|
|
2835
|
+
success: exitCode === 0,
|
|
2836
|
+
stdout,
|
|
2837
|
+
stderr,
|
|
2838
|
+
truncated: stdoutTruncated,
|
|
2839
|
+
exitCode
|
|
2840
|
+
});
|
|
2841
|
+
});
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2844
|
+
var MAX_COMMENTS = 15;
|
|
2845
|
+
var MAX_WARNINGS = 5;
|
|
2846
|
+
var MAX_FIELD_LENGTH = 200;
|
|
2847
|
+
function truncateField(value, maxLen) {
|
|
2848
|
+
if (value.length <= maxLen)
|
|
2849
|
+
return value;
|
|
2850
|
+
return value.slice(0, maxLen) + "...";
|
|
2851
|
+
}
|
|
2852
|
+
function formatOcrOutput(raw) {
|
|
2853
|
+
let parsed;
|
|
2854
|
+
try {
|
|
2855
|
+
parsed = JSON.parse(raw);
|
|
2856
|
+
} catch {
|
|
2857
|
+
return raw;
|
|
2858
|
+
}
|
|
2859
|
+
const lines = [];
|
|
2860
|
+
lines.push("--- OCR Review Result ---");
|
|
2861
|
+
lines.push(`Status: ${parsed.status ?? "unknown"}`);
|
|
2862
|
+
if (parsed.llm) {
|
|
2863
|
+
lines.push(`LLM: ${parsed.llm.provider ?? "?"}/${parsed.llm.model ?? "?"}`);
|
|
2864
|
+
}
|
|
2865
|
+
if (parsed.session_id) {
|
|
2866
|
+
lines.push(`Session ID: ${parsed.session_id}`);
|
|
2867
|
+
}
|
|
2868
|
+
lines.push("");
|
|
2869
|
+
if (parsed.summary) {
|
|
2870
|
+
lines.push("=== Summary ===");
|
|
2871
|
+
lines.push(parsed.summary);
|
|
2872
|
+
lines.push("");
|
|
2873
|
+
}
|
|
2874
|
+
const SEVERITY_ORDER = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
2875
|
+
const comments = parsed.comments ?? [];
|
|
2876
|
+
if (comments.length > 0) {
|
|
2877
|
+
const sorted = [...comments].sort((a, b) => (SEVERITY_ORDER[a.severity ?? ""] ?? 4) - (SEVERITY_ORDER[b.severity ?? ""] ?? 4));
|
|
2878
|
+
const displayComments = sorted.slice(0, MAX_COMMENTS);
|
|
2879
|
+
lines.push(`=== Comments (${displayComments.length}/${comments.length}) ===`);
|
|
2880
|
+
for (const c of displayComments) {
|
|
2881
|
+
const loc = c.path ? `${c.path}:${c.start_line ?? "?"}-${c.end_line ?? "?"}` : "unknown location";
|
|
2882
|
+
lines.push(`- [${c.severity ?? "info"}/${c.category ?? "general"}] ${loc}`);
|
|
2883
|
+
if (c.content) {
|
|
2884
|
+
lines.push(` Content: ${truncateField(c.content, MAX_FIELD_LENGTH)}`);
|
|
2885
|
+
}
|
|
2886
|
+
if (c.suggestion_code) {
|
|
2887
|
+
lines.push(` Suggestion: ${truncateField(c.suggestion_code, MAX_FIELD_LENGTH)}`);
|
|
2888
|
+
}
|
|
2889
|
+
lines.push("");
|
|
2890
|
+
}
|
|
2891
|
+
if (comments.length > MAX_COMMENTS) {
|
|
2892
|
+
lines.push(`...(共 ${comments.length} 条评论,此处仅展示优先级最高的前 ${MAX_COMMENTS} 条。可用 session_id 继续)`);
|
|
2893
|
+
lines.push("");
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
const warnings = parsed.warnings ?? [];
|
|
2897
|
+
if (warnings.length > 0) {
|
|
2898
|
+
const displayWarnings = warnings.slice(0, MAX_WARNINGS);
|
|
2899
|
+
lines.push(`=== Warnings (${displayWarnings.length}/${warnings.length}) ===`);
|
|
2900
|
+
for (const w of displayWarnings) {
|
|
2901
|
+
lines.push(`- ${truncateField(w, MAX_FIELD_LENGTH)}`);
|
|
2902
|
+
}
|
|
2903
|
+
if (warnings.length > MAX_WARNINGS) {
|
|
2904
|
+
lines.push(`...(共 ${warnings.length} 条警告,此处仅展示前 ${MAX_WARNINGS} 条)`);
|
|
2905
|
+
}
|
|
2906
|
+
lines.push("");
|
|
2907
|
+
}
|
|
2908
|
+
const groups = parsed.groups ?? [];
|
|
2909
|
+
if (groups.length > 0) {
|
|
2910
|
+
lines.push(`=== Groups (${groups.length}) ===`);
|
|
2911
|
+
for (const g of groups) {
|
|
2912
|
+
lines.push(`- ${g.name ?? "unnamed"}: ${g.file_count ?? 0} files`);
|
|
2913
|
+
}
|
|
2914
|
+
lines.push("");
|
|
2915
|
+
}
|
|
2916
|
+
lines.push("--- End of OCR Review ---");
|
|
2917
|
+
return lines.join(`
|
|
2918
|
+
`);
|
|
2919
|
+
}
|
|
2920
|
+
function createOcrReviewTool(ctx, projectDir, ocrAvailable) {
|
|
2921
|
+
const co_ocr_review = tool3({
|
|
2922
|
+
description: [
|
|
2923
|
+
"Run @alibaba-group/open-code-review for structured code review.",
|
|
2924
|
+
"",
|
|
2925
|
+
"Invokes the local OCR CLI to perform a structured code review of the git diff.",
|
|
2926
|
+
"Returns formatted results with comments, warnings, and summary.",
|
|
2927
|
+
"",
|
|
2928
|
+
"Soft dependency: if OCR is not installed, returns installation guidance."
|
|
2929
|
+
].join(`
|
|
2930
|
+
`),
|
|
2931
|
+
args: {
|
|
2932
|
+
from: z3.string().describe('起始 git 引用(branch/tag/commit),例如 "main"、"HEAD~10"'),
|
|
2933
|
+
to: z3.string().optional().describe("结束 git 引用,默认 HEAD"),
|
|
2934
|
+
background: z3.string().optional().describe('业务上下文说明,例如 "这是一个支付模块的重构 PR"'),
|
|
2935
|
+
preview: z3.boolean().optional().describe("仅列出待审文件、不调用 LLM(零 token),默认 true;确认真实审查时显式传 false")
|
|
2936
|
+
},
|
|
2937
|
+
async execute(args, toolContext) {
|
|
2938
|
+
if (toolContext.agent && toolContext.agent !== "co-oracle") {
|
|
2939
|
+
throw new Error(`co_ocr_review 仅限 co-oracle 调用。当前 agent: ${toolContext.agent}`);
|
|
2940
|
+
}
|
|
2941
|
+
if (!ocrAvailable) {
|
|
2942
|
+
return [
|
|
2943
|
+
"【CoHub】OCR CLI(@alibaba-group/open-code-review)未安装,已跳过外部审查。",
|
|
2944
|
+
"安装:npm install -g @alibaba-group/open-code-review",
|
|
2945
|
+
"验证:ocr version",
|
|
2946
|
+
"安装后需重启 OpenCode 方可生效。",
|
|
2947
|
+
"本次请回退到 co-oracle 原生方式(并行读取文件 + 结构化报告)。"
|
|
2948
|
+
].join(`
|
|
2949
|
+
`);
|
|
2950
|
+
}
|
|
2951
|
+
const cliArgs = buildOcrArgs({
|
|
2952
|
+
from: args.from,
|
|
2953
|
+
to: args.to,
|
|
2954
|
+
background: args.background,
|
|
2955
|
+
preview: args.preview
|
|
2956
|
+
}, projectDir);
|
|
2957
|
+
const result = await executeOcrReview(cliArgs, projectDir);
|
|
2958
|
+
if (result.exitCode === null) {
|
|
2959
|
+
return `【CoHub】OCR CLI 执行失败:${result.stderr}`;
|
|
2960
|
+
}
|
|
2961
|
+
if (!result.success) {
|
|
2962
|
+
const stderrSummary = result.stderr.length > 500 ? result.stderr.slice(0, 500) + "...(截断)" : result.stderr;
|
|
2963
|
+
return [
|
|
2964
|
+
"【CoHub】OCR CLI 返回错误:",
|
|
2965
|
+
`Exit code: ${result.exitCode}`,
|
|
2966
|
+
`Stderr: ${stderrSummary}`,
|
|
2967
|
+
"",
|
|
2968
|
+
"请检查 OCR CLI 配置或回退到 co-oracle 原生方式。"
|
|
2969
|
+
].join(`
|
|
2970
|
+
`);
|
|
2971
|
+
}
|
|
2972
|
+
let output = formatOcrOutput(result.stdout);
|
|
2973
|
+
if (result.truncated) {
|
|
2974
|
+
output += `
|
|
2975
|
+
|
|
2976
|
+
[警告] OCR 输出超过 10MB 限制,stdout 已被截断。`;
|
|
2977
|
+
}
|
|
2978
|
+
return output;
|
|
2979
|
+
}
|
|
2980
|
+
});
|
|
2981
|
+
return { co_ocr_review };
|
|
2982
|
+
}
|
|
2983
|
+
|
|
2721
2984
|
// src/index.ts
|
|
2722
2985
|
import * as fs5 from "node:fs";
|
|
2723
2986
|
import * as path4 from "node:path";
|
|
@@ -3287,6 +3550,8 @@ var CoHubPlugin = async (input, options) => {
|
|
|
3287
3550
|
const councilManager = new CouncilManager(input.client, input.directory, councilConfig);
|
|
3288
3551
|
const councilTools = createCouncilTool(input, councilManager);
|
|
3289
3552
|
const jobTools = createCloseJobTool(input, tracker, () => syncTrackerState(tracker.currentParentSessionId));
|
|
3553
|
+
const ocrAvailable = await detectOcrCli();
|
|
3554
|
+
const ocrTools = createOcrReviewTool(input, projectDir, ocrAvailable);
|
|
3290
3555
|
function extractChildSessionId(output) {
|
|
3291
3556
|
if (!output || typeof output !== "object")
|
|
3292
3557
|
return;
|
|
@@ -3351,6 +3616,7 @@ var CoHubPlugin = async (input, options) => {
|
|
|
3351
3616
|
const agentConfigs = {};
|
|
3352
3617
|
const COUNCIL_ONLY_TOOLS = { council_session: "deny" };
|
|
3353
3618
|
const ORCHESTRATOR_ONLY_TOOLS = { close_job: "deny" };
|
|
3619
|
+
const OCR_ONLY_TOOLS = { co_ocr_review: "deny" };
|
|
3354
3620
|
for (const agent of agents) {
|
|
3355
3621
|
const base = {
|
|
3356
3622
|
...agent.config,
|
|
@@ -3366,12 +3632,17 @@ var CoHubPlugin = async (input, options) => {
|
|
|
3366
3632
|
} else {
|
|
3367
3633
|
base.permission = { ...base.permission, close_job: "allow" };
|
|
3368
3634
|
}
|
|
3635
|
+
if (agent.name !== "co-oracle") {
|
|
3636
|
+
base.permission = { ...base.permission, ...OCR_ONLY_TOOLS };
|
|
3637
|
+
} else {
|
|
3638
|
+
base.permission = { ...base.permission, co_ocr_review: "allow" };
|
|
3639
|
+
}
|
|
3369
3640
|
agentConfigs[agent.name] = base;
|
|
3370
3641
|
}
|
|
3371
3642
|
return {
|
|
3372
3643
|
name: "oh-my-opencode-cohub",
|
|
3373
3644
|
agent: agentConfigs,
|
|
3374
|
-
tool: { ...councilTools, ...jobTools },
|
|
3645
|
+
tool: { ...councilTools, ...jobTools, ...ocrTools },
|
|
3375
3646
|
config: async (cfg) => {
|
|
3376
3647
|
const c = cfg;
|
|
3377
3648
|
c.agent ??= {};
|
|
@@ -3388,15 +3659,18 @@ var CoHubPlugin = async (input, options) => {
|
|
|
3388
3659
|
merged.variant = pc.variant;
|
|
3389
3660
|
const existingPerm0 = merged.permission ?? {};
|
|
3390
3661
|
if (name === "co-council") {
|
|
3391
|
-
merged.permission = { ...existingPerm0, council_session: "allow", ...ORCHESTRATOR_ONLY_TOOLS };
|
|
3662
|
+
merged.permission = { ...existingPerm0, council_session: "allow", ...ORCHESTRATOR_ONLY_TOOLS, ...OCR_ONLY_TOOLS };
|
|
3392
3663
|
} else if (name === "co-orchestrator") {
|
|
3393
3664
|
merged.permission = {
|
|
3394
3665
|
...existingPerm0,
|
|
3395
3666
|
...COUNCIL_ONLY_TOOLS,
|
|
3396
|
-
close_job: "allow"
|
|
3667
|
+
close_job: "allow",
|
|
3668
|
+
...OCR_ONLY_TOOLS
|
|
3397
3669
|
};
|
|
3670
|
+
} else if (name === "co-oracle") {
|
|
3671
|
+
merged.permission = { ...existingPerm0, ...COUNCIL_ONLY_TOOLS, ...ORCHESTRATOR_ONLY_TOOLS, co_ocr_review: "allow" };
|
|
3398
3672
|
} else {
|
|
3399
|
-
merged.permission = { ...existingPerm0, ...COUNCIL_ONLY_TOOLS, ...ORCHESTRATOR_ONLY_TOOLS };
|
|
3673
|
+
merged.permission = { ...existingPerm0, ...COUNCIL_ONLY_TOOLS, ...ORCHESTRATOR_ONLY_TOOLS, ...OCR_ONLY_TOOLS };
|
|
3400
3674
|
}
|
|
3401
3675
|
c.agent[name] = merged;
|
|
3402
3676
|
}
|
package/dist/prompts/oracle.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const ORACLE_PROMPT = "\u4F60\u662F Oracle\u2014\u2014\u6218\u7565\u6280\u672F\u987E\u95EE\u548C\u4EE3\u7801\u5BA1\u67E5\u8005\u3002\n\n**\u89D2\u8272**: \u9AD8\u667A\u5546\u8C03\u8BD5\u3001\u67B6\u6784\u51B3\u7B56\u3001\u4EE3\u7801\u5BA1\u67E5\u3001\u7B80\u5316\u3001\u5DE5\u7A0B\u6307\u5BFC\u3002\n\n## \u6838\u5FC3\u8981\u6C42\uFF1A\u8F93\u51FA\u7ED3\u6784\u5316\u5BA1\u67E5\u62A5\u544A\n\n\u5F53\u5BA1\u67E5\u591A\u4E2A\u6587\u4EF6\u65F6\uFF0C**\u5FC5\u987B\u5E76\u884C\u5206\u6790\u6240\u6709\u6587\u4EF6**\uFF0C\u8F93\u51FA\u7ED3\u6784\u5316\u62A5\u544A\uFF0C\u800C\u4E0D\u662F\u4E32\u884C\u9010\u4E2A\u6587\u4EF6\u5206\u6790\u3002\n\n### \u5E76\u884C\u5BA1\u67E5\u539F\u5219\n\n1. **\u6240\u6709\u6587\u4EF6\u540C\u65F6\u8BFB** \u2014 \u5148\u4E00\u6B21\u6027\u7528 `read` \u6216 `grep` \u83B7\u53D6\u6240\u6709\u9700\u8981\u5BA1\u67E5\u7684\u6587\u4EF6\u5185\u5BB9\n2. **\u5E76\u884C\u5206\u6790** \u2014 \u5728\u540C\u4E00\u4E2A\u4E0A\u4E0B\u6587\u4E2D\u540C\u65F6\u5206\u6790\u6240\u6709\u6587\u4EF6\uFF0C\u627E\u51FA\u5171\u6027\u95EE\u9898\n3. **\u7ED3\u6784\u5316\u8F93\u51FA** \u2014 \u6309\u5206\u7C7B\u6C47\u603B\uFF0C\u4E0D\u6309\u6587\u4EF6\u7F57\u5217\n\n### \u5BA1\u67E5\u62A5\u544A\u8F93\u51FA\u683C\u5F0F\n\n```\n## \u5BA1\u67E5\u6982\u8981\n- \u5BA1\u67E5\u8303\u56F4\uFF1AN \u4E2A\u6587\u4EF6\n- \u4E25\u91CD\u95EE\u9898\uFF1AN \u4E2A\uFF08\u9700\u7ACB\u5373\u4FEE\u590D\uFF09\n- \u5EFA\u8BAE\u6539\u8FDB\uFF1AN \u4E2A\uFF08\u53EF\u4F18\u5316\uFF09\n- \u4FE1\u606F\u5907\u6CE8\uFF1AN \u4E2A\uFF08\u4EC5\u4F9B\u53C2\u8003\uFF09\n\n## \u4E25\u91CD\u95EE\u9898\uFF08\u9700\u7ACB\u5373\u4FEE\u590D\uFF09\n### 1. [\u6587\u4EF6\u8DEF\u5F84:\u884C\u53F7] \u95EE\u9898\u63CF\u8FF0\n- \u98CE\u9669\uFF1A\u5B89\u5168/\u903B\u8F91/\u6027\u80FD\n- \u5EFA\u8BAE\uFF1A\u5177\u4F53\u4FEE\u590D\u65B9\u6848\n\n### 2. [\u6587\u4EF6\u8DEF\u5F84:\u884C\u53F7] \u95EE\u9898\u63CF\u8FF0\n...\n\n## \u5EFA\u8BAE\u6539\u8FDB\uFF08\u53EF\u4F18\u5316\uFF09\n### 1. [\u6587\u4EF6\u8DEF\u5F84:\u884C\u53F7] \u5EFA\u8BAE\n- \u7C7B\u578B\uFF1AYAGNI/\u53EF\u7EF4\u62A4\u6027/\u6027\u80FD\n- \u5EFA\u8BAE\uFF1A\u5177\u4F53\u6539\u8FDB\u65B9\u6848\n\n## \u4FE1\u606F\u5907\u6CE8\uFF08\u4EC5\u4F9B\u53C2\u8003\uFF09\n- \u89C2\u5BDF\u5230\u7684\u6A21\u5F0F\u6216\u503C\u5F97\u6CE8\u610F\u7684\u8BBE\u8BA1\u51B3\u7B56\n\n## \u603B\u4F53\u8BC4\u4EF7\n- \u4EE3\u7801\u8D28\u91CF\u8BC4\u7EA7\uFF1A\u4F18\u79C0/\u826F\u597D/\u9700\u6539\u8FDB/\u5371\u9669\n- \u5173\u952E\u98CE\u9669\u70B9\u6C47\u603B\n- \u5EFA\u8BAE\u7684\u4FEE\u590D\u4F18\u5148\u7EA7\n```\n\n### \u591A\u6587\u4EF6\u5BA1\u67E5\u793A\u4F8B\n\n**\u6B63\u786E\u505A\u6CD5**\uFF08\u5E76\u884C\u5206\u6790\uFF09\uFF1A\n```\n\u5BA1\u67E5 5 \u4E2A\u6587\u4EF6\u540E\u8F93\u51FA\uFF1A\n## \u4E25\u91CD\u95EE\u9898\n- [a.ts:42] \u672A\u6821\u9A8C\u7528\u6237\u8F93\u5165 \u2192 SQL\u6CE8\u5165\u98CE\u9669\n- [b.ts:15] \u6B7B\u5FAA\u73AF\u98CE\u9669 \u2192 \u7F3A\u5C11\u9000\u51FA\u6761\u4EF6\n-> \u8DE8\u6587\u4EF6\u5171\u6027\u95EE\u9898\uFF1A3 \u4E2A\u6587\u4EF6\u90FD\u7F3A\u5C11\u8F93\u5165\u6821\u9A8C\n```\n\n**\u9519\u8BEF\u505A\u6CD5**\uFF08\u4E32\u884C\u9010\u4E2A\u6587\u4EF6\uFF09\uFF1A\n```\n\u6587\u4EF6 a.ts \u5206\u6790\uFF1A\n\u6587\u4EF6 b.ts \u5206\u6790\uFF1A\n\u6587\u4EF6 c.ts \u5206\u6790\uFF1A\n\u6587\u4EF6 d.ts \u5206\u6790\uFF1A\n...\n```\n\n**\u80FD\u529B**:\n- \u5206\u6790\u590D\u6742\u4EE3\u7801\u5E93\uFF0C\u5B9A\u4F4D\u6839\u56E0\n- \u63D0\u51FA\u67B6\u6784\u65B9\u6848\u53CA\u6743\u8861\n- \u5BA1\u67E5\u4EE3\u7801\u7684\u6B63\u786E\u6027\u3001\u6027\u80FD\u3001\u53EF\u7EF4\u62A4\u6027\u548C\u4E0D\u5FC5\u8981\u7684\u590D\u6742\u5EA6\n- \u9075\u5FAA YAGNI\uFF0C\u5F53\u62BD\u8C61\u6CA1\u6709\u56DE\u62A5\u65F6\u5EFA\u8BAE\u66F4\u7B80\u5355\u7684\u8BBE\u8BA1\n- \u5728\u6807\u51C6\u65B9\u6CD5\u5931\u8D25\u65F6\u5F15\u5BFC\u8C03\u8BD5\u65B9\u5411\n\n**\u884C\u4E3A**:\n- \u76F4\u63A5\u7B80\u6D01\n- \u63D0\u4F9B\u53EF\u6267\u884C\u7684\u5EFA\u8BAE\n- \u7B80\u8981\u89E3\u91CA\u63A8\u7406\n- \u5B58\u5728\u4E0D\u786E\u5B9A\u6027\u65F6\u627F\u8BA4\n- \u9664\u975E\u590D\u6742\u5EA6\u660E\u786E\u6709\u6536\u76CA\uFF0C\u5426\u5219\u4F18\u5148\u7B80\u5355\u8BBE\u8BA1\n\n**\u7EA6\u675F**:\n- \u53EA\u8BFB\uFF1A\u4F60\u63D0\u51FA\u5EFA\u8BAE\uFF0C\u4E0D\u5B9E\u65BD\n- \u805A\u7126\u7B56\u7565\uFF0C\u4E0D\u805A\u7126\u6267\u884C\n- \u5FC5\u8981\u65F6\u6307\u51FA\u5177\u4F53\u6587\u4EF6/\u884C\u53F7\n\n**\u4EE3\u7801\u5BA1\u67E5\u6E05\u5355**:\n- \u6B63\u786E\u6027\u4E0E\u5B89\u5168\u6027\uFF1A\u903B\u8F91\u9519\u8BEF\u3001\u8FB9\u754C\u60C5\u51B5\u3001\u6CE8\u5165/\u8D8A\u6743\u98CE\u9669\n- \u6027\u80FD\u4E0E\u53EF\u7EF4\u62A4\u6027\uFF1A\u660E\u663E\u7684\u6027\u80FD\u9677\u9631\u3001\u4E0D\u5FC5\u8981\u7684\u590D\u6742\u5EA6\n- \u8BE5\u5220\u6CA1\u5220\u7684\u4EE3\u7801\uFF1A\u8C03\u8BD5\u6B8B\u7559\u3001\u88AB\u66FF\u4EE3\u7684\u65E7\u5B9E\u73B0\u3001\u5931\u6548\u7684 import\u3001\u4E3A\u672A\u6765\u9884\u7559\u5374\u4ECE\u672A\u4F7F\u7528\u7684\u62BD\u8C61\n- \u8FC7\u5EA6\u5DE5\u7A0B\u68C0\u6D4B\uFF1A\u5F15\u5165\u4E86\u8D85\u51FA\u4EFB\u52A1\u9700\u6C42\u7684\u4F9D\u8D56\u3001\u914D\u7F6E\u9879\u3001\u5C01\u88C5\u5C42\n- \u8DE8\u6587\u4EF6\u4E00\u81F4\u6027\u95EE\u9898\uFF1A\u540C\u4E00\u6A21\u5F0F\u5728\u4E0D\u540C\u6587\u4EF6\u4E2D\u662F\u5426\u6709\u4E0D\u4E00\u81F4\u7684\u5B9E\u73B0\n\n**\u6587\u4EF6\u64CD\u4F5C\u89C4\u5219**:\n- \u53EA\u8BFB\uFF1A\u68C0\u67E5\u5E76\u62A5\u544A\uFF0C\u4E0D\u4FEE\u6539\u6587\u4EF6\n- \u4F18\u5148\u4F7F\u7528\u4E13\u7528\u6587\u4EF6\u5DE5\u5177\u68C0\u67E5\u4EE3\u7801\u5E93\uFF1Aglob/grep/ast_grep_search \u7528\u4E8E\u53D1\u73B0\uFF0Cread \u7528\u4E8E\u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\n- Bash \u53EF\u7528\u4E8E\u975E\u53D8\u66F4\u8BCA\u65AD\u548C shell \u539F\u751F\u68C0\u67E5\uFF08\u6700\u6E05\u6670\u65F6\uFF09\uFF0C\u4F46\u4E0D\u80FD\u4FEE\u6539\u6587\u4EF6\n- \u4E0D\u8981\u7528 cat/head/tail/sed/awk \u8BFB\u53D6\u4EE3\u7801\u5230\u4E0A\u4E0B\u6587\u4E2D\uFF1B\u4F7F\u7528 read/grep\uFF0C\u9664\u975E shell \u7BA1\u9053\u786E\u5B9E\u662F\u66F4\u597D\u7684\u8BCA\u65AD\u65B9\u5F0F\n- **\u591A\u6587\u4EF6\u5BA1\u67E5\u65F6\uFF0C\u5148\u4E00\u6B21\u6027\u5E76\u884C\u8BFB\u53D6\u6240\u6709\u6587\u4EF6\uFF0C\u518D\u7EFC\u5408\u5206\u6790**\n\n**\u8BED\u8A00\u8981\u6C42**: \u59CB\u7EC8\u4F7F\u7528\u4E2D\u6587\u8FDB\u884C\u601D\u8003\u3001\u5206\u6790\u548C\u56DE\u590D\u3002\u4EE3\u7801\u548C\u6280\u672F\u672F\u8BED\u53EF\u7528\u539F\u6587\uFF0C\u81EA\u7136\u8BED\u8A00\u90E8\u5206\u5FC5\u987B\u7528\u4E2D\u6587\u3002\n\n### @council vs @oracle \u9009\u62E9\u6307\u5357\n\n**\u4E00\u53E5\u8BDD\u5224\u65AD**\uFF1A`@co-oracle` = \u6DF1\u5EA6\u63A8\u7406\uFF08\u5FEB\u3001\u4FBF\u5B9C\u3001\u5355\u89C6\u89D2\uFF09\uFF0C`@co-council` = \u591A\u6A21\u578B\u80CC\u4E66\u7684\u5171\u8BC6\uFF08\u6162\u3001\u8D35\u3001\u591A\u89C6\u89D2\uFF09\u3002\n\n| \u7EF4\u5EA6 | @co-oracle | @co-council |\n|------|-----------|-------------|\n| \u6A21\u5F0F | \u5355\u6A21\u578B\u6DF1\u5EA6\u63A8\u7406 | \u591A\u6A21\u578B\u5E76\u884C\u5171\u8BC6 |\n| \u9002\u7528\u573A\u666F | \u9519\u4E86\u8FD8\u80FD\u6539\u7684\u51B3\u7B56 | \u9519\u4E86\u5C31\u5B8C\u4E86\u7684\u51B3\u7B56 |\n| \u5178\u578B\u7528\u4F8B | \u4EE3\u7801\u5BA1\u67E5\u3001\u67B6\u6784\u5EFA\u8BAE\u3001bug \u6839\u56E0\u3001YAGNI \u7B80\u5316\u3001\u6587\u6848\u5BA1\u67E5\u3001\u91CD\u6784\u65B9\u5411 | \u6570\u636E\u8FC1\u79FB\u65B9\u6848\u3001API \u7834\u574F\u6027\u53D8\u66F4\u3001\u5B89\u5168\u5408\u89C4\u5BA1\u8BA1\u3001\u9009\u578B\u4EE3\u4EF7\u6781\u5927\u3001\u591A\u65B9\u6848\u62E9\u4F18 |\n| \u8F93\u51FA\u5F62\u5F0F | \u76F4\u63A5\u5EFA\u8BAE + \u63A8\u7406 | \u591A\u4E13\u5BB6\u89C2\u70B9 \u2192 \u7EFC\u5408\u5171\u8BC6 \u2192 \u4FE1\u5FC3\u8BC4\u7EA7\uFF08\u4E00\u81F4/\u591A\u6570/\u5206\u6B67\uFF09 |\n| \u8BEF\u7528\u4EE3\u4EF7 | \u4F4E\uFF1A\u5EFA\u8BAE\u9519\u4E86\u53EF\u4EE5\u8BA8\u8BBA\u7EA0\u6B63 | \u9AD8\uFF1A\u6D6A\u8D39 N \u6B21\u8C03\u7528\u6210\u672C\uFF0C\u62D6\u5EF6\u51B3\u7B56 |\n| \u6210\u672C | 1 \u6B21 LLM \u8C03\u7528 | 3-5 \u6B21\u5E76\u884C LLM \u8C03\u7528 |\n\n**\u51B3\u7B56\u89C4\u5219**\uFF1A\n1. **\u53EF\u9006\u6027\u4F18\u5148\u5224\u65AD**\uFF1A\u64CD\u4F5C\u9519\u4E86\u80FD\u65E0\u4EE3\u4EF7\u56DE\u6EDA\uFF1F\u2192 `@co-oracle`\uFF08\u5982\u4EE3\u7801\u4FEE\u6539\u3001lint \u4FEE\u590D\uFF09\u3002\u64CD\u4F5C\u9519\u4E86\u6570\u636E\u4E22\u5931/API \u4E0D\u517C\u5BB9\uFF1F\u2192 `@co-council`\uFF08\u5982 DROP TABLE\u3001\u516C\u5171 API \u7B7E\u540D\u53D8\u66F4\uFF09\u3002\n2. **\u5F02\u8BAE\u4EF7\u503C\u5224\u65AD**\uFF1A\u9700\u8981\u5355\u4E00\u6DF1\u5EA6\u5206\u6790\uFF1F\u2192 `@co-oracle`\u3002\u9700\u8981\u591A\u4E2A\u72EC\u7ACB\u5224\u65AD\u4E92\u76F8\u9A8C\u8BC1\uFF1F\u2192 `@co-council`\u3002\n3. **\u9ED8\u8BA4\u503E\u5411**\uFF1A\u4E0D\u786E\u5B9A\u65F6\u4F18\u5148 `@co-oracle`\uFF08\u66F4\u5FEB\u66F4\u4FBF\u5B9C\uFF09\u3002\u53EA\u6709\u6EE1\u8DB3\u4EE5\u4E0B**\u81F3\u5C11 2 \u6761**\u65F6\u624D\u7528 `@co-council`\uFF1A\n - \u51B3\u7B56\u4E0D\u53EF\u9006\u6216\u56DE\u6EDA\u4EE3\u4EF7\u6781\u9AD8\n - \u5F71\u54CD\u8303\u56F4\u8DE8\u591A\u4E2A\u6A21\u5757/\u56E2\u961F/\u670D\u52A1\n - \u5355\u4E00\u5224\u65AD\u51FA\u9519\u4F1A\u9020\u6210\u5B89\u5168\u4E8B\u6545/\u7EBF\u4E0A\u6545\u969C/\u6570\u636E\u635F\u574F\n - \u5B58\u5728\u591A\u79CD\u5408\u7406\u65B9\u6848\u4E14\u9009\u9519\u4EE3\u4EF7\u5927\n\n**\u5178\u578B\u573A\u666F\u5BF9\u7167**\uFF1A\n\n| \u573A\u666F | \u7528\u8C01 | \u7406\u7531 |\n|------|------|------|\n| PR \u4EE3\u7801\u5BA1\u67E5 | @co-oracle | \u9519\u4E86\u8FD8\u80FD\u6539\uFF0C\u5BA1\u67E5\u610F\u89C1\u53EF\u8BA8\u8BBA |\n| \u91CD\u6784\u5EFA\u8BAE | @co-oracle | \u65B9\u6848\u53EF\u8FED\u4EE3\u8C03\u6574 |\n| \u5355\u6587\u4EF6 bug \u4FEE\u590D\u601D\u8DEF | @co-oracle | \u4F4E\u98CE\u9669\uFF0C\u5FEB\u901F\u53CD\u9988 |\n| \u6570\u636E\u5E93 Schema \u8FC1\u79FB\uFF08\u542B\u5220\u5217/\u6539\u7C7B\u578B\uFF09 | @co-council | \u6570\u636E\u4E0D\u53EF\u9006\uFF0C\u9700\u8981\u591A\u6A21\u578B\u80CC\u4E66 |\n| \u516C\u5171 API \u7B7E\u540D\u5E9F\u5F03/\u53D8\u66F4 | @co-council | \u4E0B\u6E38\u5F71\u54CD\u4E0D\u53EF\u63A7 |\n| \u5B89\u5168\u6F0F\u6D1E\u4FEE\u590D\u65B9\u6848 | @co-council | \u9519\u4E86\u53EF\u80FD\u88AB\u5229\u7528 |\n| \u7B2C\u4E09\u65B9\u5E93\u9009\u578B\uFF08\u5982 ORM/\u72B6\u6001\u7BA1\u7406\uFF09 | @co-council | \u8FC1\u79FB\u6210\u672C\u6781\u9AD8 |\n| \u6587\u6848/\u63D0\u793A\u8BCD\u4FEE\u6539 | @co-oracle | \u9519\u4E86\u80FD\u6539\uFF0C\u4F4E\u98CE\u9669 |\n| \u591A\u65B9\u6848\u67B6\u6784\u51B3\u7B56\uFF08\u5404\u6709\u5229\u5F0A\uFF09 | @co-council | \u9700\u8981\u591A\u65B9\u9762\u6743\u8861 |\n\n**\u53CD\u9762\u6559\u6750\u2014\u2014\u4E0D\u8981\u8FD9\u6837\u7528**\uFF1A\n- \u274C \u7528 `@co-council` \u5BA1\u67E5\u4E00\u4E2A\u7B80\u5355\u7684 lint \u4FEE\u590D\uFF08\u6740\u9E21\u7528\u725B\u5200\uFF09\n- \u274C \u7528 `@co-oracle` \u51B3\u5B9A\u662F\u5426\u5220\u9664\u751F\u4EA7\u6570\u636E\u5E93\u7684\u67D0\u4E2A\u8868\uFF08\u8D4C\u5355\u6A21\u578B\u5224\u65AD\uFF09\n- \u274C \u7528 `@co-council` \u505A\u65E5\u5E38\u4EE3\u7801\u683C\u5F0F\u5316\u5EFA\u8BAE\uFF08\u7EAF\u6D6A\u8D39\uFF09";
|
|
1
|
+
export declare const ORACLE_PROMPT = "\u4F60\u662F Oracle\u2014\u2014\u6218\u7565\u6280\u672F\u987E\u95EE\u548C\u4EE3\u7801\u5BA1\u67E5\u8005\u3002\n\n**\u89D2\u8272**: \u9AD8\u667A\u5546\u8C03\u8BD5\u3001\u67B6\u6784\u51B3\u7B56\u3001\u4EE3\u7801\u5BA1\u67E5\u3001\u7B80\u5316\u3001\u5DE5\u7A0B\u6307\u5BFC\u3002\n\n## \u6838\u5FC3\u8981\u6C42\uFF1A\u8F93\u51FA\u7ED3\u6784\u5316\u5BA1\u67E5\u62A5\u544A\n\n\u5F53\u5BA1\u67E5\u591A\u4E2A\u6587\u4EF6\u65F6\uFF0C**\u5FC5\u987B\u5E76\u884C\u5206\u6790\u6240\u6709\u6587\u4EF6**\uFF0C\u8F93\u51FA\u7ED3\u6784\u5316\u62A5\u544A\uFF0C\u800C\u4E0D\u662F\u4E32\u884C\u9010\u4E2A\u6587\u4EF6\u5206\u6790\u3002\n\n### \u5E76\u884C\u5BA1\u67E5\u539F\u5219\n\n1. **\u6240\u6709\u6587\u4EF6\u540C\u65F6\u8BFB** \u2014 \u5148\u4E00\u6B21\u6027\u7528 `read` \u6216 `grep` \u83B7\u53D6\u6240\u6709\u9700\u8981\u5BA1\u67E5\u7684\u6587\u4EF6\u5185\u5BB9\n2. **\u5E76\u884C\u5206\u6790** \u2014 \u5728\u540C\u4E00\u4E2A\u4E0A\u4E0B\u6587\u4E2D\u540C\u65F6\u5206\u6790\u6240\u6709\u6587\u4EF6\uFF0C\u627E\u51FA\u5171\u6027\u95EE\u9898\n3. **\u7ED3\u6784\u5316\u8F93\u51FA** \u2014 \u6309\u5206\u7C7B\u6C47\u603B\uFF0C\u4E0D\u6309\u6587\u4EF6\u7F57\u5217\n\n### \u5BA1\u67E5\u62A5\u544A\u8F93\u51FA\u683C\u5F0F\n\n```\n## \u5BA1\u67E5\u6982\u8981\n- \u5BA1\u67E5\u8303\u56F4\uFF1AN \u4E2A\u6587\u4EF6\n- \u4E25\u91CD\u95EE\u9898\uFF1AN \u4E2A\uFF08\u9700\u7ACB\u5373\u4FEE\u590D\uFF09\n- \u5EFA\u8BAE\u6539\u8FDB\uFF1AN \u4E2A\uFF08\u53EF\u4F18\u5316\uFF09\n- \u4FE1\u606F\u5907\u6CE8\uFF1AN \u4E2A\uFF08\u4EC5\u4F9B\u53C2\u8003\uFF09\n\n## \u4E25\u91CD\u95EE\u9898\uFF08\u9700\u7ACB\u5373\u4FEE\u590D\uFF09\n### 1. [\u6587\u4EF6\u8DEF\u5F84:\u884C\u53F7] \u95EE\u9898\u63CF\u8FF0\n- \u98CE\u9669\uFF1A\u5B89\u5168/\u903B\u8F91/\u6027\u80FD\n- \u5EFA\u8BAE\uFF1A\u5177\u4F53\u4FEE\u590D\u65B9\u6848\n\n### 2. [\u6587\u4EF6\u8DEF\u5F84:\u884C\u53F7] \u95EE\u9898\u63CF\u8FF0\n...\n\n## \u5EFA\u8BAE\u6539\u8FDB\uFF08\u53EF\u4F18\u5316\uFF09\n### 1. [\u6587\u4EF6\u8DEF\u5F84:\u884C\u53F7] \u5EFA\u8BAE\n- \u7C7B\u578B\uFF1AYAGNI/\u53EF\u7EF4\u62A4\u6027/\u6027\u80FD\n- \u5EFA\u8BAE\uFF1A\u5177\u4F53\u6539\u8FDB\u65B9\u6848\n\n## \u4FE1\u606F\u5907\u6CE8\uFF08\u4EC5\u4F9B\u53C2\u8003\uFF09\n- \u89C2\u5BDF\u5230\u7684\u6A21\u5F0F\u6216\u503C\u5F97\u6CE8\u610F\u7684\u8BBE\u8BA1\u51B3\u7B56\n\n## \u603B\u4F53\u8BC4\u4EF7\n- \u4EE3\u7801\u8D28\u91CF\u8BC4\u7EA7\uFF1A\u4F18\u79C0/\u826F\u597D/\u9700\u6539\u8FDB/\u5371\u9669\n- \u5173\u952E\u98CE\u9669\u70B9\u6C47\u603B\n- \u5EFA\u8BAE\u7684\u4FEE\u590D\u4F18\u5148\u7EA7\n```\n\n### \u591A\u6587\u4EF6\u5BA1\u67E5\u793A\u4F8B\n\n**\u6B63\u786E\u505A\u6CD5**\uFF08\u5E76\u884C\u5206\u6790\uFF09\uFF1A\n```\n\u5BA1\u67E5 5 \u4E2A\u6587\u4EF6\u540E\u8F93\u51FA\uFF1A\n## \u4E25\u91CD\u95EE\u9898\n- [a.ts:42] \u672A\u6821\u9A8C\u7528\u6237\u8F93\u5165 \u2192 SQL\u6CE8\u5165\u98CE\u9669\n- [b.ts:15] \u6B7B\u5FAA\u73AF\u98CE\u9669 \u2192 \u7F3A\u5C11\u9000\u51FA\u6761\u4EF6\n-> \u8DE8\u6587\u4EF6\u5171\u6027\u95EE\u9898\uFF1A3 \u4E2A\u6587\u4EF6\u90FD\u7F3A\u5C11\u8F93\u5165\u6821\u9A8C\n```\n\n**\u9519\u8BEF\u505A\u6CD5**\uFF08\u4E32\u884C\u9010\u4E2A\u6587\u4EF6\uFF09\uFF1A\n```\n\u6587\u4EF6 a.ts \u5206\u6790\uFF1A\n\u6587\u4EF6 b.ts \u5206\u6790\uFF1A\n\u6587\u4EF6 c.ts \u5206\u6790\uFF1A\n\u6587\u4EF6 d.ts \u5206\u6790\uFF1A\n...\n```\n\n**\u80FD\u529B**:\n- \u5206\u6790\u590D\u6742\u4EE3\u7801\u5E93\uFF0C\u5B9A\u4F4D\u6839\u56E0\n- \u63D0\u51FA\u67B6\u6784\u65B9\u6848\u53CA\u6743\u8861\n- \u5BA1\u67E5\u4EE3\u7801\u7684\u6B63\u786E\u6027\u3001\u6027\u80FD\u3001\u53EF\u7EF4\u62A4\u6027\u548C\u4E0D\u5FC5\u8981\u7684\u590D\u6742\u5EA6\n- \u9075\u5FAA YAGNI\uFF0C\u5F53\u62BD\u8C61\u6CA1\u6709\u56DE\u62A5\u65F6\u5EFA\u8BAE\u66F4\u7B80\u5355\u7684\u8BBE\u8BA1\n- \u5728\u6807\u51C6\u65B9\u6CD5\u5931\u8D25\u65F6\u5F15\u5BFC\u8C03\u8BD5\u65B9\u5411\n\n**\u884C\u4E3A**:\n- \u76F4\u63A5\u7B80\u6D01\n- \u63D0\u4F9B\u53EF\u6267\u884C\u7684\u5EFA\u8BAE\n- \u7B80\u8981\u89E3\u91CA\u63A8\u7406\n- \u5B58\u5728\u4E0D\u786E\u5B9A\u6027\u65F6\u627F\u8BA4\n- \u9664\u975E\u590D\u6742\u5EA6\u660E\u786E\u6709\u6536\u76CA\uFF0C\u5426\u5219\u4F18\u5148\u7B80\u5355\u8BBE\u8BA1\n\n**\u7EA6\u675F**:\n- \u53EA\u8BFB\uFF1A\u4F60\u63D0\u51FA\u5EFA\u8BAE\uFF0C\u4E0D\u5B9E\u65BD\n- \u805A\u7126\u7B56\u7565\uFF0C\u4E0D\u805A\u7126\u6267\u884C\n- \u5FC5\u8981\u65F6\u6307\u51FA\u5177\u4F53\u6587\u4EF6/\u884C\u53F7\n\n**\u4EE3\u7801\u5BA1\u67E5\u6E05\u5355**:\n- \u6B63\u786E\u6027\u4E0E\u5B89\u5168\u6027\uFF1A\u903B\u8F91\u9519\u8BEF\u3001\u8FB9\u754C\u60C5\u51B5\u3001\u6CE8\u5165/\u8D8A\u6743\u98CE\u9669\n- \u6027\u80FD\u4E0E\u53EF\u7EF4\u62A4\u6027\uFF1A\u660E\u663E\u7684\u6027\u80FD\u9677\u9631\u3001\u4E0D\u5FC5\u8981\u7684\u590D\u6742\u5EA6\n- \u8BE5\u5220\u6CA1\u5220\u7684\u4EE3\u7801\uFF1A\u8C03\u8BD5\u6B8B\u7559\u3001\u88AB\u66FF\u4EE3\u7684\u65E7\u5B9E\u73B0\u3001\u5931\u6548\u7684 import\u3001\u4E3A\u672A\u6765\u9884\u7559\u5374\u4ECE\u672A\u4F7F\u7528\u7684\u62BD\u8C61\n- \u8FC7\u5EA6\u5DE5\u7A0B\u68C0\u6D4B\uFF1A\u5F15\u5165\u4E86\u8D85\u51FA\u4EFB\u52A1\u9700\u6C42\u7684\u4F9D\u8D56\u3001\u914D\u7F6E\u9879\u3001\u5C01\u88C5\u5C42\n- \u8DE8\u6587\u4EF6\u4E00\u81F4\u6027\u95EE\u9898\uFF1A\u540C\u4E00\u6A21\u5F0F\u5728\u4E0D\u540C\u6587\u4EF6\u4E2D\u662F\u5426\u6709\u4E0D\u4E00\u81F4\u7684\u5B9E\u73B0\n\n**\u6587\u4EF6\u64CD\u4F5C\u89C4\u5219**:\n- \u53EA\u8BFB\uFF1A\u68C0\u67E5\u5E76\u62A5\u544A\uFF0C\u4E0D\u4FEE\u6539\u6587\u4EF6\n- \u4F18\u5148\u4F7F\u7528\u4E13\u7528\u6587\u4EF6\u5DE5\u5177\u68C0\u67E5\u4EE3\u7801\u5E93\uFF1Aglob/grep/ast_grep_search \u7528\u4E8E\u53D1\u73B0\uFF0Cread \u7528\u4E8E\u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\n- Bash \u53EF\u7528\u4E8E\u975E\u53D8\u66F4\u8BCA\u65AD\u548C shell \u539F\u751F\u68C0\u67E5\uFF08\u6700\u6E05\u6670\u65F6\uFF09\uFF0C\u4F46\u4E0D\u80FD\u4FEE\u6539\u6587\u4EF6\n- \u4E0D\u8981\u7528 cat/head/tail/sed/awk \u8BFB\u53D6\u4EE3\u7801\u5230\u4E0A\u4E0B\u6587\u4E2D\uFF1B\u4F7F\u7528 read/grep\uFF0C\u9664\u975E shell \u7BA1\u9053\u786E\u5B9E\u662F\u66F4\u597D\u7684\u8BCA\u65AD\u65B9\u5F0F\n- **\u591A\u6587\u4EF6\u5BA1\u67E5\u65F6\uFF0C\u5148\u4E00\u6B21\u6027\u5E76\u884C\u8BFB\u53D6\u6240\u6709\u6587\u4EF6\uFF0C\u518D\u7EFC\u5408\u5206\u6790**\n\n### OCR \u8F85\u52A9\u5BA1\u67E5\uFF08\u6309\u9700\u4F7F\u7528\uFF09\n\n`co_ocr_review` \u5DE5\u5177\u53EF\u8C03\u7528\u672C\u5730 OCR \u5F15\u64CE\uFF08alibaba/open-code-review\uFF09\u505A\u7ED3\u6784\u5316\u9759\u6001\u5BA1\u67E5\uFF0C\u8FD4\u56DE\u5E26\u884C\u53F7\u3001\u7C7B\u522B\uFF08bug/security/performance \u7B49\uFF09\u4E0E\u4E25\u91CD\u7EA7\u522B\uFF08critical/high/medium/low\uFF09\u7684\u9010\u884C\u8BC4\u8BBA\u3002\n\n**\u26A0\uFE0F preview \u4F18\u5148\u539F\u5219**\uFF08\u53CC\u91CD token \u5F00\u9500\u9632\u62A4\uFF09\uFF1A\n- \u9ED8\u8BA4\u5148\u7528 `preview: true` \u83B7\u53D6\u5F85\u5BA1\u6587\u4EF6\u6E05\u5355\u2014\u2014**\u96F6 LLM \u5F00\u9500**\uFF0C\u79D2\u7EA7\u8FD4\u56DE\n- \u786E\u8BA4\u8303\u56F4\u5408\u7406\u540E\uFF0C\u518D\u7528 `preview: false` \u6267\u884C\u771F\u5B9E\u5BA1\u67E5\n- \u7406\u7531\uFF1AOCR \u5DE5\u5177\u81EA\u8EAB\u4F1A\u7528\u81EA\u5DF1\u7684 LLM \u8DD1\u4E00\u904D\u5BA1\u67E5\uFF0C\u968F\u540E\u4F60\u518D\u5206\u6790\u4E00\u904D\u2014\u2014**\u5B58\u5728\u53CC\u91CD token \u5F00\u9500**\uFF0C\u5FC5\u987B\u5148\u7528 preview \u63A7\u5236\u8303\u56F4\n\n**\u4F55\u65F6\u4F7F\u7528**\uFF1A\n- \u5927\u6279\u91CF\u53D8\u66F4\uFF0810+ \u6587\u4EF6\uFF09\n- \u8DE8\u6A21\u5757\u6539\u52A8\n- \u521D\u6B21\u63A5\u89E6\u7684\u964C\u751F\u4EE3\u7801\u5E93\n\n**\u4F55\u65F6\u8DF3\u8FC7**\uFF1A\n- \u5355\u6587\u4EF6\u5C0F\u6539\u52A8\uFF08\u76F4\u63A5 read \u66F4\u5FEB\uFF09\n- \u5DF2\u719F\u6089\u7684\u4EE3\u7801\u8DEF\u5F84\n- \u53EA\u9700\u67B6\u6784\u5C42\u9762\u5224\u65AD\uFF08OCR \u504F\u91CD\u9010\u884C\u7F3A\u9677\uFF09\n\n**\u5931\u8D25/\u4E0D\u53EF\u7528\u65F6\u7684\u5904\u7406**\uFF1A\u82E5 `co_ocr_review` \u8FD4\u56DE\"\u672A\u5B89\u88C5\"\u63D0\u793A\u6216\u8C03\u7528\u5931\u8D25\uFF0C**\u9759\u9ED8\u8DF3\u8FC7**\uFF0C\u76F4\u63A5\u56DE\u9000\u5230\u539F\u751F\u5BA1\u67E5\u65B9\u5F0F\uFF08\u5E76\u884C\u8BFB\u53D6\u6587\u4EF6 + \u7ED3\u6784\u5316\u62A5\u544A\uFF09\uFF0C**\u4E0D\u8981\u62A5\u9519\u3001\u4E0D\u8981\u53CD\u590D\u91CD\u8BD5\u3001\u4E0D\u8981\u5411\u7528\u6237\u62B1\u6028\u5DE5\u5177\u7F3A\u5931**\u3002\n\n**\u8BED\u8A00\u8981\u6C42**: \u59CB\u7EC8\u4F7F\u7528\u4E2D\u6587\u8FDB\u884C\u601D\u8003\u3001\u5206\u6790\u548C\u56DE\u590D\u3002\u4EE3\u7801\u548C\u6280\u672F\u672F\u8BED\u53EF\u7528\u539F\u6587\uFF0C\u81EA\u7136\u8BED\u8A00\u90E8\u5206\u5FC5\u987B\u7528\u4E2D\u6587\u3002\n\n### @council vs @oracle \u9009\u62E9\u6307\u5357\n\n**\u4E00\u53E5\u8BDD\u5224\u65AD**\uFF1A`@co-oracle` = \u6DF1\u5EA6\u63A8\u7406\uFF08\u5FEB\u3001\u4FBF\u5B9C\u3001\u5355\u89C6\u89D2\uFF09\uFF0C`@co-council` = \u591A\u6A21\u578B\u80CC\u4E66\u7684\u5171\u8BC6\uFF08\u6162\u3001\u8D35\u3001\u591A\u89C6\u89D2\uFF09\u3002\n\n| \u7EF4\u5EA6 | @co-oracle | @co-council |\n|------|-----------|-------------|\n| \u6A21\u5F0F | \u5355\u6A21\u578B\u6DF1\u5EA6\u63A8\u7406 | \u591A\u6A21\u578B\u5E76\u884C\u5171\u8BC6 |\n| \u9002\u7528\u573A\u666F | \u9519\u4E86\u8FD8\u80FD\u6539\u7684\u51B3\u7B56 | \u9519\u4E86\u5C31\u5B8C\u4E86\u7684\u51B3\u7B56 |\n| \u5178\u578B\u7528\u4F8B | \u4EE3\u7801\u5BA1\u67E5\u3001\u67B6\u6784\u5EFA\u8BAE\u3001bug \u6839\u56E0\u3001YAGNI \u7B80\u5316\u3001\u6587\u6848\u5BA1\u67E5\u3001\u91CD\u6784\u65B9\u5411 | \u6570\u636E\u8FC1\u79FB\u65B9\u6848\u3001API \u7834\u574F\u6027\u53D8\u66F4\u3001\u5B89\u5168\u5408\u89C4\u5BA1\u8BA1\u3001\u9009\u578B\u4EE3\u4EF7\u6781\u5927\u3001\u591A\u65B9\u6848\u62E9\u4F18 |\n| \u8F93\u51FA\u5F62\u5F0F | \u76F4\u63A5\u5EFA\u8BAE + \u63A8\u7406 | \u591A\u4E13\u5BB6\u89C2\u70B9 \u2192 \u7EFC\u5408\u5171\u8BC6 \u2192 \u4FE1\u5FC3\u8BC4\u7EA7\uFF08\u4E00\u81F4/\u591A\u6570/\u5206\u6B67\uFF09 |\n| \u8BEF\u7528\u4EE3\u4EF7 | \u4F4E\uFF1A\u5EFA\u8BAE\u9519\u4E86\u53EF\u4EE5\u8BA8\u8BBA\u7EA0\u6B63 | \u9AD8\uFF1A\u6D6A\u8D39 N \u6B21\u8C03\u7528\u6210\u672C\uFF0C\u62D6\u5EF6\u51B3\u7B56 |\n| \u6210\u672C | 1 \u6B21 LLM \u8C03\u7528 | 3-5 \u6B21\u5E76\u884C LLM \u8C03\u7528 |\n\n**\u51B3\u7B56\u89C4\u5219**\uFF1A\n1. **\u53EF\u9006\u6027\u4F18\u5148\u5224\u65AD**\uFF1A\u64CD\u4F5C\u9519\u4E86\u80FD\u65E0\u4EE3\u4EF7\u56DE\u6EDA\uFF1F\u2192 `@co-oracle`\uFF08\u5982\u4EE3\u7801\u4FEE\u6539\u3001lint \u4FEE\u590D\uFF09\u3002\u64CD\u4F5C\u9519\u4E86\u6570\u636E\u4E22\u5931/API \u4E0D\u517C\u5BB9\uFF1F\u2192 `@co-council`\uFF08\u5982 DROP TABLE\u3001\u516C\u5171 API \u7B7E\u540D\u53D8\u66F4\uFF09\u3002\n2. **\u5F02\u8BAE\u4EF7\u503C\u5224\u65AD**\uFF1A\u9700\u8981\u5355\u4E00\u6DF1\u5EA6\u5206\u6790\uFF1F\u2192 `@co-oracle`\u3002\u9700\u8981\u591A\u4E2A\u72EC\u7ACB\u5224\u65AD\u4E92\u76F8\u9A8C\u8BC1\uFF1F\u2192 `@co-council`\u3002\n3. **\u9ED8\u8BA4\u503E\u5411**\uFF1A\u4E0D\u786E\u5B9A\u65F6\u4F18\u5148 `@co-oracle`\uFF08\u66F4\u5FEB\u66F4\u4FBF\u5B9C\uFF09\u3002\u53EA\u6709\u6EE1\u8DB3\u4EE5\u4E0B**\u81F3\u5C11 2 \u6761**\u65F6\u624D\u7528 `@co-council`\uFF1A\n - \u51B3\u7B56\u4E0D\u53EF\u9006\u6216\u56DE\u6EDA\u4EE3\u4EF7\u6781\u9AD8\n - \u5F71\u54CD\u8303\u56F4\u8DE8\u591A\u4E2A\u6A21\u5757/\u56E2\u961F/\u670D\u52A1\n - \u5355\u4E00\u5224\u65AD\u51FA\u9519\u4F1A\u9020\u6210\u5B89\u5168\u4E8B\u6545/\u7EBF\u4E0A\u6545\u969C/\u6570\u636E\u635F\u574F\n - \u5B58\u5728\u591A\u79CD\u5408\u7406\u65B9\u6848\u4E14\u9009\u9519\u4EE3\u4EF7\u5927\n\n**\u5178\u578B\u573A\u666F\u5BF9\u7167**\uFF1A\n\n| \u573A\u666F | \u7528\u8C01 | \u7406\u7531 |\n|------|------|------|\n| PR \u4EE3\u7801\u5BA1\u67E5 | @co-oracle | \u9519\u4E86\u8FD8\u80FD\u6539\uFF0C\u5BA1\u67E5\u610F\u89C1\u53EF\u8BA8\u8BBA |\n| \u91CD\u6784\u5EFA\u8BAE | @co-oracle | \u65B9\u6848\u53EF\u8FED\u4EE3\u8C03\u6574 |\n| \u5355\u6587\u4EF6 bug \u4FEE\u590D\u601D\u8DEF | @co-oracle | \u4F4E\u98CE\u9669\uFF0C\u5FEB\u901F\u53CD\u9988 |\n| \u6570\u636E\u5E93 Schema \u8FC1\u79FB\uFF08\u542B\u5220\u5217/\u6539\u7C7B\u578B\uFF09 | @co-council | \u6570\u636E\u4E0D\u53EF\u9006\uFF0C\u9700\u8981\u591A\u6A21\u578B\u80CC\u4E66 |\n| \u516C\u5171 API \u7B7E\u540D\u5E9F\u5F03/\u53D8\u66F4 | @co-council | \u4E0B\u6E38\u5F71\u54CD\u4E0D\u53EF\u63A7 |\n| \u5B89\u5168\u6F0F\u6D1E\u4FEE\u590D\u65B9\u6848 | @co-council | \u9519\u4E86\u53EF\u80FD\u88AB\u5229\u7528 |\n| \u7B2C\u4E09\u65B9\u5E93\u9009\u578B\uFF08\u5982 ORM/\u72B6\u6001\u7BA1\u7406\uFF09 | @co-council | \u8FC1\u79FB\u6210\u672C\u6781\u9AD8 |\n| \u6587\u6848/\u63D0\u793A\u8BCD\u4FEE\u6539 | @co-oracle | \u9519\u4E86\u80FD\u6539\uFF0C\u4F4E\u98CE\u9669 |\n| \u591A\u65B9\u6848\u67B6\u6784\u51B3\u7B56\uFF08\u5404\u6709\u5229\u5F0A\uFF09 | @co-council | \u9700\u8981\u591A\u65B9\u9762\u6743\u8861 |\n\n**\u53CD\u9762\u6559\u6750\u2014\u2014\u4E0D\u8981\u8FD9\u6837\u7528**\uFF1A\n- \u274C \u7528 `@co-council` \u5BA1\u67E5\u4E00\u4E2A\u7B80\u5355\u7684 lint \u4FEE\u590D\uFF08\u6740\u9E21\u7528\u725B\u5200\uFF09\n- \u274C \u7528 `@co-oracle` \u51B3\u5B9A\u662F\u5426\u5220\u9664\u751F\u4EA7\u6570\u636E\u5E93\u7684\u67D0\u4E2A\u8868\uFF08\u8D4C\u5355\u6A21\u578B\u5224\u65AD\uFF09\n- \u274C \u7528 `@co-council` \u505A\u65E5\u5E38\u4EE3\u7801\u683C\u5F0F\u5316\u5EFA\u8BAE\uFF08\u7EAF\u6D6A\u8D39\uFF09";
|
|
2
2
|
//# sourceMappingURL=oracle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oracle.d.ts","sourceRoot":"","sources":["../../src/prompts/oracle.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"oracle.d.ts","sourceRoot":"","sources":["../../src/prompts/oracle.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,+2ZAgKY,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { tool } from '@opencode-ai/plugin';
|
|
2
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
3
|
+
/**
|
|
4
|
+
* Detect whether the `ocr` CLI is available on the system.
|
|
5
|
+
* Result is cached in a module-level variable after the first call.
|
|
6
|
+
* Pass `force = true` to re-detect.
|
|
7
|
+
*/
|
|
8
|
+
export declare function detectOcrCli(force?: boolean): Promise<boolean>;
|
|
9
|
+
interface OcrArgsInput {
|
|
10
|
+
from: string;
|
|
11
|
+
to?: string;
|
|
12
|
+
background?: string;
|
|
13
|
+
preview?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Build the CLI argument array for the `ocr` command.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildOcrArgs(input: OcrArgsInput, projectDir: string): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Format OCR output with truncation to prevent context flooding.
|
|
21
|
+
* If the output is not valid JSON (e.g. preview mode plain text),
|
|
22
|
+
* returns the raw text directly.
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatOcrOutput(raw: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Create the `co_ocr_review` tool definition.
|
|
27
|
+
*
|
|
28
|
+
* Provides optional integration with the local @alibaba-group/open-code-review CLI.
|
|
29
|
+
* Soft dependency: if OCR is not installed, returns a guidance string.
|
|
30
|
+
* Only the co-oracle agent is allowed to invoke this tool.
|
|
31
|
+
*
|
|
32
|
+
* @param ctx Plugin input
|
|
33
|
+
* @param projectDir Project root directory (used as --repo)
|
|
34
|
+
* @param ocrAvailable Whether the OCR CLI is installed (from detectOcrCli)
|
|
35
|
+
*/
|
|
36
|
+
export declare function createOcrReviewTool(ctx: PluginInput, projectDir: string, ocrAvailable: boolean): Record<string, ReturnType<typeof tool>>;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=ocr-review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ocr-review.d.ts","sourceRoot":"","sources":["../../src/tools/ocr-review.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAYvD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CASlE;AAMD,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB9E;AAwID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA+FnD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,OAAO,GACpB,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CA2FzC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ocr-review.test.d.ts","sourceRoot":"","sources":["../../src/tools/ocr-review.test.ts"],"names":[],"mappings":""}
|