nextjs-ide-helper 1.0.0 → 1.1.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 CHANGED
@@ -1,25 +1,23 @@
1
- # NextJS Cursor Helper
1
+ # NextJS IDE Helper
2
2
 
3
- A Next.js plugin that automatically adds cursor buttons to React components in development mode, enabling seamless IDE integration and faster development workflow.
3
+ A Next.js plugin that automatically adds IDE buttons to React components in development mode, enabling seamless IDE integration and faster development workflow. Supports Cursor, VS Code, WebStorm, and Atom.
4
4
 
5
5
  ## Features
6
6
 
7
- - 🚀 **Automatic Integration**: Automatically wraps React components with cursor buttons
7
+ - 🚀 **Automatic Integration**: Automatically wraps React components with IDE buttons
8
8
  - 🎯 **Smart Detection**: Only processes components in specified directories
9
- - 🔧 **Zero Configuration**: Works out of the box with sensible defaults
9
+ - 🔧 **Zero Configuration**: Works out of the box with sensible defaults (Cursor as default IDE)
10
10
  - 🏎️ **Development Only**: Only active in development mode, no production overhead
11
11
  - 🎨 **Non-intrusive**: Uses absolute positioning to avoid layout disruption
12
12
  - ⚡ **Hydration Safe**: No SSR/client hydration mismatches
13
13
  - 📱 **TypeScript Support**: Full TypeScript definitions included
14
+ - 🔌 **Multi-IDE Support**: Supports Cursor, VS Code, WebStorm, and Atom
14
15
 
15
16
  ## Installation
16
17
 
17
18
  ```bash
18
- npm install nextjs-cursor-helper --save-dev
19
19
  # or
20
- yarn add nextjs-cursor-helper --dev
21
20
  # or
22
- pnpm add nextjs-cursor-helper --save-dev
23
21
  ```
24
22
 
25
23
  ## Quick Start
@@ -29,36 +27,37 @@ pnpm add nextjs-cursor-helper --save-dev
29
27
  Add the plugin to your `next.config.js`:
30
28
 
31
29
  ```javascript
32
- const withCursorHelper = require('nextjs-cursor-helper');
30
+ const withIdeHelper = require('nextjs-ide-plugin');
33
31
 
34
32
  /** @type {import('next').NextConfig} */
35
33
  const nextConfig = {
36
34
  // your existing config
37
35
  };
38
36
 
39
- module.exports = withCursorHelper()(nextConfig);
37
+ module.exports = withIdeHelper()(nextConfig);
40
38
  ```
41
39
 
42
40
  ### 2. That's it!
43
41
 
44
- All React components in your `src/components` directory will automatically get cursor buttons in development mode.
42
+ All React components in your `src/components` directory will automatically get IDE buttons in development mode (defaults to Cursor IDE).
45
43
 
46
44
  ## Configuration
47
45
 
48
46
  You can customize the plugin behavior:
49
47
 
50
48
  ```javascript
51
- const withCursorHelper = require('nextjs-cursor-helper');
49
+ const withIdeHelper = require('nextjs-ide-plugin');
52
50
 
53
51
  const nextConfig = {
54
52
  // your existing config
55
53
  };
56
54
 
57
- module.exports = withCursorHelper({
55
+ module.exports = withIdeHelper({
58
56
  componentPaths: ['src/components', 'components', 'src/ui'], // directories to scan
59
57
  projectRoot: process.cwd(), // project root directory
60
- importPath: 'nextjs-cursor-helper/withCursorButton', // import path for the HOC
61
- enabled: process.env.NODE_ENV === 'development' // enable/disable
58
+ importPath: 'nextjs-ide-plugin/withIdeButton', // import path for the HOC
59
+ enabled: process.env.NODE_ENV === 'development', // enable/disable
60
+ ideType: 'cursor' // IDE to use: 'cursor', 'vscode', 'webstorm', 'atom'
62
61
  })(nextConfig);
63
62
  ```
