@pinfix/plugin 0.1.0 → 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ <div align="center">
2
+ <h1>PinFix</h1>
3
+ <p><em>Edit frontend pages like leaving comments on a design.</em></p>
4
+ <p>
5
+ Click any UI, describe what you want to change, and PinFix lets Claude Code precisely find the source code and apply the edit in real time.<br>
6
+ No context switching. No copy-pasting file paths. Just point, describe, and see HMR apply the change.
7
+ </p>
8
+ </div>
9
+
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/@pinfix/plugin"><img src="https://img.shields.io/npm/v/%40pinfix%2Fplugin?label=version&style=flat-square&color=0070ea" alt="Version"></a>
12
+ <img src="https://img.shields.io/badge/Vite-8-646CFF?style=flat-square&logo=vite&logoColor=white" alt="Vite">
13
+ <img src="https://img.shields.io/badge/Webpack-5-8DD6F9?style=flat-square&logo=webpack&logoColor=black" alt="Webpack">
14
+ <img src="https://img.shields.io/badge/Rspack-2-FF6600?style=flat-square&logo=rspack&logoColor=white" alt="Rspack">
15
+ </p>
16
+
17
+ <p align="center">
18
+ <a href="./README_ZH.md">中文</a>
19
+ </p>
20
+
21
+ ## Why PinFix?
22
+
23
+ Traditional Claude Code workflows require you to explain *where* in the codebase something needs to change. PinFix flips this — you visually select the element in the browser, and it already knows the exact source file, line, and column. Your conversation starts with full context.
24
+
25
+ - **Visual Selection** — Alt+Shift+Z activates crosshair mode. Hover to highlight, click to pin.
26
+ - **Multi-turn Chat** — Each pin opens a chat dialog. All pins share a workspace-level Claude Code session, supporting multi-turn conversations with full project context.
27
+ - **Real-time Edits** — Claude Code modifies your source files directly. HMR applies changes instantly.
28
+ - **Framework Agnostic** — Works with React, Vue, Svelte, or any JSX/TSX-based framework.
29
+ - **Zero Config** — One plugin line in your build config. The channel server spawns and cleans up automatically.
30
+
31
+ ## Quick Start
32
+
33
+ ```bash
34
+ npm install -D @pinfix/plugin
35
+ ```
36
+
37
+ Add the plugin to your build config:
38
+
39
+ **Vite**
40
+ ```ts
41
+ // vite.config.ts
42
+ import pinfix from '@pinfix/plugin/vite'
43
+
44
+ export default defineConfig({
45
+ plugins: [pinfix()]
46
+ })
47
+ ```
48
+
49
+ **Webpack**
50
+ ```ts
51
+ // webpack.config.js
52
+ import pinfix from '@pinfix/plugin/webpack'
53
+
54
+ export default {
55
+ plugins: [pinfix()]
56
+ }
57
+ ```
58
+
59
+ **Rspack / Rsbuild**
60
+ ```ts
61
+ // rsbuild.config.ts
62
+ import pinfix from '@pinfix/plugin/rspack'
63
+
64
+ export default {
65
+ tools: {
66
+ rspack: { plugins: [pinfix()] }
67
+ }
68
+ }
69
+ ```
70
+
71
+ Then start your dev server as usual. PinFix activates automatically in development mode.
72
+
73
+ ## Usage
74
+
75
+ 1. Start your dev server (`npm run dev`)
76
+ 2. Press **Alt + Shift + Z** (Option + Shift + Z on Mac) to enter annotation mode
77
+ 3. Hover over any component — it highlights with a blue border
78
+ 4. Click to place a pin on the element
79
+ 5. Type your change request in the chat dialog
80
+ 6. Claude Code streams a response and edits your source code
81
+ 7. HMR applies the change — see the result immediately
82
+ 8. Continue the conversation for iterative refinements
83
+
84
+ ## How It Works
85
+
86
+ ```
87
+ ┌─────────────────┐ WebSocket ┌─────────────────┐ Claude Agent SDK
88
+ │ Browser Client │ ◄──────────────────────► │ Channel Server │ ◄─────────────────────► Claude Code
89
+ │ (Shadow DOM) │ port 24816 │ (auto-spawned) │
90
+ └─────────────────┘ └─────────────────┘
91
+ ```
92
+
93
+ 1. **Build plugin** transforms your JSX/TSX/Vue files to inject `data-pinfix-source` attributes with file path, line, and column metadata.
94
+ 2. **Client overlay** renders inside Shadow DOM — isolated from your app's styles. Handles pin placement, chat UI, and WebSocket communication.
95
+ 3. **Channel server** spawns automatically alongside your dev server. All pins share a workspace-level Claude Code session with full project context.
96
+
97
+ ## Configuration
98
+
99
+ ```ts
100
+ pinfix({
101
+ port: 24816, // WebSocket port (default: 24816)
102
+ hotkey: 'alt+shift+z', // Activation hotkey
103
+ fab: true, // Show floating action button
104
+ prompt: 'Custom system prompt...', // Additional context for Claude Code
105
+ escapeTags: ['Layout', 'Provider'], // Skip these wrapper components
106
+ match: /\.(tsx|jsx|vue)$/, // Only transform matching files
107
+ exclude: /node_modules/, // Exclude from transform
108
+ debug: false, // Enable debug logging
109
+ })
110
+ ```
111
+
112
+ ## Supported Bundlers
113
+
114
+ | Bundler | Import Path | Status |
115
+ |---------|-------------|--------|
116
+ | Vite 5+ | `@pinfix/plugin/vite` | Stable |
117
+ | Webpack 5 | `@pinfix/plugin/webpack` | Stable |
118
+ | Rspack 2 | `@pinfix/plugin/rspack` | Stable |
119
+
120
+ ## Requirements
121
+
122
+ - Node.js 18+
123
+ - Claude Code installed and usable on your machine
124
+ - A dev server with HMR support
125
+
126
+ ## Development
127
+
128
+ ```bash
129
+ git clone https://github.com/foreversc/pinfix.git
130
+ cd pinfix
131
+ pnpm install
132
+ pnpm build
133
+ pnpm dev:vite-react # Run the Vite + React example
134
+ ```
135
+
136
+ ## License
137
+
138
+ MIT
@@ -7723,10 +7723,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
7723
7723
  const pressed = /* @__PURE__ */ new Set();
