Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/.husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pnpm exec commitlint --edit $1
1 change: 1 addition & 0 deletions .github/.husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pnpm exec lint-staged
76 changes: 76 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: CI

on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
NODE_VERSION: "24"
PNPM_VERSION: "10.20.0"

jobs:
format:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm format:check

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint

typecheck:
name: Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm typecheck

build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
21 changes: 0 additions & 21 deletions .github/workflows/keepalive.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ dist-ssr
.claude
CLAUDE.md
.env-share
LLM_FLOW.md
12 changes: 12 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
**/node_modules
**/dist
**/dist-ssr
**/build
**/.next
**/pnpm-lock.yaml
**/package-lock.json
**/bun.lock
convex-server/convex/_generated
*.log
.env
.env.*
48 changes: 31 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Automate accurate GitHub README maintenance through codebase analysis, commit tr
## ✨ Key Features

### AI-Powered Document Lifecycle

- **Dual-mode pipeline**:
- _Full generation_: Create initial READMEs from repository structure
- _Patch mode_: Update only changed sections using SHA-256 hashing
Expand All @@ -20,6 +21,7 @@ Automate accurate GitHub README maintenance through codebase analysis, commit tr
- Live activity logging with real-time progress streaming

### Core Capabilities

- **GitHub Integration**:
- Webhook-based commit tracking
- Secure OAuth with encrypted token storage
Expand All @@ -42,6 +44,7 @@ Automate accurate GitHub README maintenance through codebase analysis, commit tr
```

**Key Components**:

- **Frontend**: React 19 + Vite 7 SPA with Convex subscriptions
- **Backend**: Express.js 5 API with MongoDB (Mongoose)
- **Workers**: BullMQ/Redis for async AI generation
Expand All @@ -52,15 +55,15 @@ Automate accurate GitHub README maintenance through codebase analysis, commit tr

## 🧰 Tech Stack

| Layer | Technologies |
|---------------|---------------------------------------------------------------------------------------------------|
| **Frontend** | React 19, Next.js, Vite 7, Tailwind CSS 4, Shadcn UI, Convex React Client |
| **Backend** | Node.js 20+, Express 5, Mongoose, pnpm workspace |
| **Workers** | BullMQ 5.76, Redis (IORedis) |
| **Real-time** | Convex 1.39 |
| **Database** | MongoDB (user profiles, logs) |
| **AI** | Google Gemini (1M context), Groq (fallback) |
| **Email** | Resend for transactional communications |
| Layer | Technologies |
| ------------- | ------------------------------------------------------------------------- |
| **Frontend** | React 19, Next.js, Vite 7, Tailwind CSS 4, Shadcn UI, Convex React Client |
| **Backend** | Node.js 20+, Express 5, Mongoose, pnpm workspace |
| **Workers** | BullMQ 5.76, Redis (IORedis) |
| **Real-time** | Convex 1.39 |
| **Database** | MongoDB (user profiles, logs) |
| **AI** | Google Gemini (1M context), Groq (fallback) |
| **Email** | Resend for transactional communications |

---

Expand All @@ -76,6 +79,7 @@ Automate accurate GitHub README maintenance through codebase analysis, commit tr
- 3+ API keys for Gemini and Groq

2. **Setup**

```bash
git clone https://github.com/kaihere14/daemondoc.git
cd daemondoc
Expand All @@ -98,6 +102,7 @@ Automate accurate GitHub README maintenance through codebase analysis, commit tr
### Required Environment Variables

**Backend (server/.env)**:

```env
MONGO_URI=
JWT_SECRET=
Expand All @@ -115,12 +120,14 @@ README_FILE_NAME=README.md
```

**Frontend (client/.env)**:

```env
VITE_BACKEND_URL=http://localhost:3000
VITE_CONVEX_URL=your_convex_deployment_url
```

**SEO Landing (seo-client/.env)**:

```env
NEXT_PUBLIC_APP_URL=https://daemondoc.online
BACKEND_URL=http://localhost:3000
Expand All @@ -131,6 +138,7 @@ BACKEND_URL=http://localhost:3000
## 📡 API Endpoints

### Authentication

| Method | Endpoint | Description |
| ------ | ----------------------- | --------------------- |
| GET | `/auth/github` | Initiate OAuth flow |
Expand All @@ -139,6 +147,7 @@ BACKEND_URL=http://localhost:3000
| DELETE | `/auth/delete` | Delete user account |

### Repository Management

| Method | Endpoint | Description |
| ------ | ------------------------------------ | --------------------------------------------------- |
| GET | `/api/github/getGithubRepos` | List user repositories |
Expand All @@ -148,33 +157,38 @@ BACKEND_URL=http://localhost:3000
| POST | `/api/github/webhookhandler` | Handle GitHub push events |

### System Monitoring
| Method | Endpoint | Description |
| ------ | --------------------------- | ---------------------------------------------- |
| GET | `/api/github/fetchUserLogs` | Retrieve documentation activity logs |
| GET | `/health` | Redis status + uptime |

| Method | Endpoint | Description |
| ------ | --------------------------- | ------------------------------------ |
| GET | `/api/github/fetchUserLogs` | Retrieve documentation activity logs |
| GET | `/health` | Redis status + uptime |

### Admin Operations
| Method | Endpoint | Description |
| ------ | ----------------------------- | ---------------------------------------------- |
| GET | `/api/github/admin/analytics` | Retrieve system-wide analytics (cached) |
| GET | `/api/github/admin/users` | Browse and search all registered users |

| Method | Endpoint | Description |
| ------ | ----------------------------- | --------------------------------------- |
| GET | `/api/github/admin/analytics` | Retrieve system-wide analytics (cached) |
| GET | `/api/github/admin/users` | Browse and search all registered users |

---

## 🚀 Deployment

**1. Backend (Render)**

- Root: Project root directory
- Build: `corepack enable && pnpm install --frozen-lockfile --filter server`
- Start: `pnpm --filter server start`
- Required env vars: All backend variables + public URLs

**2. Frontend (Vercel)**

- Root: `client` directory
- Build: `pnpm run build`
- Env var: `VITE_BACKEND_URL=production_url`

**3. SEO Landing (Vercel)**

- Root: `seo-client` directory
- Env vars:
- `NEXT_PUBLIC_APP_URL=https://daemondoc.online`
Expand Down
22 changes: 21 additions & 1 deletion client/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,28 @@ export default defineConfig([
},
},
rules: {
"no-unused-vars": ["error", { varsIgnorePattern: "^([A-Z_]|motion$)", argsIgnorePattern: "^([A-Z_]|motion$)" }],
"no-unused-vars": [
"error",
{
varsIgnorePattern: "^([A-Z_]|motion$)",
argsIgnorePattern: "^([A-Z_]|motion$)",
},
],
"react-refresh/only-export-components": "warn",
},
},
{
// Pre-existing effect-timing patterns (animation kickoff, data-fetch-on-mount)
// that predate the react-hooks/set-state-in-effect and react-hooks/refs rules.
// Not refactoring behavior here — just acknowledging these as known exceptions.
files: [
"src/components/admin/CountUpNumber.jsx",
"src/hooks/useRepos.js",
"src/components/animate-ui/icons/icon.jsx",
],
rules: {
"react-hooks/set-state-in-effect": "off",
"react-hooks/refs": "off",
},
},
]);
1 change: 0 additions & 1 deletion client/src/components/admin/CountUpNumber.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react/prop-types */
import React from "react";

const CountUpNumber = ({ value, suffix = "", duration = 1100 }) => {
Expand Down
6 changes: 3 additions & 3 deletions client/src/components/animate-ui/icons/activity.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import * as React from "react";
import { motion } from "motion/react";

import { IconWrapper } from "@/components/animate-ui/icons/icon";
import {
getVariants,
useAnimateIconContext,
IconWrapper,
} from "@/components/animate-ui/icons/icon";
} from "@/components/animate-ui/icons/icon-context";

const animations = {
default: {
Expand Down Expand Up @@ -103,4 +103,4 @@ function Activity(props) {
return <IconWrapper icon={IconComponent} {...props} />;
}

export { animations, Activity, Activity as ActivityIcon };
export { Activity, Activity as ActivityIcon };
6 changes: 3 additions & 3 deletions client/src/components/animate-ui/icons/clipboard-check.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import * as React from "react";
import { motion } from "motion/react";

import { IconWrapper } from "@/components/animate-ui/icons/icon";
import {
getVariants,
useAnimateIconContext,
IconWrapper,
} from "@/components/animate-ui/icons/icon";
} from "@/components/animate-ui/icons/icon-context";

const animations = {
default: {
Expand Down Expand Up @@ -102,4 +102,4 @@ function ClipboardCheck(props) {
return <IconWrapper icon={IconComponent} {...props} />;
}

export { animations, ClipboardCheck, ClipboardCheck as ClipboardCheckIcon };
export { ClipboardCheck, ClipboardCheck as ClipboardCheckIcon };
6 changes: 3 additions & 3 deletions client/src/components/animate-ui/icons/disc-3.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import * as React from "react";
import { motion } from "motion/react";

import { IconWrapper } from "@/components/animate-ui/icons/icon";
import {
getVariants,
useAnimateIconContext,
IconWrapper,
} from "@/components/animate-ui/icons/icon";
} from "@/components/animate-ui/icons/icon-context";

const animations = {
default: {
Expand Down Expand Up @@ -86,4 +86,4 @@ function Disc3(props) {
return <IconWrapper icon={IconComponent} {...props} />;
}

export { animations, Disc3, Disc3 as Disc3Icon };
export { Disc3, Disc3 as Disc3Icon };
6 changes: 3 additions & 3 deletions client/src/components/animate-ui/icons/hammer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import * as React from "react";
import { motion } from "motion/react";

import { IconWrapper } from "@/components/animate-ui/icons/icon";
import {
getVariants,
useAnimateIconContext,
IconWrapper,
} from "@/components/animate-ui/icons/icon";
} from "@/components/animate-ui/icons/icon-context";

const animations = {
default: {
Expand Down Expand Up @@ -72,4 +72,4 @@ function Hammer(props) {
return <IconWrapper icon={IconComponent} {...props} />;
}

export { animations, Hammer, Hammer as HammerIcon };
export { Hammer, Hammer as HammerIcon };
Loading
Loading