Skip to content

feat: Source Discovery v0.1 boundary + source intake integration#24

Merged
sasazaki1994 merged 2 commits intomainfrom
codex/implement-source-discovery-v0.1
May 7, 2026
Merged

feat: Source Discovery v0.1 boundary + source intake integration#24
sasazaki1994 merged 2 commits intomainfrom
codex/implement-source-discovery-v0.1

Conversation

@sasazaki1994
Copy link
Copy Markdown
Owner

@sasazaki1994 sasazaki1994 commented May 7, 2026

Motivation

  • Provide a minimal, pluggable search/provider boundary so TraceMap can discover source candidates from a research topic when users do not paste URLs, without changing DB schema or breaking existing intake/fetch/cache/provider flows.
  • Allow future replacement with real search providers while keeping manual URL extraction and safety checks as the primary behavior.

Description

  • Added a new spec specs/source-discovery.md and acceptance acceptance/source-discovery.feature to document purpose, scope, provider strategy, dedup rules, error handling, security and test requirements.
  • Introduced SourceDiscoveryProvider boundary and types in src/server/analysis/source-discovery/source-discovery-provider.ts with a resolver resolveSourceDiscoveryProvider and constants in source-discovery-service.ts.
  • Implemented a deterministic mock discovery provider at src/server/analysis/source-discovery/mock-source-discovery-provider.ts and a disabled default provider via the resolver, controllable with TRACEMAP_SOURCE_DISCOVERY_PROVIDER.
  • Integrated discovery into the existing intake flow by extending buildSourceIntakeFromQuestion in src/server/analysis/source-intake/source-intake-service.ts to: extract manual URLs, call discovery when enabled, merge manual+discovered URLs (manual-first), normalize/dedupe by normalized URL, resolve cache/fetch metadata via resolveSourceCacheForUrl, and produce SourceCandidate[] while recording ignoredUrls for failures.
  • Added origin?: "manual_url" | "discovered" to SourceCandidate in src/types/source-intake.ts (optional, non-breaking).
  • Applied candidate and discovery caps via DEFAULT_DISCOVERY_MAX_RESULTS and DEFAULT_SOURCE_CANDIDATE_MAX_RESULTS (both set to 5) to control cost surface.
  • Added unit tests for provider behavior and intake integration in tests/source-discovery-provider.test.ts and tests/source-intake-integration.test.ts, and updated specs/README.md and acceptance/README.md to list the new spec/acceptance files.

Testing

  • Ran lint with pnpm lint and it succeeded.
  • Ran type checks with pnpm typecheck and it succeeded.
  • Ran the full test suite with pnpm test and all tests passed: "Test Files 32 passed (32), Tests 146 passed (146)" and the new unit tests (provider + intake integration) also passed.
  • Built the app with pnpm build and Next.js compiled successfully.
  • pnpm exec prisma validate failed due to missing DATABASE_URL in the environment (local validation error), so Prisma validation could not be completed in this CI-less environment.

Codex Task

Summary by CodeRabbit

リリースノート

  • 新機能

    • 調査トピックから自動的にソース候補を発見できるようになりました。
    • 手動で入力されたURLは発見されたURLより優先されます。
    • ソース発見の失敗は調査プロセスに影響しません。
  • テスト

    • ソース発見に関する受け入れテストを追加しました。
    • ソース発見とソース取り込みの統合テストを追加しました。

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

ウォークスルー

TraceMapにソースディスカバリー機能を追加し、ユーザーが提供する研究トピックから自動的にソースURL候補を検出します。プラガブルなSourceDiscoveryProviderインターフェースを介して、手動入力と検出候補をマージして既存のソースインテークパイプラインに統合し、エラー耐性と優先度制御を備えています。

変更内容

ソースディスカバリー機能

