@react-grab/claude-code 0.0.59 → 0.0.61

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
@@ -18,46 +18,61 @@ yarn add @react-grab/claude-code
18
18
 
19
19
  The server runs on port `4567` by default.
20
20
 
21
+ ### Quick Start (CLI)
22
+
23
+ Start the server in the background before running your dev server:
24
+
25
+ ```bash
26
+ npx @react-grab/claude-code && pnpm run dev
27
+ ```
28
+
29
+ The server will run as a detached background process. **Note:** Stopping your dev server (Ctrl+C) won't stop the React Grab server. To stop it:
30
+
31
+ ```bash
32
+ pkill -f "react-grab.*server"
33
+ ```
34
+
35
+ ### Recommended: Config File (Automatic Lifecycle)
36
+
37
+ For better lifecycle management, start the server from your config file. This ensures the server stops when your dev server stops:
38
+
21
39
  ### Vite
22
40
 
23
41
  ```ts
24
42
  // vite.config.ts
25
- import "@react-grab/claude-code/server";
43
+ import { startServer } from "@react-grab/claude-code/server";
44
+
45
+ if (process.env.NODE_ENV === "development") {
46
+ startServer();
47
+ }
26
48
  ```
27
49
 
28
50
  ### Next.js
29
51
 
30
52
  ```ts
31
53
  // next.config.ts
32
- import "@react-grab/claude-code/server";
54
+ import { startServer } from "@react-grab/claude-code/server";
55
+
56
+ if (process.env.NODE_ENV === "development") {
57
+ startServer();
58
+ }
33
59
  ```
34
60
 
35
61
  ## Client Usage
36
62
 
37
- ```tsx
38
- import { init } from "react-grab/core";
39
- import { createClaudeAgentProvider } from "@react-grab/claude-code/client";
40
-
41
- const agentProvider = createClaudeAgentProvider();
63
+ ### Script Tag
42
64
 
43
- init({
44
- agent: {
45
- provider: agentProvider,
46
- },
47
- });
65
+ ```html
66
+ <script src="//unpkg.com/react-grab/dist/index.global.js"></script>
67
+ <script src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"></script>
48
68
  ```
49
69
 
50
- ## Configuration
51
-
52
- You can customize the server URL and default options:
70
+ ### ES Module
53
71
 
54
72
  ```tsx
