rune-grab 0.1.7 → 0.1.9
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 +8 -7
- package/dist/cli.js +47 -16
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
<
|
|
2
|
-
<img src="public/rune-grab.png" alt="rune-grab" width="80"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<h1 align="center">rune-grab</h1>
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img src="public/rune-grab-logo.png" alt="rune-grab" width="80" /><br>
|
|
3
|
+
Rune Grab
|
|
4
|
+
</h1>
|
|
6
5
|
|
|
7
6
|
<p align="center">
|
|
8
7
|
Point at any element. Get the component, file path, and line number. Send it to your AI tool.
|
|
@@ -16,12 +15,12 @@
|
|
|
16
15
|
</p>
|
|
17
16
|
|
|
18
17
|
<p align="center">
|
|
19
|
-
<
|
|
18
|
+
<img src="public/rune-grab.gif" width="720" alt="rune-grab demo" />
|
|
20
19
|
</p>
|
|
21
20
|
|
|
22
21
|
<p align="center">
|
|
23
22
|
Works with React, Vue, Svelte, and plain HTML.<br />
|
|
24
|
-
Supports Vite, Next.js, and Webpack.
|
|
23
|
+
Supports Vite, Next.js, and Webpack.
|
|
25
24
|
</p>
|
|
26
25
|
|
|
27
26
|
---
|
|
@@ -32,6 +31,8 @@
|
|
|
32
31
|
npx rune-grab init
|
|
33
32
|
```
|
|
34
33
|
|
|
34
|
+
This adds a snippet to your app's entry file (e.g. `src/main.tsx`). Make sure it ends up in the file where your app renders. It only loads in development, nothing ships to production.
|
|
35
|
+
|
|
35
36
|
Run your dev server and press **Cmd+Shift+G** to start grabbing.
|
|
36
37
|
|
|
37
38
|
## How it works
|
package/dist/cli.js
CHANGED
|
@@ -183,8 +183,8 @@ var iifePath = join2(__dirname, "rune-grab.iife.global.js");
|
|
|
183
183
|
var args = process.argv.slice(2);
|
|
184
184
|
var command = args[0];
|
|
185
185
|
var SNIPPET_VITE = `
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
// rune-grab: dev-only element grabber
|
|
187
|
+
if (import.meta.env.DEV) import('rune-grab');`;
|
|
188
188
|
var SNIPPET_NEXT_APP = `
|
|
189
189
|
{/* rune-grab: dev-only element grabber */}
|
|
190
190
|
{process.env.NODE_ENV === 'development' && <script src="https://unpkg.com/rune-grab/dist/rune-grab.iife.global.js" />}`;
|
|
@@ -196,8 +196,28 @@ var SNIPPET_WEBPACK = `
|
|
|
196
196
|
if (process.env.NODE_ENV === 'development') import('rune-grab');`;
|
|
197
197
|
function detect(cwd) {
|
|
198
198
|
if (existsSync2(join2(cwd, "vite.config.ts")) || existsSync2(join2(cwd, "vite.config.js")) || existsSync2(join2(cwd, "vite.config.mts"))) {
|
|
199
|
-
const
|
|
200
|
-
if (existsSync2(
|
|
199
|
+
const indexHtml = join2(cwd, "index.html");
|
|
200
|
+
if (existsSync2(indexHtml)) {
|
|
201
|
+
const html = readFileSync2(indexHtml, "utf-8");
|
|
202
|
+
const srcMatch = html.match(/src=["']\/?(src\/(?:main|index)\.[tj]sx?)["']/);
|
|
203
|
+
if (srcMatch) {
|
|
204
|
+
const entry = join2(cwd, srcMatch[1]);
|
|
205
|
+
if (existsSync2(entry)) return { framework: "vite", file: entry };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const viteEntries = [
|
|
209
|
+
join2(cwd, "src", "main.tsx"),
|
|
210
|
+
join2(cwd, "src", "main.ts"),
|
|
211
|
+
join2(cwd, "src", "main.jsx"),
|
|
212
|
+
join2(cwd, "src", "main.js"),
|
|
213
|
+
join2(cwd, "src", "index.tsx"),
|
|
214
|
+
join2(cwd, "src", "index.ts"),
|
|
215
|
+
join2(cwd, "src", "index.jsx"),
|
|
216
|
+
join2(cwd, "src", "index.js")
|
|
217
|
+
];
|
|
218
|
+
for (const f of viteEntries) {
|
|
219
|
+
if (existsSync2(f)) return { framework: "vite", file: f };
|
|
220
|
+
}
|
|
201
221
|
}
|
|
202
222
|
if (existsSync2(join2(cwd, "next.config.js")) || existsSync2(join2(cwd, "next.config.mjs")) || existsSync2(join2(cwd, "next.config.ts"))) {
|
|
203
223
|
const appLayouts = [
|
|
@@ -233,11 +253,6 @@ function detect(cwd) {
|
|
|
233
253
|
if (existsSync2(f)) return { framework: "webpack", file: f };
|
|
234
254
|
}
|
|
235
255
|
}
|
|
236
|
-
const indexHtml = join2(cwd, "index.html");
|
|
237
|
-
if (existsSync2(indexHtml)) {
|
|
238
|
-
const content = readFileSync2(indexHtml, "utf-8");
|
|
239
|
-
if (content.includes("import.meta")) return { framework: "vite", file: indexHtml };
|
|
240
|
-
}
|
|
241
256
|
return { framework: "unknown", file: null };
|
|
242
257
|
}
|
|
243
258
|
function alreadyInstalled(content) {
|
|
@@ -268,10 +283,10 @@ function initCommand() {
|
|
|
268
283
|
const { framework, file } = detect(cwd);
|
|
269
284
|
if (framework === "unknown" || !file) {
|
|
270
285
|
console.log("\n Could not detect your framework.\n");
|
|
271
|
-
console.log(" Add this to your
|
|
272
|
-
console.log(
|
|
273
|
-
console.log("
|
|
274
|
-
console.log("
|
|
286
|
+
console.log(" Add this to your app entry file (e.g. src/main.ts, src/index.tsx):\n");
|
|
287
|
+
console.log(" // rune-grab: dev-only element grabber");
|
|
288
|
+
console.log(" if (import.meta.env.DEV) import('rune-grab')\n");
|
|
289
|
+
console.log(" This must go in the file where your app renders, not in index.html.\n");
|
|
275
290
|
return;
|
|
276
291
|
}
|
|
277
292
|
const content = readFileSync2(file, "utf-8");
|
|
@@ -284,8 +299,7 @@ function initCommand() {
|
|
|
284
299
|
let updated;
|
|
285
300
|
switch (framework) {
|
|
286
301
|
case "vite": {
|
|
287
|
-
updated = content
|
|
288
|
-
</body>`);
|
|
302
|
+
updated = content + SNIPPET_VITE + "\n";
|
|
289
303
|
break;
|
|
290
304
|
}
|
|
291
305
|
case "next-app": {
|
|
@@ -314,8 +328,25 @@ function initCommand() {
|
|
|
314
328
|
rune-grab installed for ${label}`);
|
|
315
329
|
console.log(` Modified: ${relative(cwd, file)}`);
|
|
316
330
|
console.log(`
|
|
317
|
-
|
|
331
|
+
Make sure this is the file where your app renders (e.g. main.tsx).`);
|
|
332
|
+
console.log(` If not, move the snippet to the correct entry file.
|
|
318
333
|
`);
|
|
334
|
+
console.log(` Run your dev server and press Cmd+Shift+G to start grabbing.`);
|
|
335
|
+
try {
|
|
336
|
+
const pkgPath = join2(cwd, "package.json");
|
|
337
|
+
if (existsSync2(pkgPath)) {
|
|
338
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
339
|
+
const devScript = pkg.scripts?.dev || "";
|
|
340
|
+
if (devScript && !devScript.includes("rune-grab")) {
|
|
341
|
+
console.log(`
|
|
342
|
+
For auto-paste to Claude, Cursor, or Codex, update your dev script:`);
|
|
343
|
+
console.log(`
|
|
344
|
+
"dev": "rune-grab serve & ${devScript}"`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
} catch {
|
|
348
|
+
}
|
|
349
|
+
console.log("");
|
|
319
350
|
}
|
|
320
351
|
function relative(from, to) {
|
|
321
352
|
if (to.startsWith(from)) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/targets/helper-server.ts","../src/targets/app.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { startHelperServer, DEFAULT_PORT } from './targets/helper-server.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst iifePath = join(__dirname, 'rune-grab.iife.global.js');\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nconst SNIPPET_VITE = `\\n<!-- rune-grab: dev-only element grabber -->\\n<script type=\"module\">if(import.meta.env.DEV)import('rune-grab')</script>`;\n\nconst SNIPPET_NEXT_APP = `\\n{/* rune-grab: dev-only element grabber */}\\n{process.env.NODE_ENV === 'development' && <script src=\"https://unpkg.com/rune-grab/dist/rune-grab.iife.global.js\" />}`;\n\nconst SNIPPET_NEXT_PAGES = `\\n {/* rune-grab: dev-only element grabber */}\\n {process.env.NODE_ENV === 'development' && <script src=\"https://unpkg.com/rune-grab/dist/rune-grab.iife.global.js\" />}`;\n\nconst SNIPPET_WEBPACK = `\\n// rune-grab: dev-only element grabber\\nif (process.env.NODE_ENV === 'development') import('rune-grab');`;\n\ntype Framework = 'vite' | 'next-app' | 'next-pages' | 'webpack' | 'unknown';\n\nfunction detect(cwd: string): { framework: Framework; file: string | null } {\n if (existsSync(join(cwd, 'vite.config.ts')) || existsSync(join(cwd, 'vite.config.js')) || existsSync(join(cwd, 'vite.config.mts'))) {\n const indexHtml = join(cwd, 'index.html');\n if (existsSync(indexHtml)) return { framework: 'vite', file: indexHtml };\n }\n\n if (existsSync(join(cwd, 'next.config.js')) || existsSync(join(cwd, 'next.config.mjs')) || existsSync(join(cwd, 'next.config.ts'))) {\n const appLayouts = [\n join(cwd, 'app', 'layout.tsx'),\n join(cwd, 'app', 'layout.jsx'),\n join(cwd, 'src', 'app', 'layout.tsx'),\n join(cwd, 'src', 'app', 'layout.jsx'),\n ];\n for (const f of appLayouts) {\n if (existsSync(f)) return { framework: 'next-app', file: f };\n }\n\n const pagesDocuments = [\n join(cwd, 'pages', '_document.tsx'),\n join(cwd, 'pages', '_document.jsx'),\n join(cwd, 'src', 'pages', '_document.tsx'),\n join(cwd, 'src', 'pages', '_document.jsx'),\n ];\n for (const f of pagesDocuments) {\n if (existsSync(f)) return { framework: 'next-pages', file: f };\n }\n\n return { framework: 'next-app', file: null };\n }\n\n if (existsSync(join(cwd, 'webpack.config.js')) || existsSync(join(cwd, 'webpack.config.ts'))) {\n const entries = [\n join(cwd, 'src', 'index.tsx'),\n join(cwd, 'src', 'index.ts'),\n join(cwd, 'src', 'index.jsx'),\n join(cwd, 'src', 'index.js'),\n join(cwd, 'src', 'main.tsx'),\n join(cwd, 'src', 'main.ts'),\n ];\n for (const f of entries) {\n if (existsSync(f)) return { framework: 'webpack', file: f };\n }\n }\n\n const indexHtml = join(cwd, 'index.html');\n if (existsSync(indexHtml)) {\n const content = readFileSync(indexHtml, 'utf-8');\n if (content.includes('import.meta')) return { framework: 'vite', file: indexHtml };\n }\n\n return { framework: 'unknown', file: null };\n}\n\nfunction alreadyInstalled(content: string): boolean {\n return content.includes('rune-grab');\n}\n\nfunction detectPackageManager(cwd: string): 'pnpm' | 'yarn' | 'bun' | 'npm' {\n if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';\n if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) return 'bun';\n return 'npm';\n}\n\nfunction installPackage(cwd: string): void {\n if (existsSync(join(cwd, 'node_modules', 'rune-grab'))) return;\n\n const pm = detectPackageManager(cwd);\n const cmd = pm === 'yarn' ? 'yarn add -D rune-grab' : `${pm} install -D rune-grab`;\n\n console.log(`\\n Installing rune-grab with ${pm}...`);\n try {\n execSync(cmd, { cwd, stdio: 'pipe' });\n } catch {\n console.log(` Could not install automatically. Run: ${cmd}\\n`);\n }\n}\n\nfunction initCommand(): void {\n const cwd = process.cwd();\n\n installPackage(cwd);\n\n const { framework, file } = detect(cwd);\n\n if (framework === 'unknown' || !file) {\n console.log('\\n Could not detect your framework.\\n');\n console.log(' Add this to your HTML before </body>:\\n');\n console.log(' <script type=\"module\">');\n console.log(' if (import.meta.env.DEV) import(\\'rune-grab\\')');\n console.log(' </script>\\n');\n return;\n }\n\n const content = readFileSync(file, 'utf-8');\n\n if (alreadyInstalled(content)) {\n console.log(`\\n rune-grab is already set up in ${relative(cwd, file)}\\n`);\n return;\n }\n\n let updated: string;\n\n switch (framework) {\n case 'vite': {\n updated = content.replace('</body>', `${SNIPPET_VITE}\\n</body>`);\n break;\n }\n case 'next-app': {\n updated = content.replace('</body>', `${SNIPPET_NEXT_APP}\\n </body>`);\n break;\n }\n case 'next-pages': {\n if (content.includes('<Main')) {\n updated = content.replace(/<Main\\s*\\/?>/, `$&${SNIPPET_NEXT_PAGES}`);\n } else {\n updated = content.replace('</Head>', `</Head>${SNIPPET_NEXT_PAGES}`);\n }\n break;\n }\n case 'webpack': {\n updated = SNIPPET_WEBPACK + '\\n' + content;\n break;\n }\n default:\n return;\n }\n\n writeFileSync(file, updated, 'utf-8');\n\n const label = framework === 'vite' ? 'Vite'\n : framework === 'next-app' ? 'Next.js (App Router)'\n : framework === 'next-pages' ? 'Next.js (Pages Router)'\n : 'Webpack';\n\n console.log(`\\n rune-grab installed for ${label}`);\n console.log(` Modified: ${relative(cwd, file)}`);\n console.log(`\\n Run your dev server and press Cmd+Shift+G to start grabbing.\\n`);\n}\n\nfunction relative(from: string, to: string): string {\n if (to.startsWith(from)) {\n const rel = to.slice(from.length);\n return rel.startsWith('/') ? rel.slice(1) : rel;\n }\n return to;\n}\n\nfunction uninstallPackage(cwd: string): void {\n const pm = detectPackageManager(cwd);\n const cmd = pm === 'yarn' ? 'yarn remove rune-grab' : `${pm} uninstall rune-grab`;\n\n console.log(`\\n Uninstalling rune-grab with ${pm}...`);\n try {\n execSync(cmd, { cwd, stdio: 'pipe' });\n } catch {\n console.log(` Could not uninstall automatically. Run: ${cmd}\\n`);\n }\n}\n\nfunction removeSnippet(content: string): string {\n const lines = content.split('\\n');\n const result: string[] = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n if (line.includes('rune-grab') && (line.includes('<!--') || line.includes('{/*') || line.includes('//'))) {\n i++;\n while (i < lines.length) {\n const next = lines[i];\n if (next.includes('rune-grab') || next.includes('import(') || next.includes('unpkg.com/rune-grab') || next.includes(\"import('rune-grab')\")) {\n i++;\n continue;\n }\n if (next.trim() === '' && i > 0 && (lines[i - 1].includes('rune-grab') || lines[i - 1].includes('import(') || lines[i - 1].includes('unpkg.com'))) {\n i++;\n continue;\n }\n break;\n }\n continue;\n }\n\n if (line.includes('rune-grab') && (line.includes('import(') || line.includes('import '))) {\n i++;\n continue;\n }\n\n if (line.includes('rune-grab') && line.includes('unpkg.com')) {\n i++;\n continue;\n }\n\n result.push(line);\n i++;\n }\n\n return result.join('\\n');\n}\n\nfunction uninitCommand(): void {\n const cwd = process.cwd();\n const { framework, file } = detect(cwd);\n\n if (!file) {\n console.log('\\n Could not detect your framework setup.');\n console.log(' Remove any rune-grab snippets from your code manually.');\n console.log(' (Search for \"rune-grab\" in your HTML or layout files.)\\n');\n uninstallPackage(cwd);\n return;\n }\n\n const content = readFileSync(file, 'utf-8');\n\n if (!alreadyInstalled(content)) {\n console.log(`\\n No rune-grab snippet found in ${relative(cwd, file)}`);\n uninstallPackage(cwd);\n console.log(' Done.\\n');\n return;\n }\n\n const updated = removeSnippet(content);\n writeFileSync(file, updated, 'utf-8');\n\n console.log(`\\n Removed rune-grab snippet from ${relative(cwd, file)}`);\n uninstallPackage(cwd);\n console.log(' Done.\\n');\n}\n\nfunction printUsage(): void {\n console.log(`\n rune-grab\n\n Usage:\n npx rune-grab init Set up rune-grab in your project\n npx rune-grab remove Remove rune-grab from your project\n npx rune-grab serve [--port PORT] Start the dev server (for auto-paste)\n`);\n}\n\nswitch (command) {\n case 'init':\n initCommand();\n break;\n case 'remove':\n case 'uninit':\n case 'uninstall':\n uninitCommand();\n break;\n case 'serve': {\n const portIdx = args.indexOf('--port');\n const port = portIdx !== -1 ? parseInt(args[portIdx + 1], 10) : DEFAULT_PORT;\n startHelperServer(port, iifePath);\n break;\n }\n default:\n printUsage();\n break;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { execSync } from 'node:child_process';\nimport { writeFileSync, mkdtempSync, rmSync, readFileSync, existsSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { TargetApp } from '../core/types.js';\nimport { APP_NAMES, APP_BUNDLE_IDS } from './app.js';\n\nconst DEFAULT_PORT = 19274;\nlet cachedIIFE: string | null = null;\n\ninterface PasteRequest {\n target: TargetApp;\n text: string;\n image: string | null;\n label: string;\n}\n\nfunction copyText(text: string): void {\n execSync('pbcopy', { input: text, encoding: 'utf-8' });\n}\n\nfunction copyImage(base64DataUrl: string): string {\n const tmpDir = mkdtempSync(join(tmpdir(), 'rune-grab-'));\n const imgPath = join(tmpDir, 'grab.png');\n\n const base64 = base64DataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n writeFileSync(imgPath, Buffer.from(base64, 'base64'));\n\n return imgPath;\n}\n\nfunction activateAndPaste(target: TargetApp): void {\n if (target === 'claude-code') {\n const script = `\n set iTermRunning to false\n tell application \"System Events\"\n if exists (process \"iTerm2\") then set iTermRunning to true\n end tell\n if iTermRunning then\n tell application \"iTerm2\" to activate\n else\n tell application \"Terminal\" to activate\n end if\n delay 0.3\n tell application \"System Events\"\n keystroke \"v\" using command down\n end tell\n `;\n execSync(`osascript -e '${script.replace(/'/g, \"'\\\"'\\\"'\")}'`);\n return;\n }\n\n const bundleId = APP_BUNDLE_IDS[target];\n if (!bundleId) return;\n\n const script = `\n tell application id \"${bundleId}\"\n activate\n end tell\n delay 0.3\n tell application \"System Events\"\n keystroke \"v\" using command down\n end tell\n `;\n execSync(`osascript -e '${script.replace(/'/g, \"'\\\"'\\\"'\")}'`);\n}\n\nfunction parseBody(req: IncomingMessage): Promise<PasteRequest> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => (body += chunk));\n req.on('end', () => {\n try {\n resolve(JSON.parse(body));\n } catch (e) {\n reject(e);\n }\n });\n req.on('error', reject);\n });\n}\n\nfunction setCors(res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n}\n\nfunction loadIIFE(iifePath?: string): string | null {\n if (cachedIIFE) return cachedIIFE;\n if (iifePath && existsSync(iifePath)) {\n cachedIIFE = readFileSync(iifePath, 'utf-8');\n return cachedIIFE;\n }\n return null;\n}\n\nexport function startHelperServer(port = DEFAULT_PORT, iifePath?: string): void {\n loadIIFE(iifePath);\n\n const server = createServer(async (req, res) => {\n setCors(res);\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, version: '0.1.0' }));\n return;\n }\n if (req.method === 'GET' && req.url === '/rune-grab.js') {\n const script = cachedIIFE;\n if (script) {\n res.writeHead(200, { 'Content-Type': 'application/javascript', 'Cache-Control': 'no-cache' });\n res.end(script);\n } else {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'IIFE bundle not found' }));\n }\n return;\n }\n if (req.method === 'POST' && req.url === '/paste') {\n let tmpImgPath: string | null = null;\n try {\n const data = await parseBody(req);\n const { target, text, image } = data;\n\n if (image) {\n tmpImgPath = copyImage(image);\n execSync(`osascript -e 'set the clipboard to (read (POSIX file \"${tmpImgPath}\") as «class PNGf»)'`);\n } else {\n copyText(text);\n }\n\n activateAndPaste(target);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, target, app: APP_NAMES[target] }));\n } catch (e: any) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: e.message }));\n } finally {\n if (tmpImgPath) {\n try { rmSync(tmpImgPath, { recursive: true }); } catch { }\n }\n }\n return;\n }\n\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n });\n\n server.listen(port, '127.0.0.1', () => {\n console.log(`\\n rune-grab running on http://127.0.0.1:${port}`);\n if (cachedIIFE) {\n console.log(` Add this to your HTML:`);\n console.log(` <script src=\"http://localhost:${port}/rune-grab.js\"><\\/script>`);\n }\n console.log(` Auto-paste targets: ${Object.values(APP_NAMES).filter(Boolean).join(', ')}\\n`);\n });\n\n process.on('SIGINT', () => {\n server.close();\n process.exit(0);\n });\n process.on('SIGTERM', () => {\n server.close();\n process.exit(0);\n });\n}\n\nexport { DEFAULT_PORT };\n","import type { GrabResult, TargetApp } from '../core/types.js';\nimport { copyToClipboard } from './clipboard.js';\n\nconst HELPER_PORT = 19274;\n\nasync function isHelperRunning(): Promise<boolean> {\n try {\n const ac = new AbortController();\n const timer = setTimeout(() => ac.abort(), 500);\n const res = await fetch(`http://127.0.0.1:${HELPER_PORT}/health`, {\n signal: ac.signal,\n });\n clearTimeout(timer);\n return res.ok;\n } catch {\n return false;\n }\n}\n\nasync function sendToHelper(target: TargetApp, result: GrabResult): Promise<boolean> {\n try {\n const res = await fetch(`http://127.0.0.1:${HELPER_PORT}/paste`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n target,\n text: result.text,\n image: result.image ?? null,\n label: result.label,\n }),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nexport const APP_BUNDLE_IDS: Record<TargetApp, string> = {\n claude: 'com.anthropic.claudefordesktop',\n cursor: 'com.todesktop.230313mzl4w4u92',\n codex: 'com.openai.codex',\n 'claude-code': '',\n clipboard: '',\n};\n\nexport const APP_NAMES: Record<TargetApp, string> = {\n claude: 'Claude',\n cursor: 'Cursor',\n codex: 'Codex',\n 'claude-code': 'Claude Code',\n clipboard: 'Clipboard',\n};\n\nexport async function sendToApp(target: TargetApp, result: GrabResult): Promise<{ success: boolean; method: 'auto' | 'clipboard' }> {\n await copyToClipboard(result);\n\n if (target === 'clipboard') {\n return { success: true, method: 'clipboard' };\n }\n\n const helperUp = await isHelperRunning();\n if (helperUp) {\n const ok = await sendToHelper(target, result);\n if (ok) return { success: true, method: 'auto' };\n }\n\n return { success: true, method: 'clipboard' };\n}\n\n"],"mappings":"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","names":["join","existsSync","readFileSync","writeFileSync","execSync","script","iifePath","join","existsSync","indexHtml","readFileSync","execSync","writeFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/targets/helper-server.ts","../src/targets/app.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { startHelperServer, DEFAULT_PORT } from './targets/helper-server.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst iifePath = join(__dirname, 'rune-grab.iife.global.js');\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nconst SNIPPET_VITE = `\\n// rune-grab: dev-only element grabber\\nif (import.meta.env.DEV) import('rune-grab');`;\n\nconst SNIPPET_NEXT_APP = `\\n{/* rune-grab: dev-only element grabber */}\\n{process.env.NODE_ENV === 'development' && <script src=\"https://unpkg.com/rune-grab/dist/rune-grab.iife.global.js\" />}`;\n\nconst SNIPPET_NEXT_PAGES = `\\n {/* rune-grab: dev-only element grabber */}\\n {process.env.NODE_ENV === 'development' && <script src=\"https://unpkg.com/rune-grab/dist/rune-grab.iife.global.js\" />}`;\n\nconst SNIPPET_WEBPACK = `\\n// rune-grab: dev-only element grabber\\nif (process.env.NODE_ENV === 'development') import('rune-grab');`;\n\ntype Framework = 'vite' | 'next-app' | 'next-pages' | 'webpack' | 'unknown';\n\nfunction detect(cwd: string): { framework: Framework; file: string | null } {\n if (existsSync(join(cwd, 'vite.config.ts')) || existsSync(join(cwd, 'vite.config.js')) || existsSync(join(cwd, 'vite.config.mts'))) {\n // Find the JS/TS entry file referenced from index.html, or common entry paths\n const indexHtml = join(cwd, 'index.html');\n if (existsSync(indexHtml)) {\n const html = readFileSync(indexHtml, 'utf-8');\n const srcMatch = html.match(/src=[\"']\\/?(src\\/(?:main|index)\\.[tj]sx?)[\"']/);\n if (srcMatch) {\n const entry = join(cwd, srcMatch[1]);\n if (existsSync(entry)) return { framework: 'vite', file: entry };\n }\n }\n const viteEntries = [\n join(cwd, 'src', 'main.tsx'),\n join(cwd, 'src', 'main.ts'),\n join(cwd, 'src', 'main.jsx'),\n join(cwd, 'src', 'main.js'),\n join(cwd, 'src', 'index.tsx'),\n join(cwd, 'src', 'index.ts'),\n join(cwd, 'src', 'index.jsx'),\n join(cwd, 'src', 'index.js'),\n ];\n for (const f of viteEntries) {\n if (existsSync(f)) return { framework: 'vite', file: f };\n }\n }\n\n if (existsSync(join(cwd, 'next.config.js')) || existsSync(join(cwd, 'next.config.mjs')) || existsSync(join(cwd, 'next.config.ts'))) {\n const appLayouts = [\n join(cwd, 'app', 'layout.tsx'),\n join(cwd, 'app', 'layout.jsx'),\n join(cwd, 'src', 'app', 'layout.tsx'),\n join(cwd, 'src', 'app', 'layout.jsx'),\n ];\n for (const f of appLayouts) {\n if (existsSync(f)) return { framework: 'next-app', file: f };\n }\n\n const pagesDocuments = [\n join(cwd, 'pages', '_document.tsx'),\n join(cwd, 'pages', '_document.jsx'),\n join(cwd, 'src', 'pages', '_document.tsx'),\n join(cwd, 'src', 'pages', '_document.jsx'),\n ];\n for (const f of pagesDocuments) {\n if (existsSync(f)) return { framework: 'next-pages', file: f };\n }\n\n return { framework: 'next-app', file: null };\n }\n\n if (existsSync(join(cwd, 'webpack.config.js')) || existsSync(join(cwd, 'webpack.config.ts'))) {\n const entries = [\n join(cwd, 'src', 'index.tsx'),\n join(cwd, 'src', 'index.ts'),\n join(cwd, 'src', 'index.jsx'),\n join(cwd, 'src', 'index.js'),\n join(cwd, 'src', 'main.tsx'),\n join(cwd, 'src', 'main.ts'),\n ];\n for (const f of entries) {\n if (existsSync(f)) return { framework: 'webpack', file: f };\n }\n }\n\n return { framework: 'unknown', file: null };\n}\n\nfunction alreadyInstalled(content: string): boolean {\n return content.includes('rune-grab');\n}\n\nfunction detectPackageManager(cwd: string): 'pnpm' | 'yarn' | 'bun' | 'npm' {\n if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';\n if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) return 'bun';\n return 'npm';\n}\n\nfunction installPackage(cwd: string): void {\n if (existsSync(join(cwd, 'node_modules', 'rune-grab'))) return;\n\n const pm = detectPackageManager(cwd);\n const cmd = pm === 'yarn' ? 'yarn add -D rune-grab' : `${pm} install -D rune-grab`;\n\n console.log(`\\n Installing rune-grab with ${pm}...`);\n try {\n execSync(cmd, { cwd, stdio: 'pipe' });\n } catch {\n console.log(` Could not install automatically. Run: ${cmd}\\n`);\n }\n}\n\nfunction initCommand(): void {\n const cwd = process.cwd();\n\n installPackage(cwd);\n\n const { framework, file } = detect(cwd);\n\n if (framework === 'unknown' || !file) {\n console.log('\\n Could not detect your framework.\\n');\n console.log(' Add this to your app entry file (e.g. src/main.ts, src/index.tsx):\\n');\n console.log(' // rune-grab: dev-only element grabber');\n console.log(' if (import.meta.env.DEV) import(\\'rune-grab\\')\\n');\n console.log(' This must go in the file where your app renders, not in index.html.\\n');\n return;\n }\n\n const content = readFileSync(file, 'utf-8');\n\n if (alreadyInstalled(content)) {\n console.log(`\\n rune-grab is already set up in ${relative(cwd, file)}\\n`);\n return;\n }\n\n let updated: string;\n\n switch (framework) {\n case 'vite': {\n updated = content + SNIPPET_VITE + '\\n';\n break;\n }\n case 'next-app': {\n updated = content.replace('</body>', `${SNIPPET_NEXT_APP}\\n </body>`);\n break;\n }\n case 'next-pages': {\n if (content.includes('<Main')) {\n updated = content.replace(/<Main\\s*\\/?>/, `$&${SNIPPET_NEXT_PAGES}`);\n } else {\n updated = content.replace('</Head>', `</Head>${SNIPPET_NEXT_PAGES}`);\n }\n break;\n }\n case 'webpack': {\n updated = SNIPPET_WEBPACK + '\\n' + content;\n break;\n }\n default:\n return;\n }\n\n writeFileSync(file, updated, 'utf-8');\n\n const label = framework === 'vite' ? 'Vite'\n : framework === 'next-app' ? 'Next.js (App Router)'\n : framework === 'next-pages' ? 'Next.js (Pages Router)'\n : 'Webpack';\n\n console.log(`\\n rune-grab installed for ${label}`);\n console.log(` Modified: ${relative(cwd, file)}`);\n console.log(`\\n Make sure this is the file where your app renders (e.g. main.tsx).`);\n console.log(` If not, move the snippet to the correct entry file.\\n`);\n console.log(` Run your dev server and press Cmd+Shift+G to start grabbing.`);\n\n // Suggest adding rune-grab serve for auto-paste\n try {\n const pkgPath = join(cwd, 'package.json');\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const devScript = pkg.scripts?.dev || '';\n if (devScript && !devScript.includes('rune-grab')) {\n console.log(`\\n For auto-paste to Claude, Cursor, or Codex, update your dev script:`);\n console.log(`\\n \"dev\": \"rune-grab serve & ${devScript}\"`);\n }\n }\n } catch {\n // ignore\n }\n\n console.log('');\n}\n\nfunction relative(from: string, to: string): string {\n if (to.startsWith(from)) {\n const rel = to.slice(from.length);\n return rel.startsWith('/') ? rel.slice(1) : rel;\n }\n return to;\n}\n\nfunction uninstallPackage(cwd: string): void {\n const pm = detectPackageManager(cwd);\n const cmd = pm === 'yarn' ? 'yarn remove rune-grab' : `${pm} uninstall rune-grab`;\n\n console.log(`\\n Uninstalling rune-grab with ${pm}...`);\n try {\n execSync(cmd, { cwd, stdio: 'pipe' });\n } catch {\n console.log(` Could not uninstall automatically. Run: ${cmd}\\n`);\n }\n}\n\nfunction removeSnippet(content: string): string {\n const lines = content.split('\\n');\n const result: string[] = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n if (line.includes('rune-grab') && (line.includes('<!--') || line.includes('{/*') || line.includes('//'))) {\n i++;\n while (i < lines.length) {\n const next = lines[i];\n if (next.includes('rune-grab') || next.includes('import(') || next.includes('unpkg.com/rune-grab') || next.includes(\"import('rune-grab')\")) {\n i++;\n continue;\n }\n if (next.trim() === '' && i > 0 && (lines[i - 1].includes('rune-grab') || lines[i - 1].includes('import(') || lines[i - 1].includes('unpkg.com'))) {\n i++;\n continue;\n }\n break;\n }\n continue;\n }\n\n if (line.includes('rune-grab') && (line.includes('import(') || line.includes('import '))) {\n i++;\n continue;\n }\n\n if (line.includes('rune-grab') && line.includes('unpkg.com')) {\n i++;\n continue;\n }\n\n result.push(line);\n i++;\n }\n\n return result.join('\\n');\n}\n\nfunction uninitCommand(): void {\n const cwd = process.cwd();\n const { framework, file } = detect(cwd);\n\n if (!file) {\n console.log('\\n Could not detect your framework setup.');\n console.log(' Remove any rune-grab snippets from your code manually.');\n console.log(' (Search for \"rune-grab\" in your HTML or layout files.)\\n');\n uninstallPackage(cwd);\n return;\n }\n\n const content = readFileSync(file, 'utf-8');\n\n if (!alreadyInstalled(content)) {\n console.log(`\\n No rune-grab snippet found in ${relative(cwd, file)}`);\n uninstallPackage(cwd);\n console.log(' Done.\\n');\n return;\n }\n\n const updated = removeSnippet(content);\n writeFileSync(file, updated, 'utf-8');\n\n console.log(`\\n Removed rune-grab snippet from ${relative(cwd, file)}`);\n uninstallPackage(cwd);\n console.log(' Done.\\n');\n}\n\nfunction printUsage(): void {\n console.log(`\n rune-grab\n\n Usage:\n npx rune-grab init Set up rune-grab in your project\n npx rune-grab remove Remove rune-grab from your project\n npx rune-grab serve [--port PORT] Start the dev server (for auto-paste)\n`);\n}\n\nswitch (command) {\n case 'init':\n initCommand();\n break;\n case 'remove':\n case 'uninit':\n case 'uninstall':\n uninitCommand();\n break;\n case 'serve': {\n const portIdx = args.indexOf('--port');\n const port = portIdx !== -1 ? parseInt(args[portIdx + 1], 10) : DEFAULT_PORT;\n startHelperServer(port, iifePath);\n break;\n }\n default:\n printUsage();\n break;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { execSync } from 'node:child_process';\nimport { writeFileSync, mkdtempSync, rmSync, readFileSync, existsSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { TargetApp } from '../core/types.js';\nimport { APP_NAMES, APP_BUNDLE_IDS } from './app.js';\n\nconst DEFAULT_PORT = 19274;\nlet cachedIIFE: string | null = null;\n\ninterface PasteRequest {\n target: TargetApp;\n text: string;\n image: string | null;\n label: string;\n}\n\nfunction copyText(text: string): void {\n execSync('pbcopy', { input: text, encoding: 'utf-8' });\n}\n\nfunction copyImage(base64DataUrl: string): string {\n const tmpDir = mkdtempSync(join(tmpdir(), 'rune-grab-'));\n const imgPath = join(tmpDir, 'grab.png');\n\n const base64 = base64DataUrl.replace(/^data:image\\/\\w+;base64,/, '');\n writeFileSync(imgPath, Buffer.from(base64, 'base64'));\n\n return imgPath;\n}\n\nfunction activateAndPaste(target: TargetApp): void {\n if (target === 'claude-code') {\n const script = `\n set iTermRunning to false\n tell application \"System Events\"\n if exists (process \"iTerm2\") then set iTermRunning to true\n end tell\n if iTermRunning then\n tell application \"iTerm2\" to activate\n else\n tell application \"Terminal\" to activate\n end if\n delay 0.3\n tell application \"System Events\"\n keystroke \"v\" using command down\n end tell\n `;\n execSync(`osascript -e '${script.replace(/'/g, \"'\\\"'\\\"'\")}'`);\n return;\n }\n\n const bundleId = APP_BUNDLE_IDS[target];\n if (!bundleId) return;\n\n const script = `\n tell application id \"${bundleId}\"\n activate\n end tell\n delay 0.3\n tell application \"System Events\"\n keystroke \"v\" using command down\n end tell\n `;\n execSync(`osascript -e '${script.replace(/'/g, \"'\\\"'\\\"'\")}'`);\n}\n\nfunction parseBody(req: IncomingMessage): Promise<PasteRequest> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => (body += chunk));\n req.on('end', () => {\n try {\n resolve(JSON.parse(body));\n } catch (e) {\n reject(e);\n }\n });\n req.on('error', reject);\n });\n}\n\nfunction setCors(res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n}\n\nfunction loadIIFE(iifePath?: string): string | null {\n if (cachedIIFE) return cachedIIFE;\n if (iifePath && existsSync(iifePath)) {\n cachedIIFE = readFileSync(iifePath, 'utf-8');\n return cachedIIFE;\n }\n return null;\n}\n\nexport function startHelperServer(port = DEFAULT_PORT, iifePath?: string): void {\n loadIIFE(iifePath);\n\n const server = createServer(async (req, res) => {\n setCors(res);\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n if (req.method === 'GET' && req.url === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, version: '0.1.0' }));\n return;\n }\n if (req.method === 'GET' && req.url === '/rune-grab.js') {\n const script = cachedIIFE;\n if (script) {\n res.writeHead(200, { 'Content-Type': 'application/javascript', 'Cache-Control': 'no-cache' });\n res.end(script);\n } else {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'IIFE bundle not found' }));\n }\n return;\n }\n if (req.method === 'POST' && req.url === '/paste') {\n let tmpImgPath: string | null = null;\n try {\n const data = await parseBody(req);\n const { target, text, image } = data;\n\n if (image) {\n tmpImgPath = copyImage(image);\n execSync(`osascript -e 'set the clipboard to (read (POSIX file \"${tmpImgPath}\") as «class PNGf»)'`);\n } else {\n copyText(text);\n }\n\n activateAndPaste(target);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, target, app: APP_NAMES[target] }));\n } catch (e: any) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: e.message }));\n } finally {\n if (tmpImgPath) {\n try { rmSync(tmpImgPath, { recursive: true }); } catch { }\n }\n }\n return;\n }\n\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n });\n\n server.listen(port, '127.0.0.1', () => {\n console.log(`\\n rune-grab running on http://127.0.0.1:${port}`);\n if (cachedIIFE) {\n console.log(` Add this to your HTML:`);\n console.log(` <script src=\"http://localhost:${port}/rune-grab.js\"><\\/script>`);\n }\n console.log(` Auto-paste targets: ${Object.values(APP_NAMES).filter(Boolean).join(', ')}\\n`);\n });\n\n process.on('SIGINT', () => {\n server.close();\n process.exit(0);\n });\n process.on('SIGTERM', () => {\n server.close();\n process.exit(0);\n });\n}\n\nexport { DEFAULT_PORT };\n","import type { GrabResult, TargetApp } from '../core/types.js';\nimport { copyToClipboard } from './clipboard.js';\n\nconst HELPER_PORT = 19274;\n\nasync function isHelperRunning(): Promise<boolean> {\n try {\n const ac = new AbortController();\n const timer = setTimeout(() => ac.abort(), 500);\n const res = await fetch(`http://127.0.0.1:${HELPER_PORT}/health`, {\n signal: ac.signal,\n });\n clearTimeout(timer);\n return res.ok;\n } catch {\n return false;\n }\n}\n\nasync function sendToHelper(target: TargetApp, result: GrabResult): Promise<boolean> {\n try {\n const res = await fetch(`http://127.0.0.1:${HELPER_PORT}/paste`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n target,\n text: result.text,\n image: result.image ?? null,\n label: result.label,\n }),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nexport const APP_BUNDLE_IDS: Record<TargetApp, string> = {\n claude: 'com.anthropic.claudefordesktop',\n cursor: 'com.todesktop.230313mzl4w4u92',\n codex: 'com.openai.codex',\n 'claude-code': '',\n clipboard: '',\n};\n\nexport const APP_NAMES: Record<TargetApp, string> = {\n claude: 'Claude',\n cursor: 'Cursor',\n codex: 'Codex',\n 'claude-code': 'Claude Code',\n clipboard: 'Clipboard',\n};\n\nexport async function sendToApp(target: TargetApp, result: GrabResult): Promise<{ success: boolean; method: 'auto' | 'clipboard' }> {\n await copyToClipboard(result);\n\n if (target === 'clipboard') {\n return { success: true, method: 'clipboard' };\n }\n\n const helperUp = await isHelperRunning();\n if (helperUp) {\n const ok = await sendToHelper(target, result);\n if (ok) return { success: true, method: 'auto' };\n }\n\n return { success: true, method: 'clipboard' };\n}\n\n"],"mappings":"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","names":["join","existsSync","readFileSync","writeFileSync","execSync","script","iifePath","join","existsSync","readFileSync","execSync","writeFileSync"]}
|
package/package.json
CHANGED