poke-gate 0.1.9 → 0.2.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/.github/workflows/release.yml +53 -3
- package/Gate.app +0 -0
- package/README.md +48 -14
- package/bin/poke-gate.js +17 -0
- package/clients/Poke macOS Gate/Poke macOS Gate/AboutView.swift +7 -1
- package/clients/Poke macOS Gate/Poke macOS Gate/AccessibilityPermissionView.swift +58 -0
- package/clients/Poke macOS Gate/Poke macOS Gate/GateService.swift +389 -23
- package/clients/Poke macOS Gate/Poke macOS Gate/Info.plist +2 -0
- package/clients/Poke macOS Gate/Poke macOS Gate/LogsView.swift +1 -1
- package/clients/Poke macOS Gate/Poke macOS Gate/MacVisualStyle.swift +89 -0
- package/clients/Poke macOS Gate/Poke macOS Gate/PermissionRowView.swift +55 -0
- package/clients/Poke macOS Gate/Poke macOS Gate/Poke_macOS_GateApp.swift +234 -91
- package/clients/Poke macOS Gate/Poke macOS Gate/SettingsView.swift +125 -81
- package/clients/Poke macOS Gate/Poke macOS Gate/SetupView.swift +157 -0
- package/clients/Poke macOS Gate/Poke macOS Gate.xcodeproj/project.pbxproj +31 -11
- package/docs/cli.md +19 -0
- package/docs/getting-started.md +9 -6
- package/docs/index.md +23 -18
- package/docs/macos-app.md +39 -4
- package/docs/security.md +62 -18
- package/examples/agents/battery.30m.js +1 -1
- package/examples/agents/screentime.24h.js +5 -6
- package/macOS +0 -0
- package/package.json +3 -1
- package/src/agents.js +5 -8
- package/src/app.js +29 -5
- package/src/mcp-server.js +502 -27
- package/src/permission-service.js +128 -0
- package/test/mcp-server-access-policy.test.js +40 -0
- package/test/mcp-server-loop-guard.test.js +57 -0
- package/test/mcp-server-sandbox-command.test.js +18 -0
- package/test/permission-service.test.js +97 -0
package/src/agents.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { readdirSync, readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
2
|
-
import { join,
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { exec } from "node:child_process";
|
|
5
5
|
import { createInterface } from "node:readline";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
6
7
|
|
|
7
8
|
const CONFIG_DIR = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
8
9
|
const AGENTS_DIR = join(CONFIG_DIR, "poke-gate", "agents");
|
|
@@ -113,7 +114,7 @@ export function discoverAgents() {
|
|
|
113
114
|
import { symlinkSync, lstatSync } from "node:fs";
|
|
114
115
|
|
|
115
116
|
function ensureNodeModulesLink() {
|
|
116
|
-
const pkgRoot = join(
|
|
117
|
+
const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
117
118
|
const source = join(pkgRoot, "node_modules");
|
|
118
119
|
const target = join(AGENTS_DIR, "node_modules");
|
|
119
120
|
|
|
@@ -125,7 +126,8 @@ function ensureNodeModulesLink() {
|
|
|
125
126
|
} catch {}
|
|
126
127
|
|
|
127
128
|
try {
|
|
128
|
-
|
|
129
|
+
const type = process.platform === "win32" ? "junction" : "dir";
|
|
130
|
+
symlinkSync(source, target, type);
|
|
129
131
|
} catch {}
|
|
130
132
|
}
|
|
131
133
|
|
|
@@ -187,11 +189,6 @@ export async function downloadAgent(name) {
|
|
|
187
189
|
|
|
188
190
|
console.log(`Fetching agent "${name}" from GitHub...`);
|
|
189
191
|
|
|
190
|
-
const indexRes = await fetch(`${REPO_BASE}/`).catch(() => null);
|
|
191
|
-
|
|
192
|
-
const jsUrl = `${REPO_BASE}/${name}`;
|
|
193
|
-
const envUrl = `${REPO_BASE}/.env.${name}`;
|
|
194
|
-
|
|
195
192
|
// Try to find the exact file first, or search for name.*.js pattern
|
|
196
193
|
let jsFileName = null;
|
|
197
194
|
let jsContent = null;
|
package/src/app.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { startMcpServer, enableLogging } from "./mcp-server.js";
|
|
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
4
|
import { Poke, isLoggedIn, login, getToken } from "poke";
|
|
@@ -30,7 +30,6 @@ async function ensureAuthenticated() {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
let currentTunnel = null;
|
|
33
|
-
let reconnectTimer = null;
|
|
34
33
|
let reconnectWatchdog = null;
|
|
35
34
|
|
|
36
35
|
async function connectWithRetry(mcpUrl, token) {
|
|
@@ -104,6 +103,7 @@ function scheduleReconnect(mcpUrl, token) {
|
|
|
104
103
|
|
|
105
104
|
async function main() {
|
|
106
105
|
log("poke-gate starting...");
|
|
106
|
+
log(`Access mode: ${getPermissionMode()}`);
|
|
107
107
|
|
|
108
108
|
const token = await ensureAuthenticated();
|
|
109
109
|
|
|
@@ -115,14 +115,38 @@ async function main() {
|
|
|
115
115
|
await connectWithRetry(mcpUrl, token);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
function buildAccessModeMessage(mode) {
|
|
119
|
+
switch (mode) {
|
|
120
|
+
case "limited":
|
|
121
|
+
return (
|
|
122
|
+
"Access mode: Limited. " +
|
|
123
|
+
"You can read files, list directories, and run safe read-only commands (ls, cat, grep, curl, jq…). " +
|
|
124
|
+
"You cannot write files, take screenshots, or run other commands."
|
|
125
|
+
);
|
|
126
|
+
case "sandbox":
|
|
127
|
+
return (
|
|
128
|
+
"Access mode: Sandbox. " +
|
|
129
|
+
"You can read files, list directories, and run commands like brew, node, python, ffmpeg, curl, and more. " +
|
|
130
|
+
"File writes are restricted to ~/Downloads and /tmp by macOS sandbox. Screenshots are disabled."
|
|
131
|
+
);
|
|
132
|
+
default:
|
|
133
|
+
return (
|
|
134
|
+
"Access mode: Full. " +
|
|
135
|
+
"You can run any shell command, read and write files, list directories, take screenshots, and check system info. " +
|
|
136
|
+
"Risky actions (commands, file writes, screenshots) require user approval in chat before execution."
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
118
141
|
async function notifyPoke(connectionId, token) {
|
|
119
142
|
try {
|
|
143
|
+
const mode = getPermissionMode();
|
|
120
144
|
const poke = new Poke({ token });
|
|
121
145
|
await poke.sendMessage(
|
|
122
146
|
`Hey! I've connected my computer to you via Poke Gate (tunnel: ${connectionId}). ` +
|
|
123
|
-
|
|
124
|
-
`Just use the tools whenever I ask you to do something on my computer
|
|
125
|
-
`Now reply me
|
|
147
|
+
`${buildAccessModeMessage(mode)} ` +
|
|
148
|
+
`Just use the tools whenever I ask you to do something on my computer. ` +
|
|
149
|
+
`Now reply me with "now I am connected to your computer" but everytime write those replies in most creative fun way.`
|
|
126
150
|
);
|
|
127
151
|
log("Notified Poke agent about connection.");
|
|
128
152
|
} catch (err) {
|