@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.
- package/dist/cli.js +121 -121
- package/dist/extension/popup.html +156 -92
- package/dist/extension/popup.js +75 -92
- package/dist/native-host.js +1 -1
- package/package.json +1 -1
|
@@ -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
|
-
:
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
background: #
|
|
17
|
-
color: #
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
border-radius:
|
|
47
|
-
|
|
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
|
-
|
|
50
|
-
font:
|
|
51
|
-
cursor: pointer;
|
|
37
|
+
font-weight: 700;
|
|
38
|
+
font-size: 11px;
|
|
52
39
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
/* Product card */
|
|
87
|
+
.product-card {
|
|
88
|
+
background: #fafafa;
|
|
89
|
+
border: 1px solid #f0f0f0;
|
|
68
90
|
border-radius: 10px;
|
|
69
|
-
|
|
91
|
+
padding: 12px;
|
|
92
|
+
margin-top: 10px;
|
|
70
93
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
font-size:
|
|
74
|
-
letter-spacing: 0.04em;
|
|
94
|
+
.product-card[hidden] { display: none; }
|
|
95
|
+
.product-label {
|
|
96
|
+
font-size: 10px;
|
|
75
97
|
text-transform: uppercase;
|
|
76
|
-
|
|
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
|
-
|
|
80
|
-
|
|
119
|
+
/* Empty state */
|
|
120
|
+
.empty {
|
|
121
|
+
text-align: center;
|
|
122
|
+
padding: 20px 0;
|
|
123
|
+
color: #a3a3a3;
|
|
81
124
|
font-size: 13px;
|
|
82
|
-
|
|
125
|
+
line-height: 1.5;
|
|
83
126
|
}
|
|
84
127
|
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
90
|
-
|
|
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
|
-
<
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
<
|
|
99
|
-
</
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
<
|
|
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
|
-
<
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<div class="
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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>
|
package/dist/extension/popup.js
CHANGED
|
@@ -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
|
|
18
|
-
var
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
77
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
90
|
-
if (button) {
|
|
91
|
-
button.disabled = true;
|
|
92
|
-
}
|
|
93
|
-
setBanner("Working…");
|
|
84
|
+
var init = async () => {
|
|
94
85
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
114
|
-
|
|
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();
|
package/dist/native-host.js
CHANGED
|
@@ -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.
|
|
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();
|