レイヤー・ファイル 要約
型定義・コントラクト
src/server/analysis/source-discovery/source-discovery-provider.tssrc/types/source-intake.ts
SourceDiscoveryProviderSourceDiscoveryCandidateSourceDiscoveryInputSourceDiscoveryResultの型を定義し、SourceCandidateoriginフィールドを追加します。
プロバイダー実装
src/server/analysis/source-discovery/mock-source-discovery-provider.ts
研究トピックをスラグに正規化するtoTopicSlugヘルパー、および決定的なモック候補を生成するmockSourceDiscoveryProviderを実装します。
プロバイダー解決
src/server/analysis/source-discovery/resolve-source-discovery-provider.tssrc/server/analysis/source-discovery/source-discovery-service.ts
環境変数に基づいてプロバイダーを解決し、デフォルト設定定数を定義します。
ソースインテーク統合
src/server/analysis/source-intake/source-intake-service.ts
buildSourceIntakeFromQuestionを拡張して、手動URLと検出URLをマージ・除重複し、各候補にoriginを付与します。
仕様・ドキュメント
specs/source-discovery.mdspecs/README.mdacceptance/source-discovery.featureacceptance/README.md
Source Discovery v0.1仕様、受け入れシナリオ4件、ドキュメント参照を追加します。
ユニット・統合テスト
tests/source-discovery-provider.test.tstests/source-intake-integration.test.ts
プロバイダー解決・モック決定性・maxResults制約、および統合時のoriginメタデータ設定をテストします。
CI設定
.github/workflows/ci.yml
install-and-static-checksdatabase-checkse2eジョブでCorepackではなくpnpm/action-setup@v4を使用します。

推奨される関連PR

  • sasazaki1994/TraceMap#23: このPRはPR #23で導入されたソースインテークパイプラインを拡張し、プラガブルなSourceDiscoveryProviderと検出候補のbuildSourceIntakeFromQuestionへの統合を追加するため、コードレベルで直接関連しています。

推定レビュー工数

🎯 3 (中程度) | ⏱️ 約20分

🐰 トピックから候補を見つけ出し
手動と検出がひとつになり
エラーも優しく受け止めて
Source Discovery、新しい道
TraceMapの冒険は続く ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the two main changes: introducing a Source Discovery v0.1 boundary and its integration into source intake, matching the core objectives and changes shown in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/implement-source-discovery-v0.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
tests/source-discovery-provider.test.ts (1)

20-24: 💤 Low value

result.kind アサション後の if ガードは不要です

Line 22 の expect(result.kind).toBe("success") が成功した後、Line 23 の if (result.kind === "success") は常に真であるため、実質的に意味のないガードです。Vitest の assert によるタイプナローイングか、直接アサションするパターンへ整理すると意図が明確になります。