7724
7724
  const onKeyDown = (e) => {
7725
7725
  pressed.add(normalizeHotkeyEvent(e));
7726
- if (isHotkeyPressed(keys, pressed) && !active) {
7727
- active = true;
7728
- document.body.style.cursor = "crosshair";
7729
- if (fabEl) fabEl.classList.add("active");
7726
+ if (isHotkeyPressed(keys, pressed)) {
7727
+ e.preventDefault();
7728
+ e.stopPropagation();
7729
+ if (!active) {
7730
+ active = true;
7731
+ document.body.style.cursor = "crosshair";
7732
+ if (fabEl) fabEl.classList.add("active");
7733
+ }
7730
7734
  }
7731
7735
  };
7732
7736
  const onKeyUp = (e) => {
@@ -7822,14 +7826,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
7822
7826
  hideHighlight();
7823
7827
  }
7824
7828
  };
7825
- document.addEventListener("keydown", onKeyDown);
7826
- document.addEventListener("keyup", onKeyUp);
7829
+ document.addEventListener("keydown", onKeyDown, { capture: true });
7830
+ document.addEventListener("keyup", onKeyUp, { capture: true });
7827
7831
  document.addEventListener("mousemove", onMouseMove);
7828
7832
  document.addEventListener("click", onClick, { capture: true });
7829
7833
  window.addEventListener("blur", onBlur);
7830
7834
  cleanupFns.push(() => {
7831
- document.removeEventListener("keydown", onKeyDown);
7832
- document.removeEventListener("keyup", onKeyUp);
7835
+ document.removeEventListener("keydown", onKeyDown, true);
7836
+ document.removeEventListener("keyup", onKeyUp, true);
7833
7837
  document.removeEventListener("mousemove", onMouseMove);
7834
7838
  document.removeEventListener("click", onClick, true);
7835
7839
  window.removeEventListener("blur", onBlur);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinfix/plugin",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "Visual UI annotation overlay for Claude Code-powered source editing in dev servers.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -62,7 +62,8 @@
62
62
  "@pinfix/shared": "0.1.0"
63
63
  },
64
64
  "files": [
65
- "dist"
65
+ "dist",
66
+ "README.md"
66
67
  ],
67
68
  "scripts": {
68
69
  "build": "tsup",