55
- const agentProvider = createClaudeAgentProvider({
56
- getOptions: () => ({
57
- model: "opus",
58
- maxTurns: 20,
59
- }),
60
- });
73
+ import { attachAgent } from "@react-grab/claude-code/client";
74
+
75
+ attachAgent();
61
76
  ```
62
77
 
63
78
  ## How It Works
package/dist/cli.cjs ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ var child_process = require('child_process');
5
+ var url = require('url');
6
+ var path = require('path');
7
+
8
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
+ var __filename$1 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)));
10
+ var __dirname$1 = path.dirname(__filename$1);
11
+ var serverPath = path.join(__dirname$1, "server.js");
12
+ child_process.spawn(process.execPath, [serverPath], {
13
+ detached: true,
14
+ stdio: "ignore"
15
+ }).unref();
16
+ console.log("[React Grab] Server starting on port 4567...");
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'child_process';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join } from 'path';
5
+
6
+ var __filename = fileURLToPath(import.meta.url);
7
+ var __dirname = dirname(__filename);
8
+ var serverPath = join(__dirname, "server.js");
9
+ spawn(process.execPath, [serverPath], {
10
+ detached: true,
11
+ stdio: "ignore"
12
+ }).unref();
13
+ console.log("[React Grab] Server starting on port 4567...");
package/dist/client.cjs CHANGED
@@ -117,6 +117,7 @@ var attachAgent = async () => {
117
117
  { once: true }
118
118
  );
119
119
  };
120
+ attachAgent();
120
121
 
121
122
  exports.attachAgent = attachAgent;
122
123
  exports.createClaudeAgentProvider = createClaudeAgentProvider;
@@ -0,0 +1,6 @@
1
+ var ReactGrabClaudeCode=(function(exports){'use strict';var g=`http://localhost:${4567}`,f="react-grab:agent-sessions",m={systemPrompt:{type:"preset",preset:"claude_code",append:`You are helping a user make changes to a React component based on a selected element.
2
+ The user has selected an element from their UI and wants you to help modify it.
3
+ Provide clear, concise status updates as you work.`},model:"haiku",permissionMode:"bypassPermissions",maxTurns:10},y=n=>{let t="",o="";for(let e of n.split(`
4
+ `))e.startsWith("event:")?t=e.slice(6).trim():e.startsWith("data:")&&(o=e.slice(5).trim());return {eventType:t,data:o}};async function*A(n){let t=n.getReader(),o=new TextDecoder,e="";try{for(;;){let{done:r,value:i}=await t.read();i&&(e+=o.decode(i,{stream:!0}));let s;for(;(s=e.indexOf(`
5
+
6
+ `))!==-1;){let{eventType:d,data:a}=y(e.slice(0,s));if(e=e.slice(s+2),d==="done")return;if(d==="error")throw new Error(a||"Agent error");a&&(yield a);}if(r)break}}finally{t.releaseLock();}}async function*l(n,t,o){let e=await fetch(`${n}/agent`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:o});if(!e.ok)throw new Error(`Server error: ${e.status}`);if(!e.body)throw new Error("No response body");yield*A(e.body);}var E=(n={})=>{let{serverUrl:t=g,getOptions:o}=n,e=r=>({...m,...o?.()??{},...r??{}});return {send:async function*(r,i){let s={...r,options:e(r.options)};yield*l(t,s,i);},resume:async function*(r,i){let s=sessionStorage.getItem(f);if(!s)throw new Error("No sessions to resume");let a=JSON.parse(s)[r];if(!a)throw new Error(`Session ${r} not found`);let c=a.context,p={...c,options:e(c.options)};yield "Resuming...",yield*l(t,p,i);},supportsResume:true}},C=async()=>{if(typeof window>"u")return;let n=E(),t=window.__REACT_GRAB__;if(t){t.setAgent({provider:n});return}window.addEventListener("react-grab:init",o=>{o.detail.setAgent({provider:n});},{once:true});};C();exports.attachAgent=C;exports.createClaudeAgentProvider=E;return exports;})({});
package/dist/client.js CHANGED
@@ -115,5 +115,6 @@ var attachAgent = async () => {
115
115
  { once: true }
116
116
  );
117
117
  };
118
+ attachAgent();
118
119
 
119
120
  export { attachAgent, createClaudeAgentProvider };
package/dist/server.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var child_process = require('child_process');
3
+ var net = require('net');
4
4
  var http = require('http');
5
5
  var http2 = require('http2');
6
6
  var stream = require('stream');
@@ -8,6 +8,7 @@ var crypto = require('crypto');
8
8
  var path = require('path');
9
9
  var url = require('url');
10
10
  var events = require('events');
11
+ var child_process = require('child_process');
11
12
  var readline = require('readline');
12
13
  var fs = require('fs');
13
14
  var promises = require('fs/promises');
@@ -35,6 +36,7 @@ function _interopNamespace(e) {
35
36
  return Object.freeze(n);
36
37
  }
37
38
 
39
+ var net__default = /*#__PURE__*/_interopDefault(net);
38
40
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
39
41
  var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
40
42
 
@@ -14646,28 +14648,26 @@ ${content}`;
14646
14648
  });
14647
14649
  return app;
14648
14650
  };
