refactor: restructure to clean architecture

fix: restore ScoringConfig improvements lost in refactor commit

docs: rewrite README and CLAUDE.md to reflect current architecture

code-format

code fixes
This commit is contained in:
Kazuma
2026-06-03 00:02:55 -04:00
parent 19fc052d14
commit cd74497de6
60 changed files with 4610 additions and 796 deletions
+52
View File
@@ -0,0 +1,52 @@
import { YahooClient } from '../market/YahooClient.js';
const NEWS_QUERIES = ['stock market today', 'earnings report', 'market news'];
const MAX_STORIES = 15;
const TICKER_REGEX = /^[A-Z]{1,6}$/;
export class CatalystAnalyst {
constructor() {
this.client = new YahooClient();
}
async run() {
process.stdout.write('🔍 Fetching market news...');
const stories = await this._fetchNews();
const tickers = this._extractTickers(stories);
process.stdout.write(` ${stories.length} stories, ${tickers.length} tickers\n`);
return { tickers, stories };
}
async _fetchNews() {
const seen = new Map();
for (const query of NEWS_QUERIES) {
try {
const { news = [] } = await this.client.yf.search(query, { newsCount: 8, quotesCount: 0 });
for (const s of news) {
if (!seen.has(s.title)) {
seen.set(s.title, {
title: s.title,
publisher: s.publisher,
link: s.link,
relatedTickers: s.relatedTickers ?? [],
});
}
}
} catch {
/* skip failed query */
}
}
return [...seen.values()].slice(0, MAX_STORIES);
}
_extractTickers(stories) {
const tickers = new Set();
for (const { relatedTickers } of stories) {
for (const t of relatedTickers) {
const clean = t.split(':')[0].toUpperCase();
if (TICKER_REGEX.test(clean)) tickers.add(clean);
}
}
return [...tickers];
}
}