@react-grab/opencode 0.0.82 → 0.0.84

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/dist/client.cjs CHANGED
@@ -1,29 +1,25 @@
1
1
  'use strict';
2
2
 
3
- // src/constants.ts
4
- var DEFAULT_PORT = 6567;
3
+ // ../utils/dist/client.js
5
4
  var CONNECTION_CHECK_TTL_MS = 5e3;
6
-
7
- // src/client.ts
8
- var DEFAULT_SERVER_URL = `http://localhost:${DEFAULT_PORT}`;
9
5
  var STORAGE_KEY = "react-grab:agent-sessions";
10
- var parseServerSentEvent = (eventStringBlock) => {
6
+ var parseSSEEvent = (eventBlock) => {
11
7
  let eventType = "";
12
8
  let data = "";
13
- for (const line of eventStringBlock.split("\n")) {
9
+ for (const line of eventBlock.split("\n")) {
14
10
  if (line.startsWith("event:")) eventType = line.slice(6).trim();
15
11
  else if (line.startsWith("data:")) data = line.slice(5).trim();
16
12
  }
17
13
  return { eventType, data };
18
14
  };
19
- var streamSSE = async function* (stream, signal) {
20
- const streamReader = stream.getReader();
21
- const textDecoder = new TextDecoder();
22
- let textBuffer = "";
15
+ async function* streamSSE(stream, signal) {
16
+ const reader = stream.getReader();
17
+ const decoder = new TextDecoder();
18
+ let buffer = "";
23
19
  let aborted = false;
24
20
  const onAbort = () => {
25
21
  aborted = true;
26
- streamReader.cancel().catch(() => {
22
+ reader.cancel().catch(() => {
27
23
  });
28
24
  };
29
25
  signal.addEventListener("abort", onAbort);
@@ -32,18 +28,16 @@ var streamSSE = async function* (stream, signal) {
32
28
  throw new DOMException("Aborted", "AbortError");
33
29
  }
34
30
  while (true) {
35
- const result = await streamReader.read();
31
+ const result = await reader.read();
36
32
  if (aborted || signal.aborted) {
37
33
  throw new DOMException("Aborted", "AbortError");
38
34
  }
39
35
  const { done, value } = result;
40
- if (value) textBuffer += textDecoder.decode(value, { stream: true });
41
- let boundaryIndex;
42
- while ((boundaryIndex = textBuffer.indexOf("\n\n")) !== -1) {
43
- const { eventType, data } = parseServerSentEvent(
44
- textBuffer.slice(0, boundaryIndex)
45
- );
46
- textBuffer = textBuffer.slice(boundaryIndex + 2);
36
+ if (value) buffer += decoder.decode(value, { stream: true });
37
+ let boundary;
38
+ while ((boundary = buffer.indexOf("\n\n")) !== -1) {
39
+ const { eventType, data } = parseSSEEvent(buffer.slice(0, boundary));
40
+ buffer = buffer.slice(boundary + 2);
47
41
  if (eventType === "done") return;
48
42
  if (eventType === "error") throw new Error(data || "Agent error");
49
43
  if (data) yield data;
@@ -53,12 +47,19 @@ var streamSSE = async function* (stream, signal) {
53
47
  } finally {
54
48
  signal.removeEventListener("abort", onAbort);
55
49
  try {
56
- streamReader.releaseLock();
50
+ reader.releaseLock();
57
51
  } catch {
58
52
  }
59
53
  }
60
- };
54
+ }
55
+
56
+ // src/constants.ts
57
+ var DEFAULT_PORT = 6567;
58
+
59
+ // src/client.ts
60
+ var DEFAULT_SERVER_URL = `http://localhost:${DEFAULT_PORT}`;
61
61
  var streamFromServer = async function* (serverUrl, context, signal) {
62
+ const startTime = Date.now();
62
63
  const sessionId = context.sessionId;
63
64
  const handleAbort = () => {
64
65
  if (sessionId) {
@@ -82,12 +83,42 @@ var streamFromServer = async function* (serverUrl, context, signal) {
82
83
  if (!response.body) {
83
84
  throw new Error("No response body");
84
85
  }
85
- yield* streamSSE(response.body, signal);
86
+ const iterator = streamSSE(response.body, signal)[Symbol.asyncIterator]();
87
+ let done = false;
88
+ let pendingNext = iterator.next();
89
+ while (!done) {
90
+ const result = await Promise.race([
91
+ pendingNext.then((iteratorResult) => ({
92
+ type: "status",
93
+ iteratorResult
94
+ })),
95
+ new Promise(
96
+ (resolve) => setTimeout(() => resolve({ type: "timeout" }), 100)
97
+ )
98
+ ]);
99
+ if (result.type === "timeout") {
100
+ const elapsedSeconds = (Date.now() - startTime) / 1e3;
101
+ yield `Working\u2026 ${elapsedSeconds.toFixed(1)}s`;
102
+ } else {
103
+ const iteratorResult = result.iteratorResult;
104
+ done = iteratorResult.done ?? false;
105
+ if (!done && iteratorResult.value) {
106
+ const status = iteratorResult.value;
107
+ if (status === "Completed successfully") {
108
+ const totalSeconds = ((Date.now() - startTime) / 1e3).toFixed(1);
109
+ yield `Completed in ${totalSeconds}s`;
110
+ } else {
111
+ yield status;
112
+ }
113
+ pendingNext = iterator.next();
114
+ }
115
+ }
116
+ }
86
117
  } finally {
87
118
  signal.removeEventListener("abort", handleAbort);
88
119
  }
89
120
  };
90
- var createOpencodeAgentProvider = (options = {}) => {
121
+ var createOpenCodeAgentProvider = (options = {}) => {
91
122
  const { serverUrl = DEFAULT_SERVER_URL, getOptions } = options;
92
123
  let connectionCache = null;
93
124
  const mergeOptions = (contextOptions) => ({
@@ -147,7 +178,7 @@ var createOpencodeAgentProvider = (options = {}) => {
147
178
  };
148
179
  var attachAgent = async () => {
149
180
  if (typeof window === "undefined") return;
150
- const provider = createOpencodeAgentProvider();
181
+ const provider = createOpenCodeAgentProvider();
151
182
  const attach = (api2) => {
152
183
  api2.setAgent({ provider, storage: sessionStorage });
153
184
  };
@@ -172,4 +203,4 @@ var attachAgent = async () => {
172
203
  attachAgent();
173
204
 
174
205
  exports.attachAgent = attachAgent;
175
- exports.createOpencodeAgentProvider = createOpencodeAgentProvider;
206
+ exports.createOpenCodeAgentProvider = createOpenCodeAgentProvider;
@@ -1,4 +1,5 @@
1
- var ReactGrabOpencode=(function(exports){'use strict';var m=`http://localhost:${6567}`,E="react-grab:agent-sessions",y=s=>{let t="",o="";for(let n of s.split(`
2
- `))n.startsWith("event:")?t=n.slice(6).trim():n.startsWith("data:")&&(o=n.slice(5).trim());return {eventType:t,data:o}},O=async function*(s,t){let o=s.getReader(),n=new TextDecoder,r="",e=false,a=()=>{e=true,o.cancel().catch(()=>{});};t.addEventListener("abort",a);try{if(t.aborted)throw new DOMException("Aborted","AbortError");for(;;){let i=await o.read();if(e||t.aborted)throw new DOMException("Aborted","AbortError");let{done:l,value:g}=i;g&&(r+=n.decode(g,{stream:!0}));let c;for(;(c=r.indexOf(`
1
+ var ReactGrabOpenCode=(function(exports){'use strict';var f=5e3,m="react-grab:agent-sessions",y=c=>{let e="",n="";for(let t of c.split(`
2
+ `))t.startsWith("event:")?e=t.slice(6).trim():t.startsWith("data:")&&(n=t.slice(5).trim());return {eventType:e,data:n}};async function*g(c,e){let n=c.getReader(),t=new TextDecoder,r="",o=false,i=()=>{o=true,n.cancel().catch(()=>{});};e.addEventListener("abort",i);try{if(e.aborted)throw new DOMException("Aborted","AbortError");for(;;){let a=await n.read();if(o||e.aborted)throw new DOMException("Aborted","AbortError");let{done:p,value:u}=a;u&&(r+=t.decode(u,{stream:!0}));let d;for(;(d=r.indexOf(`
3
3
 
4
- `))!==-1;){let{eventType:d,data:p}=y(r.slice(0,c));if(r=r.slice(c+2),d==="done")return;if(d==="error")throw new Error(p||"Agent error");p&&(yield p);}if(l)break}}finally{t.removeEventListener("abort",a);try{o.releaseLock();}catch{}}},A=async function*(s,t,o){let n=t.sessionId,r=()=>{n&&fetch(`${s}/abort/${n}`,{method:"POST"}).catch(()=>{});};o.addEventListener("abort",r);try{let e=await fetch(`${s}/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*O(e.body,o);}finally{o.removeEventListener("abort",r);}},b=(s={})=>{let{serverUrl:t=m,getOptions:o}=s,n=null,r=e=>({...o?.()??{},...e??{}});return {send:async function*(e,a){let i={...e,options:r(e.options)};yield*A(t,i,a);},resume:async function*(e,a,i){let l=i.getItem(E);if(!l)throw new Error("No sessions to resume");let c=JSON.parse(l)[e];if(!c)throw new Error(`Session ${e} not found`);let d=c.context,p={...d,options:r(d.options)};yield "Resuming...",yield*A(t,p,a);},supportsResume:true,supportsFollowUp:true,checkConnection:async()=>{let e=Date.now();if(n&&e-n.timestamp<5e3)return n.result;try{let i=(await fetch(`${t}/health`,{method:"GET"})).ok;return n={result:i,timestamp:e},i}catch{return n={result:false,timestamp:e},false}},undo:async()=>{try{await fetch(`${t}/undo`,{method:"POST"});}catch{}}}},S=async()=>{if(typeof window>"u")return;let s=b(),t=r=>{r.setAgent({provider:s,storage:sessionStorage});},o=window.__REACT_GRAB__;if(o){t(o);return}window.addEventListener("react-grab:init",r=>{t(r.detail);},{once:true});let n=window.__REACT_GRAB__;n&&t(n);};S();exports.attachAgent=S;exports.createOpencodeAgentProvider=b;return exports;})({});
4
+ `))!==-1;){let{eventType:s,data:l}=y(r.slice(0,d));if(r=r.slice(d+2),s==="done")return;if(s==="error")throw new Error(l||"Agent error");l&&(yield l);}if(p)break}}finally{e.removeEventListener("abort",i);try{n.releaseLock();}catch{}}}var C=`http://localhost:${6567}`,A=async function*(c,e,n){let t=Date.now(),r=e.sessionId,o=()=>{r&&fetch(`${c}/abort/${r}`,{method:"POST"}).catch(()=>{});};n.addEventListener("abort",o);try{let i=await fetch(`${c}/agent`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),signal:n});if(!i.ok)throw new Error(`Server error: ${i.status}`);if(!i.body)throw new Error("No response body");let a=g(i.body,n)[Symbol.asyncIterator](),p=!1,u=a.next();for(;!p;){let d=await Promise.race([u.then(s=>({type:"status",iteratorResult:s})),new Promise(s=>setTimeout(()=>s({type:"timeout"}),100))]);if(d.type==="timeout")yield `Working\u2026 ${((Date.now()-t)/1e3).toFixed(1)}s`;else {let s=d.iteratorResult;if(p=s.done??!1,!p&&s.value){let l=s.value;l==="Completed successfully"?yield `Completed in ${((Date.now()-t)/1e3).toFixed(1)}s`:yield l,u=a.next();}}}}finally{n.removeEventListener("abort",o);}},E=(c={})=>{let{serverUrl:e=C,getOptions:n}=c,t=null,r=o=>({...n?.()??{},...o??{}});return {send:async function*(o,i){let a={...o,options:r(o.options)};yield*A(e,a,i);},resume:async function*(o,i,a){let p=a.getItem(m);if(!p)throw new Error("No sessions to resume");let d=JSON.parse(p)[o];if(!d)throw new Error(`Session ${o} not found`);let s=d.context,l={...s,options:r(s.options)};yield "Resuming...",yield*A(e,l,i);},supportsResume:true,supportsFollowUp:true,checkConnection:async()=>{let o=Date.now();if(t&&o-t.timestamp<f)return t.result;try{let a=(await fetch(`${e}/health`,{method:"GET"})).ok;return t={result:a,timestamp:o},a}catch{return t={result:false,timestamp:o},false}},undo:async()=>{try{await fetch(`${e}/undo`,{method:"POST"});}catch{}}}},O=async()=>{if(typeof window>"u")return;let c=E(),e=r=>{r.setAgent({provider:c,storage:sessionStorage});},n=window.__REACT_GRAB__;if(n){e(n);return}window.addEventListener("react-grab:init",r=>{e(r.detail);},{once:true});let t=window.__REACT_GRAB__;t&&e(t);};O();
5
+ exports.attachAgent=O;exports.createOpenCodeAgentProvider=E;return exports;})({});
package/dist/client.js CHANGED
@@ -1,27 +1,23 @@
1
- // src/constants.ts
2
- var DEFAULT_PORT = 6567;
1
+ // ../utils/dist/client.js
3
2
  var CONNECTION_CHECK_TTL_MS = 5e3;
4
-
5
- // src/client.ts
6
- var DEFAULT_SERVER_URL = `http://localhost:${DEFAULT_PORT}`;
7
3
  var STORAGE_KEY = "react-grab:agent-sessions";
8
- var parseServerSentEvent = (eventStringBlock) => {
4
+ var parseSSEEvent = (eventBlock) => {
9
5
  let eventType = "";
10
6
  let data = "";
11
- for (const line of eventStringBlock.split("\n")) {
7
+ for (const line of eventBlock.split("\n")) {
12
8
  if (line.startsWith("event:")) eventType = line.slice(6).trim();
13
9
  else if (line.startsWith("data:")) data = line.slice(5).trim();
14
10
  }
15
11
  return { eventType, data };
16
12
  };
17
- var streamSSE = async function* (stream, signal) {
18
- const streamReader = stream.getReader();
19
- const textDecoder = new TextDecoder();
20
- let textBuffer = "";
13
+ async function* streamSSE(stream, signal) {
14
+ const reader = stream.getReader();
15
+ const decoder = new TextDecoder();
16
+ let buffer = "";
21
17
  let aborted = false;
22
18
  const onAbort = () => {
23
19
  aborted = true;
24
- streamReader.cancel().catch(() => {
20
+ reader.cancel().catch(() => {
25
21
  });
26
22
  };
27
23
  signal.addEventListener("abort", onAbort);
@@ -30,18 +26,16 @@ var streamSSE = async function* (stream, signal) {
30
26
  throw new DOMException("Aborted", "AbortError");
31
27
  }
32
28
  while (true) {
33
- const result = await streamReader.read();
29
+ const result = await reader.read();
34
30
  if (aborted || signal.aborted) {
35
31
  throw new DOMException("Aborted", "AbortError");
36
32
  }
37
33
  const { done, value } = result;
38
- if (value) textBuffer += textDecoder.decode(value, { stream: true });
39
- let boundaryIndex;
40
- while ((boundaryIndex = textBuffer.indexOf("\n\n")) !== -1) {
41
- const { eventType, data } = parseServerSentEvent(
42
- textBuffer.slice(0, boundaryIndex)
43
- );
44
- textBuffer = textBuffer.slice(boundaryIndex + 2);
34
+ if (value) buffer += decoder.decode(value, { stream: true });
35
+ let boundary;
36
+ while ((boundary = buffer.indexOf("\n\n")) !== -1) {
37
+ const { eventType, data } = parseSSEEvent(buffer.slice(0, boundary));
38
+ buffer = buffer.slice(boundary + 2);
45
39
  if (eventType === "done") return;
46
40
  if (eventType === "error") throw new Error(data || "Agent error");
47
41
  if (data) yield data;
@@ -51,12 +45,19 @@ var streamSSE = async function* (stream, signal) {
51
45
  } finally {
52
46
  signal.removeEventListener("abort", onAbort);
53
47
  try {
54
- streamReader.releaseLock();
48
+ reader.releaseLock();
55
49
  } catch {
56
50
  }
57
51
  }
58
- };
52
+ }
53
+
54
+ // src/constants.ts
55
+ var DEFAULT_PORT = 6567;
56
+
57
+ // src/client.ts
58
+ var DEFAULT_SERVER_URL = `http://localhost:${DEFAULT_PORT}`;
59
59
  var streamFromServer = async function* (serverUrl, context, signal) {
60
+ const startTime = Date.now();
60
61
  const sessionId = context.sessionId;
61
62
  const handleAbort = () => {
62
63
  if (sessionId) {
@@ -80,12 +81,42 @@ var streamFromServer = async function* (serverUrl, context, signal) {
80
81
  if (!response.body) {
81
82
  throw new Error("No response body");
82
83
  }
83
- yield* streamSSE(response.body, signal);
84
+ const iterator = streamSSE(response.body, signal)[Symbol.asyncIterator]();
85
+ let done = false;
86
+ let pendingNext = iterator.next();
87
+ while (!done) {
88
+ const result = await Promise.race([
89
+ pendingNext.then((iteratorResult) => ({
90
+ type: "status",
91
+ iteratorResult
92
+ })),
93
+ new Promise(
94
+ (resolve) => setTimeout(() => resolve({ type: "timeout" }), 100)
95
+ )
96
+ ]);
97
+ if (result.type === "timeout") {
98
+ const elapsedSeconds = (Date.now() - startTime) / 1e3;
99
+ yield `Working\u2026 ${elapsedSeconds.toFixed(1)}s`;
100
+ } else {
101
+ const iteratorResult = result.iteratorResult;
102
+ done = iteratorResult.done ?? false;
103
+ if (!done && iteratorResult.value) {
104
+ const status = iteratorResult.value;
105
+ if (status === "Completed successfully") {
106
+ const totalSeconds = ((Date.now() - startTime) / 1e3).toFixed(1);
107
+ yield `Completed in ${totalSeconds}s`;
108
+ } else {
109
+ yield status;
110
+ }
111
+ pendingNext = iterator.next();
112
+ }
113
+ }
114
+ }
84
115
  } finally {
85
116
  signal.removeEventListener("abort", handleAbort);
86
117
  }
87
118
  };
88
- var createOpencodeAgentProvider = (options = {}) => {
119
+ var createOpenCodeAgentProvider = (options = {}) => {
89
120
  const { serverUrl = DEFAULT_SERVER_URL, getOptions } = options;
90
121
  let connectionCache = null;
91
122
  const mergeOptions = (contextOptions) => ({
@@ -145,7 +176,7 @@ var createOpencodeAgentProvider = (options = {}) => {
145
176
  };
146
177
  var attachAgent = async () => {
147
178
  if (typeof window === "undefined") return;
148
- const provider = createOpencodeAgentProvider();
179
+ const provider = createOpenCodeAgentProvider();
149
180
  const attach = (api2) => {
150
181
  api2.setAgent({ provider, storage: sessionStorage });
151
182
  };
@@ -169,4 +200,4 @@ var attachAgent = async () => {
169
200
  };
170
201
  attachAgent();
171
202
 
172
- export { attachAgent, createOpencodeAgentProvider };
203
+ export { attachAgent, createOpenCodeAgentProvider };
package/dist/server.cjs CHANGED
@@ -7339,17 +7339,21 @@ var import_picocolors = __toESM(require_picocolors());
7339
7339
 
7340
7340
  // src/constants.ts
7341
7341
  var DEFAULT_PORT = 6567;
7342
- var VERSION = "0.0.82";
7343
- var OPENCODE_SDK_PORT = 4096;
7342
+
7343
+ // ../utils/dist/server.js
7344
7344
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
7345
+ var VERSION = "0.0.84";
7346
+ var OPENCODE_SDK_PORT = 4096;
7345
7347
  var opencodeInstance = null;
7346
7348
  var sessionMap = /* @__PURE__ */ new Map();
7347
7349
  var abortedSessions = /* @__PURE__ */ new Set();
7348
- var lastOpencodeSessionId;
7349
- var getOpencodeClient = async () => {
7350
+ var lastOpenCodeSessionId;
7351
+ var getOpenCodeClient = async () => {
7350
7352
  if (!opencodeInstance) {
7351
- await fkill(`:${OPENCODE_SDK_PORT}`, { force: true, silent: true }).catch(() => {
7352
- });
7353
+ await fkill(`:${OPENCODE_SDK_PORT}`, { force: true, silent: true }).catch(
7354
+ () => {
7355
+ }
7356
+ );
7353
7357
  await sleep(100);
7354
7358
  const instance = await createOpencode({
7355
7359
  hostname: "127.0.0.1",
@@ -7359,8 +7363,8 @@ var getOpencodeClient = async () => {
7359
7363
  }
7360
7364
  return opencodeInstance.client;
7361
7365
  };
7362
- var executeOpencodePrompt = async (prompt, options, onStatus, reactGrabSessionId) => {
7363
- const client2 = await getOpencodeClient();
7366
+ var executeOpenCodePrompt = async (prompt, options, onStatus, reactGrabSessionId) => {
7367
+ const client2 = await getOpenCodeClient();
7364
7368
  onStatus?.("Thinking...");
7365
7369
  let opencodeSessionId;
7366
7370
  if (reactGrabSessionId && sessionMap.has(reactGrabSessionId)) {
@@ -7377,7 +7381,7 @@ var executeOpencodePrompt = async (prompt, options, onStatus, reactGrabSessionId
7377
7381
  sessionMap.set(reactGrabSessionId, opencodeSessionId);
7378
7382
  }
7379
7383
  }
7380
- lastOpencodeSessionId = opencodeSessionId;
7384
+ lastOpenCodeSessionId = opencodeSessionId;
7381
7385
  const modelConfig = options?.model ? {
7382
7386
  providerID: options.model.split("/")[0],
7383
7387
  modelID: options.model.split("/")[1] || options.model
@@ -7414,7 +7418,7 @@ ${content}
7414
7418
  return streamSSE(context, async (stream2) => {
7415
7419
  const isAborted = () => sessionId && abortedSessions.has(sessionId);
7416
7420
  try {
7417
- await executeOpencodePrompt(
7421
+ await executeOpenCodePrompt(
7418
7422
  formattedPrompt,
7419
7423
  options,
7420
7424
  (text) => {
@@ -7461,13 +7465,13 @@ ${stderr.trim()}` : errorMessage;
7461
7465
  return context.json({ status: "ok" });
7462
7466
  });
7463
7467
  honoApplication.post("/undo", async (context) => {
7464
- if (!lastOpencodeSessionId) {
7468
+ if (!lastOpenCodeSessionId) {
7465
7469
  return context.json({ status: "error", message: "No session to undo" });
7466
7470
  }
7467
7471
  try {
7468
- const client2 = await getOpencodeClient();
7472
+ const client2 = await getOpenCodeClient();
7469
7473
  await client2.session.prompt({
7470
- path: { id: lastOpencodeSessionId },
7474
+ path: { id: lastOpenCodeSessionId },
7471
7475
  body: {
7472
7476
  parts: [{ type: "text", text: "/undo" }]
7473
7477
  }
@@ -7489,7 +7493,9 @@ var startServer = async (port = DEFAULT_PORT) => {
7489
7493
  await sleep(100);
7490
7494
  const honoApplication = createServer();
7491
7495
  serve({ fetch: honoApplication.fetch, port });
7492
- console.log(`${import_picocolors.default.magenta("\u269B")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(Opencode)")}`);
7496
+ console.log(
7497
+ `${import_picocolors.default.magenta("\u269B")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(OpenCode)")}`
7498
+ );
7493
7499
  console.log(`- Local: ${import_picocolors.default.cyan(`http://localhost:${port}`)}`);
7494
7500
  };
7495
7501
  if ((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('server.cjs', document.baseURI).href)) === url.pathToFileURL(process.argv[1]).href) {
package/dist/server.js CHANGED
@@ -7328,17 +7328,21 @@ var import_picocolors = __toESM(require_picocolors());
7328
7328
 
7329
7329
  // src/constants.ts
7330
7330
  var DEFAULT_PORT = 6567;
7331
- var VERSION = "0.0.82";
7332
- var OPENCODE_SDK_PORT = 4096;
7331
+
7332
+ // ../utils/dist/server.js
7333
7333
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
7334
+ var VERSION = "0.0.84";
7335
+ var OPENCODE_SDK_PORT = 4096;
7334
7336
  var opencodeInstance = null;
7335
7337
  var sessionMap = /* @__PURE__ */ new Map();
7336
7338
  var abortedSessions = /* @__PURE__ */ new Set();
7337
- var lastOpencodeSessionId;
7338
- var getOpencodeClient = async () => {
7339
+ var lastOpenCodeSessionId;
7340
+ var getOpenCodeClient = async () => {
7339
7341
  if (!opencodeInstance) {
7340
- await fkill(`:${OPENCODE_SDK_PORT}`, { force: true, silent: true }).catch(() => {
7341
- });
7342
+ await fkill(`:${OPENCODE_SDK_PORT}`, { force: true, silent: true }).catch(
7343
+ () => {
7344
+ }
7345
+ );
7342
7346
  await sleep(100);
7343
7347
  const instance = await createOpencode({
7344
7348
  hostname: "127.0.0.1",
@@ -7348,8 +7352,8 @@ var getOpencodeClient = async () => {
7348
7352
  }
7349
7353
  return opencodeInstance.client;
7350
7354
  };
7351
- var executeOpencodePrompt = async (prompt, options, onStatus, reactGrabSessionId) => {
7352
- const client2 = await getOpencodeClient();
7355
+ var executeOpenCodePrompt = async (prompt, options, onStatus, reactGrabSessionId) => {
7356
+ const client2 = await getOpenCodeClient();
7353
7357
  onStatus?.("Thinking...");
7354
7358
  let opencodeSessionId;
7355
7359
  if (reactGrabSessionId && sessionMap.has(reactGrabSessionId)) {
@@ -7366,7 +7370,7 @@ var executeOpencodePrompt = async (prompt, options, onStatus, reactGrabSessionId
7366
7370
  sessionMap.set(reactGrabSessionId, opencodeSessionId);
7367
7371
  }
7368
7372
  }
7369
- lastOpencodeSessionId = opencodeSessionId;
7373
+ lastOpenCodeSessionId = opencodeSessionId;
7370
7374
  const modelConfig = options?.model ? {
7371
7375
  providerID: options.model.split("/")[0],
7372
7376
  modelID: options.model.split("/")[1] || options.model
@@ -7403,7 +7407,7 @@ ${content}
7403
7407
  return streamSSE(context, async (stream2) => {
7404
7408
  const isAborted = () => sessionId && abortedSessions.has(sessionId);
7405
7409
  try {
7406
- await executeOpencodePrompt(
7410
+ await executeOpenCodePrompt(
7407
7411
  formattedPrompt,
7408
7412
  options,
7409
7413
  (text) => {
@@ -7450,13 +7454,13 @@ ${stderr.trim()}` : errorMessage;
7450
7454
  return context.json({ status: "ok" });
7451
7455
  });
7452
7456
  honoApplication.post("/undo", async (context) => {
7453
- if (!lastOpencodeSessionId) {
7457
+ if (!lastOpenCodeSessionId) {
7454
7458
  return context.json({ status: "error", message: "No session to undo" });
7455
7459
  }
7456
7460
  try {
7457
- const client2 = await getOpencodeClient();
7461
+ const client2 = await getOpenCodeClient();
7458
7462
  await client2.session.prompt({
7459
- path: { id: lastOpencodeSessionId },
7463
+ path: { id: lastOpenCodeSessionId },
7460
7464
  body: {
7461
7465
  parts: [{ type: "text", text: "/undo" }]
7462
7466
  }
@@ -7478,7 +7482,9 @@ var startServer = async (port = DEFAULT_PORT) => {
7478
7482
  await sleep(100);
7479
7483
  const honoApplication = createServer();
7480
7484
  serve({ fetch: honoApplication.fetch, port });
7481
- console.log(`${import_picocolors.default.magenta("\u269B")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(Opencode)")}`);
7485
+ console.log(
7486
+ `${import_picocolors.default.magenta("\u269B")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(OpenCode)")}`
7487
+ );
7482
7488
  console.log(`- Local: ${import_picocolors.default.cyan(`http://localhost:${port}`)}`);
7483
7489
  };
7484
7490
  if (import.meta.url === pathToFileURL(process.argv[1]).href) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-grab/opencode",
3
- "version": "0.0.82",
3
+ "version": "0.0.84",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "react-grab-opencode": "./dist/cli.cjs"
@@ -24,17 +24,17 @@
24
24
  "dist"
25
25
  ],
26
26
  "devDependencies": {
27
- "@types/cross-spawn": "^6.0.6",
28
- "tsup": "^8.4.0"
27
+ "tsup": "^8.4.0",
28
+ "@react-grab/utils": "0.0.84"
29
29
  },
30
30
  "dependencies": {
31
31
  "@hono/node-server": "^1.19.6",
32
32
  "@opencode-ai/sdk": "^1.0.0",
33
- "cross-spawn": "^7.0.6",
33
+ "execa": "^9.6.0",
34
34
  "fkill": "^9.0.0",
35
35
  "hono": "^4.0.0",
36
36
  "picocolors": "^1.1.1",
37
- "react-grab": "0.0.82"
37
+ "react-grab": "0.0.84"
38
38
  },
39
39
  "scripts": {
40
40
  "dev": "tsup --watch",