mirror of
https://github.com/yusufipk/YTChatHub.git
synced 2026-09-11 10:56:17 +00:00
initializing the files and the memory bank.
This commit is contained in:
@@ -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"
|
||||
@@ -0,0 +1,9 @@
|
||||
node_modules
|
||||
pnpm-lock.yaml
|
||||
.env.local
|
||||
.env
|
||||
.DS_Store
|
||||
.next
|
||||
out
|
||||
dist
|
||||
coverage
|
||||
@@ -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.
|
||||
@@ -0,0 +1,10 @@
|
||||
:root {
|
||||
color-scheme: dark light;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: system-ui, sans-serif;
|
||||
background: #0f0f0f;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<main>
|
||||
<h1>youtube-client</h1>
|
||||
<p>Operator dashboard under construction.</p>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
@@ -0,0 +1,9 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
experimental: {
|
||||
serverActions: true
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"]
|
||||
}
|
||||
@@ -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.
|
||||
@@ -0,0 +1,20 @@
|
||||
# Product Context
|
||||
|
||||
## Why This Project Exists
|
||||
Live streamers rely on YouTube’s 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.
|
||||
@@ -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.
|
||||
@@ -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 streamer’s 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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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}'"
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"module": "CommonJS",
|
||||
"target": "ES2021",
|
||||
"noEmit": false
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -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}'"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export type ChatMessage = {
|
||||
id: string;
|
||||
author: string;
|
||||
text: string;
|
||||
publishedAt: string;
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"module": "ESNext",
|
||||
"target": "ES2021",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"noEmit": false
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
packages:
|
||||
- 'apps/*'
|
||||
- 'packages/*'
|
||||
@@ -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": "."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "apps/client" },
|
||||
{ "path": "packages/backend" },
|
||||
{ "path": "packages/shared" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user