poke-gate 0.3.1 → 0.3.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.
@@ -286,7 +286,7 @@
286
286
  "@executable_path/../Frameworks",
287
287
  );
288
288
  MACOSX_DEPLOYMENT_TARGET = 15.0;
289
- MARKETING_VERSION = 0.3.0;
289
+ MARKETING_VERSION = 0.3.1;
290
290
  PRODUCT_BUNDLE_IDENTIFIER = "dev.fka.Poke-macOS-Gate";
291
291
  PRODUCT_NAME = "$(TARGET_NAME)";
292
292
  REGISTER_APP_GROUPS = YES;
@@ -322,7 +322,7 @@
322
322
  "@executable_path/../Frameworks",
323
323
  );
324
324
  MACOSX_DEPLOYMENT_TARGET = 15.0;
325
- MARKETING_VERSION = 0.3.0;
325
+ MARKETING_VERSION = 0.3.1;
326
326
  PRODUCT_BUNDLE_IDENTIFIER = "dev.fka.Poke-macOS-Gate";
327
327
  PRODUCT_NAME = "$(TARGET_NAME)";
328
328
  REGISTER_APP_GROUPS = YES;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poke-gate",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Expose your machine to your Poke AI assistant via MCP tunnel",
5
5
  "type": "module",
6
6
  "bin": {
package/src/app.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { startMcpServer, enableLogging, getPermissionMode } from "./mcp-server.js";
2
2
  import { startTunnel } from "./tunnel.js";
3
3
  import { startAgentScheduler, stopAgentScheduler } from "./agents.js";
4
- import { Poke, isLoggedIn, login, getToken } from "poke";
4
+ import { sendToWebhook } from "./webhook.js";
5
+ import { isLoggedIn, login, getToken } from "poke";
5
6
  import { execSync } from "node:child_process";
6
7
 
7
8
  const verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
@@ -67,7 +68,7 @@ async function connectWithRetry(mcpUrl, token) {
67
68
  reconnectWatchdog = null;
68
69
  log(`Tunnel connected (${data.connectionId})`);
69
70
  log("Ready — your Poke agent can now access this machine.");
70
- notifyPoke(data.connectionId, token);
71
+ notifyPoke(data.connectionId);
71
72
  startAgentScheduler();
72
73
  break;
73
74
  case "disconnected":
@@ -153,11 +154,10 @@ function buildAccessModeMessage(mode) {
153
154
  }
154
155
  }
155
156
 
156
- async function notifyPoke(connectionId, token) {
157
+ async function notifyPoke(connectionId) {
157
158
  try {
158
159
  const mode = getPermissionMode();
159
- const poke = new Poke({ token });
160
- await poke.sendMessage(
160
+ await sendToWebhook(
161
161
  `Hey! I've connected my computer to you via Poke Gate (tunnel: ${connectionId}). ` +
162
162
  `${buildAccessModeMessage(mode)} ` +
163
163
  `Just use the tools whenever I ask you to do something on my computer. ` +
@@ -2,7 +2,8 @@ import { execSync } from "node:child_process";
2
2
  import { readFileSync, unlinkSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { tmpdir, platform } from "node:os";
5
- import { Poke, getToken, isLoggedIn, login } from "poke";
5
+ import { isLoggedIn, login } from "poke";
6
+ import { sendToWebhook } from "./webhook.js";
6
7
 
7
8
  export async function takeScreenshot() {
8
9
  if (platform() !== "darwin") {
@@ -15,12 +16,6 @@ export async function takeScreenshot() {
15
16
  await login();
16
17
  }
17
18
 
18
- const token = getToken();
19
- if (!token) {
20
- console.error("Authentication failed: no token returned by Poke SDK.");
21
- process.exit(1);
22
- }
23
-
24
19
  const dest = join(tmpdir(), `poke-gate-screenshot-${Date.now()}.png`);
25
20
 
26
21
  console.log("Capturing screenshot...");
@@ -37,8 +32,7 @@ export async function takeScreenshot() {
37
32
  console.log(`Screenshot captured (${(png.length / 1024).toFixed(0)} KB). Sending to Poke...`);
38
33
 
39
34
  try {
40
- const poke = new Poke({ token });
41
- await poke.sendMessage(
35
+ await sendToWebhook(
42
36
  `Here is a screenshot of my screen right now. Reply me with the image.\n\n\`\`\`\ndata:image/png;base64,${base64}\n\`\`\``
43
37
  );
44
38
  console.log("Screenshot sent to Poke.");
package/src/tunnel.js CHANGED
@@ -1,29 +1,11 @@
1
1
  import { PokeTunnel, getToken } from "poke";
2
- import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
3
- import { join } from "node:path";
4
- import { homedir } from "node:os";
5
-
6
- const CONFIG_DIR = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
7
- const STATE_PATH = join(CONFIG_DIR, "poke-gate", "state.json");
2
+ import { loadState, saveState } from "./webhook.js";
8
3
 
9
4
  function log(msg) {
10
5
  const ts = new Date().toISOString().slice(11, 19);
11
6
  console.log(`[${ts}] ${msg}`);
12
7
  }
13
8
 
14
- function loadState() {
15
- try {
16
- return JSON.parse(readFileSync(STATE_PATH, "utf-8"));
17
- } catch {
18
- return {};
19
- }
20
- }
21
-
22
- function saveState(state) {
23
- mkdirSync(join(CONFIG_DIR, "poke-gate"), { recursive: true });
24
- writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
25
- }
26
-
27
9
  async function cleanupStaleConnections() {
28
10
  const token = getToken();
29
11
  if (!token) return;
@@ -49,7 +31,8 @@ async function cleanupStaleConnections() {
49
31
  } catch {}
50
32
  }
51
33
 
52
- saveState({});
34
+ const { webhookUrl, webhookToken } = loadState();
35
+ saveState({ webhookUrl, webhookToken });
53
36
  }
54
37
 
55
38
  export async function startTunnel({ mcpUrl, onEvent }) {
@@ -72,6 +55,7 @@ export async function startTunnel({ mcpUrl, onEvent }) {
72
55
  const history = state.connectionHistory || [];
73
56
  history.push(info.connectionId);
74
57
  saveState({
58
+ ...state,
75
59
  connectionId: info.connectionId,
76
60
  connectionHistory: history.slice(-10),
77
61
  });
package/src/webhook.js ADDED
@@ -0,0 +1,43 @@
1
+ import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { Poke, getToken } from "poke";
5
+
6
+ const CONFIG_DIR = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
7
+ const STATE_PATH = join(CONFIG_DIR, "poke-gate", "state.json");
8
+
9
+ export function loadState() {
10
+ try {
11
+ return JSON.parse(readFileSync(STATE_PATH, "utf-8"));
12
+ } catch {
13
+ return {};
14
+ }
15
+ }
16
+
17
+ export function saveState(state) {
18
+ mkdirSync(join(CONFIG_DIR, "poke-gate"), { recursive: true });
19
+ writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
20
+ }
21
+
22
+ export async function getWebhook() {
23
+ const state = loadState();
24
+ if (state.webhookUrl && state.webhookToken) {
25
+ return { webhookUrl: state.webhookUrl, webhookToken: state.webhookToken };
26
+ }
27
+
28
+ const token = getToken();
29
+ if (!token) throw new Error("No Poke auth token available.");
30
+
31
+ const poke = new Poke({ token });
32
+ const result = await poke.createWebhook({ condition: "poke-gate", action: "poke-gate" });
33
+
34
+ const webhook = { webhookUrl: result.webhookUrl, webhookToken: result.webhookToken };
35
+ saveState({ ...state, ...webhook });
36
+ return webhook;
37
+ }
38
+
39
+ export async function sendToWebhook(message) {
40
+ const { webhookUrl, webhookToken } = await getWebhook();
41
+ const poke = new Poke({ token: getToken() });
42
+ return poke.sendWebhook({ webhookUrl, webhookToken, data: { message } });
43
+ }