64
63
 
@@ -68,21 +67,28 @@ module.exports = withCursorHelper({
68
67
  |--------|------|---------|-------------|
69
68
  | `componentPaths` | `string[]` | `['src/components']` | Directories to scan for React components |
70
69
  | `projectRoot` | `string` | `process.cwd()` | Root directory of your project |
71
- | `importPath` | `string` | `'nextjs-cursor-helper/withCursorButton'` | Import path for the withCursorButton HOC |
70
+ | `importPath` | `string` | `'nextjs-ide-plugin/withIdeButton'` | Import path for the withIdeButton HOC |
72
71
  | `enabled` | `boolean` | `process.env.NODE_ENV === 'development'` | Enable/disable the plugin |
72
+ | `ideType` | `'cursor' \| 'vscode' \| 'webstorm' \| 'atom'` | `'cursor'` | IDE to open files in |
73
73
 
74
74
  ## Manual Usage
75
75
 
76
76
  You can also manually wrap components:
77
77
 
78
78
  ```tsx
79
- import { withCursorButton } from 'nextjs-cursor-helper';
79
+ import { withIdeButton } from 'nextjs-ide-plugin';
80
80
 
81
81
  const MyComponent = () => {
82
82
  return <div>Hello World</div>;
83
83
  };
84
84
 
85
- export default withCursorButton(MyComponent, 'src/components/MyComponent.tsx');
85
+ // Default (Cursor)
86
+ export default withIdeButton(MyComponent, 'src/components/MyComponent.tsx');
87
+
88
+ // With specific IDE
89
+ export default withIdeButton(MyComponent, 'src/components/MyComponent.tsx', {
90
+ ideType: 'vscode'
91
+ });
86
92
  ```
87
93
 
88
94
  ## How It Works
@@ -90,7 +96,7 @@ export default withCursorButton(MyComponent, 'src/components/MyComponent.tsx');
90
96
  1. **Webpack Loader**: The plugin uses a custom webpack loader to transform your React components at build time
91
97
  2. **Automatic Detection**: It scans specified directories for `.tsx` and `.jsx` files
92
98
  3. **Smart Wrapping**: Only wraps components that export a default React component
93
- 4. **Development Only**: The cursor buttons only appear in development mode
99
+ 4. **Development Only**: The IDE buttons only appear in development mode
94
100
  5. **Hydration Safe**: Uses client-side state to prevent SSR/hydration mismatches
95
101
 
96
102
  ## Example
@@ -115,7 +121,7 @@ After (automatically transformed):
115
121
  ```tsx
116
122
  // src/components/Button.tsx (transformed by the plugin)
117
123
  import React from 'react';
118
- import { withCursorButton } from 'nextjs-cursor-helper/withCursorButton';
124
+ import { withIdeButton } from 'nextjs-ide-plugin/withIdeButton';
119
125
 
120
126
  const Button = ({ children, onClick }) => {
121
127
  return (
@@ -125,7 +131,10 @@ const Button = ({ children, onClick }) => {
125
131
  );
126
132
  };
127
133
 
128
- export default withCursorButton(Button, 'src/components/Button.tsx', { projectRoot: '/path/to/project' });
134
+ export default withIdeButton(Button, 'src/components/Button.tsx', {
135
+ projectRoot: '/path/to/project',
136
+ ideType: 'cursor' // defaults to cursor, can be 'vscode', 'webstorm', 'atom'
137
+ });
129
138
  ```
130
139
 
131
140
  ## Troubleshooting
@@ -141,14 +150,19 @@ export default withCursorButton(Button, 'src/components/Button.tsx', { projectRo
141
150
  The plugin is designed to prevent hydration errors, but if you encounter any:
142
151
 
143
152
  1. Make sure you're using the latest version
144
- 2. Check that the 'use client' directive is present in the withCursorButton module
153
+ 2. Check that the 'use client' directive is present in the withIdeButton module
145
154
  3. File an issue with details about your setup
146
155
 
147
- ### Cursor not opening files
156
+ ### IDE not opening files
148
157
 
149
- 1. Ensure you have Cursor IDE installed
158
+ 1. Ensure you have your IDE installed and properly configured
159
+ - **Cursor**: Make sure Cursor IDE is installed
160
+ - **VS Code**: Make sure VS Code is installed and set up to handle `vscode://` links
161
+ - **WebStorm**: Ensure WebStorm is installed and configured
162
+ - **Atom**: Make sure Atom is installed (note: Atom is deprecated)
150
163
  2. Check that the file paths are correct
151
- 3. Verify your browser allows `cursor://` protocol links
164
+ 3. Verify your browser allows protocol links for your IDE
165
+ 4. Try setting the `ideType` option explicitly in your configuration
152
166
 
153
167
  ## Contributing
154
168
 
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { withCursorButton } from './withCursorButton';
2
- export type { WithCursorButtonOptions } from './withCursorButton';
3
- declare const withCursorHelper: any;
4
- export default withCursorHelper;
5
- export { withCursorHelper };
1
+ export { withIdeButton } from './withIdeButton';
2
+ export type { WithIdeButtonOptions } from './withIdeButton';
3
+ declare const withIdeHelper: any;
4
+ export default withIdeHelper;
5
+ export { withIdeHelper };
package/lib/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withCursorHelper = exports.withCursorButton = void 0;
3
+ exports.withIdeHelper = exports.withIdeButton = void 0;
4
4
  // Main exports
5
- var withCursorButton_1 = require("./withCursorButton");
6
- Object.defineProperty(exports, "withCursorButton", { enumerable: true, get: function () { return withCursorButton_1.withCursorButton; } });
5
+ var withIdeButton_1 = require("./withIdeButton");
6
+ Object.defineProperty(exports, "withIdeButton", { enumerable: true, get: function () { return withIdeButton_1.withIdeButton; } });
7
7
  // Next.js plugin
8
- const withCursorHelper = require('./plugin');
9
- exports.withCursorHelper = withCursorHelper;
10
- exports.default = withCursorHelper;
8
+ const withIdeHelper = require('./plugin');
9
+ exports.withIdeHelper = withIdeHelper;
10
+ exports.default = withIdeHelper;
package/lib/loader.js CHANGED
@@ -31,7 +31,7 @@ module.exports = function cursorButtonLoader(source) {
31
31
  }
32
32
 
33
33
  // Check if it's already wrapped
34
- if (source.includes('withCursorButton')) {
34
+ if (source.includes('withIdeButton')) {
35
35
  return source;
36
36
  }
37
37
 
@@ -58,17 +58,17 @@ module.exports = function cursorButtonLoader(source) {
58
58
 
59
59
  if (imports.length === 0) {
60
60
  // No imports found, add at top
61
- const importStatement = `import { withCursorButton } from '${importPath}';\n`;
62
- const wrappedExport = `export default withCursorButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
61
+ const importStatement = `import { withIdeButton } from '${importPath}';\n`;
62
+ const wrappedExport = `export default withIdeButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
63
63
  modifiedSource = importStatement + source.replace(/export\s+default\s+\w+;?/, wrappedExport);
64
64
  } else {
65
65
  const lastImportIndex = source.lastIndexOf(imports[imports.length - 1]) + imports[imports.length - 1].length;
66
66
 
67
67
  // Add import statement
68
- const importStatement = `\nimport { withCursorButton } from '${importPath}';`;
68
+ const importStatement = `\nimport { withIdeButton } from '${importPath}';`;
69
69
 
70
70
  // Replace the export
71
- const wrappedExport = `export default withCursorButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
71
+ const wrappedExport = `export default withIdeButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
72
72
 
73
73
  modifiedSource = source.slice(0, lastImportIndex) +
74
74
  importStatement +
package/lib/plugin.js CHANGED
@@ -5,7 +5,7 @@ const path = require('path');
5
5
  * @typedef {Object} CursorHelperOptions
6
6
  * @property {string[]} [componentPaths=['src/components']] - Paths to scan for React components
7
7
  * @property {string} [projectRoot=process.cwd()] - Root directory of the project
8
- * @property {string} [importPath='nextjs-cursor-helper/withCursorButton'] - Import path for withCursorButton
8
+ * @property {string} [importPath='nextjs-cursor-helper/withIdeButton'] - Import path for withIdeButton
9
9
  * @property {boolean} [enabled=process.env.NODE_ENV === 'development'] - Enable/disable the plugin
10
10
  */
11
11
 
@@ -18,7 +18,7 @@ function withCursorHelper(options = {}) {
18
18
  const defaultOptions = {
19
19
  componentPaths: ['src/components'],
20
20
  projectRoot: process.cwd(),
21
- importPath: 'nextjs-cursor-helper/withCursorButton',
21
+ importPath: 'nextjs-cursor-helper/withIdeButton',
22
22
  enabled: process.env.NODE_ENV === 'development'
23
23
  };
24
24
 
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface WithIdeButtonOptions {
3
+ projectRoot?: string;
4
+ enabled?: boolean;
5
+ ideType?: 'cursor' | 'vscode' | 'webstorm' | 'atom';
6
+ }
7
+ export declare function withIdeButton<T extends object>(WrappedComponent: React.ComponentType<T>, filePath: string, options?: WithIdeButtonOptions): React.FC<T>;
@@ -1,13 +1,28 @@
1
1
  "use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.withCursorButton = withCursorButton;
4
+ exports.withIdeButton = withIdeButton;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const react_1 = require("react");
7
- const CursorButton = ({ filePath, projectRoot }) => {
7
+ const IdeButton = ({ filePath, projectRoot, ideType = 'cursor' }) => {
8
+ const getIdeUrl = (ide, path) => {
9
+ const fullPath = projectRoot ? `${projectRoot}/${path}` : path;
10
+ switch (ide) {
11
+ case 'cursor':
12
+ return `cursor://file${fullPath}`;
13
+ case 'vscode':
14
+ return `vscode://file${fullPath}`;
15
+ case 'webstorm':
16
+ return `webstorm://open?file=${fullPath}`;
17
+ case 'atom':
18
+ return `atom://open?path=${fullPath}`;
19
+ default:
20
+ return `cursor://file${fullPath}`;
21
+ }
22
+ };
8
23
  const handleClick = () => {
9
- const fullPath = projectRoot ? `${projectRoot}/${filePath}` : filePath;
10
- window.open(`cursor://file${fullPath}`, '_blank');
24
+ const url = getIdeUrl(ideType, filePath);
25
+ window.open(url, '_blank');
11
26
  };
12
27
  return ((0, jsx_runtime_1.jsx)("button", { onClick: handleClick, style: {
13
28
  position: 'absolute',
@@ -24,11 +39,11 @@ const CursorButton = ({ filePath, projectRoot }) => {
24
39
  opacity: 0.7,
25
40
  transition: 'opacity 0.2s',
26
41
  fontFamily: 'monospace'
27
- }, onMouseEnter: (e) => (e.currentTarget.style.opacity = '1'), onMouseLeave: (e) => (e.currentTarget.style.opacity = '0.7'), title: `Open ${filePath} in Cursor`, children: "\uD83D\uDCDD" }));
42
+ }, onMouseEnter: (e) => (e.currentTarget.style.opacity = '1'), onMouseLeave: (e) => (e.currentTarget.style.opacity = '0.7'), title: `Open ${filePath} in ${ideType.toUpperCase()}`, children: "\uD83D\uDCDD" }));
28
43
  };
29
- function withCursorButton(WrappedComponent, filePath, options = {}) {
30
- const { projectRoot, enabled = process.env.NODE_ENV === 'development' } = options;
31
- const WithCursorButtonComponent = (props) => {
44
+ function withIdeButton(WrappedComponent, filePath, options = {}) {
45
+ const { projectRoot, enabled = process.env.NODE_ENV === 'development', ideType = 'cursor' } = options;
46
+ const WithIdeButtonComponent = (props) => {
32
47
  const [isClient, setIsClient] = (0, react_1.useState)(false);
33
48
  (0, react_1.useEffect)(() => {
34
49
  setIsClient(true);
@@ -37,8 +52,8 @@ function withCursorButton(WrappedComponent, filePath, options = {}) {
37
52
  if (!enabled || !isClient) {
38
53
  return (0, jsx_runtime_1.jsx)(WrappedComponent, { ...props });
39
54
  }
40
- return ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative' }, children: [(0, jsx_runtime_1.jsx)(CursorButton, { filePath: filePath, projectRoot: projectRoot }), (0, jsx_runtime_1.jsx)(WrappedComponent, { ...props })] }));
55
+ return ((0, jsx_runtime_1.jsxs)("div", { style: { position: 'relative' }, children: [(0, jsx_runtime_1.jsx)(IdeButton, { filePath: filePath, projectRoot: projectRoot, ideType: ideType }), (0, jsx_runtime_1.jsx)(WrappedComponent, { ...props })] }));
41
56
  };
42
- WithCursorButtonComponent.displayName = `withCursorButton(${WrappedComponent.displayName || WrappedComponent.name})`;
43
- return WithCursorButtonComponent;
57
+ WithIdeButtonComponent.displayName = `withIdeButton(${WrappedComponent.displayName || WrappedComponent.name})`;
58
+ return WithIdeButtonComponent;
44
59
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nextjs-ide-helper",
3
- "version": "1.0.0",
4
- "description": "A Next.js plugin that automatically adds cursor buttons to React components for seamless IDE integration",
3
+ "version": "1.1.0",
4
+ "description": "A Next.js plugin that automatically adds IDE buttons to React components for seamless IDE integration. Supports Cursor, VS Code, WebStorm, and Atom.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
@@ -17,6 +17,9 @@
17
17
  "nextjs",
18
18
  "react",
19
19
  "cursor",
20
+ "vscode",
21
+ "webstorm",
22
+ "atom",
20
23
  "ide",
21
24
  "development",
22
25
  "webpack",
@@ -36,10 +39,10 @@
36
39
  },
37
40
  "repository": {
38
41
  "type": "git",
39
- "url": "https://github.com/yourusername/nextjs-cursor-helper.git"
42
+ "url": "https://github.com/yourusername/nextjs-ide-plugin.git"
40
43
  },
41
44
  "bugs": {
42
- "url": "https://github.com/yourusername/nextjs-cursor-helper/issues"
45
+ "url": "https://github.com/yourusername/nextjs-ide-plugin/issues"
43
46
  },
44
- "homepage": "https://github.com/yourusername/nextjs-cursor-helper#readme"
47
+ "homepage": "https://github.com/yourusername/nextjs-ide-plugin#readme"
45
48
  }
package/src/index.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  // Main exports
2
- export { withCursorButton } from './withCursorButton';
3
- export type { WithCursorButtonOptions } from './withCursorButton';
2
+ export { withIdeButton } from './withIdeButton';
3
+ export type { WithIdeButtonOptions } from './withIdeButton';
4
4
 
5
5
  // Next.js plugin
6
- const withCursorHelper = require('./plugin');
7
- export default withCursorHelper;
8
- export { withCursorHelper };
6
+ const withIdeHelper = require('./plugin');
7
+ export default withIdeHelper;
8
+ export { withIdeHelper };
package/src/loader.js CHANGED
@@ -12,7 +12,7 @@ module.exports = function cursorButtonLoader(source) {
12
12
  const {
13
13
  componentPaths = ['src/components'],
14
14
  projectRoot = process.cwd(),
15
- importPath = 'nextjs-cursor-helper/withCursorButton',
15
+ importPath = 'nextjs-cursor-helper/withIdeButton',
16
16
  enabled = process.env.NODE_ENV === 'development'
17
17
  } = options;
18
18
 
@@ -31,7 +31,7 @@ module.exports = function cursorButtonLoader(source) {
31
31
  }
32
32
 
33
33
  // Check if it's already wrapped
34
- if (source.includes('withCursorButton')) {
34
+ if (source.includes('withIdeButton')) {
35
35
  return source;
36
36
  }
37
37
 
@@ -58,17 +58,17 @@ module.exports = function cursorButtonLoader(source) {
58
58
 
59
59
  if (imports.length === 0) {
60
60
  // No imports found, add at top
61
- const importStatement = `import { withCursorButton } from '${importPath}';\n`;
62
- const wrappedExport = `export default withCursorButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
61
+ const importStatement = `import { withIdeButton } from '${importPath}';\n`;
62
+ const wrappedExport = `export default withIdeButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
63
63
  modifiedSource = importStatement + source.replace(/export\s+default\s+\w+;?/, wrappedExport);
64
64
  } else {
65
65
  const lastImportIndex = source.lastIndexOf(imports[imports.length - 1]) + imports[imports.length - 1].length;
66
66
 
67
67
  // Add import statement
68
- const importStatement = `\nimport { withCursorButton } from '${importPath}';`;
68
+ const importStatement = `\nimport { withIdeButton } from '${importPath}';`;
69
69
 
70
70
  // Replace the export
71
- const wrappedExport = `export default withCursorButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
71
+ const wrappedExport = `export default withIdeButton(${componentName}, '${relativePath}', { projectRoot: '${projectRoot}' });`;
72
72
 
73
73
  modifiedSource = source.slice(0, lastImportIndex) +
74
74
  importStatement +
package/src/plugin.js CHANGED
@@ -5,7 +5,7 @@ const path = require('path');
5
5
  * @typedef {Object} CursorHelperOptions
6
6
  * @property {string[]} [componentPaths=['src/components']] - Paths to scan for React components
7
7
  * @property {string} [projectRoot=process.cwd()] - Root directory of the project
8
- * @property {string} [importPath='nextjs-cursor-helper/withCursorButton'] - Import path for withCursorButton
8
+ * @property {string} [importPath='nextjs-cursor-helper/withIdeButton'] - Import path for withIdeButton
9
9
  * @property {boolean} [enabled=process.env.NODE_ENV === 'development'] - Enable/disable the plugin
10
10
  */
11
11
 
@@ -18,7 +18,7 @@ function withCursorHelper(options = {}) {
18
18
  const defaultOptions = {
19
19
  componentPaths: ['src/components'],
20
20
  projectRoot: process.cwd(),
21
- importPath: 'nextjs-cursor-helper/withCursorButton',
21
+ importPath: 'nextjs-cursor-helper/withIdeButton',
22
22
  enabled: process.env.NODE_ENV === 'development'
23
23
  };
24
24
 
@@ -1,15 +1,33 @@
1
1
  'use client';
2
2
  import React, { useState, useEffect } from 'react';
3
3
 
4
- interface CursorButtonProps {
4
+ interface IdeButtonProps {
5
5
  filePath: string;
6
6
  projectRoot?: string;
7
+ ideType?: 'cursor' | 'vscode' | 'webstorm' | 'atom';
7
8
  }
8
9
 
9
- const CursorButton: React.FC<CursorButtonProps> = ({ filePath, projectRoot }) => {
10
+ const IdeButton: React.FC<IdeButtonProps> = ({ filePath, projectRoot, ideType = 'cursor' }) => {
11
+ const getIdeUrl = (ide: string, path: string) => {
12
+ const fullPath = projectRoot ? `${projectRoot}/${path}` : path;
13
+
14
+ switch (ide) {
15
+ case 'cursor':
16
+ return `cursor://file${fullPath}`;
17
+ case 'vscode':
18
+ return `vscode://file${fullPath}`;
19
+ case 'webstorm':
20
+ return `webstorm://open?file=${fullPath}`;
21
+ case 'atom':
22
+ return `atom://open?path=${fullPath}`;
23
+ default:
24
+ return `cursor://file${fullPath}`;
25
+ }
26
+ };
27
+
10
28
  const handleClick = () => {
11
- const fullPath = projectRoot ? `${projectRoot}/${filePath}` : filePath;
12
- window.open(`cursor://file${fullPath}`, '_blank');
29
+ const url = getIdeUrl(ideType, filePath);
30
+ window.open(url, '_blank');
13
31
  };
14
32
 
15
33
  return (
@@ -33,26 +51,27 @@ const CursorButton: React.FC<CursorButtonProps> = ({ filePath, projectRoot }) =>
33
51
  }}
34
52
  onMouseEnter={(e) => (e.currentTarget.style.opacity = '1')}
35
53
  onMouseLeave={(e) => (e.currentTarget.style.opacity = '0.7')}
36
- title={`Open ${filePath} in Cursor`}
54
+ title={`Open ${filePath} in ${ideType.toUpperCase()}`}
37
55
  >
38
56
  📝
39
57
  </button>
40
58
  );
41
59
  };
42
60
 
43
- export interface WithCursorButtonOptions {
61
+ export interface WithIdeButtonOptions {
44
62
  projectRoot?: string;
45
63
  enabled?: boolean;
64
+ ideType?: 'cursor' | 'vscode' | 'webstorm' | 'atom';
46
65
  }
47
66
 
48
- export function withCursorButton<T extends object>(
67
+ export function withIdeButton<T extends object>(
49
68
  WrappedComponent: React.ComponentType<T>,
50
69
  filePath: string,
51
- options: WithCursorButtonOptions = {}
70
+ options: WithIdeButtonOptions = {}
52
71
  ) {
53
- const { projectRoot, enabled = process.env.NODE_ENV === 'development' } = options;
72
+ const { projectRoot, enabled = process.env.NODE_ENV === 'development', ideType = 'cursor' } = options;
54
73
 
55
- const WithCursorButtonComponent: React.FC<T> = (props) => {
74
+ const WithIdeButtonComponent: React.FC<T> = (props) => {
56
75
  const [isClient, setIsClient] = useState(false);
57
76
 
58
77
  useEffect(() => {
@@ -66,13 +85,13 @@ export function withCursorButton<T extends object>(
66
85
 
67
86
  return (
68
87
  <div style={{ position: 'relative' }}>
69
- <CursorButton filePath={filePath} projectRoot={projectRoot} />
88
+ <IdeButton filePath={filePath} projectRoot={projectRoot} ideType={ideType} />
70
89
  <WrappedComponent {...props} />
71
90
  </div>
72
91
  );
73
92
  };
74
93
 
75
- WithCursorButtonComponent.displayName = `withCursorButton(${WrappedComponent.displayName || WrappedComponent.name})`;
94
+ WithIdeButtonComponent.displayName = `withIdeButton(${WrappedComponent.displayName || WrappedComponent.name})`;
76
95
 
77
- return WithCursorButtonComponent;
96
+ return WithIdeButtonComponent;
78
97
  }
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- export interface WithCursorButtonOptions {
3
- projectRoot?: string;
4
- enabled?: boolean;
5
- }
6
- export declare function withCursorButton<T extends object>(WrappedComponent: React.ComponentType<T>, filePath: string, options?: WithCursorButtonOptions): React.FC<T>;