initializing the files and the memory bank.

This commit is contained in:
Yusuf İpek
2025-10-05 04:42:47 +03:00
parent 2dddb27902
commit ddda9fb9dd
28 changed files with 467 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
YOUTUBE_LIVE_ID=""
INNERTUBE_API_KEY="" # optional override
INNERTUBE_CLIENT_NAME="" # optional override
INNERTUBE_CLIENT_VERSION="" # optional override
SESSION_SECRET="change-me"
+9
View File
@@ -0,0 +1,9 @@
node_modules
pnpm-lock.yaml
.env.local
.env
.DS_Store
.next
out
dist
coverage
+121
View File
@@ -0,0 +1,121 @@
# Cline's Memory Bank
I am Cline, an expert software engineer with a unique characteristic: my memory resets completely between sessions. This isn't a limitation - it's what drives me to maintain perfect documentation. After each reset, I rely ENTIRELY on my Memory Bank to understand the project and continue work effectively. I MUST read ALL memory bank files at the start of EVERY task - this is not optional.
## Memory Bank Structure
The Memory Bank consists of core files and optional context files, all in Markdown format. Files build upon each other in a clear hierarchy:
flowchart TD
PB[projectbrief.md] --> PC[productContext.md]
PB --> SP[systemPatterns.md]
PB --> TC[techContext.md]
PC --> AC[activeContext.md]
SP --> AC
TC --> AC
AC --> P[progress.md]
### Core Files (Required)
1. `projectbrief.md`
- Foundation document that shapes all other files
- Created at project start if it doesn't exist
- Defines core requirements and goals
- Source of truth for project scope
2. `productContext.md`
- Why this project exists
- Problems it solves
- How it should work
- User experience goals
3. `activeContext.md`
- Current work focus
- Recent changes
- Next steps
- Active decisions and considerations
- Important patterns and preferences
- Learnings and project insights
4. `systemPatterns.md`
- System architecture
- Key technical decisions
- Design patterns in use
- Component relationships
- Critical implementation paths
5. `techContext.md`
- Technologies used
- Development setup
- Technical constraints
- Dependencies
- Tool usage patterns
6. `progress.md`
- What works
- What's left to build
- Current status
- Known issues
- Evolution of project decisions
### Additional Context
Create additional files/folders within memory-bank/ when they help organize:
- Complex feature documentation
- Integration specifications
- API documentation
- Testing strategies
- Deployment procedures
## Core Workflows
### Plan Mode
flowchart TD
Start[Start] --> ReadFiles[Read Memory Bank]
ReadFiles --> CheckFiles{Files Complete?}
CheckFiles -->|No| Plan[Create Plan]
Plan --> Document[Document in Chat]
CheckFiles -->|Yes| Verify[Verify Context]
Verify --> Strategy[Develop Strategy]
Strategy --> Present[Present Approach]
### Act Mode
flowchart TD
Start[Start] --> Context[Check Memory Bank]
Context --> Update[Update Documentation]
Update --> Execute[Execute Task]
Execute --> Document[Document Changes]
## Documentation Updates
Memory Bank updates occur when:
1. Discovering new project patterns
2. After implementing significant changes
3. When user requests with **update memory bank** (MUST review ALL files)
4. When context needs clarification
flowchart TD
Start[Update Process]
subgraph Process
P1[Review ALL Files]
P2[Document Current State]
P3[Clarify Next Steps]
P4[Document Insights & Patterns]
P1 --> P2 --> P3 --> P4
end
Start --> Process
Note: When triggered by **update memory bank**, I MUST review every memory bank file, even if some don't require updates. Focus particularly on activeContext.md and progress.md as they track current state.
REMEMBER: After every memory reset, I begin completely fresh. The Memory Bank is my only link to previous work. It must be maintained with precision and clarity, as my effectiveness depends entirely on its accuracy.
+10
View File
@@ -0,0 +1,10 @@
:root {
color-scheme: dark light;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
background: #0f0f0f;
color: #f5f5f5;
}
+15
View File
@@ -0,0 +1,15 @@
import './globals.css';
import type { ReactNode } from 'react';
export const metadata = {
title: 'YouTube Chat Client',
description: 'High-performance YouTube Live chat dashboard'
};
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
+8
View File
@@ -0,0 +1,8 @@
export default function HomePage() {
return (
<main>
<h1>youtube-client</h1>
<p>Operator dashboard under construction.</p>
</main>
);
}
+3
View File
@@ -0,0 +1,3 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />
+9
View File
@@ -0,0 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
experimental: {
serverActions: true
}
};
module.exports = nextConfig;
+12
View File
@@ -0,0 +1,12 @@
{
"name": "client",
"version": "0.1.0",
"private": true,
"description": "Operator dashboard and overlay UI.",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"jsx": "preserve",
"types": ["next", "next/types/global", "next/image-types/global"],
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"noEmit": true
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": ["node_modules", "dist"]
}
+19
View File
@@ -0,0 +1,19 @@
# Active Context
## Current Focus
- Maintain Memory Bank documentation and scaffold the monorepo structure for the YouTube Live chat client.
- Define onboarding flow for Innertube-based chat ingestion and configuration.
## Recent Decisions
- Switch from official YouTube Data API to Innertube (`youtubei.js`) ingestion to avoid quota issues.
- Use Next.js for operator UI and OBS overlay, with a separate backend worker for polling and realtime events.
- Prefer Server-Sent Events for one-way overlay updates; keep WebSocket option in mind for future enhancements.
## Immediate Next Steps
1. Initialize `pnpm` workspace with `apps/client`, `packages/backend`, and `packages/shared` directories. (Scaffolded.)
2. Configure baseline project files: `package.json`, `pnpm-workspace.yaml`, TS configs, linting setup. (Scaffolded.)
3. Stub backend poller using `youtubei.js` to verify dev scripts once dependencies are installed.
## Open Questions
- How to persist or refresh Innertube context data (visitor data, API key) between sessions for reliability.
- Whether to include optional SQLite persistence from the outset or add once basic flow is working.
+20
View File
@@ -0,0 +1,20 @@
# Product Context
## Why This Project Exists
Live streamers rely on YouTubes default chat panel, which can feel sluggish, cluttered, and unreliable during high-traffic moments. Streamers also need a smoother workflow to feature chat messages inside OBS without manual copy/paste or third-party widgets.
## Target Users
- Primary: Single YouTube streamer operating their own broadcast setup.
- Secondary: Community contributors who want to customize or extend the client for similar use cases.
## User Goals
- Launch the app locally and connect to their live chat with minimal configuration.
- View chat in a fast, filterable interface that highlights new messages clearly.
- Select a message to instantly display in an overlay browser source within OBS.
- Trust that the app will keep running throughout long streams without desync or crashes.
## Experience Principles
- **Performance First:** Avoid lag by batching updates, minimizing re-renders, and offloading work to background processes.
- **Operational Clarity:** Provide clear status indicators for connection health, rate limits, and overlay sync.
- **Low Friction:** Onboarding should consist of OAuth login once and a simple start command.
- **Extensible:** Keep architecture modular so advanced users can add features (moderation tools, multi-stream support) later.
+29
View File
@@ -0,0 +1,29 @@
# Progress Tracker
## Phase 0 Foundations
- [x] Create Memory Bank documentation.
- [x] Scaffold pnpm workspace structure.
- [ ] Commit baseline configs and ensure dev scripts run.
## Phase 1 Core Infrastructure
- [ ] Implement Innertube client bootstrap (retrieve context, manage continuation tokens).
- [ ] Build backend poller with message normalization and rate/error handling.
- [ ] Expose REST+SSE endpoints for chat and overlay delivery.
## Phase 2 Operator Dashboard
- [ ] Implement chat feed UI with filters/search and live updates.
- [ ] Provide message selection controls and status indicators.
- [ ] Handle error states (rate limits, disconnects) gracefully in UI.
## Phase 3 OBS Overlay Experience
- [ ] Create minimal overlay page that consumes SSE stream.
- [ ] Style overlay for readability and ensure quick updates in OBS browser source.
- [ ] Add local preview within dashboard for operator verification.
## Phase 4 Reliability & Polish
- [ ] Add optional persistence (SQLite) and crash recovery.
- [ ] Expand logging/metrics for long-stream observability.
- [ ] Write tests (unit/integration) and contributor documentation.
## Current Status
- Memory Bank established; repository scaffolding in place; backend ingestion stubs pending.
+21
View File
@@ -0,0 +1,21 @@
# Project Brief
## Vision
Build a desktop-operated, open-source YouTube Live chat client that delivers a fast, reliable stream of messages and allows a streamer to spotlight a selected chat message on an OBS-ready overlay.
## Core Requirements
- Mirror chat from a single YouTube Live stream with low latency and high stability.
- Provide an operator dashboard to browse, search, and filter live chat messages.
- Enable one-click selection of a message and broadcast it to an overlay page consumable in OBS.
- Keep setup approachable: clone repo, configure environment variables/OAuth, and run locally.
- Prioritize performance and resilience over advanced user management or multi-stream support.
## Constraints
- Runs on the streamers personal computer; no external hosting assumed.
- No end-user authentication beyond stored YouTube OAuth credentials.
- Must tolerate YouTube API rate limits and intermittent network issues without crashing.
## Success Criteria
- Operator dashboard stays responsive during long streams (>4 hours) without memory leaks.
- Overlay updates within ~1 second of operator selection.
- Project documentation enables others to reproduce setup from scratch.
+18
View File
@@ -0,0 +1,18 @@
# System Patterns
## Architecture Overview
- **Monorepo Layout:** `pnpm` workspaces with `apps/client` (Next.js dashboard + overlay), `packages/backend` (Node ingestion + realtime gateway), `packages/shared` (types, schemas).
- **Data Flow:**
1. Backend worker polls YouTube Live chat through the Innertube (youtubei) API, maintaining continuation tokens.
2. Messages stored in-memory (and optionally SQLite) and emitted over an internal event bus.
3. Client dashboard fetches chat via HTTP (React Query) and pushes selection back via REST.
4. Overlay page listens to Server-Sent Events stream for the currently highlighted message.
- **Realtime Delivery:** SSE chosen for one-directional updates to OBS browser source; can swap to WebSocket if bidirectional control is required later.
- **Configuration:** Environment variables drive stream IDs and optional auth tokens; local secrets persisted in `.env.local` or config files.
## Key Patterns & Practices
- Abstract ingestion behind an interface so alternate providers (official API, headless browser) can be swapped in quickly.
- Cache Innertube visitor data and API keys locally to reduce startup latency and handle rotations gracefully.
- Use Zod schemas in shared package to validate external responses and internal payloads.
- Centralized error reporting/logging with structured logs for monitoring during streams.
- Graceful degradation: exponential backoff on fetch failures, last-known overlay message cached to disk to survive restarts.
+17
View File
@@ -0,0 +1,17 @@
# Tech Context
## Primary Stack
- **Frontend:** Next.js 14 (App Router) + React 18 + TypeScript, styled with Tailwind CSS and optional shadcn/ui components.
- **Backend Worker:** Node.js (Fastify) with `youtubei.js` for Innertube chat ingestion, `better-sqlite3` for persistence, EventEmitter for internal pub/sub.
- **Realtime:** Server-Sent Events for overlay updates; potential future WebSocket support via `ws`.
- **Tooling:** `pnpm` for workspace management, ESLint + Prettier, Zod for schema validation, Vitest/Playwright for testing (to be introduced later).
## Environment & Dependencies
- No official API quota required; ingestion relies on Innertube visitor tokens produced at runtime.
- Required env values: `YOUTUBE_LIVE_ID` (or stream URL), optional overrides for Innertube API key/context if we need to pin versions.
- Local `.env.local` file manages configuration; sample `.env.example` committed for contributors.
## Constraints & Considerations
- Innertube endpoints change occasionally; design ingestion to update keys dynamically and fall back to alternate strategies if responses shift.
- Application expected to run on Windows/macOS/Linux desktops used for streaming; keep dependencies cross-platform and avoid native build steps when possible.
- No external database by default; design backend to operate fully in-process with optional local persistence.
+14
View File
@@ -0,0 +1,14 @@
{
"name": "youtube-client",
"version": "0.1.0",
"private": true,
"description": "High-performance YouTube Live chat client for streamers.",
"license": "MIT",
"packageManager": "[email protected]",
"scripts": {
"dev": "pnpm -r dev",
"build": "pnpm -r build",
"lint": "pnpm -r lint",
"start": "pnpm -r start"
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"name": "backend",
"version": "0.1.0",
"private": true,
"description": "YouTube chat poller and realtime bridge.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"dev": "ts-node src/index.ts",
"build": "tsc -p tsconfig.build.json",
"start": "node dist/index.js",
"lint": "eslint 'src/**/*.{ts,tsx}'"
}
}
+12
View File
@@ -0,0 +1,12 @@
import { bootstrapInnertube, fetchChatBatch } from './ingestion/youtubei';
export async function startBackend() {
console.log('Starting backend worker (youtubei ingestion pending).');
const state = await bootstrapInnertube();
console.log('Initial continuation state', state);
await fetchChatBatch(state);
}
if (require.main === module) {
void startBackend();
}
@@ -0,0 +1,18 @@
export type ContinuationState = {
token: string | null;
apiKey?: string;
};
export async function bootstrapInnertube(): Promise<ContinuationState> {
// TODO: fetch initial visitor data and live chat continuation token via youtubei.js
return { token: null };
}
export async function fetchChatBatch(state: ContinuationState) {
// TODO: use youtubei.js to fetch messages with the provided continuation token
// return both normalized messages and the next continuation token
return {
messages: [],
next: state.token
};
}
+7
View File
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": false
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"module": "CommonJS",
"target": "ES2021",
"noEmit": false
},
"include": ["src"]
}
+14
View File
@@ -0,0 +1,14 @@
{
"name": "shared",
"version": "0.1.0",
"private": true,
"description": "Shared types and schemas.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"dev": "tsc --watch -p tsconfig.json",
"build": "tsc -p tsconfig.json",
"start": "node dist/index.js",
"lint": "eslint 'src/**/*.{ts,tsx}'"
}
}
+6
View File
@@ -0,0 +1,6 @@
export type ChatMessage = {
id: string;
author: string;
text: string;
publishedAt: string;
};
+12
View File
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"module": "ESNext",
"target": "ES2021",
"declaration": true,
"declarationMap": true,
"noEmit": false
},
"include": ["src"]
}
+3
View File
@@ -0,0 +1,3 @@
packages:
- 'apps/*'
- 'packages/*'
+17
View File
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2021",
"module": "ESNext",
"moduleResolution": "Node",
"allowJs": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"strict": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"types": ["node"],
"baseUrl": "."
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"files": [],
"references": [
{ "path": "apps/client" },
{ "path": "packages/backend" },
{ "path": "packages/shared" }
]
}