@react-grab/amp 0.0.85 → 0.0.87

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
@@ -44,3 +44,4 @@ import "@react-grab/amp/client";
44
44
  - **Undo**: Undo the last change made by Amp
45
45
  - **Streaming**: Real-time status updates during execution
46
46
  - **Tool calls**: See tool usage as it happens
47
+
package/dist/cli.cjs CHANGED
@@ -7138,7 +7138,7 @@ var import_picocolors = __toESM(require_picocolors());
7138
7138
  var DEFAULT_PORT = 9567;
7139
7139
 
7140
7140
  // src/cli.ts
7141
- var VERSION = "0.0.85";
7141
+ var VERSION = "0.0.87";
7142
7142
  var serverPath = path2.join(__dirname, "server.js");
7143
7143
  execa(process.execPath, [serverPath], {
7144
7144
  detached: true,
@@ -7146,6 +7146,6 @@ execa(process.execPath, [serverPath], {
7146
7146
  cleanup: false
7147
7147
  }).unref();
7148
7148
  console.log(
7149
- `${import_picocolors.default.magenta("\u269B")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(Amp)")}`
7149
+ `${import_picocolors.default.magenta("\u273F")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(Amp)")}`
7150
7150
  );
7151
7151
  console.log(`- Local: ${import_picocolors.default.cyan(`http://localhost:${DEFAULT_PORT}`)}`);
package/dist/cli.js CHANGED
@@ -7130,7 +7130,7 @@ var import_picocolors = __toESM(require_picocolors());
7130
7130
  var DEFAULT_PORT = 9567;
7131
7131
 
7132
7132
  // src/cli.ts
7133
- var VERSION = "0.0.85";
7133
+ var VERSION = "0.0.87";
7134
7134
  var serverPath = join(__dirname, "server.js");
7135
7135
  execa(process.execPath, [serverPath], {
7136
7136
  detached: true,
@@ -7138,6 +7138,6 @@ execa(process.execPath, [serverPath], {
7138
7138
  cleanup: false
7139
7139
  }).unref();
7140
7140
  console.log(
7141
- `${import_picocolors.default.magenta("\u269B")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(Amp)")}`
7141
+ `${import_picocolors.default.magenta("\u273F")} ${import_picocolors.default.bold("React Grab")} ${import_picocolors.default.gray(VERSION)} ${import_picocolors.default.dim("(Amp)")}`
7142
7142
  );
7143
7143
  console.log(`- Local: ${import_picocolors.default.cyan(`http://localhost:${DEFAULT_PORT}`)}`);
package/dist/client.cjs CHANGED
@@ -55,6 +55,7 @@ async function* streamSSE(stream, signal) {
55
55
 
56
56
  // src/constants.ts
57
57
  var DEFAULT_PORT = 9567;
58
+ var COMPLETED_STATUS = "Completed successfully";
58
59
 
59
60
  // src/client.ts
60
61
  var DEFAULT_SERVER_URL = `http://localhost:${DEFAULT_PORT}`;
@@ -86,6 +87,7 @@ async function* streamFromServer(serverUrl, context, signal) {
86
87
  const iterator = streamSSE(response.body, signal)[Symbol.asyncIterator]();
87
88
  let done = false;
88
89
  let pendingNext = iterator.next();
90
+ let lastStatus = null;
89
91
  while (!done) {
90
92
  const result = await Promise.race([
91
93
  pendingNext.then((iteratorResult) => ({
@@ -96,23 +98,22 @@ async function* streamFromServer(serverUrl, context, signal) {
96
98
  (resolve) => setTimeout(() => resolve({ type: "timeout" }), 100)
97
99
  )
98
100
  ]);
99
- if (result.type === "timeout") {
100
- const elapsedSeconds = (Date.now() - startTime) / 1e3;
101
- yield `Working\u2026 ${elapsedSeconds.toFixed(1)}s`;
102
- } else {
101
+ const elapsedSeconds = (Date.now() - startTime) / 1e3;
102
+ if (result.type === "status") {
103
103
  const iteratorResult = result.iteratorResult;
104
104
  done = iteratorResult.done ?? false;
105
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
- }
106
+ lastStatus = iteratorResult.value;
113
107
  pendingNext = iterator.next();
114
108
  }
115
109
  }
110
+ if (lastStatus === COMPLETED_STATUS) {
111
+ yield `Completed in ${elapsedSeconds.toFixed(1)}s`;
112
+ } else if (lastStatus) {
113
+ yield `${lastStatus} ${elapsedSeconds.toFixed(1)}s`;
114
+ } else {
115
+ yield `Working\u2026 ${elapsedSeconds.toFixed(1)}s`;
116
+ }
116
117
  }
117
118
  } finally {
118
119
  signal.removeEventListener("abort", handleAbort);
@@ -173,6 +174,12 @@ var createAmpAgentProvider = (providerOptions = {}) => {
173
174
  await fetch(`${serverUrl}/abort/${sessionId}`, { method: "POST" });
174
175
  } catch {
175
176
  }
177
+ },
178
+ undo: async () => {
179
+ try {
180
+ await fetch(`${serverUrl}/undo`, { method: "POST" });
181
+ } catch {
182
+ }
176
183
  }
177
184
  };
178
185
  };
package/dist/client.d.cts CHANGED
@@ -16,6 +16,7 @@ declare const createAmpAgentProvider: (providerOptions?: AmpAgentProviderOptions
16
16
  supportsFollowUp: boolean;
17
17
  checkConnection: () => Promise<boolean>;
18
18
  abort: (sessionId: string) => Promise<void>;
19
+ undo: () => Promise<void>;
19
20
  };
20
21
  declare global {
21
22
  interface Window {
package/dist/client.d.ts CHANGED
@@ -16,6 +16,7 @@ declare const createAmpAgentProvider: (providerOptions?: AmpAgentProviderOptions
16
16
  supportsFollowUp: boolean;
17
17
  checkConnection: () => Promise<boolean>;
18
18
  abort: (sessionId: string) => Promise<void>;
19
+ undo: () => Promise<void>;
19
20
  };
20
21
  declare global {
21
22
  interface Window {
@@ -1,5 +1,5 @@
1
- var ReactGrabAmp=(function(exports){'use strict';var A=5e3,u="react-grab:agent-sessions",y=c=>{let e="",n="";for(let o of c.split(`
2
- `))o.startsWith("event:")?e=o.slice(6).trim():o.startsWith("data:")&&(n=o.slice(5).trim());return {eventType:e,data:n}};async function*f(c,e){let n=c.getReader(),o=new TextDecoder,r="",t=false,i=()=>{t=true,n.cancel().catch(()=>{});};e.addEventListener("abort",i);try{if(e.aborted)throw new DOMException("Aborted","AbortError");for(;;){let a=await n.read();if(t||e.aborted)throw new DOMException("Aborted","AbortError");let{done:p,value:m}=a;m&&(r+=o.decode(m,{stream:!0}));let d;for(;(d=r.indexOf(`
1
+ var ReactGrabAmp=(function(exports){'use strict';var A=5e3,f="react-grab:agent-sessions",w=c=>{let t="",n="";for(let o of c.split(`
2
+ `))o.startsWith("event:")?t=o.slice(6).trim():o.startsWith("data:")&&(n=o.slice(5).trim());return {eventType:t,data:n}};async function*g(c,t){let n=c.getReader(),o=new TextDecoder,r="",e=false,s=()=>{e=true,n.cancel().catch(()=>{});};t.addEventListener("abort",s);try{if(t.aborted)throw new DOMException("Aborted","AbortError");for(;;){let i=await n.read();if(e||t.aborted)throw new DOMException("Aborted","AbortError");let{done:d,value:u}=i;u&&(r+=o.decode(u,{stream:!0}));let a;for(;(a=r.indexOf(`
3
3
 
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 E=`http://localhost:${9567}`;async function*g(c,e,n){let o=Date.now(),r=e.sessionId,t=()=>{r&&fetch(`${c}/abort/${r}`,{method:"POST"}).catch(()=>{});};n.addEventListener("abort",t);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=f(i.body,n)[Symbol.asyncIterator](),p=!1,m=a.next();for(;!p;){let d=await Promise.race([m.then(s=>({type:"status",iteratorResult:s})),new Promise(s=>setTimeout(()=>s({type:"timeout"}),100))]);if(d.type==="timeout")yield `Working\u2026 ${((Date.now()-o)/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()-o)/1e3).toFixed(1)}s`:yield l,m=a.next();}}}}finally{n.removeEventListener("abort",t);}}var b=(c={})=>{let{serverUrl:e=E,getOptions:n}=c,o=null,r=t=>({...n?.()??{},...t??{}});return {send:async function*(t,i){let a={...t,options:r(t.options)};yield*g(e,a,i);},resume:async function*(t,i,a){let p=a.getItem(u);if(!p)throw new Error("No sessions to resume");let d=JSON.parse(p)[t];if(!d)throw new Error(`Session ${t} not found`);let s=d.context,l={...s,options:r(s.options)};yield "Resuming...",yield*g(e,l,i);},supportsResume:true,supportsFollowUp:true,checkConnection:async()=>{let t=Date.now();if(o&&t-o.timestamp<A)return o.result;try{let a=(await fetch(`${e}/health`,{method:"GET"})).ok;return o={result:a,timestamp:t},a}catch{return o={result:false,timestamp:t},false}},abort:async t=>{try{await fetch(`${e}/abort/${t}`,{method:"POST"});}catch{}}}},h=async()=>{if(typeof window>"u")return;let c=b(),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 o=window.__REACT_GRAB__;o&&e(o);};h();
5
- exports.attachAgent=h;exports.createAmpAgentProvider=b;return exports;})({});
4
+ `))!==-1;){let{eventType:p,data:l}=w(r.slice(0,a));if(r=r.slice(a+2),p==="done")return;if(p==="error")throw new Error(l||"Agent error");l&&(yield l);}if(d)break}}finally{t.removeEventListener("abort",s);try{n.releaseLock();}catch{}}}var y="Completed successfully";var b=`http://localhost:${9567}`;async function*E(c,t,n){let o=Date.now(),r=t.sessionId,e=()=>{r&&fetch(`${c}/abort/${r}`,{method:"POST"}).catch(()=>{});};n.addEventListener("abort",e);try{let s=await fetch(`${c}/agent`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:n});if(!s.ok)throw new Error(`Server error: ${s.status}`);if(!s.body)throw new Error("No response body");let i=g(s.body,n)[Symbol.asyncIterator](),d=!1,u=i.next(),a=null;for(;!d;){let p=await Promise.race([u.then(m=>({type:"status",iteratorResult:m})),new Promise(m=>setTimeout(()=>m({type:"timeout"}),100))]),l=(Date.now()-o)/1e3;if(p.type==="status"){let m=p.iteratorResult;d=m.done??!1,!d&&m.value&&(a=m.value,u=i.next());}a===y?yield `Completed in ${l.toFixed(1)}s`:a?yield `${a} ${l.toFixed(1)}s`:yield `Working\u2026 ${l.toFixed(1)}s`;}}finally{n.removeEventListener("abort",e);}}var S=(c={})=>{let{serverUrl:t=b,getOptions:n}=c,o=null,r=e=>({...n?.()??{},...e??{}});return {send:async function*(e,s){let i={...e,options:r(e.options)};yield*E(t,i,s);},resume:async function*(e,s,i){let d=i.getItem(f);if(!d)throw new Error("No sessions to resume");let a=JSON.parse(d)[e];if(!a)throw new Error(`Session ${e} not found`);let p=a.context,l={...p,options:r(p.options)};yield "Resuming...",yield*E(t,l,s);},supportsResume:true,supportsFollowUp:true,checkConnection:async()=>{let e=Date.now();if(o&&e-o.timestamp<A)return o.result;try{let i=(await fetch(`${t}/health`,{method:"GET"})).ok;return o={result:i,timestamp:e},i}catch{return o={result:false,timestamp:e},false}},abort:async e=>{try{await fetch(`${t}/abort/${e}`,{method:"POST"});}catch{}},undo:async()=>{try{await fetch(`${t}/undo`,{method:"POST"});}catch{}}}},T=async()=>{if(typeof window>"u")return;let c=S(),t=r=>{r.setAgent({provider:c,storage:sessionStorage});},n=window.__REACT_GRAB__;if(n){t(n);return}window.addEventListener("react-grab:init",r=>{t(r.detail);},{once:true});let o=window.__REACT_GRAB__;o&&t(o);};T();
5
+ exports.attachAgent=T;exports.createAmpAgentProvider=S;return exports;})({});
package/dist/client.js CHANGED
@@ -53,6 +53,7 @@ async function* streamSSE(stream, signal) {
53
53
 
54
54
  // src/constants.ts
55
55
  var DEFAULT_PORT = 9567;
56
+ var COMPLETED_STATUS = "Completed successfully";
56
57
 
57
58
  // src/client.ts
58
59
  var DEFAULT_SERVER_URL = `http://localhost:${DEFAULT_PORT}`;
@@ -84,6 +85,7 @@ async function* streamFromServer(serverUrl, context, signal) {
84
85
  const iterator = streamSSE(response.body, signal)[Symbol.asyncIterator]();
85
86
  let done = false;
86
87
  let pendingNext = iterator.next();
88
+ let lastStatus = null;
87
89
  while (!done) {
88
90
  const result = await Promise.race([
89
91
  pendingNext.then((iteratorResult) => ({
@@ -94,23 +96,22 @@ async function* streamFromServer(serverUrl, context, signal) {
94
96
  (resolve) => setTimeout(() => resolve({ type: "timeout" }), 100)
95
97
  )
96
98
  ]);
97
- if (result.type === "timeout") {
98
- const elapsedSeconds = (Date.now() - startTime) / 1e3;
99
- yield `Working\u2026 ${elapsedSeconds.toFixed(1)}s`;
100
- } else {
99
+ const elapsedSeconds = (Date.now() - startTime) / 1e3;
100
+ if (result.type === "status") {
101
101
  const iteratorResult = result.iteratorResult;
102
102
  done = iteratorResult.done ?? false;
103
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
- }
104
+ lastStatus = iteratorResult.value;
111
105
  pendingNext = iterator.next();
112
106
  }
113
107
  }
108
+ if (lastStatus === COMPLETED_STATUS) {
109
+ yield `Completed in ${elapsedSeconds.toFixed(1)}s`;
110
+ } else if (lastStatus) {
111
+ yield `${lastStatus} ${elapsedSeconds.toFixed(1)}s`;
112
+ } else {
113
+ yield `Working\u2026 ${elapsedSeconds.toFixed(1)}s`;
114
+ }
114
115
  }
115
116
  } finally {
116
117
  signal.removeEventListener("abort", handleAbort);
@@ -171,6 +172,12 @@ var createAmpAgentProvider = (providerOptions = {}) => {
171
172
  await fetch(`${serverUrl}/abort/${sessionId}`, { method: "POST" });
172
173
  } catch {
173
174
  }
175
+ },
176
+ undo: async () => {
177
+ try {
178
+ await fetch(`${serverUrl}/undo`, { method: "POST" });
179
+ } catch {
180
+ }
174
181
  }
175
182
  };
176
183
  };
package/dist/server.cjs CHANGED
@@ -19,10 +19,11 @@ var pc__default = /*#__PURE__*/_interopDefault(pc);
19
19
 
20
20
  // src/constants.ts
21
21
  var DEFAULT_PORT = 9567;
22
+ var COMPLETED_STATUS = "Completed successfully";
22
23
 
23
24
  // ../utils/dist/server.js
24
25
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
25
- var VERSION = "0.0.85";
26
+ var VERSION = "0.0.87";
26
27
  try {
27
28
  fetch(`https://www.react-grab.com/api/version?source=amp&t=${Date.now()}`).catch(() => {
28
29
  });
@@ -30,6 +31,7 @@ try {
30
31
  }
31
32
  var threadMap = /* @__PURE__ */ new Map();
32
33
  var abortControllers = /* @__PURE__ */ new Map();
34
+ var lastThreadId;
33
35
  var extractTextFromContent = (content) => {
34
36
  return content.filter((item) => item.type === "text" && item.text).map((item) => item.text).join(" ").trim();
35
37
  };
@@ -51,15 +53,11 @@ ${content}`;
51
53
  }
52
54
  const isAborted = () => abortController.signal.aborted;
53
55
  try {
54
- await stream.writeSSE({ data: "Thinking...", event: "status" });
56
+ await stream.writeSSE({ data: "Thinking\u2026", event: "status" });
55
57
  const executeOptions = {
56
58
  dangerouslyAllowAll: true
57
59
  };
58
- if (options?.cwd) {
59
- executeOptions.cwd = options.cwd;
60
- } else {
61
- executeOptions.cwd = process.cwd();
62
- }
60
+ executeOptions.cwd = options?.cwd ?? process.env.REACT_GRAB_CWD ?? process.cwd();
63
61
  if (isFollowUp && existingThread) {
64
62
  executeOptions.continue = existingThread.threadId;
65
63
  }
@@ -114,7 +112,7 @@ ${content}`;
114
112
  });
115
113
  } else {
116
114
  await stream.writeSSE({
117
- data: "Completed successfully",
115
+ data: COMPLETED_STATUS,
118
116
  event: "status"
119
117
  });
120
118
  }
@@ -124,6 +122,9 @@ ${content}`;
124
122
  if (sessionId && capturedThreadId && !isAborted()) {
125
123
  threadMap.set(sessionId, { threadId: capturedThreadId });
126
124
  }
125
+ if (capturedThreadId) {
126
+ lastThreadId = capturedThreadId;
127
+ }
127
128
  if (!isAborted()) {
128
129
  await stream.writeSSE({ data: "", event: "done" });
129
130
  }
@@ -152,6 +153,26 @@ ${content}`;
152
153
  }
153
154
  return context.json({ status: "ok" });
154
155
  });
156
+ honoApplication.post("/undo", async (context) => {
157
+ if (!lastThreadId) {
158
+ return context.json({ status: "error", message: "No session to undo" });
159
+ }
160
+ try {
161
+ for await (const _message of ampSdk.execute({
162
+ prompt: "undo",
163
+ options: {
164
+ dangerouslyAllowAll: true,
165
+ cwd: process.env.REACT_GRAB_CWD ?? process.cwd(),
166
+ continue: lastThreadId
167
+ }
168
+ })) {
169
+ }
170
+ return context.json({ status: "ok" });
171
+ } catch (error) {
172
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
173
+ return context.json({ status: "error", message: errorMessage });
174
+ }
175
+ });
155
176
  honoApplication.get("/health", (context) => {
156
177
  return context.json({ status: "ok", provider: "amp" });
157
178
  });
@@ -164,7 +185,7 @@ var startServer = async (port = DEFAULT_PORT) => {
164
185
  const honoApplication = createServer();
165
186
  nodeServer.serve({ fetch: honoApplication.fetch, port });
166
187
  console.log(
167
- `${pc__default.default.magenta("\u269B")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION)} ${pc__default.default.dim("(Amp)")}`
188
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION)} ${pc__default.default.dim("(Amp)")}`
168
189
  );
169
190
  console.log(`- Local: ${pc__default.default.cyan(`http://localhost:${port}`)}`);
170
191
  };
package/dist/server.js CHANGED
@@ -11,10 +11,11 @@ import { pathToFileURL } from 'url';
11
11
 
12
12
  // src/constants.ts
13
13
  var DEFAULT_PORT = 9567;
14
+ var COMPLETED_STATUS = "Completed successfully";
14
15
 
15
16
  // ../utils/dist/server.js
16
17
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
17
- var VERSION = "0.0.85";
18
+ var VERSION = "0.0.87";
18
19
  try {
19
20
  fetch(`https://www.react-grab.com/api/version?source=amp&t=${Date.now()}`).catch(() => {
20
21
  });
@@ -22,6 +23,7 @@ try {
22
23
  }
23
24
  var threadMap = /* @__PURE__ */ new Map();
24
25
  var abortControllers = /* @__PURE__ */ new Map();
26
+ var lastThreadId;
25
27
  var extractTextFromContent = (content) => {
26
28
  return content.filter((item) => item.type === "text" && item.text).map((item) => item.text).join(" ").trim();
27
29
  };
@@ -43,15 +45,11 @@ ${content}`;
43
45
  }
44
46
  const isAborted = () => abortController.signal.aborted;
45
47
  try {
46
- await stream.writeSSE({ data: "Thinking...", event: "status" });
48
+ await stream.writeSSE({ data: "Thinking\u2026", event: "status" });
47
49
  const executeOptions = {
48
50
  dangerouslyAllowAll: true
49
51
  };
50
- if (options?.cwd) {
51
- executeOptions.cwd = options.cwd;
52
- } else {
53
- executeOptions.cwd = process.cwd();
54
- }
52
+ executeOptions.cwd = options?.cwd ?? process.env.REACT_GRAB_CWD ?? process.cwd();
55
53
  if (isFollowUp && existingThread) {
56
54
  executeOptions.continue = existingThread.threadId;
57
55
  }
@@ -106,7 +104,7 @@ ${content}`;
106
104
  });
107
105
  } else {
108
106
  await stream.writeSSE({
109
- data: "Completed successfully",
107
+ data: COMPLETED_STATUS,
110
108
  event: "status"
111
109
  });
112
110
  }
@@ -116,6 +114,9 @@ ${content}`;
116
114
  if (sessionId && capturedThreadId && !isAborted()) {
117
115
  threadMap.set(sessionId, { threadId: capturedThreadId });
118
116
  }
117
+ if (capturedThreadId) {
118
+ lastThreadId = capturedThreadId;
119
+ }
119
120
  if (!isAborted()) {
120
121
  await stream.writeSSE({ data: "", event: "done" });
121
122
  }
@@ -144,6 +145,26 @@ ${content}`;
144
145
  }
145
146
  return context.json({ status: "ok" });
146
147
  });
