@tienne/gestalt 0.86.0 → 0.87.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 (42) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +2 -2
  3. package/dist/plugin/skills/review/SKILL.md +9 -2
  4. package/dist/src/cli/commands/harness-refs.d.ts +10 -0
  5. package/dist/src/cli/commands/harness-refs.d.ts.map +1 -1
  6. package/dist/src/cli/commands/harness-refs.js +40 -0
  7. package/dist/src/cli/commands/harness-refs.js.map +1 -1
  8. package/dist/src/cli/index.d.ts.map +1 -1
  9. package/dist/src/cli/index.js +10 -1
  10. package/dist/src/cli/index.js.map +1 -1
  11. package/dist/src/harness-review/backward-search.d.ts +15 -2
  12. package/dist/src/harness-review/backward-search.d.ts.map +1 -1
  13. package/dist/src/harness-review/backward-search.js +101 -43
  14. package/dist/src/harness-review/backward-search.js.map +1 -1
  15. package/dist/src/harness-review/collect.d.ts +10 -1
  16. package/dist/src/harness-review/collect.d.ts.map +1 -1
  17. package/dist/src/harness-review/collect.js +66 -6
  18. package/dist/src/harness-review/collect.js.map +1 -1
  19. package/dist/src/harness-review/github-code-search.d.ts +32 -1
  20. package/dist/src/harness-review/github-code-search.d.ts.map +1 -1
  21. package/dist/src/harness-review/github-code-search.js +86 -2
  22. package/dist/src/harness-review/github-code-search.js.map +1 -1
  23. package/dist/src/harness-review/hybrid-search.d.ts +35 -0
  24. package/dist/src/harness-review/hybrid-search.d.ts.map +1 -0
  25. package/dist/src/harness-review/hybrid-search.js +63 -0
  26. package/dist/src/harness-review/hybrid-search.js.map +1 -0
  27. package/dist/src/harness-review/related-clones.d.ts +66 -0
  28. package/dist/src/harness-review/related-clones.d.ts.map +1 -0
  29. package/dist/src/harness-review/related-clones.js +309 -0
  30. package/dist/src/harness-review/related-clones.js.map +1 -0
  31. package/dist/src/harness-review/search-backend.d.ts +23 -1
  32. package/dist/src/harness-review/search-backend.d.ts.map +1 -1
  33. package/dist/src/harness-review/search-backend.js +13 -1
  34. package/dist/src/harness-review/search-backend.js.map +1 -1
  35. package/dist/src/humanize/detectors.js +1 -1
  36. package/dist/src/humanize/detectors.js.map +1 -1
  37. package/package.json +1 -1
  38. package/plugin/.codex-plugin/plugin.json +1 -1
  39. package/plugin/.mcp.json +1 -1
  40. package/plugin/mcp.json +1 -1
  41. package/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +2 -2
  42. package/plugin/skills/review/SKILL.md +9 -2
@@ -12,8 +12,10 @@ import { runGh } from '../review-loop/fetch.js';
12
12
  import { backwardSearch, } from './backward-search.js';
13
13
  import { findCopyDrift } from './copy-drift.js';
14
14
  import { forwardSearch } from './forward-search.js';
15
- import { GithubCodeSearchAdapter, orgWildcard } from './github-code-search.js';
15
+ import { GithubCodeSearchAdapter, isOrgWildcard, orgWildcard } from './github-code-search.js';
16
+ import { HybridSearchBackend } from './hybrid-search.js';
16
17
  import { extractIdentifiersFromGit, isHarnessPath, isRuleDocPath } from './identifiers.js';
18
+ import { defaultCloneRoot, prepareRelatedClones, pruneWorktreeClones, worktreeCloneRoot, } from './related-clones.js';
17
19
  import { detectRelatedRepos, readOriginRepo } from './related-repos.js';
18
20
  import { findRuleIdListGapsFromGit } from './rule-id-lists.js';
19
21
  import { findRuleOverlapFromGit } from './rule-overlap.js';
@@ -196,10 +198,32 @@ export async function collectReferenceCandidates(opts) {
196
198
  }
