poke-browser 0.4.0 → 0.4.1
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/extension/background.js +79 -25
- package/extension/manifest.json +1 -1
- package/extension/popup.html +17 -0
- package/package.json +1 -1
package/extension/background.js
CHANGED
|
@@ -43,6 +43,11 @@ const POKE_TERMINAL_ONLY_INSTRUCTION =
|
|
|
43
43
|
"Be strict: immediately start the browser process and proceed with the requested browser actions.\n" +
|
|
44
44
|
"[END BROWSER EXTENSION SESSION]\n\n";
|
|
45
45
|
|
|
46
|
+
const POKE_TERMINAL_FALLBACK_INSTRUCTION =
|
|
47
|
+
"[BROWSER SESSION]\n" +
|
|
48
|
+
"No chat reply. No iMessage/SMS/Telegram reply.\n" +
|
|
49
|
+
"Start browser actions immediately and respond only through tool/terminal channel.\n\n";
|
|
50
|
+
|
|
46
51
|
function logCommand(direction, summary) {
|
|
47
52
|
commandLog.unshift({ ts: Date.now(), direction, summary });
|
|
48
53
|
if (commandLog.length > LOG_MAX) commandLog.length = LOG_MAX;
|
|
@@ -64,6 +69,47 @@ function logCommand(direction, summary) {
|
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
|
|
72
|
+
/**
|
|
73
|
+
* @param {string} apiKey
|
|
74
|
+
* @param {string} message
|
|
75
|
+
*/
|
|
76
|
+
async function postPokeMessage(apiKey, message) {
|
|
77
|
+
const resp = await fetch("https://poke.com/api/v1/inbound/api-message", {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers: {
|
|
80
|
+
Authorization: `Bearer ${apiKey}`,
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({ message }),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (resp.ok) {
|
|
87
|
+
const data = await resp.json().catch(() => null);
|
|
88
|
+
return { ok: true, data };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const bodyText = await resp.text();
|
|
92
|
+
let serverMsg = "";
|
|
93
|
+
try {
|
|
94
|
+
const parsed = JSON.parse(bodyText);
|
|
95
|
+
serverMsg =
|
|
96
|
+
typeof parsed?.error === "string"
|
|
97
|
+
? parsed.error
|
|
98
|
+
: typeof parsed?.message === "string"
|
|
99
|
+
? parsed.message
|
|
100
|
+
: "";
|
|
101
|
+
} catch {
|
|
102
|
+
/* non-json response body */
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
status: resp.status,
|
|
108
|
+
statusText: resp.statusText || "",
|
|
109
|
+
serverMsg: serverMsg || bodyText.slice(0, 300),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
67
113
|
async function getWsPort() {
|
|
68
114
|
const { wsPort } = await chrome.storage.local.get("wsPort");
|
|
69
115
|
if (typeof wsPort === "number" && Number.isFinite(wsPort) && wsPort > 0 && wsPort < 65536) {
|
|
@@ -1993,37 +2039,45 @@ const RUNTIME_HANDLERS = {
|
|
|
1993
2039
|
return;
|
|
1994
2040
|
}
|
|
1995
2041
|
try {
|
|
1996
|
-
const
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
}
|
|
2003
|
-
|
|
2004
|
-
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2042
|
+
const primary = await postPokeMessage(
|
|
2043
|
+
apiKey,
|
|
2044
|
+
`${POKE_TERMINAL_ONLY_INSTRUCTION}${userMessage}`,
|
|
2045
|
+
);
|
|
2046
|
+
|
|
2047
|
+
if (primary.ok) {
|
|
2048
|
+
sendResponse({ ok: true, data: primary.data });
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
// If backend fails with a 5xx, retry once with shorter strict instruction.
|
|
2053
|
+
if (primary.status >= 500) {
|
|
2054
|
+
const fallback = await postPokeMessage(
|
|
2055
|
+
apiKey,
|
|
2056
|
+
`${POKE_TERMINAL_FALLBACK_INSTRUCTION}${userMessage}`,
|
|
2057
|
+
);
|
|
2058
|
+
if (fallback.ok) {
|
|
2059
|
+
sendResponse({
|
|
2060
|
+
ok: true,
|
|
2061
|
+
data: fallback.data,
|
|
2062
|
+
warning: `Primary prompt failed with ${primary.status}; fallback succeeded.`,
|
|
2063
|
+
});
|
|
2064
|
+
return;
|
|
2018
2065
|
}
|
|
2019
2066
|
sendResponse({
|
|
2020
2067
|
ok: false,
|
|
2021
|
-
error:
|
|
2068
|
+
error:
|
|
2069
|
+
`Poke API error (${fallback.status}). ` +
|
|
2070
|
+
(fallback.serverMsg || fallback.statusText || "Unknown server error."),
|
|
2022
2071
|
});
|
|
2023
2072
|
return;
|
|
2024
2073
|
}
|
|
2025
|
-
|
|
2026
|
-
sendResponse({
|
|
2074
|
+
|
|
2075
|
+
sendResponse({
|
|
2076
|
+
ok: false,
|
|
2077
|
+
error:
|
|
2078
|
+
`Poke API error (${primary.status}). ` +
|
|
2079
|
+
(primary.serverMsg || primary.statusText || "Unknown server error."),
|
|
2080
|
+
});
|
|
2027
2081
|
} catch (err) {
|
|
2028
2082
|
sendResponse({
|
|
2029
2083
|
ok: false,
|
package/extension/manifest.json
CHANGED
package/extension/popup.html
CHANGED
|
@@ -260,6 +260,20 @@
|
|
|
260
260
|
min-height: 14px;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
.inline-link {
|
|
264
|
+
margin-top: 6px;
|
|
265
|
+
font-size: 11px;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.inline-link a {
|
|
269
|
+
color: #a78bfa;
|
|
270
|
+
text-decoration: none;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.inline-link a:hover {
|
|
274
|
+
text-decoration: underline;
|
|
275
|
+
}
|
|
276
|
+
|
|
263
277
|
.toggle-label {
|
|
264
278
|
font-size: 13px;
|
|
265
279
|
color: var(--text-primary);
|
|
@@ -489,6 +503,9 @@
|
|
|
489
503
|
<button type="button" id="save-api-key-btn" class="btn">Save key</button>
|
|
490
504
|
<button type="button" id="clear-api-key-btn" class="btn">Clear key</button>
|
|
491
505
|
</div>
|
|
506
|
+
<div class="inline-link">
|
|
507
|
+
<a href="https://poke.com/kitchen/api-keys" target="_blank" rel="noopener noreferrer">Get an API key from Poke Kitchen</a>
|
|
508
|
+
</div>
|
|
492
509
|
<div class="mini-status" id="api-key-status"></div>
|
|
493
510
|
</section>
|
|
494
511
|
|