doppelgangers 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+
3
+ # Get list of staged files before running check
4
+ STAGED_FILES=$(git diff --cached --name-only)
5
+
6
+ # Run the check script (formatting, linting, and type checking)
7
+ echo "Running formatting, linting, and type checking..."
8
+ npm run check
9
+ if [ $? -ne 0 ]; then
10
+ echo "❌ Checks failed. Please fix the errors before committing."
11
+ exit 1
12
+ fi
13
+
14
+ # Restage files that were previously staged and may have been modified by formatting
15
+ for file in $STAGED_FILES; do
16
+ if [ -f "$file" ]; then
17
+ git add "$file"
18
+ fi
19
+ done
20
+
21
+ echo "✅ All pre-commit checks passed!"
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Doppelgangers
2
+
3
+ Find duplicate issues and PRs through embedding visualization. Fetches issues/PRs from a GitHub repo, generates embeddings, and renders an interactive 2D/3D scatter plot where similar items cluster together.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g doppelgangers
9
+ ```
10
+
11
+ Or run directly:
12
+
13
+ ```bash
14
+ npx doppelgangers --repo owner/repo
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ export OPENAI_API_KEY=...
21
+ doppelgangers --repo https://github.com/facebook/react
22
+ ```
23
+
24
+ This will:
25
+ 1. Fetch all open issues and PRs from the repo
26
+ 2. Generate embeddings using OpenAI
27
+ 3. Project them into 2D and 3D using UMAP
28
+ 4. Output `triage.html` with an interactive viewer
29
+
30
+ ## Options
31
+
32
+ ```
33
+ --repo <url|owner/repo> GitHub repository (required)
34
+ --state <state> Item state: open, closed, or all (default: open)
35
+ --type <type> Item type: pr, issue, or all (default: all)
36
+ --output <path> Output path for items JSON (default: prs.json)
37
+ --embeddings <path> Output path for embeddings (default: embeddings.jsonl)
38
+ --html <path> Output path for HTML viewer (default: triage.html)
39
+ --model <model> OpenAI embedding model (default: text-embedding-3-small)
40
+ --batch <n> Batch size for embeddings (default: 100)
41
+ --max-chars <n> Max chars for embedding input (default: 4000)
42
+ --body-chars <n> Max chars for body snippet (default: 2000)
43
+ --neighbors <n> UMAP neighbors (default: 15)
44
+ --min-dist <n> UMAP min distance (default: 0.1)
45
+ --search Include embeddings for semantic search (increases file size)
46
+ ```
47
+
48
+ ## Viewer Features
49
+
50
+ **Filtering:**
51
+ - Toggle PRs and Issues visibility
52
+ - Toggle Open and Closed items
53
+ - Semantic search (requires `--search` flag, prompts for API key)
54
+
55
+ **Selection:**
56
+ - Shift+drag to select (replaces selection)
57
+ - Ctrl/Cmd+Shift+drag to select (adds to selection)
58
+ - Click empty space to deselect
59
+
60
+ **Sidebar Actions:**
61
+ - "Open All" opens all selected items in new tabs (allow popups in browser)
62
+ - "Copy" copies selection as formatted list to clipboard
63
+
64
+ **2D Mode:**
65
+ - Drag to pan
66
+ - Scroll to zoom
67
+ - Ctrl/Cmd+drag to select (adds to selection)
68
+
69
+ **3D Mode:**
70
+ - Drag to rotate
71
+ - Ctrl/Cmd+drag to pan
72
+ - Scroll to zoom
73
+
74
+ **Visual Encoding:**
75
+ - Circles = PRs, Diamonds = Issues
76
+ - Green = Open, Purple = Closed
77
+ - Orange = Selected
78
+
79
+ ## Requirements
80
+
81
+ - Node.js 20+
82
+ - `gh` CLI (authenticated)
83
+ - `OPENAI_API_KEY` environment variable
84
+
85
+ ## License
86
+
87
+ MIT
package/biome.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.5/schema.json",
3
+ "linter": {
4
+ "enabled": true,
5
+ "rules": {
6
+ "recommended": true,
7
+ "style": {
8
+ "noNonNullAssertion": "off",
9
+ "useConst": "error",
10
+ "useNodejsImportProtocol": "off"
11
+ },
12
+ "suspicious": {
13
+ "noExplicitAny": "off"
14
+ }
15
+ }
16
+ },
17
+ "formatter": {
18
+ "enabled": true,
19
+ "formatWithErrors": false,
20
+ "indentStyle": "tab",
21
+ "indentWidth": 3,
22
+ "lineWidth": 120
23
+ },
24
+ "files": {
25
+ "includes": ["src/**/*.ts", "!node_modules", "!dist"]
26
+ }
27
+ }
@@ -0,0 +1,10 @@
1
+ export interface BuildOptions {
2
+ input: string;
3
+ output: string;
4
+ projections: string;
5
+ neighbors: number;
6
+ minDist: number;
7
+ includeEmbeddings: boolean;
8
+ }
9
+ export declare function build(options: BuildOptions): void;
10
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;CAC3B;AA2BD,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAkGjD"}