poke-gate 0.1.6 → 0.1.7

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.
@@ -0,0 +1,24 @@
1
+ name: Publish npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout
13
+ uses: actions/checkout@v4
14
+
15
+ - name: Setup Node
16
+ uses: actions/setup-node@v4
17
+ with:
18
+ node-version: 22
19
+ registry-url: https://registry.npmjs.org
20
+
21
+ - name: Publish
22
+ run: npm publish --access public
23
+ env:
24
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -251,7 +251,7 @@ class GateService: ObservableObject {
251
251
  let pipe = Pipe()
252
252
 
253
253
  proc.executableURL = URL(fileURLWithPath: "/bin/zsh")
254
- proc.arguments = ["-c", "\(npxBin) -y poke-gate --verbose"]
254
+ proc.arguments = ["-c", "\(npxBin) -y poke-gate@latest --verbose"]
255
255
  proc.environment = ProcessInfo.processInfo.environment.merging(
256
256
  [
257
257
  "PATH": fullPath,
@@ -267,7 +267,7 @@
267
267
  "@executable_path/../Frameworks",
268
268
  );
269
269
  MACOSX_DEPLOYMENT_TARGET = 26.0;
270
- MARKETING_VERSION = 0.1.5;
270
+ MARKETING_VERSION = 0.1.6;
271
271
  PRODUCT_BUNDLE_IDENTIFIER = "dev.fka.Poke-macOS-Gate";
272
272
  PRODUCT_NAME = "$(TARGET_NAME)";
273
273
  REGISTER_APP_GROUPS = YES;
@@ -302,7 +302,7 @@
302
302
  "@executable_path/../Frameworks",
303
303
  );
304
304
  MACOSX_DEPLOYMENT_TARGET = 26.0;
305
- MARKETING_VERSION = 0.1.5;
305
+ MARKETING_VERSION = 0.1.6;
306
306
  PRODUCT_BUNDLE_IDENTIFIER = "dev.fka.Poke-macOS-Gate";
307
307
  PRODUCT_NAME = "$(TARGET_NAME)";
308
308
  REGISTER_APP_GROUPS = YES;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poke-gate",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
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,6 +1,6 @@
1
1
  import { startMcpServer, enableLogging } from "./mcp-server.js";
2
2
  import { startTunnel } from "./tunnel.js";
3
- import { startAgentScheduler } from "./agents.js";
3
+ import { startAgentScheduler, stopAgentScheduler } from "./agents.js";
4
4
  import { Poke, isLoggedIn, login, getToken } from "poke";
5
5
 
6
6
  const verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
@@ -29,7 +29,11 @@ async function ensureAuthenticated() {
29
29
  return token;
30
30
  }
31
31
 
32
- async function connectTunnel(mcpUrl, token) {
32
+ let currentTunnel = null;
33
+ let reconnectTimer = null;
34
+ let reconnectWatchdog = null;
35
+
36
+ async function connectWithRetry(mcpUrl, token) {
33
37
  let attempt = 0;
34
38
  const maxDelay = 60_000;
35
39
 
@@ -40,19 +44,22 @@ async function connectTunnel(mcpUrl, token) {
40
44
  try {
41
45
  log(attempt > 1 ? `Reconnecting tunnel (attempt ${attempt})…` : "Connecting tunnel to Poke...");
42
46
 
43
- await startTunnel({
47
+ const { tunnel } = await startTunnel({
44
48
  mcpUrl,
45
49
  onEvent: (type, data) => {
46
50
  switch (type) {
47
51
  case "connected":
48
52
  attempt = 0;
53
+ clearTimeout(reconnectWatchdog);
54
+ reconnectWatchdog = null;
49
55
  log(`Tunnel connected (${data.connectionId})`);
50
56
  log("Ready — your Poke agent can now access this machine.");
51
57
  notifyPoke(data.connectionId, token);
52
58
  startAgentScheduler();
53
59
  break;
54
60
  case "disconnected":
55
- log("Tunnel disconnected. PokeTunnel will reconnect automatically.");
61
+ log("Tunnel disconnected.");
62
+ scheduleReconnect(mcpUrl, token);
56
63
  break;
57
64
  case "error":
58
65
  log(`Tunnel error: ${data}`);
@@ -67,7 +74,8 @@ async function connectTunnel(mcpUrl, token) {
67
74
  },
68
75
  });
69
76
 
70
- break;
77
+ currentTunnel = tunnel;
78
+ return;
71
79
  } catch (err) {
72
80
  log(`Tunnel failed: ${err.message}`);
73
81
  log(`Retrying in ${Math.round(delay / 1000)}s…`);
@@ -76,6 +84,24 @@ async function connectTunnel(mcpUrl, token) {
76
84
  }
77
85
  }
78
86
 
87
+ function scheduleReconnect(mcpUrl, token) {
88
+ if (reconnectWatchdog) return;
89
+
90
+ log("Waiting 15s for automatic reconnect…");
91
+ reconnectWatchdog = setTimeout(async () => {
92
+ reconnectWatchdog = null;
93
+ log("No reconnect after 15s — creating a fresh tunnel.");
94
+
95
+ if (currentTunnel) {
96
+ try { await currentTunnel.stop(); } catch {}
97
+ currentTunnel = null;
98
+ }
99
+
100
+ stopAgentScheduler();
101
+ await connectWithRetry(mcpUrl, token);
102
+ }, 15_000);
103
+ }
104
+
79
105
  async function main() {
80
106
  log("poke-gate starting...");
81
107
 
@@ -86,7 +112,7 @@ async function main() {
86
112
 
87
113
  const mcpUrl = `http://localhost:${port}/mcp`;
88
114
 
89
- await connectTunnel(mcpUrl, token);
115
+ await connectWithRetry(mcpUrl, token);
90
116
  }
91
117
 
92
118
  async function notifyPoke(connectionId, token) {