Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .agents/workflows/makro-guncelleme-ajani.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
description: Makroekonomi Haber ve Küresel Veri Sentezi Ajanı
---

# 🤖 "Makro Güncelleme" Otonom İş Akışı

Bu iş akışı (workflow), kilit yabancı (CNBC, WSJ) ve yerli (Bloomberg HT) ekonomi kaynaklarındaki en güncel kırılmaları otomatik olarak tarayıp "Altın, Gümüş, Petro-Dolar ve Jeopolitik" ekseninde sentezleyerek `haber-ajansi` klasörüne yazar.

**🚨 KRİTİK KURAL:** Bilgisayarın terminal (Node/NPM) dünyasında "dış internete bağlanma engeli (DNS/Firewall)" olduğu için asla Terminal tabanlı bir betik (`curl`, `npm install`, `node`) veya Python Kodu yazıp/çalıştırıp internete çıkmaya çalışma! Verileri KESİNLİKLE sadece AI modelinin saf yeteneği olan `read_url_content` veya `browser_subagent` araçlarıyla çek.

## 🎯 Adımlar:

1. Kendi sistemindeki `read_url_content` ve web arama araçlarını kullanarak aşağıdaki ağları tara:
- **WSJ Markets RSS:** `https://feeds.a.dj.com/rss/RSSMarketsMain.xml`
- **CNBC Economy RSS:** `https://search.cnbc.com/rs/search/combinedcms/view.xml?partnerId=wrss01&id=10000664`
- **CoinDesk (Kripto):** `https://www.coindesk.com/arc/outboundfeeds/rss/`
- **Sosyal Medya (X/Twitter):** O günün Ekonomi ve Finans alanında en çok etkileşim alan, trend olan global ve yerel analiz tweetlerini araştır.
- **YouTube (Genel Ekonomi):** O günün en çok izlenen/beğenilen kilit makroekonomi değerlendirme videolarının özetlerini al.
- **🚨 ÖZEL TAKİP (Bloomberg HT Sabah Raporu):** YouTube üzerinden Bloomberg HT kanalının en son "Sabah Raporu" yayınını (videoyu) mutlaka bul ve kaydet.
- **Bloomberg HT Son Dakika:** `https://www.bloomberght.com/sondakika`
- *(Eğer istenirse/seçenek)* **Investing Turkiye Emtia RSS:** `https://tr.investing.com/rss/commodities.rss`

2. Okuduğun ham İngilizce ve Türkçe başlıkları anında çevirip zihninde analiz et. Verileri şu makro kutulara yerleştirerek değerlendir:
- **Altın ve Gümüş'te (🔼, 🔽, ↔️) Trend Yönü** *(Hedge Fon Tavsiyeleri, Merkez Bankası Alımları)*
- **Enerji & Petro-Dolar Radarı** *(Kızıldeniz/Hürmüz Jeopolitiği, 100$ Petrol korkusu)*
- **Kur Savaşları ve Gümrük/Tarifeler** *(Örn: Kahve, Emtia kotaları)*
- **Borsa ve Faiz Paradoksu** *(ABD Russell 2000 Düzeltmeleri, Kredi Daralması, TCMB Rezervleri)*
- **Kripto Varlıklar & Dedolarizasyon** *(Stablecoin'lerin Doların Tahtını Tehdidi ve Bitcoin Hacmi)*

3. Hazırladığın bu yeni analiz sentezini, `write_to_file` aracıyla doğrudan `/Users/oguzkurker/Projects/Makro/haber-ajansi/` dizininin içine, `vX-tam-sentez-[BUGUNUN-TARIHI].md` adıyla kaydet.

4. **[ÇOK KRİTİK] NOTEBOOKLM ENTEGRASYONU:**
İş akışının tüm gücü NotebookLM kütüphanesiyle birleşmelidir. Dosyayı kaydettikten YAPMAN GEREKEN SON İŞLEM:
- `browser_subagent` aracını çalıştırarak Chrome'u aç.
- `notebooklm.google.com` adresine git ve kullanıcının "Küresel Piyasalar: Altın, Petrol..." adlı projesini aç.
- **Oluşturulan yepyeni V4 Sentez Raporunu** NotebookLM'e yeni bir kaynak (Metin/Note) olarak ekle.
- **Bloomberg HT "Sabah Raporu" YouTube linkini** de doğrudan yeni YouTube Kaynağı olarak NotebookLM'e yükle.

5. İşi saniyeler içinde sessizce bitirdikten sonra kullanıcıya güncel NotebookLM raporuyla birlikte haber ver.
2 changes: 2 additions & 0 deletions ATLASIAN/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Buraya API Anahtarınızı girip dosya adını .env olarak kaydedin
GEMINI_API_KEY="AIzaSyXXXXXXXXXXXXXXXXXXXX"
14 changes: 14 additions & 0 deletions ATLASIAN/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "atlasian",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "tsx src/index.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
32 changes: 32 additions & 0 deletions ATLASIAN/src/analyzer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { GoogleGenAI } from "@google/genai";
import * as dotenv from "dotenv";
import { LLM_PROMPT } from "./config";

dotenv.config();

export async function analyzeAndSynthesize(newsText: string): Promise<string> {
const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
throw new Error("❌ GEMINI_API_KEY bulunamadı! Lütfen ATLASIAN/ klasöründe .env dosyası oluşturup içine GEMINI_API_KEY='anahtarınız' şeklinde ekleyin.");
}

// Initialize the official Google Gen AI SDK
const ai = new GoogleGenAI({ apiKey });

// Inject the raw news data into the prompt template
const prompt = LLM_PROMPT.replace("{{NEWS_DATA}}", newsText);

console.log("🧠 ATLASIAN Yapay Zeka (Gemini) verileri sizin için okuyor ve sentezliyor...");

try {
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: prompt,
});