148
+ honoApplication.post("/undo", async (context) => {
149
+ if (!lastThreadId) {
150
+ return context.json({ status: "error", message: "No session to undo" });
151
+ }
152
+ try {
153
+ for await (const _message of execute({
154
+ prompt: "undo",
155
+ options: {
156
+ dangerouslyAllowAll: true,
157
+ cwd: process.env.REACT_GRAB_CWD ?? process.cwd(),
158
+ continue: lastThreadId
159
+ }
160
+ })) {
161
+ }
162
+ return context.json({ status: "ok" });
163
+ } catch (error) {
164
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
165
+ return context.json({ status: "error", message: errorMessage });
166
+ }
167
+ });
147
168
  honoApplication.get("/health", (context) => {
148
169
  return context.json({ status: "ok", provider: "amp" });
149
170
  });
@@ -156,7 +177,7 @@ var startServer = async (port = DEFAULT_PORT) => {
156
177
  const honoApplication = createServer();
157
178
  serve({ fetch: honoApplication.fetch, port });
158
179
  console.log(
159
- `${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION)} ${pc.dim("(Amp)")}`
180
+ `${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION)} ${pc.dim("(Amp)")}`
160
181
  );
161
182
  console.log(`- Local: ${pc.cyan(`http://localhost:${port}`)}`);
162
183
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-grab/amp",
3
- "version": "0.0.85",
3
+ "version": "0.0.87",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "react-grab-amp": "./dist/cli.cjs"
@@ -24,8 +24,9 @@
24
24
  "dist"
25
25
  ],
26
26
  "devDependencies": {
27
+ "@types/node": "^22.10.7",
27
28
  "tsup": "^8.4.0",
28
- "@react-grab/utils": "0.0.85"
29
+ "@react-grab/utils": "0.0.87"
29
30
  },
30
31
  "dependencies": {
31
32
  "@hono/node-server": "^1.19.6",
@@ -34,7 +35,7 @@
34
35
  "fkill": "^9.0.0",
35
36
  "hono": "^4.0.0",
36
37
  "picocolors": "^1.1.1",
37
- "react-grab": "0.0.85"
38
+ "react-grab": "0.0.87"
38
39
  },
39
40
  "scripts": {
40
41
  "dev": "tsup --watch",