feat: retro Claude ekip konsolunu kur

This commit is contained in:
2026-03-16 23:38:15 +03:00
parent 9294028fb2
commit 68d5c2afea
32 changed files with 5207 additions and 0 deletions

153
web/src/lib/teamFeed.js Normal file
View File

@@ -0,0 +1,153 @@
const TEAM_MEMBERS = [
{ id: "mazlum", name: "Mazlum", role: "Team Lead", icon: "🎩" },
{ id: "berkecan", name: "Berkecan", role: "Frontend Developer", icon: "💻" },
{ id: "simsar", name: "Simsar", role: "Backend Developer", icon: "⚙️" },
{ id: "aybuke", name: "Aybuke", role: "UI/UX Designer", icon: "🎨" },
{ id: "ive", name: "Ive", role: "iOS Developer", icon: "📱" },
{ id: "irgatov", name: "Irgatov", role: "Trainee", icon: "☕" }
];
function normalizeSpeaker(value) {
return String(value ?? "")
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.toLowerCase();
}
const memberMap = new Map(TEAM_MEMBERS.map((member) => [normalizeSpeaker(member.name), member]));
function isNoiseLine(line) {
const trimmed = line.trim();
if (!trimmed) {
return true;
}
return [
/^╭|^╰|^│|^─/.test(trimmed),
/^/.test(trimmed),
/^⏵⏵/.test(trimmed),
/^⏺/.test(trimmed),
/^✻|^✽|^✳|^✢|^· /.test(trimmed),
/^Auth conflict:/i.test(trimmed),
/^unset ANTHROPIC_API_KEY/i.test(trimmed),
/^Tips for getting/i.test(trimmed),
/^Recent activity/i.test(trimmed),
/^No recent activity/i.test(trimmed),
/^glm-5/i.test(trimmed),
/^Org$/i.test(trimmed),
/^Press up to edit/i.test(trimmed),
/^Deliberating/i.test(trimmed),
/^Cultivating/i.test(trimmed),
/^Sistem yonlendirmesi:/i.test(trimmed),
/^Hedef kisi:/i.test(trimmed),
/^Yalnizca /i.test(trimmed),
/^Cevap zorunlu/i.test(trimmed),
/^Baska hicbir/i.test(trimmed),
/^Kullanici mesaji:/i.test(trimmed),
/^Takim ici /i.test(trimmed),
/^Her cevap /i.test(trimmed),
/^Etiketsiz cevap /i.test(trimmed),
/^Gecerli ornek:/i.test(trimmed),
/^Kullanici tek bir kisiye/i.test(trimmed),
/^Kullanici tum takima/i.test(trimmed),
/^Her ekip uyesi/i.test(trimmed),
/^Ilk cevap olarak/i.test(trimmed),
/^Bu ilk cevap/i.test(trimmed),
/^\(erkek\)|^\(disi\)/i.test(trimmed)
].some(Boolean);
}
function shouldBreakCurrentEntry(line) {
const trimmed = line.trim();
if (!trimmed) {
return false;
}
return [
isNoiseLine(trimmed),
/^[-=]{4,}$/.test(trimmed),
/^>/.test(trimmed),
/^Kullanici /i.test(trimmed),
/^Mazlum nasilsin\?/i.test(trimmed),
/^[A-Za-zÀ-ÿ]+,/.test(trimmed)
].some(Boolean);
}
function isContinuationLine(line) {
const trimmed = line.trim();
if (!trimmed) {
return true;
}
return [
/^[A-Za-zÀ-ÿ0-9ÇĞİÖŞÜçğıöşü"'`(]/.test(trimmed),
/^[.!?…]/.test(trimmed),
/^💪|^😊|^🚀|^☕|^🎨|^📱/.test(trimmed)
].some(Boolean);
}
function dedupeMessages(messages) {
const seen = new Set();
const result = [];
for (const message of messages) {
const key = `${message.speaker}::${message.text}`;
if (seen.has(key)) {
continue;
}
seen.add(key);
result.push(message);
}
return result;
}
export function parseTeamFeed(chat) {
const entries = [];
let currentEntry = null;
for (const rawLine of String(chat ?? "").split("\n")) {
const line = rawLine.trim();
const speakerMatch = line.match(/^[•*\-⏺]?\s*([A-Za-zÀ-ÿ]+):\s*(.*)$/);
if (speakerMatch) {
const member = memberMap.get(normalizeSpeaker(speakerMatch[1]));
if (!member) {
currentEntry = null;
continue;
}
currentEntry = {
id: `${member.id}_${entries.length}_${Date.now()}`,
speaker: member.name,
text: speakerMatch[2] || ""
};
entries.push(currentEntry);
continue;
}
if (!currentEntry) {
continue;
}
if (shouldBreakCurrentEntry(line)) {
currentEntry = null;
continue;
}
if (!isContinuationLine(line)) {
continue;
}
currentEntry.text = currentEntry.text ? `${currentEntry.text}\n${line}` : line;
}
return TEAM_MEMBERS.map((member) => ({
...member,
messages: dedupeMessages(entries.filter((entry) => entry.speaker === member.name))
}));
}
export { TEAM_MEMBERS };