return response.text || "Yapay zeka analiz sonucu üretemedi.";
} catch (e) {
console.error("❌ Sentezleme Hatası (API veya Kota Sınırı):", e);
throw e;
}
}
37 changes: 37 additions & 0 deletions ATLASIAN/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export const RSS_SOURCES = [
{
name: "Wall Street Journal (WSJ) - Piyasalar",
url: "https://feeds.a.dj.com/rss/RSSMarketsMain.xml",
},
{
name: "CNBC - Ekonomi Haberleri",
url: "https://search.cnbc.com/rs/search/combinedcms/view.xml?partnerId=wrss01&id=10000664",
},
{
name: "CoinDesk - Küresel Kripto ve Stablecoin Akışı",
url: "https://www.coindesk.com/arc/outboundfeeds/rss/",
},
{
name: "Yahoo Finance - Dünya ve Emtia",
url: "https://finance.yahoo.com/news/rssindex",
},
{
name: "Investing Türkiye - Finans Akışı",
url: "https://tr.investing.com/rss/news_25.rss",
}
];

export const LLM_PROMPT = `Sen ATLASIAN isimli çok yetenekli bir "Derin Ekonomi / Finans Sentez" botusun.
Aşağıda dünyanın kilit haber ajanslarından (WSJ, CNBC, vb.) son saatlerde düşmüş en güncel başlıklar ve haber metinleri bulunuyor (RSS Feed'lerinden çekildi).

Senin görevin:
1. Bu yabancı kaynaklı haberleri oku ve Türkiye piyasaları dahil olmak üzere küresel ekonomik etkilerini analiz et.
2. Bu haberi daha önceki 'Küresel Yatırım Yönelimi' raporlarımıza uygun (Altın 🔼 , Petrol 🔽, Enflasyon ve Jeopolitik Riskler) kıstaslarına göre sentezle.
3. Bana V3 (Üçüncü Jenerasyon) Küresel Haber & Yabancı Kaynak Sentezi adlı şık, Markdown formatında bir rapor hazırla.
4. Özellikle "Stablecoin kullanımı ve Kripto Varlıkların (Dedolarizasyon)" geleneksel para birimlerini nasıl sarsabileceğine dair verileri mutlaka rapora ekle.

Her önemli çıkarımda trend sembolleri (🔼, 🔽, ↔️) kullanmayı unutma!

İşte Anlık Ham Haber Verisi:
{{NEWS_DATA}}
`;
28 changes: 28 additions & 0 deletions ATLASIAN/src/fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Parser from "rss-parser";
import { RSS_SOURCES } from "./config";

const parser = new Parser();