14649
- var killProcessOnPort = (port) => {
14650
- try {
14651
- if (process.platform === "win32") {
14652
- child_process.execSync(
14653
- `for /f "tokens=5" %a in ('netstat -aon ^| findstr :${port} ^| findstr LISTENING') do taskkill /F /PID %a`,
14654
- { stdio: "ignore", timeout: 1e3, shell: "cmd.exe" }
14655
- );
14656
- } else {
14657
- child_process.execSync(`lsof -ti:${port} | xargs kill -9 2>/dev/null`, {
14658
- stdio: "ignore",
14659
- timeout: 1e3
14660
- });
14661
- }
14662
- } catch {
14651
+ var isPortInUse = (port) => new Promise((resolve) => {
14652
+ const server = net__default.default.createServer();
14653
+ server.once("error", () => resolve(true));
14654
+ server.once("listening", () => {
14655
+ server.close();
14656
+ resolve(false);
14657
+ });
14658
+ server.listen(port);
14659
+ });
14660
+ var startServer = async (port = DEFAULT_PORT) => {
14661
+ if (await isPortInUse(port)) {
14662
+ return;
14663
14663
  }
14664
- };
14665
- var startServer = (port = DEFAULT_PORT) => {
14666
- killProcessOnPort(port);
14667
14664
  const app = createServer();
14668
14665
  serve({ fetch: app.fetch, port });
14669
- console.log("React Grab Claude Code server running on port", port);
14666
+ console.log(`[React Grab] Server started on port ${port}`);
14670
14667
  };
14668
+ if ((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('server.cjs', document.baseURI).href)) === `file://${process.argv[1]}`) {
14669
+ startServer(DEFAULT_PORT).catch(console.error);
14670
+ }
14671
14671
 
14672
14672
  exports.createServer = createServer;
14673
14673
  exports.startServer = startServer;
package/dist/server.d.cts CHANGED
@@ -2,6 +2,6 @@ import * as hono_types from 'hono/types';
2
2
  import { Hono } from 'hono';
3
3
 
4
4
  declare const createServer: () => Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
5
- declare const startServer: (port?: number) => void;
5
+ declare const startServer: (port?: number) => Promise<void>;
6
6
 
7
7
  export { createServer, startServer };
package/dist/server.d.ts CHANGED
@@ -2,6 +2,6 @@ import * as hono_types from 'hono/types';
2
2
  import { Hono } from 'hono';
3
3
 
4
4
  declare const createServer: () => Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
5
- declare const startServer: (port?: number) => void;
5
+ declare const startServer: (port?: number) => Promise<void>;
6
6
 
7
7
  export { createServer, startServer };
package/dist/server.js CHANGED
@@ -1,4 +1,4 @@
1
- import { execSync, spawn } from 'child_process';
1
+ import net from 'net';
2
2
  import { createServer as createServer$1 } from 'http';
3
3
  import { Http2ServerRequest } from 'http2';
4
4
  import { Readable } from 'stream';
@@ -6,6 +6,7 @@ import crypto, { randomUUID } from 'crypto';
6
6
  import { dirname, join } from 'path';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { setMaxListeners } from 'events';
9
+ import { spawn } from 'child_process';
9
10
  import { createInterface } from 'readline';
10
11
  import * as fs from 'fs';
11
12
  import { realpathSync } from 'fs';
@@ -14621,27 +14622,25 @@ ${content}`;
14621
14622
  });
14622
14623
  return app;
14623
14624
  };
14624
- var killProcessOnPort = (port) => {
14625
- try {
14626
- if (process.platform === "win32") {
14627
- execSync(
14628
- `for /f "tokens=5" %a in ('netstat -aon ^| findstr :${port} ^| findstr LISTENING') do taskkill /F /PID %a`,
14629
- { stdio: "ignore", timeout: 1e3, shell: "cmd.exe" }
14630
- );
14631
- } else {
14632
- execSync(`lsof -ti:${port} | xargs kill -9 2>/dev/null`, {
14633
- stdio: "ignore",
14634
- timeout: 1e3
14635
- });
14636
- }
14637
- } catch {
14625
+ var isPortInUse = (port) => new Promise((resolve) => {
14626
+ const server = net.createServer();
14627
+ server.once("error", () => resolve(true));
14628
+ server.once("listening", () => {
14629
+ server.close();
14630
+ resolve(false);
14631
+ });
14632
+ server.listen(port);
14633
+ });
14634
+ var startServer = async (port = DEFAULT_PORT) => {
14635
+ if (await isPortInUse(port)) {
14636
+ return;
14638
14637
  }
14639
- };
14640
- var startServer = (port = DEFAULT_PORT) => {
14641
- killProcessOnPort(port);
14642
14638
  const app = createServer();
14643
14639
  serve({ fetch: app.fetch, port });
14644
- console.log("React Grab Claude Code server running on port", port);
14640
+ console.log(`[React Grab] Server started on port ${port}`);
14645
14641
  };
14642
+ if (import.meta.url === `file://${process.argv[1]}`) {
14643
+ startServer(DEFAULT_PORT).catch(console.error);
14644
+ }
14646
14645
 
14647
14646
  export { createServer, startServer };
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "@react-grab/claude-code",
3
- "version": "0.0.59",
3
+ "version": "0.0.61",
4
4
  "type": "module",
5
+ "bin": {
6
+ "react-grab-claude-code": "./dist/cli.js"
7
+ },
5
8
  "exports": {
6
9
  "./client": {
7
10
  "types": "./dist/client.d.ts",
@@ -12,8 +15,11 @@
12
15
  "types": "./dist/server.d.ts",
13
16
  "import": "./dist/server.js",
14
17
  "require": "./dist/server.cjs"
15
- }
18
+ },
19
+ "./dist/*": "./dist/*.js",
20
+ "./dist/*.js": "./dist/*.js"
16
21
  },
22
+ "browser": "dist/client.global.js",
17
23
  "files": [
18
24
  "dist"
19
25
  ],
@@ -24,10 +30,10 @@
24
30
  "@anthropic-ai/claude-agent-sdk": "^0.1.0",
25
31
  "@hono/node-server": "^1.19.6",
26
32
  "hono": "^4.0.0",
27
- "react-grab": "0.0.59"
33
+ "react-grab": "0.0.61"
28
34
  },
29
35
  "scripts": {
30
36
  "dev": "tsup --watch",
31
- "build": "NODE_ENV=production tsup"
37
+ "build": "rm -rf dist && NODE_ENV=production tsup"
32
38
  }
33
39
  }