197
199
  else {
198
200
  let backend;
199
- if (opts.backend === 'github' && org !== null) {
200
- adapter = new GithubCodeSearchAdapter({ owner: org, selfRepo: repo, gh });
201
- backend = adapter;
202
- searchedRepos = [...relatedRepos, orgWildcard(org)];
201
+ if (opts.backend === 'github' && found && org !== null) {
202
+ adapter = new GithubCodeSearchAdapter({ owner: org, selfRepo: repo, gh, sleep: opts.sleep });
203
+ // 관련 레포는 로컬 클론에서 찾고 GitHub 코드 검색(분당 10회)은 클론으로 못 덮는 자리에만 쓴다
204
+ const cloneBase = opts.cloneRoot ?? defaultCloneRoot();
205
+ // 이 워크트리의 쓴 시각을 먼저 갱신한다. 정리를 먼저 돌리면 오래 묵은 자기 클론을 지우고
206
+ // 바로 다시 받는다
207
+ const cloneRoot = worktreeCloneRoot(cloneBase, repoRoot);
208
+ pruneWorktreeClones(cloneBase, { now: opts.now });
209
+ const clones = prepareRelatedClones({
210
+ targets: cloneTargets(found.relatedRepos, repoDirs, repo),
211
+ cloneRoot,
212
+ gh,
213
+ git: opts.cloneGit,
214
+ now: opts.now,
215
+ });
216
+ limitations.push(...clones.limitations);
217
+ backend = new HybridSearchBackend({
218
+ local: new LocalCloneBackend(clones.sources),
219
+ localRepos: clones.sources.map((s) => s.repo),
220
+ github: adapter,
221
+ owner: org,
222
+ });
223
+ searchedRepos = [
224
+ ...new Set([...relatedRepos, ...repoDirs.map((d) => d.repo)]),
225
+ orgWildcard(org),
226
+ ];
203
227
  limitations.push(...adapter.limitations);
204
228
  }
205
229
  else {
@@ -222,7 +246,17 @@ export async function collectReferenceCandidates(opts) {
222
246
  catch (e) {
223
247
  skip('backwardSearch', errorMessage(e));
224
248
  }
225
- noteBlocked('backwardSearch', adapter?.blocked);
249
+ const scopedRepos = searchedRepos.filter((r) => !isOrgWildcard(r));
250
+ if (backward && onlyOrgWideRateLimited(adapter?.blocked, backward.skipped, scopedRepos)) {
251
+ // 관련 레포는 전부 찾았고 한도 때문에 조직 전체 검색만 덜 봤다. 막힘으로 올리면 이름이 수십 개인
252
+ // PR은 라운드마다 막힌다. 대신 얼마나 봤는지를 남겨 리포트가 그대로 보이게 한다
253
+ const ow = backward.coverage.orgWide;
254
+ limitations.push(`조직 전체 검색은 질의 ${ow?.searched ?? 0}/${ow?.planned ?? 0}개만 봤다. 관련 레포는 전부 찾았다 (${adapter.blocked.detail})`);
255
+ backward.skipped = [];
256
+ }
257
+ else {
258
+ noteBlocked('backwardSearch', adapter?.blocked);
259
+ }
226
260
  }
227
261
  if (backward) {
228
262
  addCandidates(backward.backwardRefs);
@@ -251,8 +285,34 @@ export async function collectReferenceCandidates(opts) {
251
285
  noGitHubRemote,
252
286
  referenceCheckSkipped: noGitHubRemote || lookupBlocked.length > 0 || skippedRepos.length > 0 || crossRepoSkipped,
253
287
  skippedRepos,
288
+ backwardSearchCoverage: backward?.coverage ?? null,
254
289
  detectors,
255
290
  limitations,
256
291
  };
257
292
  }
293
+ /** 관련 레포와 `--repo-dir` 레포를 클론 대상으로 합친다. 같은 레포면 사람이 준 클론을 쓴다 */
294
+ function cloneTargets(related, repoDirs, self) {
295
+ const byKey = new Map();
296
+ for (const r of related) {
297
+ const key = `${r.owner}/${r.name}`.toLowerCase();
298
+ byKey.set(key, { repo: `${r.owner}/${r.name}`, defaultBranch: r.defaultBranch });
299
+ }
300
+ for (const d of repoDirs) {
301
+ const key = d.repo.toLowerCase();
302
+ const prev = byKey.get(key);
303
+ byKey.set(key, { ...(prev ?? { repo: d.repo }), userDir: d.dir });
304
+ }
305
+ byKey.delete(self.toLowerCase());
306
+ return [...byKey.values()];
307
+ }
308
+ /**
309
+ * 한도 때문에 조직 와일드카드만 덜 봤는지. 관련 레포가 하나도 없으면 와일드카드가 검색의 전부라
310
+ * 여기에 안 든다. 받기만 하는 레포는 그 검색으로만 자기를 부르는 레포를 찾는다
311
+ */
312
+ function onlyOrgWideRateLimited(blocked, skipped, scopedRepos) {
313
+ return (blocked?.reason === 'rateLimited' &&
314
+ scopedRepos.length > 0 &&
315
+ skipped.length > 0 &&
316
+ skipped.every((s) => isOrgWildcard(s.repo)));
317
+ }
258
318
  //# sourceMappingURL=collect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../src/harness-review/collect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../src/harness-review/collect.ts"],"names":[],"mappings":"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"}
@@ -5,10 +5,14 @@
5
5
  * 식별자와 레포 목록을 주고 hits와 skipped를 받는 꼴이라 둘을 이어 줄 자리가 필요하다.
6
6
  * 조회가 한 번 막히면 뒤 질의는 gh를 부르지 않고 전부 skipped로 돌려준다. 속도 제한에 걸린 채
7
7
  * 같은 호출을 수십 번 반복하면 제한이 풀리는 시점만 늦어진다.
8
+ *
9
+ * 코드 검색은 분당 10회다. 403을 맞고 나서 멈추면 그 뒤 1분이 통째로 막히므로 시작할 때
10
+ * `gh api rate_limit`(한도에서 안 빠진다)으로 남은 횟수를 읽고 그만큼만 보낸다. 다 쓰면 남은 질의가
11
+ * 다음 창 하나로 끝나고 1분 안에 풀릴 때만 한 번 기다린다. 그보다 길게 기다리면 리뷰가 멈춘다.
8
12
  */
9
13
  import type { GhRunner } from '../review-loop/fetch.js';
10
14
  import { type BlockReason, type GithubSearchBackend } from './github-backend.js';
11
- import { type CodeSearchBackend, type SearchOptions, type SearchResult } from './search-backend.js';
15
+ import { type BackendCounts, type CodeSearchBackend, type SearchOptions, type SearchResult } from './search-backend.js';
12
16
  export interface GithubLookupBlocked {
13
17
  reason: BlockReason;
14
18
  detail: string;
@@ -21,7 +25,20 @@ export interface GithubCodeSearchOptions {
21
25
  /** 테스트에서 가짜 gh로 바꾼다. backend를 주면 쓰지 않는다 */
22
26
  gh?: GhRunner;
23
27
  backend?: GithubSearchBackend;
28
+ /** 테스트에서 실제로 자지 않게 바꾼다 */
29
+ sleep?: (ms: number) => Promise<void>;
30
+ now?: () => number;
31
+ }
32
+ export interface RateLimitWindow {
33
+ limit: number;
34
+ remaining: number;
35
+ /** 한도가 다시 차는 시각 (epoch ms) */
36
+ resetAt: number;
24
37
  }
38
+ /** rate_limit을 못 읽었을 때 가정하는 코드 검색 한도. 로그인한 사용자의 분당 한도다 */
39
+ export declare const DEFAULT_CODE_SEARCH_LIMIT = 10;
40
+ export declare const MAX_RATE_LIMIT_WAIT_MS = 60000;
41
+ export declare function readCodeSearchWindow(gh: GhRunner): RateLimitWindow | null;
25
42
  /** GitHub 결과에는 줄 번호가 없다. 이 값이면 줄을 모른다는 뜻이다 */
26
43
  export declare const UNKNOWN_LINE = 0;
27
44
  /**
@@ -29,6 +46,7 @@ export declare const UNKNOWN_LINE = 0;
29
46
  * 비어 있어서 조직 전체를 찾지 않으면 자기를 부르는 레포를 영영 못 찾는다
30
47
  */
31
48
  export declare function orgWildcard(owner: string): string;
49
+ export declare function isOrgWildcard(repo: string): boolean;
32
50
  export declare class GithubCodeSearchAdapter implements CodeSearchBackend {
33
51
  readonly kind: "githubSearch";
34
52
  readonly capabilities: Record<string, unknown>;
@@ -38,7 +56,20 @@ export declare class GithubCodeSearchAdapter implements CodeSearchBackend {
38
56
  private readonly backend;
39
57
  private readonly owner;
40
58
  private readonly selfRepo;
59
+ private readonly gh;
60
+ private readonly sleep;
61
+ private readonly now;
62
+ private window;
63
+ private waited;
64
+ private planned;
65
+ private searched;
66
+ private skippedQueries;
41
67
  constructor(opts: GithubCodeSearchOptions);
68
+ plan(queryRepos: string[][]): void;
69
+ counts(): Partial<Record<'githubSearch', BackendCounts>>;
70
+ private readWindow;
71
+ /** 이번 질의를 보내도 되면 true. 안 되면 blocked를 채운다 */
72
+ private takeBudget;
42
73
  get rateLimitState(): Record<string, unknown> | undefined;
43
74
  search(identifier: string, repos: string[], opts?: SearchOptions): Promise<SearchResult>;
44
75
  private filterHits;
@@ -1 +1 @@
1
- {"version":3,"file":"github-code-search.d.ts","sourceRoot":"","sources":["../../../src/harness-review/github-code-search.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,qDAAqD;IACrD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,EAAE,CAAC,EAAE,QAAQ,CAAC;IACd,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B;AAED,8CAA8C;AAC9C,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAmBD,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAU;IACxC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,wCAAwC;IACxC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAQ;IAC3C,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,CAAsD;IAEpF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;gBAElC,IAAI,EAAE,uBAAuB;IAOzC,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAExD;IAEK,MAAM,CACV,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,YAAY,CAAC;IAsBxB,OAAO,CAAC,UAAU;CA6BnB"}
1
+ {"version":3,"file":"github-code-search.d.ts","sourceRoot":"","sources":["../../../src/harness-review/github-code-search.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,27 @@
1
1
  import { createGithubSearchBackend, GH_SEARCH_LIMITATIONS, GH_SEARCH_MAX_LIMIT, } from './github-backend.js';
2
2
  import { DEFAULT_MAX_HITS_PER_REPO, MAX_HIT_TEXT_LENGTH, } from './search-backend.js';
3
+ /** rate_limit을 못 읽었을 때 가정하는 코드 검색 한도. 로그인한 사용자의 분당 한도다 */
4
+ export const DEFAULT_CODE_SEARCH_LIMIT = 10;
5
+ const WINDOW_MS = 60_000;
6
+ export const MAX_RATE_LIMIT_WAIT_MS = 60_000;
7
+ // reset 시각은 초 단위라 딱 맞춰 깨면 아직 안 풀려 있을 수 있다
8
+ const RESET_SLACK_MS = 1_000;
9
+ export function readCodeSearchWindow(gh) {
10
+ try {
11
+ const json = JSON.parse(gh(['api', 'rate_limit']));
12
+ const w = json.resources?.code_search;
13
+ if (typeof w?.limit !== 'number' ||
14
+ typeof w.remaining !== 'number' ||
15
+ typeof w.reset !== 'number') {
16
+ return null;
17
+ }
18
+ return { limit: w.limit, remaining: w.remaining, resetAt: w.reset * 1000 };
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ const realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
3
25
  /** GitHub 결과에는 줄 번호가 없다. 이 값이면 줄을 모른다는 뜻이다 */
4
26
  export const UNKNOWN_LINE = 0;
5
27
  /**
@@ -9,9 +31,17 @@ export const UNKNOWN_LINE = 0;
9
31
  export function orgWildcard(owner) {
10
32
  return `${owner}/*`;
11
33
  }
34
+ export function isOrgWildcard(repo) {
35
+ return repo.endsWith('/*');
36
+ }
12
37
  function quoteQuery(identifier) {
13
38
  return `"${identifier.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
14
39
  }
40
+ function buildQuery(identifier, opts) {
41
+ return opts.requireAlso
42
+ ? `${quoteQuery(identifier)} ${quoteQuery(opts.requireAlso)}`
43
+ : quoteQuery(identifier);
44
+ }
15
45
  function hitsFromGithub(hit, identifier) {
16
46
  const lines = hit.fragments.flatMap((f) => f.split('\n')).map((l) => l.trimEnd());
17
47
  const matched = [...new Set(lines.filter((l) => l.includes(identifier)))];
@@ -33,11 +63,61 @@ export class GithubCodeSearchAdapter {
33
63
  backend;
34
64
  owner;
35
65
  selfRepo;
66
+ gh;
67
+ sleep;
68
+ now;
69
+ window = null;
70
+ waited = false;
71
+ planned = null;
72
+ searched = 0;
73
+ skippedQueries = 0;
36
74
  constructor(opts) {
37
75
  this.backend = opts.backend ?? createGithubSearchBackend(opts.gh);
38
76
  this.owner = opts.owner;
39
77
  this.selfRepo = opts.selfRepo?.toLowerCase();
40
78
  this.capabilities = { ...this.backend.capabilities, orgWide: true, lineNumbers: false };
79
+ this.gh = opts.gh;
80
+ this.sleep = opts.sleep ?? realSleep;
81
+ this.now = opts.now ?? Date.now;
82
+ }
83
+ plan(queryRepos) {
84
+ this.planned = queryRepos.filter((r) => r.length > 0).length;
85
+ }
86
+ counts() {
87
+ return { githubSearch: { searched: this.searched, skipped: this.skippedQueries } };
88
+ }
89
+ readWindow() {
90
+ const read = this.gh ? readCodeSearchWindow(this.gh) : null;
91
+ return (read ?? {
92
+ limit: DEFAULT_CODE_SEARCH_LIMIT,
93
+ remaining: DEFAULT_CODE_SEARCH_LIMIT,
94
+ resetAt: this.now() + WINDOW_MS,
95
+ });
96
+ }
97
+ /** 이번 질의를 보내도 되면 true. 안 되면 blocked를 채운다 */
98
+ async takeBudget() {
99
+ // 원격이 없으면 백엔드가 gh를 안 부르고 바로 막는다. 한도를 읽을 일도 없다
100
+ if (this.owner === null)
101
+ return true;
102
+ this.window ??= this.readWindow();
103
+ if (this.window.remaining > 0)
104
+ return true;
105
+ // plan을 안 불렀으면 남은 질의 수를 몰라 기다려도 끝난다는 보장이 없다
106
+ const left = this.planned === null ? Infinity : this.planned - this.searched;
107
+ const resetIn = Math.max(0, this.window.resetAt - this.now());
108
+ if (!this.waited && left <= this.window.limit && resetIn <= MAX_RATE_LIMIT_WAIT_MS) {
109
+ this.waited = true;
110
+ await this.sleep(resetIn + RESET_SLACK_MS);
111
+ this.window = this.readWindow();
112
+ if (this.window.remaining > 0)
113
+ return true;
114
+ }
115
+ const total = this.planned === null ? '' : `/${this.planned}`;
116
+ this.blocked = {
117
+ reason: 'rateLimited',
118
+ detail: `코드 검색 한도(${this.window.limit}회)를 다 써서 질의 ${this.searched}${total}개를 보내고 멈췄다. 한도가 다시 차는 시각: ${new Date(this.window.resetAt).toISOString()}`,
119
+ };
120
+ return false;
41
121
  }
42
122
  get rateLimitState() {
43
123
  return this.backend.rateLimitState;
@@ -46,8 +126,10 @@ export class GithubCodeSearchAdapter {
46
126
  const result = { hits: [], skipped: [] };
47
127
  if (identifier === '' || repos.length === 0)
48
128
  return result;
49
- if (!this.blocked) {
50
- const outcome = this.backend.search(quoteQuery(identifier), {
129
+ if (!this.blocked && (await this.takeBudget())) {
130
+ if (this.window)
131
+ this.window.remaining--;
132
+ const outcome = this.backend.search(buildQuery(identifier, opts), {
51
133
  owner: this.owner,
52
134
  limit: GH_SEARCH_MAX_LIMIT,
53
135
  });
@@ -55,10 +137,12 @@ export class GithubCodeSearchAdapter {
55
137
  this.blocked = { reason: outcome.reason, detail: outcome.detail };
56
138
  }
57
139
  else {
140
+ this.searched++;
58
141
  result.hits = this.filterHits(outcome.hits, identifier, repos, opts);
59
142
  return result;
60
143
  }
61
144
  }
145
+ this.skippedQueries++;
62
146
  const reason = `GitHub 조회 막힘 (${this.blocked.reason})`;
63
147
  result.skipped = repos.map((repo) => ({ repo, reason }));
64
148
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"github-code-search.js","sourceRoot":"","sources":["../../../src/harness-review/github-code-search.ts"],"names":[],"mappings":"AASA,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,GAIpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,yBAAyB,EACzB,mBAAmB,GAKpB,MAAM,qBAAqB,CAAC;AAiB7B,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAE9B;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,GAAG,KAAK,IAAI,CAAC;AACtB,CAAC;AAED,SAAS,UAAU,CAAC,UAAkB;IACpC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AACvE,CAAC;AAED,SAAS,cAAc,CAAC,GAAoB,EAAE,UAAkB;IAC9D,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAClF,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,qDAAqD;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IACxF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;KACzC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,OAAO,uBAAuB;IACzB,IAAI,GAAG,cAAuB,CAAC;IAC/B,YAAY,CAA0B;IAC/C,wCAAwC;IACxC,OAAO,GAA+B,IAAI,CAAC;IAClC,WAAW,GAAa,CAAC,GAAG,qBAAqB,EAAE,sBAAsB,CAAC,CAAC;IAEnE,OAAO,CAAsB;IAC7B,KAAK,CAAgB;IACrB,QAAQ,CAAqB;IAE9C,YAAY,IAA6B;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAC1F,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,MAAM,CACV,UAAkB,EAClB,KAAe,EACf,OAAsB,EAAE;QAExB,MAAM,MAAM,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACvD,IAAI,UAAU,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QAE3D,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;gBAC1D,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,mBAAmB;aAC3B,CAAC,CAAC;YACH,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;gBACrE,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,iBAAiB,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QACvD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,UAAU,CAChB,IAAuB,EACvB,UAAkB,EAClB,KAAe,EACf,IAAmB;QAEnB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QACzF,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,IAAI,yBAAyB,CAAC;QAC7D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,GAAG,GAAgB,EAAE,CAAC;QAE5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpC,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACrC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5C,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC;gBAChD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;gBACtD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,KAAK,IAAI,GAAG;oBAAE,MAAM;gBACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
1
+ {"version":3,"file":"github-code-search.js","sourceRoot":"","sources":["../../../src/harness-review/github-code-search.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,GAIpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,yBAAyB,EACzB,mBAAmB,GAMpB,MAAM,qBAAqB,CAAC;AA2B7B,0DAA0D;AAC1D,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAC5C,MAAM,SAAS,GAAG,MAAM,CAAC;AACzB,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAC7C,0CAA0C;AAC1C,MAAM,cAAc,GAAG,KAAK,CAAC;AAE7B,MAAM,UAAU,oBAAoB,CAAC,EAAY;IAC/C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAEhD,CAAC;QACF,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC;QACtC,IACE,OAAO,CAAC,EAAE,KAAK,KAAK,QAAQ;YAC5B,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;YAC/B,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAC3B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAE9E,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAE9B;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,GAAG,KAAK,IAAI,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,UAAU,CAAC,UAAkB;IACpC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AACvE,CAAC;AAED,SAAS,UAAU,CAAC,UAAkB,EAAE,IAAmB;IACzD,OAAO,IAAI,CAAC,WAAW;QACrB,CAAC,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;QAC7D,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,cAAc,CAAC,GAAoB,EAAE,UAAkB;IAC9D,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAClF,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,qDAAqD;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IACxF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;KACzC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,OAAO,uBAAuB;IACzB,IAAI,GAAG,cAAuB,CAAC;IAC/B,YAAY,CAA0B;IAC/C,wCAAwC;IACxC,OAAO,GAA+B,IAAI,CAAC;IAClC,WAAW,GAAa,CAAC,GAAG,qBAAqB,EAAE,sBAAsB,CAAC,CAAC;IAEnE,OAAO,CAAsB;IAC7B,KAAK,CAAgB;IACrB,QAAQ,CAAqB;IAC7B,EAAE,CAAuB;IACzB,KAAK,CAAgC;IACrC,GAAG,CAAe;IAC3B,MAAM,GAA2B,IAAI,CAAC;IACtC,MAAM,GAAG,KAAK,CAAC;IACf,OAAO,GAAkB,IAAI,CAAC;IAC9B,QAAQ,GAAG,CAAC,CAAC;IACb,cAAc,GAAG,CAAC,CAAC;IAE3B,YAAY,IAA6B;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QACxF,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;QACrC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,UAAsB;QACzB,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/D,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;IACrF,CAAC;IAEO,UAAU;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,OAAO,CACL,IAAI,IAAI;YACN,KAAK,EAAE,yBAAyB;YAChC,SAAS,EAAE,yBAAyB;YACpC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SAChC,CACF,CAAC;IACJ,CAAC;IAED,4CAA4C;IACpC,KAAK,CAAC,UAAU;QACtB,8CAA8C;QAC9C,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,4CAA4C;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,IAAI,sBAAsB,EAAE,CAAC;YACnF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC;YAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC7C,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9D,IAAI,CAAC,OAAO,GAAG;YACb,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,YAAY,IAAI,CAAC,MAAM,CAAC,KAAK,eAAe,IAAI,CAAC,QAAQ,GAAG,KAAK,6BAA6B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;SACpJ,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,MAAM,CACV,UAAkB,EAClB,KAAe,EACf,OAAsB,EAAE;QAExB,MAAM,MAAM,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACvD,IAAI,UAAU,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QAE3D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;YAC/C,IAAI,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE;gBAChE,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,mBAAmB;aAC3B,CAAC,CAAC;YACH,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;gBACrE,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,cAAc,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,iBAAiB,IAAI,CAAC,OAAQ,CAAC,MAAM,GAAG,CAAC;QACxD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,UAAU,CAChB,IAAuB,EACvB,UAAkB,EAClB,KAAe,EACf,IAAmB;QAEnB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QACzF,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,IAAI,yBAAyB,CAAC;QAC7D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,GAAG,GAAgB,EAAE,CAAC;QAE5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpC,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACrC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5C,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC;gBAChD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;gBACtD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,KAAK,IAAI,GAAG;oBAAE,MAAM;gBACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 레포마다 로컬 클론과 GitHub 코드 검색을 골라 쓰는 역방향 검색 백엔드.
3
+ *
4
+ * 클론이 있는 관련 레포는 git grep으로 한도 없이 찾는다. GitHub에는 클론으로 못 덮는 자리만 보낸다.
5
+ * 조직 와일드카드(관련 레포 목록 밖에서 이 레포를 부르는 레포)와 클론을 못 받은 레포다.
6
+ * GitHub 호출은 레포가 아니라 질의마다 하나라서, 호출 수가 주는 건 질의에 GitHub 몫이 아예 없을 때다.
7
+ * 그래서 backwardSearch가 헤딩 질의에서는 와일드카드를 빼고 넘긴다.
8
+ */
9
+ import { type GithubCodeSearchAdapter } from './github-code-search.js';
10
+ import type { BackendCounts, CodeSearchBackend, LocalCloneBackend, SearchOptions, SearchResult } from './search-backend.js';
11
+ import type { SearchBackendKind } from './types.js';
12
+ export interface HybridSearchOptions {
13
+ local: LocalCloneBackend;
14
+ /** 로컬 클론을 얻은 레포 (owner/name) */
15
+ localRepos: string[];
16
+ github: GithubCodeSearchAdapter;
17
+ owner: string;
18
+ }
19
+ export declare class HybridSearchBackend implements CodeSearchBackend {
20
+ readonly kind: "githubSearch";
21
+ readonly capabilities: Record<string, unknown>;
22
+ private readonly local;
23
+ private readonly github;
24
+ private readonly localRepos;
25
+ private readonly wildcard;
26
+ constructor(opts: HybridSearchOptions);
27
+ get blocked(): import("./github-code-search.js").GithubLookupBlocked | null;
28
+ private split;
29
+ /** GitHub으로 갈 질의만 어댑터에 알린다. 로컬은 한도가 없다 */
30
+ plan(queryRepos: string[][]): void;
31
+ search(identifier: string, repos: string[], opts?: SearchOptions): Promise<SearchResult>;
32
+ hasFile(repo: string, path: string): boolean | undefined;
33
+ counts(): Partial<Record<SearchBackendKind, BackendCounts>>;
34
+ }
35
+ //# sourceMappingURL=hybrid-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../src/harness-review/hybrid-search.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAe,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACpF,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,iBAAiB,CAAC;IACzB,gCAAgC;IAChC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,uBAAuB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,mBAAoB,YAAW,iBAAiB;IAE3D,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAU;IACxC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,IAAI,EAAE,mBAAmB;IAQrC,IAAI,OAAO,iEAEV;IAED,OAAO,CAAC,KAAK;IAOb,0CAA0C;IAC1C,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAI5B,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAoB9F,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIxD,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;CAG5D"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * 레포마다 로컬 클론과 GitHub 코드 검색을 골라 쓰는 역방향 검색 백엔드.
3
+ *
4
+ * 클론이 있는 관련 레포는 git grep으로 한도 없이 찾는다. GitHub에는 클론으로 못 덮는 자리만 보낸다.
5
+ * 조직 와일드카드(관련 레포 목록 밖에서 이 레포를 부르는 레포)와 클론을 못 받은 레포다.
6
+ * GitHub 호출은 레포가 아니라 질의마다 하나라서, 호출 수가 주는 건 질의에 GitHub 몫이 아예 없을 때다.
7
+ * 그래서 backwardSearch가 헤딩 질의에서는 와일드카드를 빼고 넘긴다.
8
+ */
9
+ import { orgWildcard } from './github-code-search.js';
10
+ export class HybridSearchBackend {
11
+ // refs.json의 backendUsed는 수집 모드를 적는다. 어느 쪽이 얼마나 찾았는지는 counts가 따로 싣는다
12
+ kind = 'githubSearch';
13
+ capabilities;
14
+ local;
15
+ github;
16
+ localRepos;
17
+ wildcard;
18
+ constructor(opts) {
19
+ this.local = opts.local;
20
+ this.github = opts.github;
21
+ this.localRepos = new Set(opts.localRepos.map((r) => r.toLowerCase()));
22
+ this.wildcard = orgWildcard(opts.owner).toLowerCase();
23
+ this.capabilities = { ...opts.github.capabilities, hybrid: true };
24
+ }
25
+ get blocked() {
26
+ return this.github.blocked;
27
+ }
28
+ split(repos) {
29
+ const local = [];
30
+ const remote = [];
31
+ for (const r of repos)
32
+ (this.localRepos.has(r.toLowerCase()) ? local : remote).push(r);
33
+ return { local, remote };
34
+ }
35
+ /** GitHub으로 갈 질의만 어댑터에 알린다. 로컬은 한도가 없다 */
36
+ plan(queryRepos) {
37
+ this.github.plan(queryRepos.map((repos) => this.split(repos).remote));
38
+ }
39
+ async search(identifier, repos, opts) {
40
+ const { local, remote } = this.split(repos);
41
+ const result = { hits: [], skipped: [] };
42
+ if (local.length > 0) {
43
+ const r = await this.local.search(identifier, local, opts);
44
+ result.hits.push(...r.hits);
45
+ result.skipped.push(...r.skipped);
46
+ }
47
+ if (remote.length > 0) {
48
+ const r = await this.github.search(identifier, remote, opts);
49
+ // 와일드카드는 조직 전체를 돌려준다. 로컬이 맡은 레포는 줄 번호까지 있는 로컬 결과만 남긴다
50
+ const orgWide = remote.some((x) => x.toLowerCase() === this.wildcard);
51
+ result.hits.push(...(orgWide ? r.hits.filter((h) => !this.localRepos.has(h.repo.toLowerCase())) : r.hits));
52
+ result.skipped.push(...r.skipped);
53
+ }
54
+ return result;
55
+ }
56
+ hasFile(repo, path) {
57
+ return this.localRepos.has(repo.toLowerCase()) ? this.local.hasFile(repo, path) : undefined;
58
+ }
59
+ counts() {
60
+ return { ...this.local.counts(), ...this.github.counts() };
61
+ }
62
+ }
63
+ //# sourceMappingURL=hybrid-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-search.js","sourceRoot":"","sources":["../../../src/harness-review/hybrid-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { type GhRunner } from '../review-loop/fetch.js';
2
+ import type { LocalRepoSource } from './search-backend.js';
3
+ export interface CloneTarget {
4
+ /** owner/name */
5
+ repo: string;
6
+ /** 관련 레포 탐지가 알아낸 기본 브랜치. 없으면 클론의 origin/HEAD를 본다 */
7
+ defaultBranch?: string;
8
+ /** `--repo-dir`로 받은 클론. 있으면 관리 클론을 만들지 않는다 */
9
+ userDir?: string;
10
+ }
11
+ export interface CloneGitRunner {
12
+ (dir: string, args: readonly string[]): string;
13
+ }
14
+ export interface PrepareClonesOptions {
15
+ targets: CloneTarget[];
16
+ /** 관리 클론을 두는 자리. 부르는 쪽이 `worktreeCloneRoot`로 워크트리마다 나눠 넘긴다 */
17
+ cloneRoot?: string;
18
+ gh?: GhRunner;
19
+ git?: CloneGitRunner;
20
+ now?: Date;
21
+ /** fetch가 잠금에 걸렸을 때 다시 시도하기 전 기다리는 함수. 테스트가 실제로 자지 않게 주입한다 */
22
+ wait?: (ms: number) => void;
23
+ }
24
+ export interface CloneFailure {
25
+ repo: string;
26
+ reason: string;
27
+ }
28
+ export interface PreparedClones {
29
+ sources: LocalRepoSource[];
30
+ /** 클론을 못 얻은 레포. 부르는 쪽이 GitHub 검색으로 넘긴다 */
31
+ failed: CloneFailure[];
32
+ limitations: string[];
33
+ }
34
+ export declare function defaultCloneRoot(): string;
35
+ /**
36
+ * 워크트리 하나가 쓸 클론 루트를 돌려준다. 이름은 사람이 알아보게 디렉토리 이름을 앞에 두고
37
+ * 같은 이름의 워크트리끼리 겹치지 않게 경로 해시를 붙인다.
38
+ */
39
+ export declare function worktreeCloneRoot(base: string, worktree: string): string;
40
+ /** 이 기간 넘게 어느 수집도 안 쓴 클론 루트는 워크트리가 살아 있어도 치운다 */
41
+ export declare const DEFAULT_CLONE_MAX_IDLE_MS: number;
42
+ export type PruneReason = 'worktreeGone' | 'idle' | 'all';
43
+ export interface PrunedClone {
44
+ root: string;
45
+ /** 표시 파일에 적힌 워크트리 경로. 표시가 없으면 null */
46
+ worktree: string | null;
47
+ reason: PruneReason;
48
+ }
49
+ export interface PruneClonesOptions {
50
+ now?: Date;
51
+ maxIdleMs?: number;
52
+ /** 표시 없는 디렉토리까지 전부 지운다. 사람이 명령으로 부를 때만 쓴다 */
53
+ all?: boolean;
54
+ }
55
+ /**
56
+ * 원래 워크트리가 지워졌거나 오래 안 쓴 클론 루트를 치운다. 쓴 시각은 수집마다
57
+ * `worktreeCloneRoot`가 표시 파일을 다시 쓰며 갱신한다. 표시 파일이 없는 디렉토리는 누가 만든
58
+ * 건지 몰라 `all`이 아니면 건드리지 않는다. 예외를 던지지 않는다.
59
+ */
60
+ export declare function pruneWorktreeClones(base: string, opts?: PruneClonesOptions): PrunedClone[];
61
+ /**
62
+ * 대상마다 클론을 확보하고 origin 기본 브랜치를 받아 온다. 예외를 던지지 않는다 — 실패는 failed와
63
+ * limitations로 돌려준다.
64
+ */
65
+ export declare function prepareRelatedClones(opts: PrepareClonesOptions): PreparedClones;
66
+ //# sourceMappingURL=related-clones.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"related-clones.d.ts","sourceRoot":"","sources":["../../../src/harness-review/related-clones.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,QAAQ,CAAC;IACd,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,8DAA8D;IAC9D,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,0CAA0C;IAC1C,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAYD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAaD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYxE;AAED,iDAAiD;AACjD,eAAO,MAAM,yBAAyB,QAAa,CAAC;AAEpD,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAYD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,WAAW,EAAE,CA2B9F;AAwHD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,GAAG,cAAc,CAgG/E"}