export async function fetchLatestNews(): Promise<string> {
console.log("🌐 Yabancı kaynaklardan küresel haber akışları taranıyor...");
let combinedNews = "";

for (const source of RSS_SOURCES) {
try {
const feed = await parser.parseURL(source.url);
combinedNews += `\n\n### Kaynak: ${source.name}\n`;
// Fetch top 6 items
const topItems = feed.items.slice(0, 6);
for (const item of topItems) {
// We clean out HTML tags if any
const rawContent = (item.contentSnippet || item.content || item.summary || "").replace(/<[^>]*>?/gm, '');
combinedNews += `- **${item.title}**: ${rawContent} (${item.pubDate})\n`;
}
console.log(`✅ [${source.name}] Başarıyla çekildi. (${topItems.length} haber okundu)`);
} catch (error) {
console.error(`❌ [${source.name}] Çekilemedi: ${(error as Error).message}`);
}
}

return combinedNews;
}
46 changes: 46 additions & 0 deletions ATLASIAN/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { fetchLatestNews } from "./fetcher";
import { analyzeAndSynthesize } from "./analyzer";
import * as fs from "fs";
import * as path from "path";

async function main() {
console.log("🚀 ATLASIAN Küresel Haber & Sentez Ajanı Başlatıldı...\n");
console.log("Veri Hattı: (WSJ, CNBC, Yahoo Finance, Investing Yabancı ve Yerle Kaynakları)\n");

try {
// 1. Haberleri Çek (İngilizce Ham Veriler)
const newsRawData = await fetchLatestNews();
if (!newsRawData.trim()) {
console.warn("Haber verisi çekilemedi. Kaynak bağlantısında bir sorun var.");
return;
}

console.log("---- ÖRNEK HAM YABANCI VERİ (LLM'E GİDECEK OLAN KISIM) ----");
console.log(newsRawData.substring(0, 800) + "\n...\n");
console.log("----------------------------------------------------------\n");

// 2. LLM Analizi (İngilizce -> Türkçe, Raporlama)
const synthesisMarkdown = await analyzeAndSynthesize(newsRawData);

// 3. Dosyaya Yaz (../haber-ajansi/ klasörüne)
const targetDir = path.resolve(__dirname, "../../haber-ajansi");
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}

// Dosya ismi için tarih-saat eklentisi
const now = new Date();
const timestamp = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
const reportPath = path.join(targetDir, `v3-uluslararasi-sentez-${timestamp}.md`);

// Final Kayıt
fs.writeFileSync(reportPath, synthesisMarkdown, "utf8");
console.log(`\n🎉 Küresel Analiz Görevi Tamamlandı! Raporunuz şuraya kaydedildi:\n👉 ${reportPath}`);

} catch (error) {
console.error("\n❌ ATLASIAN Sistem Hatası:", error);
}
}

// Botu Tetikle
main();
13 changes: 13 additions & 0 deletions ATLASIAN/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "node",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"outDir": "./dist"
},
"include": ["src/**/*"]
}
66 changes: 60 additions & 6 deletions apps/cli/src/commands/add-github-action.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import type { AgentBackend, SupportedAgent } from "@expect/agent";
import { highlighter } from "../utils/highlighter";
import { logger } from "../utils/logger";
import { prompts } from "../utils/prompts";
import { type PackageManager, detectNonInteractive, detectPackageManager } from "./init-utils";

interface AddGithubActionOptions {
yes?: boolean;
agent?: AgentBackend;
availableAgents?: readonly SupportedAgent[];
}