♻️ 提案
 it("respects maxResults", async () => {
   const result = await mockSourceDiscoveryProvider.discoverSources({ researchTopic: "Acme", maxResults: 2 });
   expect(result.kind).toBe("success");
-  if (result.kind === "success") expect(result.candidates).toHaveLength(2);
+  expect((result as { kind: "success"; candidates: unknown[] }).candidates).toHaveLength(2);
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/source-discovery-provider.test.ts` around lines 20 - 24, The test uses
a redundant runtime guard after asserting result.kind === "success"; remove the
if (result.kind === "success") check and directly assert the candidates length
instead (e.g., after calling mockSourceDiscoveryProvider.discoverSources and
expect(result.kind).toBe("success"), call
expect(result.candidates).toHaveLength(2)). Update the test around the result
variable and the mockSourceDiscoveryProvider.discoverSources call so the
assertion is clear and concise without the unnecessary type guard.
tests/source-intake-integration.test.ts (1)

16-16: 💤 Low value

candidates[0]?.origin のオプショナルチェーンがデバッグを困難にします

candidates が空の場合、?.originundefined を返し expected undefined to be 'manual_url' という誤解を招くエラーメッセージになります。長さを先に確認することでエラーの原因が明確になります。

♻️ 提案
+    expect(result.candidates).toHaveLength(1);
     expect(result.candidates[0]?.origin).toBe("manual_url");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/source-intake-integration.test.ts` at line 16, The test uses an
optional chain on candidates
(expect(result.candidates[0]?.origin).toBe("manual_url")) which hides whether
candidates is empty; first assert the array length (e.g.,
expect(result.candidates.length).toBeGreaterThan(0) or toHaveLength(expected))
and then assert the first item's origin without optional chaining
(expect(result.candidates[0].origin).toBe("manual_url")) so failures clearly
indicate an empty array vs unexpected origin.
src/server/analysis/source-discovery/resolve-source-discovery-provider.ts (1)

1-1: 💤 Low value

mockSourceDiscoveryProvider の即時インポートについて

モジュールロード時に常に mockSourceDiscoveryProvider が評価されます。モック実装が副作用のない純粋なスタブである限り実害はなく、バンドル時のツリーシェイキングで除去されますが、将来的にモックが外部依存を持つ場合に備えて遅延インポートとすることも選択肢の一つです。

現時点では問題ありません。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server/analysis/source-discovery/resolve-source-discovery-provider.ts` at
line 1,
現在の即時トップレベルインポート「mockSourceDiscoveryProvider」がモジュールロード時に常に評価されるため、将来モックが副作用や外部依存を持つ場合に備えて遅延ロードに変更してください
— 具体的にはトップレベルの import
を削り、resolveSourceDiscoveryProvider(または該当するファクトリ関数)内で条件が満たされたときに動的
import('…/mock-source-discovery-provider') を使って mockSourceDiscoveryProvider
を読み込み、その返り値(default/名前付きエクスポート)を参照するようにします。これによりモックは実際に必要なときだけ評価され、バンドルやモジュール初期化時の副作用を防げます。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 35-38: Replace every occurrence of the GitHub Action usage "uses:
pnpm/action-setup@v4" with the current recommended "uses: pnpm/action-setup@v6"
(you can pin to v6.0.5 if desired); there are three occurrences of "uses:
pnpm/action-setup@v4" in the workflow and you should update all three so each
job uses the v6 action, leaving the existing "with: version: 10.18.2" input
unchanged.

In `@src/server/analysis/source-intake/source-intake-service.ts`:
- Around line 13-23: discoverSources
の呼び出しが例外を投げると処理全体が中断してしまうので、discoveryProvider.discoverSources(...) を try/catch
で囲み、例外発生時は ignoredUrls に { url: "[source_discovery]", reason: error.message ||
String(error) } を push して discoveredUrls の更新をスキップし処理を継続するように修正してください(参照箇所:
discoveryProvider, discoverSources, ignoredUrls, discoveredUrls,
DEFAULT_DISCOVERY_MAX_RESULTS, question)。

---

Nitpick comments:
In `@src/server/analysis/source-discovery/resolve-source-discovery-provider.ts`:
- Line 1:
現在の即時トップレベルインポート「mockSourceDiscoveryProvider」がモジュールロード時に常に評価されるため、将来モックが副作用や外部依存を持つ場合に備えて遅延ロードに変更してください
— 具体的にはトップレベルの import
を削り、resolveSourceDiscoveryProvider(または該当するファクトリ関数)内で条件が満たされたときに動的
import('…/mock-source-discovery-provider') を使って mockSourceDiscoveryProvider
を読み込み、その返り値(default/名前付きエクスポート)を参照するようにします。これによりモックは実際に必要なときだけ評価され、バンドルやモジュール初期化時の副作用を防げます。

In `@tests/source-discovery-provider.test.ts`:
- Around line 20-24: The test uses a redundant runtime guard after asserting
result.kind === "success"; remove the if (result.kind === "success") check and
directly assert the candidates length instead (e.g., after calling
mockSourceDiscoveryProvider.discoverSources and
expect(result.kind).toBe("success"), call
expect(result.candidates).toHaveLength(2)). Update the test around the result
variable and the mockSourceDiscoveryProvider.discoverSources call so the
assertion is clear and concise without the unnecessary type guard.

In `@tests/source-intake-integration.test.ts`:
- Line 16: The test uses an optional chain on candidates
(expect(result.candidates[0]?.origin).toBe("manual_url")) which hides whether
candidates is empty; first assert the array length (e.g.,
expect(result.candidates.length).toBeGreaterThan(0) or toHaveLength(expected))
and then assert the first item's origin without optional chaining
(expect(result.candidates[0].origin).toBe("manual_url")) so failures clearly
indicate an empty array vs unexpected origin.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 90c6a534-45a5-43bb-a6a3-c7d5c906c959

📥 Commits

Reviewing files that changed from the base of the PR and between 6dbec5f and cd66070.

📒 Files selected for processing (13)
  • .github/workflows/ci.yml
  • acceptance/README.md
  • acceptance/source-discovery.feature
  • specs/README.md
  • specs/source-discovery.md
  • src/server/analysis/source-discovery/mock-source-discovery-provider.ts
  • src/server/analysis/source-discovery/resolve-source-discovery-provider.ts
  • src/server/analysis/source-discovery/source-discovery-provider.ts
  • src/server/analysis/source-discovery/source-discovery-service.ts
  • src/server/analysis/source-intake/source-intake-service.ts
  • src/types/source-intake.ts
  • tests/source-discovery-provider.test.ts
  • tests/source-intake-integration.test.ts

Comment thread .github/workflows/ci.yml
Comment on lines +35 to +38
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.18.2
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/ci.yml | head -200

Repository: sasazaki1994/TraceMap

Length of output: 5740


🌐 Web query:

pnpm/action-setup v4 Node.js runtime requirements

💡 Result:

The pnpm/action-setup v4 GitHub Action does not have strict Node.js runtime requirements specified in its documentation. It explicitly states: "This action does not setup Node.js for you, use actions/setup-node yourself."[1][2] You must separately configure Node.js using actions/setup-node@v4 (or equivalent), and pnpm/action-setup will use whatever Node.js runtime is available in the environment.[1][3] Key points from official sources: - v2 had compatibility issues with newer Node.js versions, prompting upgrade to v3+ (including v4).[1][2] - Recent v4 releases (v4.3.0, v4.4.0) updated the action's internal runtime to Node.js 24.[4][5] - Older v4 versions likely used Node.js 20 or earlier, but since v4.4.0, it runs on Node.js 24.[4] - Dependencies include @types/node ^20.x, indicating development against Node 20+.[6] - Example workflows use Node.js 20: uses: actions/setup-node@v4 with node-version: 20.[3][7] - Standalone mode (standalone: true) installs @pnpm/exe, a self-bundled executable that does not require Node.js.[1][2] - For pnpm versions like 11.x, Node.js 22+ is recommended due to pnpm requirements, but this is for the installed pnpm, not the action itself.[8] In practice, v4 works with Node.js 20+ in user workflows, with updates ensuring compatibility up to Node.js 24.[4][9] No minimum Node.js version is enforced by the action; compatibility depends on the pnpm version installed and GitHub Actions runner (ubuntu-latest supports Node 20-24 as of 2026).[9]

Citations:


🌐 Web query:

GitHub Actions Node.js 20 deprecation Node.js 24 June 2026

💡 Result:

As of today (2026-05-07), GitHub Actions is deprecating Node.js 20 and migrating the default JavaScript runtime to Node.js 24. 1) Key deprecation/migration dates (Node.js 20 -> Node.js 24) - GitHub’s published deprecation notice says that starting June 2, 2026, GitHub Actions runners begin using Node.js 24 by default. [1] - In that same notice, GitHub also states you can temporarily keep Node.js 20 after June 2, 2026 by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true, but it will only work until Node 20 is removed later in the fall of 2026. [1] - GitHub notes that this deprecation process was started because Node.js 20 reaches end-of-life (EOL) in April 2026. [1] 2) How to react in your workflows - If you use JavaScript actions without pinning to a version that supports Node 24, you should upgrade the action versions. GitHub’s notice explicitly recommends updating actions to run on Node 24 and checking whether newer versions are available. [1] - A common way to control your app/test Node.js version (separate from the runtime used by the GitHub-provided “JavaScript actions” on the runner) is to use actions/setup-node with node-version. [2] 3) What your workflows might be telling you right now - Users commonly see a warning that Node.js 20 actions are deprecated and that actions will be forced to run with Node.js 24 by default starting June 2, 2026; the warning also mentions how to opt into Node 24 early (FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true) and how to opt out of the default using ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. [3] If you tell me which specific GitHub Actions (e.g., actions/checkout@..., actions/setup-node@..., github/codeql-action@...) your workflows use, I can map them to what you should upgrade to avoid Node 20 runtime warnings.

Citations:


🌐 Web query:

pnpm/action-setup v6 current version recommended

💡 Result:

Recommended: use pnpm/action-setup@v6, pinned to the latest v6 patch release: pnpm/action-setup@v6.0.5 (published 2026-05-02). [1] Example (best practice: pin to an exact v6.x.y): uses: pnpm/action-setup@v6.0.5 Or, to always stay on the latest v6 line (un-pinned): uses: pnpm/action-setup@v6 Notes: - The action’s README shows usage with pnpm/action-setup@v6, and documents that you can omit the version input to use the version from the package.json packageManager field. [1] - There is a known issue where specifying package_json_file and relying on packageManager in that file may not work as expected on some v6 versions; the issue suggests a workaround of passing version explicitly. [2]

Citations:


pnpm/action-setup を v4 から v6 へアップグレードしてください

pnpm/action-setup@v6 が現在の推奨バージョンです(公式リポジトリのREADMEで明記されており、2026年5月2日に v6.0.5 がリリースされています)。3つのジョブすべてで同じアップグレードが必要です。

🔧 推奨される修正
-        uses: pnpm/action-setup@v4
+        uses: pnpm/action-setup@v6

3箇所(Line 36、Line 95、Line 154)すべてで同様の変更が必要です。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.18.2
- name: Setup pnpm
uses: pnpm/action-setup@v6
with:
version: 10.18.2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 35 - 38, Replace every occurrence of
the GitHub Action usage "uses: pnpm/action-setup@v4" with the current
recommended "uses: pnpm/action-setup@v6" (you can pin to v6.0.5 if desired);
there are three occurrences of "uses: pnpm/action-setup@v4" in the workflow and
you should update all three so each job uses the v6 action, leaving the existing
"with: version: 10.18.2" input unchanged.

Comment on lines +13 to +23
if (discoveryProvider.id !== "disabled") {
const discovery = await discoveryProvider.discoverSources({
researchTopic: question,
maxResults: DEFAULT_DISCOVERY_MAX_RESULTS,
});
if (discovery.kind === "failure") {
ignoredUrls.push({ url: "[source_discovery]", reason: discovery.errorMessage });
} else {
discoveredUrls = discovery.candidates.map((candidate) => candidate.url);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

discoverSources の例外時に調査を継続できるようにしてください。

現在は kind: "failure" のみを処理しており、discoverSources が throw するとこの関数全体が reject して調査フローが中断します。ここも ignoredUrls に記録して継続するのが安全です。

修正例
   let discoveredUrls: string[] = [];
   if (discoveryProvider.id !== "disabled") {
-    const discovery = await discoveryProvider.discoverSources({
-      researchTopic: question,
-      maxResults: DEFAULT_DISCOVERY_MAX_RESULTS,
-    });
-    if (discovery.kind === "failure") {
-      ignoredUrls.push({ url: "[source_discovery]", reason: discovery.errorMessage });
-    } else {
-      discoveredUrls = discovery.candidates.map((candidate) => candidate.url);
-    }
+    try {
+      const discovery = await discoveryProvider.discoverSources({
+        researchTopic: question,
+        maxResults: DEFAULT_DISCOVERY_MAX_RESULTS,
+      });
+      if (discovery.kind === "failure") {
+        ignoredUrls.push({ url: "[source_discovery]", reason: discovery.errorMessage });
+      } else {
+        discoveredUrls = discovery.candidates.map((candidate) => candidate.url);
+      }
+    } catch (error) {
+      ignoredUrls.push({
+        url: "[source_discovery]",
+        reason: error instanceof Error ? error.message : String(error),
+      });
+    }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (discoveryProvider.id !== "disabled") {
const discovery = await discoveryProvider.discoverSources({
researchTopic: question,
maxResults: DEFAULT_DISCOVERY_MAX_RESULTS,
});
if (discovery.kind === "failure") {
ignoredUrls.push({ url: "[source_discovery]", reason: discovery.errorMessage });
} else {
discoveredUrls = discovery.candidates.map((candidate) => candidate.url);
}
}
if (discoveryProvider.id !== "disabled") {
try {
const discovery = await discoveryProvider.discoverSources({
researchTopic: question,
maxResults: DEFAULT_DISCOVERY_MAX_RESULTS,
});
if (discovery.kind === "failure") {
ignoredUrls.push({ url: "[source_discovery]", reason: discovery.errorMessage });
} else {
discoveredUrls = discovery.candidates.map((candidate) => candidate.url);
}
} catch (error) {
ignoredUrls.push({
url: "[source_discovery]",
reason: error instanceof Error ? error.message : String(error),
});
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server/analysis/source-intake/source-intake-service.ts` around lines 13 -
23, discoverSources
の呼び出しが例外を投げると処理全体が中断してしまうので、discoveryProvider.discoverSources(...) を try/catch
で囲み、例外発生時は ignoredUrls に { url: "[source_discovery]", reason: error.message ||
String(error) } を push して discoveredUrls の更新をスキップし処理を継続するように修正してください(参照箇所:
discoveryProvider, discoverSources, ignoredUrls, discoveredUrls,
DEFAULT_DISCOVERY_MAX_RESULTS, question)。

@sasazaki1994 sasazaki1994 merged commit 7d991eb into main May 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant