Skip to content

Commit c4d0559

Browse files
committed
feat: add CLAUDE.md and ai-prompts module for centralized prompt management
1 parent bc53a43 commit c4d0559

1 file changed

Lines changed: 207 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
---
6+
7+
## What CodeLedger Is
8+
9+
A **Manifest V3 browser extension** (Chrome + Firefox) that automatically commits solved DSA problems from LeetCode, GeeksForGeeks, and Codeforces to a user-owned GitHub repository. Backed by a **Cloudflare Worker** (Hono) that handles GitHub OAuth and serves the landing page.
10+
11+
- **Domain:** `codeledger.vkrishna04.me`
12+
- **Auth worker:** `https://codeledger.vkrishna04.me/api`
13+
- **Extension root:** `src/` — this is the directory loaded unpacked in Chrome
14+
- **Stack:** Pure ES6 modules, no bundler, no transpiler. Preact + htm from CDN. Tailwind CSS for the compiled stylesheet only.
15+
16+
---
17+
18+
## Commands
19+
20+
### Extension development
21+
```bash
22+
npm install
23+
npm run build:css # Tailwind → src/ui/styles/compiled.css (run after CSS changes)
24+
npm run build # CSS + dist packaging
25+
npm run watch # rebuild on file changes (dev mode)
26+
npm run lint # tsc --noEmit (type-check only, no transpile)
27+
```
28+
29+
Load the extension unpacked from `src/` in `chrome://extensions`.
30+
31+
### Worker (Cloudflare)
32+
```bash
33+
cd worker && npm install
34+
npx wrangler dev # local dev (requires wrangler.toml with secrets)
35+
npx wrangler deploy # deploy to production
36+
cd .. && npm run deploy:worker # shorthand from root
37+
```
38+
39+
`worker/wrangler.toml` is git-ignored — create it from the template in `CODELEDGER_EXECUTION_GUIDE.md`.
40+
41+
### Dev utilities
42+
```bash
43+
node dev/generate-manifest-domains.js # regenerates host_permissions from dom-selectors DOMAINS exports
44+
node dev/build-canonical-map.js # validate data/canonical-map.json against schema
45+
node dev/package-chrome.js # produce codeledger-chrome-vX.zip
46+
node dev/package-firefox.js # produce codeledger-firefox-vX.zip
47+
node dev/import-profile/leetcode-importer.js --github-token=TOKEN --repo=owner/repo
48+
node dev/import-profile/gfg-importer.js --github-token=TOKEN --repo=owner/repo
49+
```
50+
51+
### Smoke test (post-deploy)
52+
```bash
53+
curl -sf https://codeledger.vkrishna04.me/api/health
54+
```
55+
56+
---
57+
58+
## Architecture
59+
60+
### Extension layers (all in `src/`)
61+
62+
```
63+
manifest.json
64+
├── background/service-worker.js — SW: init, event bus, handles problem:solved
65+
│ ├── git-engine.js — atomic GitHub Tree API commits
66+
│ ├── sync-engine.js — cross-device sync via repo index.json
67+
│ └── alarm-manager.js — chrome.alarms for reminders/sync
68+
├── content/handler-loader.js — matches hostname → dynamically imports platform handler
69+
│ ├── heartbeat.js — SW keepalive port
70+
│ └── presence-marker.js — injects #codeledger-present on landing page
71+
├── handlers/
72+
│ ├── _base/BasePlatformHandler.js — safeQuery(), MutationObserver lifecycle
73+
│ ├── platforms/{leetcode,geeksforgeeks,codeforces}/index.js
74+
│ ├── ai/{gemini,openai,claude,deepseek,ollama}/index.js
75+
│ └── git/{github,gitlab,bitbucket}/index.js
76+
├── core/
77+
│ ├── constants.js — SINGLE SOURCE OF TRUTH for all URLs, keys, storage key names
78+
│ ├── storage.js — unified storage abstraction (wraps browser-compat)
79+
│ ├── event-bus.js — typed pub/sub (problem:solved → service-worker)
80+
│ ├── canonical-mapper.js — resolves platform problem → canonical ID
81+
│ └── ai-prompts.js — prompt templates + normalizeAIPrompts()
82+
├── lib/
83+
│ ├── browser-compat.js — THE ONLY FILE that uses chrome.* or browser.*
84+
│ └── debug.js — createDebugger() with console.bind() trick
85+
└── ui/components/SettingsSchema.js — schema-driven settings renderer (Preact + htm)
86+
```
87+
88+
### Data flow for a solve event
89+
1. Content script (`handler-loader.js`) → imports platform handler → calls `handler.init()`
90+
2. Platform handler detects accepted submission (DOM / GraphQL / REST)
91+
3. Fires `eventBus.emit("problem:solved", data)` → caught by service-worker
92+
4. SW saves to IndexedDB, optionally calls AI review, then calls `git-engine.js`
93+
5. `git-engine.js` calls GitHub Tree API for a single atomic commit
94+
95+
### Cloudflare Worker (`worker/src/index.js`)
96+
- Built with **Hono** framework
97+
- Routes: `/api/health`, `/api/auth/github`, `/api/auth/github/callback`, `/api/webhook/github`, `/api/admin/canonical`, `/api/data/canonical-map.json`
98+
- Serves static landing page from `worker/public/`
99+
- OAuth callback posts `{ type: 'CODELEDGER_AUTH', provider, token }` — the extension listens for exactly this message type
100+
101+
### Library / Web App (`src/library/`)
102+
- Shared HTML + Preact components used both inside the extension sidebar and at `codeledger.vkrishna04.me/library`
103+
- Auto-detects context: `IS_EXTENSION = !!chrome.runtime?.id`
104+
- Extension mode: reads IndexedDB; Web app mode: reads GitHub API via OAuth token
105+
106+
---
107+
108+
## Critical Rules
109+
110+
### Never use `chrome.*` or `browser.*` directly
111+
All extension API calls must go through `src/lib/browser-compat.js`. This is the only file that touches those namespaces.
112+
113+
### Never use `console.log` directly
114+
Use `createDebugger('HandlerName')` from `src/lib/debug.js`. The `.bind()` trick preserves caller file+line in DevTools.
115+
116+
```js
117+
import { createDebugger } from '../../lib/debug.js';
118+
const dbg = createDebugger('MyHandler');
119+
dbg.log('message'); // shows at the correct source location in DevTools
120+
```
121+
122+
### Import paths from extension pages
123+
The extension root is `src/`. `chrome.runtime.getURL('handlers/...')` — no `src/` prefix in the path. This is a common bug source.
124+
125+
### UI: Preact + htm, no build step
126+
All UI files import Preact and htm from `https://esm.sh`. No JSX. No webpack. No transpilation. Every UI file starts with:
127+
```js
128+
import { h, render } from '../../vendor/preact-bundle.js';
129+
import { useState, useEffect } from '../../vendor/preact-bundle.js';
130+
import { htm } from '../../vendor/preact-bundle.js';
131+
const html = htm.bind(h);
132+
```
133+
`src/vendor/preact-bundle.js` is a CDN re-export shim — all UI files import from this single path.
134+
135+
### OAuth message contract
136+
Worker posts: `{ type: 'CODELEDGER_AUTH', provider: 'github', token: '...' }`
137+
Extension listens for exactly `data.type === 'CODELEDGER_AUTH'`. Any mismatch silently drops the token.
138+
139+
### Token storage paths
140+
- OAuth tokens: `Storage.setAuthToken(provider, token)` → stored at `auth.tokens`
141+
- AI API keys: `Storage.setAIKeys(map)` → stored at `ai.keys`
142+
- Manual PAT: `settings['github_token']`
143+
- `GitHubHandler.getToken()` checks OAuth path first, then settings PAT — order matters.
144+
145+
---
146+
147+
## Current State (as of CODELEDGER_EXECUTION_GUIDE.md)
148+
149+
The execution guide defines 5 modules of fixes needed. Status of each:
150+
151+
| Module | Problem | Files |
152+
| ------ | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
153+
| M0 | vendor bundles need CDN re-export shims | `src/vendor/preact-bundle.js`, `src/vendor/chart-bundle.js` |
154+
| M1 | Worker: PKCS#1 key bug, wrong postMessage type, missing /api/health | `worker/src/index.js` |
155+
| M2 | `src/core/ai-prompts.js` does not exist → settings page crashes | CREATE `src/core/ai-prompts.js` |
156+
| M3 | handleOAuth saves to wrong storage; getToken() checks wrong order | `src/ui/components/SettingsSchema.js`, `src/handlers/git/github/index.js`, `src/background/service-worker.js` |
157+
| M4 | LeetCode: no debounce, double commits; manifest run_at wrong, WAR too narrow, handler-loader has extra `src/` prefix | `src/handlers/platforms/leetcode/index.js`, `src/manifest.json`, `src/content/handler-loader.js` |
158+
| M5 | `worker/public/config.json` has placeholder GitHub App slug | `worker/public/config.json` |
159+
160+
Apply modules in order M0 → M5. Each has a VERIFY section that must pass before proceeding.
161+
162+
---
163+
164+
## Worker Secrets (Wrangler)
165+
166+
| Secret name | Source |
167+
| ---------------------------------- | ------------------------------------------------------------ |
168+
| `CODELEDGER_GH_APP_PRIVATE_KEY` | PKCS#8 PEM file (convert PKCS#1 with `openssl pkcs8 -topk8`) |
169+
| `CODELEDGER_GH_APP_ID` | GitHub App numeric ID |
170+
| `CODELEDGER_GH_APP_CLIENT_ID` | GitHub App Client ID |
171+
| `CODELEDGER_GH_APP_CLIENT_SECRET` | GitHub App client secret |
172+
| `CODELEDGER_GH_APP_WEBHOOK_SECRET` | `openssl rand -hex 32` |
173+
| `CANONICAL_UPLOAD_TOKEN` | `openssl rand -hex 32` |
174+
| `SESSION_SECRET` | `openssl rand -hex 32` |
175+
176+
---
177+
178+
## Adding a New Platform Handler
179+
180+
1. Create `src/handlers/platforms/{name}/index.js` extending `BasePlatformHandler`
181+
2. Create `dom-selectors.js` with versioned `SELECTORS`, `LEGACY_SELECTORS`, and `DOMAINS` export
182+
3. Create `page-detector.js` with `detectPage()` and `isSolveCapablePage()`
183+
4. Add hostname match in `src/content/handler-loader.js`
184+
5. Run `node dev/generate-manifest-domains.js` to update `manifest.json` host_permissions
185+
6. See `docs/ADDING_PLATFORM_HANDLER.md` for full contract
186+
187+
## Adding a New AI Provider
188+
189+
1. Create `src/handlers/ai/{name}/index.js` extending `BaseAIHandler`
190+
2. Create `model-fetcher.js` that fetches live models (or static list for providers without a models endpoint)
191+
3. Add provider config to `CONSTANTS.AI_PROVIDERS` in `src/core/constants.js`
192+
4. Register settings schema in `src/handlers/init.js`
193+
5. Wire into `ModelSelector.js` `loadModels()` switch
194+
195+
---
196+
197+
## Branch Strategy
198+
199+
Use feature branches off `main`:
200+
- `fix/m0-vendor-bundles` — Module 0 vendor shims
201+
- `fix/m1-worker` — Worker OAuth + health endpoint
202+
- `fix/m2-ai-prompts` — Create ai-prompts.js
203+
- `fix/m3-oauth-wiring` — Token storage + getToken priority
204+
- `fix/m4-leetcode-dedup` — Debounce + manifest + handler-loader
205+
- `fix/m5-config` — Worker config.json slug
206+
207+
Merge each back to `main` after its VERIFY section passes.

0 commit comments

Comments
 (0)