const DEV_COMMAND_DEFAULTS: Record<PackageManager, string> = {
Expand Down Expand Up @@ -35,9 +38,37 @@ const INSTALL_COMMANDS: Record<PackageManager, string> = {
vp: "npm ci",
};

const generateWorkflow = (packageManager: PackageManager, devCommand: string, devUrl: string) => {
const GITHUB_ACTION_AGENTS: readonly AgentBackend[] = ["claude", "codex"];

const GITHUB_ACTION_AGENT_LABELS: Record<AgentBackend, string> = {
claude: "Claude",
codex: "Codex",
};

const GITHUB_ACTION_AGENT_SECRETS: Record<AgentBackend, string> = {
claude: "ANTHROPIC_API_KEY",
codex: "OPENAI_API_KEY",
};

const isGithubActionAgent = (agent: SupportedAgent): agent is AgentBackend =>
agent === "claude" || agent === "codex";

const getDefaultGithubActionAgent = (
availableAgents: readonly SupportedAgent[] = [],
): AgentBackend => {
const detectedAgent = availableAgents.find(isGithubActionAgent);
return detectedAgent ?? "claude";
};

const generateWorkflow = (
packageManager: PackageManager,
devCommand: string,
devUrl: string,
agent: AgentBackend,
) => {
const dlx = DLX_COMMANDS[packageManager];
const install = INSTALL_COMMANDS[packageManager];
const secretName = GITHUB_ACTION_AGENT_SECRETS[agent];

const setupSteps = buildSetupSteps(packageManager);

Expand All @@ -52,7 +83,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
env:
ANTHROPIC_API_KEY: \${{ secrets.ANTHROPIC_API_KEY }}
${secretName}: \${{ secrets.${secretName} }}
EXPECT_BASE_URL: "${devUrl}"
steps:
- uses: actions/checkout@v4
Expand All @@ -67,7 +98,7 @@ ${setupSteps}
run: npx wait-on ${devUrl} --timeout 60000

- name: Run expect
run: ${dlx} expect-cli@latest --ci
run: ${dlx} expect-cli@latest --ci --agent ${agent}
`;
};

Expand Down Expand Up @@ -105,12 +136,32 @@ const buildSetupSteps = (packageManager: PackageManager): string => {
export const runAddGithubAction = async (options: AddGithubActionOptions = {}) => {
const nonInteractive = detectNonInteractive(options.yes ?? false);
const packageManager = detectPackageManager();
const defaultAgent = getDefaultGithubActionAgent(options.availableAgents);

let devCommand = DEV_COMMAND_DEFAULTS[packageManager];
let devUrl = DEFAULT_DEV_URL;
let agent = options.agent ?? defaultAgent;

if (!nonInteractive) {
const providerQuestion =
options.agent === undefined
? [
{
type: "select" as const,
name: "agent",
message: "GitHub Actions agent provider:",
initial: GITHUB_ACTION_AGENTS.indexOf(defaultAgent),
choices: GITHUB_ACTION_AGENTS.map((provider) => ({
title: GITHUB_ACTION_AGENT_LABELS[provider],
value: provider,
description: GITHUB_ACTION_AGENT_SECRETS[provider],
})),
},
]
: [];

const responses = await prompts([
...providerQuestion,
{
type: "text",
name: "devCommand",
Expand All @@ -124,6 +175,7 @@ export const runAddGithubAction = async (options: AddGithubActionOptions = {}) =
initial: devUrl,
},
]);
agent = responses.agent || agent;
devCommand = responses.devCommand || devCommand;
devUrl = responses.devUrl || devUrl;
}
Expand All @@ -149,14 +201,16 @@ export const runAddGithubAction = async (options: AddGithubActionOptions = {}) =
}
}

const workflow = generateWorkflow(packageManager, devCommand, devUrl);
const workflow = generateWorkflow(packageManager, devCommand, devUrl, agent);
mkdirSync(workflowDir, { recursive: true });
writeFileSync(workflowPath, workflow);

logger.break();
logger.success("Created .github/workflows/expect.yml");
logger.success(`Created .github/workflows/expect.yml for ${GITHUB_ACTION_AGENT_LABELS[agent]}`);
logger.break();
logger.log(` Add ${highlighter.info("ANTHROPIC_API_KEY")} to your repository secrets:`);
logger.log(
` Add ${highlighter.info(GITHUB_ACTION_AGENT_SECRETS[agent])} to your repository secrets:`,
);
logger.log(
` ${highlighter.dim("Settings → Secrets and variables → Actions → New repository secret")}`,
);
Expand Down
9 changes: 7 additions & 2 deletions apps/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { detectAvailableAgents } from "@expect/agent";
import { detectAvailableAgents, type AgentBackend } from "@expect/agent";
import figures from "figures";
import pc from "picocolors";
import { VERSION } from "../constants";
Expand Down Expand Up @@ -27,6 +27,7 @@ const GLOBAL_INSTALL_COMMANDS: Record<PackageManager, string> = {

interface InitOptions {
yes?: boolean;
agent?: AgentBackend;
}

export const runInit = async (options: InitOptions = {}) => {
Expand Down Expand Up @@ -91,7 +92,11 @@ export const runInit = async (options: InitOptions = {}) => {
}

if (setupGithubAction) {
await runAddGithubAction({ yes: options.yes });
await runAddGithubAction({
yes: options.yes,
agent: options.agent,
availableAgents,
});
}

logger.break();
Expand Down
Loading