@buygent/cli 0.4.0 → 0.4.2

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.
@@ -2,130 +2,194 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
5
  <title>Buygent</title>
7
6
  <style>
8
- :root {
9
- color-scheme: light dark;
10
- font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
11
- }
7
+ * { box-sizing: border-box; margin: 0; }
12
8
 
13
9
  body {
14
- margin: 0;
15
- min-width: 360px;
16
- background: #111827;
17
- color: #f9fafb;
18
- }
19
-
20
- main {
21
- padding: 16px;
22
- display: grid;
23
- gap: 12px;
24
- }
25
-
26
- h1 {
27
- margin: 0;
28
- font-size: 18px;
10
+ width: 320px;
11
+ font-family: -apple-system, system-ui, "Segoe UI", sans-serif;
12
+ background: #fff;
13
+ color: #1a1a1a;
29
14
  }
30
15
 
31
- p {
32
- margin: 0;
33
- color: #cbd5e1;
34
- font-size: 13px;
35
- line-height: 1.5;
16
+ /* Header */
17
+ .header {
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: space-between;
21
+ padding: 14px 16px;
22
+ border-bottom: 1px solid #f0f0f0;
36
23
  }
37
-
38
- .actions {
39
- display: grid;
40
- grid-template-columns: repeat(2, minmax(0, 1fr));
24
+ .brand {
25
+ display: flex;
26
+ align-items: center;
41
27
  gap: 8px;
42
28
  }
43
-
44
- button {
45
- border: 0;
46
- border-radius: 10px;
47
- background: #2563eb;
29
+ .logo {
30
+ width: 20px; height: 20px;
31
+ background: #111;
32
+ border-radius: 5px;
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: center;
48
36
  color: #fff;
49
- padding: 10px 12px;
50
- font: inherit;
51
- cursor: pointer;
37
+ font-weight: 700;
38
+ font-size: 11px;
52
39
  }
53
-
54
- button.secondary {
55
- background: #334155;
40
+ .brand-name {
41
+ font-size: 14px;
42
+ font-weight: 600;
43
+ letter-spacing: -0.01em;
44
+ }
45
+ .status-pill {
46
+ font-size: 11px;
47
+ font-weight: 500;
48
+ padding: 3px 8px;
49
+ border-radius: 99px;
50
+ background: #f0fdf4;
51
+ color: #16a34a;
52
+ }
53
+ .status-pill.off {
54
+ background: #fef2f2;
55
+ color: #dc2626;
56
+ }
57
+ .status-pill.na {
58
+ background: #f5f5f5;
59
+ color: #737373;
56
60
  }
57
61
 
58
- dl {
59
- margin: 0;
60
- display: grid;
61
- gap: 8px;
62
+ /* Content */
63
+ .content { padding: 14px 16px; }
64
+
65
+ /* Site indicator */
66
+ .site-row {
67
+ display: flex;
68
+ align-items: center;
69
+ justify-content: space-between;
70
+ padding-bottom: 12px;
71
+ }
72
+ .site-name {
73
+ font-size: 13px;
74
+ color: #525252;
75
+ }
76
+ .site-name strong {
77
+ color: #1a1a1a;
78
+ font-weight: 600;
62
79
  }
80
+ .login-status {
81
+ font-size: 11px;
82
+ color: #a3a3a3;
83
+ }
84
+ .login-status.yes { color: #16a34a; }
63
85
 
64
- .row {
65
- display: grid;
66
- gap: 2px;
67
- padding: 10px 12px;
86
+ /* Product card */
87
+ .product-card {
88
+ background: #fafafa;
89
+ border: 1px solid #f0f0f0;
68
90
  border-radius: 10px;
69
- background: #1f2937;
91
+ padding: 12px;
92
+ margin-top: 10px;
70
93
  }
71
-
72
- dt {
73
- font-size: 11px;
74
- letter-spacing: 0.04em;
94
+ .product-card[hidden] { display: none; }
95
+ .product-label {
96
+ font-size: 10px;
75
97
  text-transform: uppercase;
76
- color: #94a3b8;
98
+ letter-spacing: 0.05em;
99
+ color: #a3a3a3;
100
+ margin-bottom: 6px;
101
+ }
102
+ .product-title {
103
+ font-size: 13px;
104
+ font-weight: 500;
105
+ color: #1a1a1a;
106
+ line-height: 1.4;
107
+ display: -webkit-box;
108
+ -webkit-line-clamp: 2;
109
+ -webkit-box-orient: vertical;
110
+ overflow: hidden;
111
+ }
112
+ .product-price {
113
+ font-size: 16px;
114
+ font-weight: 700;
115
+ color: #1a1a1a;
116
+ margin-top: 4px;
77
117
  }
78
118
 
79
- dd {
80
- margin: 0;
119
+ /* Empty state */
120
+ .empty {
121
+ text-align: center;
122
+ padding: 20px 0;
123
+ color: #a3a3a3;
81
124
  font-size: 13px;
82
- word-break: break-word;
125
+ line-height: 1.5;
83
126
  }
84
127
 
85
- #status-banner[data-state="error"] {
86
- color: #fecaca;
128
+ /* Footer */
129
+ .footer {
130
+ padding: 10px 16px;
131
+ border-top: 1px solid #f0f0f0;
132
+ display: flex;
133
+ justify-content: space-between;
134
+ align-items: center;
135
+ }
136
+ .debug-btn {
137
+ background: none;
138
+ border: none;
139
+ font-size: 11px;
140
+ color: #d4d4d4;
141
+ cursor: pointer;
142
+ padding: 0;
143
+ }
144
+ .debug-btn:hover { color: #a3a3a3; }
145
+ .version {
146
+ font-size: 10px;
147
+ color: #e5e5e5;
87
148
  }
88
149
 
89
- #status-banner[data-state="ok"] {
90
- color: #bfdbfe;
150
+ /* Debug panel */
151
+ #debug { display: none; padding: 12px 16px; border-top: 1px solid #f0f0f0; }
152
+ #debug.show { display: block; }
153
+ #debug pre {
154
+ font: 10px/1.5 "SF Mono", Menlo, monospace;
155
+ color: #737373;
156
+ white-space: pre-wrap;
157
+ word-break: break-all;
91
158
  }
92
159
  </style>
93
160
  </head>
94
161
  <body>
95
- <main>
96
- <header>
97
- <h1>Buygent</h1>
98
- <p id="status-banner" data-state="ok">Ready.</p>
99
- </header>
162
+ <div class="header">
163
+ <div class="brand">
164
+ <div class="logo">B</div>
165
+ <span class="brand-name">Buygent</span>
166
+ </div>
167
+ <span id="status-pill" class="status-pill na">Checking…</span>
168
+ </div>
100
169
 
101
- <div class="actions">
102
- <button id="probe-button" type="button">Probe active tab</button>
103
- <button id="ping-button" class="secondary" type="button">Ping native host</button>
170
+ <div class="content">
171
+ <div class="site-row">
172
+ <span id="site-name" class="site-name">Detecting site…</span>
173
+ <span id="login-status" class="login-status"></span>
104
174
  </div>
105
175
 
106
- <dl>
107
- <div class="row">
108
- <dt>Active tab</dt>
109
- <dd id="active-tab">Unknown</dd>
110
- </div>
111
- <div class="row">
112
- <dt>Session</dt>
113
- <dd id="session-state">Unknown</dd>
114
- </div>
115
- <div class="row">
116
- <dt>Page context</dt>
117
- <dd id="page-context">No probe yet</dd>
118
- </div>
119
- <div class="row">
120
- <dt>Native host</dt>
121
- <dd id="native-host-state">Not checked</dd>
122
- </div>
123
- <div class="row">
124
- <dt>Last updated</dt>
125
- <dd id="last-updated">Never</dd>
126
- </div>
127
- </dl>
128
- </main>
176
+ <div id="empty" class="empty">
177
+ Navigate to a Coupang or Amazon<br>product page to get started.
178
+ </div>
179
+
180
+ <div id="product-card" class="product-card" hidden>
181
+ <div class="product-label">Detected product</div>
182
+ <div id="product-title" class="product-title"></div>
183
+ <div id="product-price" class="product-price"></div>
184
+ </div>
185
+ </div>
186
+
187
+ <div class="footer">
188
+ <button id="debug-btn" class="debug-btn">Debug</button>
189
+ <span class="version">v0.4.1</span>
190
+ </div>
191
+
192
+ <div id="debug"><pre id="debug-pre"></pre></div>
129
193
 
130
194
  <script type="module" src="./popup.js"></script>
131
195
  </body>
@@ -14,106 +14,89 @@ var createEnvelope = (type, payload, options) => ({
14
14
  var TERMINAL_ORDER_STATES = new Set(["aborted", "completed_dry_run"]);
15
15
 
16
16
  // extension/popup.ts
17
- var statusBanner = document.querySelector("#status-banner");
18
- var activeTabElement = document.querySelector("#active-tab");
19
- var sessionStateElement = document.querySelector("#session-state");
20
- var pageContextElement = document.querySelector("#page-context");
21
- var nativeHostStateElement = document.querySelector("#native-host-state");
22
- var lastUpdatedElement = document.querySelector("#last-updated");
23
- var probeButton = document.querySelector("#probe-button");
24
- var pingButton = document.querySelector("#ping-button");
25
- var createRequestId = () => globalThis.crypto?.randomUUID?.() ?? `req_${Date.now()}_${Math.random().toString(16).slice(2)}`;
26
- var setBanner = (message, state = "ok") => {
27
- if (!statusBanner) {
28
- return;
29
- }
30
- statusBanner.textContent = message;
31
- statusBanner.dataset.state = state;
32
- };
33
- var requestBackground = async (type) => await chrome.runtime.sendMessage(createEnvelope(type, {}, {
34
- source: "popup",
35
- messageId: createRequestId()
36
- }));
37
- var formatProbe = (probe) => {
38
- if (!probe) {
39
- return "No probe yet";
40
- }
41
- const summary = [`${probe.pageKind}`, probe.loggedIn ? "logged in" : probe.sessionState];
42
- if (probe.product?.title) {
43
- summary.push(probe.product.title);
44
- }
45
- if (probe.checkout?.totalPriceText) {
46
- summary.push(`checkout ${probe.checkout.totalPriceText}`);
47
- } else if (probe.product?.priceText) {
48
- summary.push(probe.product.priceText);
49
- }
50
- return summary.join(" · ");
51
- };
52
- var formatNativeHost = (response) => {
53
- if (!response) {
54
- return "Not checked";
55
- }
56
- if (response.type === "native:pong") {
57
- return `Connected · ${response.payload.hostVersion} · ${response.payload.receivedAt}`;
58
- }
59
- return `Error · ${response.payload.code} · ${response.payload.message}`;
17
+ var $ = (id) => document.getElementById(id);
18
+ var rid = () => globalThis.crypto?.randomUUID?.() ?? `req_${Date.now()}_${Math.random().toString(16).slice(2)}`;
19
+ var send = async (type) => await chrome.runtime.sendMessage(createEnvelope(type, {}, { source: "popup", messageId: rid() }));
20
+ var detectPlatform = (url) => {
21
+ if (!url)
22
+ return null;
23
+ if (url.includes("coupang.com"))
24
+ return "Coupang";
25
+ if (url.includes("amazon.com") || url.includes("amazon.co.jp"))
26
+ return "Amazon";
27
+ return null;
60
28
  };
61
- var renderState = (state) => {
62
- if (activeTabElement) {
63
- activeTabElement.textContent = state.activeTabUrl ?? "Unknown";
29
+ var render = (s) => {
30
+ const pill = $("status-pill");
31
+ const hostOk = s.lastNativeHostResponse?.type === "native:pong";
32
+ if (pill) {
33
+ pill.textContent = hostOk ? "Connected" : s.lastNativeHostResponse ? "Disconnected" : "No host";
34
+ pill.className = `status-pill ${hostOk ? "" : s.lastNativeHostResponse ? "off" : "na"}`;
64
35
  }
65
- if (sessionStateElement) {
66
- const probe = state.lastProbe;
67
- const orderState = state.lastOrderStatus?.state ?? state.lastOrderCheckpoint?.state;
68
- sessionStateElement.textContent = probe ? `${probe.sessionState} (${probe.selectorsVersion})${orderState ? ` · ${orderState}` : ""}` : state.lastError ?? "Unknown";
36
+ const platform = detectPlatform(s.activeTabUrl);
37
+ const siteName = $("site-name");
38
+ if (siteName) {
39
+ siteName.innerHTML = platform ? `Browsing <strong>${platform}</strong>` : "Not on a supported site";
69
40
  }
70
- if (pageContextElement) {
71
- pageContextElement.textContent = state.lastOrderCheckpoint?.detail ?? state.lastOrderStatus?.detail ?? formatProbe(state.lastProbe);
72
- }
73
- if (nativeHostStateElement) {
74
- nativeHostStateElement.textContent = formatNativeHost(state.lastNativeHostResponse);
41
+ const probe = s.lastProbe;
42
+ const loginEl = $("login-status");
43
+ if (loginEl) {
44
+ if (probe?.loggedIn === true) {
45
+ loginEl.textContent = "Logged in";
46
+ loginEl.className = "login-status yes";
47
+ } else if (probe?.loggedIn === false) {
48
+ loginEl.textContent = "Not logged in";
49
+ loginEl.className = "login-status";
50
+ } else {
51
+ loginEl.textContent = "";
52
+ }
75
53
  }
76
- if (lastUpdatedElement) {
77
- lastUpdatedElement.textContent = state.lastUpdatedAt ?? "Never";
54
+ const emptyEl = $("empty");
55
+ const cardEl = $("product-card");
56
+ const titleEl = $("product-title");
57
+ const priceEl = $("product-price");
58
+ if (probe?.product?.title && cardEl && titleEl) {
59
+ cardEl.hidden = false;
60
+ if (emptyEl)
61
+ emptyEl.style.display = "none";
62
+ titleEl.textContent = probe.product.title;
63
+ if (priceEl)
64
+ priceEl.textContent = probe.product.priceText ?? "";
65
+ } else {
66
+ if (cardEl)
67
+ cardEl.hidden = true;
68
+ if (emptyEl)
69
+ emptyEl.style.display = platform ? "none" : "";
78
70
  }
79
- };
80
- var syncState = async () => {
81
- const response = await requestBackground("popup:get-state");
82
- if (response.type === "error") {
83
- setBanner(response.payload.message, "error");
84
- return;
71
+ const pre = $("debug-pre");
72
+ if (pre) {
73
+ pre.textContent = JSON.stringify({
74
+ url: s.activeTabUrl,
75
+ session: probe?.sessionState,
76
+ selectors: probe?.selectorsVersion,
77
+ order: s.lastOrderStatus?.state ?? s.lastOrderCheckpoint?.state,
78
+ host: hostOk ? s.lastNativeHostResponse.payload?.hostVersion : s.lastNativeHostResponse ? s.lastNativeHostResponse.payload?.message : null,
79
+ updated: s.lastUpdatedAt,
80
+ error: s.lastError
81
+ }, null, 2);
85
82
  }
86
- renderState(response.payload.state);
87
- setBanner(response.payload.state.lastError ?? "Ready.", response.payload.state.lastError ? "error" : "ok");
88
83
  };
89
- var runAction = async (button, type, successMessage) => {
90
- if (button) {
91
- button.disabled = true;
92
- }
93
- setBanner("Working…");
84
+ var init = async () => {
94
85
  try {
95
- const response = await requestBackground(type);
96
- if (response.type === "error") {
97
- setBanner(response.payload.message, "error");
98
- await syncState();
99
- return;
100
- }
101
- if (response.type === "popup:probe-result" || response.type === "popup:native-host-response") {
102
- renderState(response.payload.state);
103
- }
104
- setBanner(successMessage);
105
- } catch (error) {
106
- setBanner(error instanceof Error ? error.message : "Extension request failed", "error");
107
- } finally {
108
- if (button) {
109
- button.disabled = false;
86
+ await Promise.allSettled([
87
+ send("popup:probe-active-tab"),
88
+ send("popup:ping-native-host")
89
+ ]);
90
+ const res = await send("popup:get-state");
91
+ if (res.type !== "error")
92
+ render(res.payload.state);
93
+ } catch {
94
+ const pill = $("status-pill");
95
+ if (pill) {
96
+ pill.textContent = "Error";
97
+ pill.className = "status-pill off";
110
98
  }
111
99
  }
112
100
  };
113
- probeButton?.addEventListener("click", () => {
114
- runAction(probeButton, "popup:probe-active-tab", "Probe updated.");
115
- });
116
- pingButton?.addEventListener("click", () => {
117
- runAction(pingButton, "popup:ping-native-host", "Native host responded.");
118
- });
119
- syncState();
101
+ $("debug-btn")?.addEventListener("click", () => $("debug")?.classList.toggle("show"));
102
+ init();
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  // @bun
3
- import{createServer as q}from"net";import{existsSync as f,mkdirSync as w,readFileSync as b,rmSync as m}from"fs";import{homedir as R}from"os";import{dirname as g,join as h}from"path";import{fileURLToPath as V}from"url";var x="0.0.0-dev",E="0.4.0",A=()=>{let e=g(V(import.meta.url));while(!0){let t=h(e,"package.json");if(f(t)){let o=JSON.parse(b(t,"utf8"));if(typeof o.version==="string"&&o.version.trim().length>0)return o.version}let r=g(e);if(r===e)break;e=r}return E==="0.4.0"?x:E},B=A(),T=1,c=h(R(),".buygent","chrome-extension","com.buygent.host.sock"),n=Buffer.alloc(0),s=new Map,p=new Map,l=new WeakMap,i=()=>globalThis.crypto?.randomUUID?.()??`req_${Date.now()}_${Math.random().toString(16).slice(2)}`,_=(e,t,r)=>({protocolVersion:T,type:e,messageId:r.messageId,...r.requestId?{requestId:r.requestId}:{},sentAt:r.sentAt??new Date().toISOString(),source:r.source,payload:t}),d=(e,t)=>_("error",e,t),O=(e)=>{if(!e||typeof e!=="object"||Array.isArray(e))return{ok:!1,error:d({code:"invalid_envelope",message:"Expected a JSON object envelope."},{source:"native-host",messageId:i()})};let t=e;if(t.protocolVersion!==T)return{ok:!1,error:d({code:"unsupported_protocol_version",message:`Unsupported protocolVersion: ${String(t.protocolVersion??"missing")}`},{source:"native-host",messageId:i()})};if(typeof t.type!=="string"||typeof t.messageId!=="string"||typeof t.sentAt!=="string"||typeof t.source!=="string")return{ok:!1,error:d({code:"invalid_envelope",message:"Envelope must include type, messageId, sentAt, and source fields."},{source:"native-host",messageId:i()})};return{ok:!0,envelope:e}},D=(e)=>JSON.stringify(e),u=(e)=>{let t=Buffer.from(JSON.stringify(e),"utf8"),r=Buffer.alloc(4);r.writeUInt32LE(t.length,0),process.stdout.write(r),process.stdout.write(t)},a=(e,t)=>{e.write(`${D(t)}
3
+ import{createServer as q}from"net";import{existsSync as f,mkdirSync as w,readFileSync as b,rmSync as m}from"fs";import{homedir as R}from"os";import{dirname as g,join as h}from"path";import{fileURLToPath as V}from"url";var x="0.0.0-dev",E="0.4.2",A=()=>{let e=g(V(import.meta.url));while(!0){let t=h(e,"package.json");if(f(t)){let o=JSON.parse(b(t,"utf8"));if(typeof o.version==="string"&&o.version.trim().length>0)return o.version}let r=g(e);if(r===e)break;e=r}return E==="0.4.2"?x:E},B=A(),T=1,c=h(R(),".buygent","chrome-extension","com.buygent.host.sock"),n=Buffer.alloc(0),s=new Map,p=new Map,l=new WeakMap,i=()=>globalThis.crypto?.randomUUID?.()??`req_${Date.now()}_${Math.random().toString(16).slice(2)}`,_=(e,t,r)=>({protocolVersion:T,type:e,messageId:r.messageId,...r.requestId?{requestId:r.requestId}:{},sentAt:r.sentAt??new Date().toISOString(),source:r.source,payload:t}),d=(e,t)=>_("error",e,t),O=(e)=>{if(!e||typeof e!=="object"||Array.isArray(e))return{ok:!1,error:d({code:"invalid_envelope",message:"Expected a JSON object envelope."},{source:"native-host",messageId:i()})};let t=e;if(t.protocolVersion!==T)return{ok:!1,error:d({code:"unsupported_protocol_version",message:`Unsupported protocolVersion: ${String(t.protocolVersion??"missing")}`},{source:"native-host",messageId:i()})};if(typeof t.type!=="string"||typeof t.messageId!=="string"||typeof t.sentAt!=="string"||typeof t.source!=="string")return{ok:!1,error:d({code:"invalid_envelope",message:"Envelope must include type, messageId, sentAt, and source fields."},{source:"native-host",messageId:i()})};return{ok:!0,envelope:e}},D=(e)=>JSON.stringify(e),u=(e)=>{let t=Buffer.from(JSON.stringify(e),"utf8"),r=Buffer.alloc(4);r.writeUInt32LE(t.length,0),process.stdout.write(r),process.stdout.write(t)},a=(e,t)=>{e.write(`${D(t)}
4
4
  `)},P=(e,t)=>{let r=p.get(e)??new Set;r.add(t),p.set(e,r)},S=(e)=>{for(let[t,r]of p.entries())if(r.delete(e),r.size===0)p.delete(t);for(let[t,r]of s.entries())if(r===e)s.delete(t)},k=(e,t)=>{let r=p.get(e);if(!r)return;for(let o of r)a(o,t)},U=(e)=>{if(e.type==="native:ping"){u(_("native:pong",{hostVersion:B,receivedAt:new Date().toISOString()},{source:"native-host",messageId:i(),requestId:e.messageId}));return}if(e.type==="order:ack"){if(e.requestId){let t=s.get(e.requestId);if(t)P(e.payload.orderId,t),a(t,e)}return}if(e.type==="runtime:state"){if(e.requestId){let t=s.get(e.requestId);if(t)s.delete(e.requestId),a(t,e)}return}if(e.type==="order:status"||e.type==="order:checkpoint"){k(e.payload.orderId,e);return}if(e.type==="error"){let t=typeof e.payload.details==="object"&&e.payload.details&&!Array.isArray(e.payload.details)?e.payload.details.orderId:void 0;if(typeof t==="string"){k(t,e);return}if(e.requestId){let r=s.get(e.requestId);if(r)s.delete(e.requestId),a(r,e)}}},L=(e)=>{let t=O(e);if(!t.ok){u(t.error);return}U(t.envelope)},H=(e,t)=>{let r=O(JSON.parse(t));if(!r.ok){a(e,r.error);return}let o=r.envelope;if(o.type==="order:start"||o.type==="runtime:get-state"){s.set(o.messageId,e),u(o);return}a(e,d({code:"unsupported_message",message:`Unsupported CLI/native-host message: ${o.type}`},{source:"native-host",messageId:i(),requestId:o.messageId}))},J=()=>{if(w(g(c),{recursive:!0,mode:448}),f(c))m(c,{force:!0})};J();var M=q((e)=>{e.setEncoding("utf8"),l.set(e,""),e.on("data",(t)=>{let o=`${l.get(e)??""}${t}`.split(/\r?\n/u);l.set(e,o.pop()??"");for(let N of o){let y=N.trim();if(!y)continue;try{H(e,y)}catch(I){a(e,d({code:"invalid_message",message:I instanceof Error?I.message:"Invalid CLI/native-host payload."},{source:"native-host",messageId:i()}))}}}),e.on("close",()=>{S(e)}),e.on("error",()=>{S(e)})});M.listen(c);process.stdin.on("data",(e)=>{n=Buffer.concat([n,e]);while(n.length>=4){let t=n.readUInt32LE(0);if(n.length<4+t)return;let r=n.subarray(4,4+t);n=n.subarray(4+t);try{L(JSON.parse(r.toString("utf8")))}catch(o){u(d({code:"invalid_message",message:o instanceof Error?o.message:"Invalid JSON payload."},{source:"native-host",messageId:i()}))}}});var v=()=>{if(M.close(),f(c))m(c,{force:!0})};process.stdin.on("end",()=>{v(),process.exit(0)});process.on("SIGTERM",()=>{v(),process.exit(0)});process.on("SIGINT",()=>{v(),process.exit(0)});process.stdin.resume();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buygent/cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Buygent CLI for one-command installation and extension setup.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",