agentgate 0.1.0

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.
Files changed (40) hide show
  1. package/README.md +216 -0
  2. package/package.json +63 -0
  3. package/public/favicon.svg +48 -0
  4. package/public/icons/bluesky.svg +1 -0
  5. package/public/icons/fitbit.svg +16 -0
  6. package/public/icons/github.svg +1 -0
  7. package/public/icons/google-calendar.svg +1 -0
  8. package/public/icons/jira.svg +1 -0
  9. package/public/icons/linkedin.svg +1 -0
  10. package/public/icons/mastodon.svg +1 -0
  11. package/public/icons/reddit.svg +1 -0
  12. package/public/icons/youtube.svg +1 -0
  13. package/public/logo.svg +52 -0
  14. package/public/style.css +584 -0
  15. package/src/cli.js +77 -0
  16. package/src/index.js +344 -0
  17. package/src/lib/db.js +325 -0
  18. package/src/lib/hsyncManager.js +57 -0
  19. package/src/lib/queueExecutor.js +362 -0
  20. package/src/routes/bluesky.js +130 -0
  21. package/src/routes/calendar.js +120 -0
  22. package/src/routes/fitbit.js +127 -0
  23. package/src/routes/github.js +72 -0
  24. package/src/routes/jira.js +77 -0
  25. package/src/routes/linkedin.js +137 -0
  26. package/src/routes/mastodon.js +91 -0
  27. package/src/routes/queue.js +186 -0
  28. package/src/routes/reddit.js +138 -0
  29. package/src/routes/ui/bluesky.js +66 -0
  30. package/src/routes/ui/calendar.js +120 -0
  31. package/src/routes/ui/fitbit.js +122 -0
  32. package/src/routes/ui/github.js +60 -0
  33. package/src/routes/ui/index.js +35 -0
  34. package/src/routes/ui/jira.js +72 -0
  35. package/src/routes/ui/linkedin.js +120 -0
  36. package/src/routes/ui/mastodon.js +140 -0
  37. package/src/routes/ui/reddit.js +120 -0
  38. package/src/routes/ui/youtube.js +120 -0
  39. package/src/routes/ui.js +1077 -0
  40. package/src/routes/youtube.js +119 -0
package/README.md ADDED
@@ -0,0 +1,216 @@
1
+ <p align="center">
2
+ <img src="public/logo.svg" alt="agentgate" width="320">
3
+ </p>
4
+
5
+ <p align="center">
6
+ API gateway for AI agents to access your personal data with human-in-the-loop write approval.
7
+ </p>
8
+
9
+ **Read requests** (GET) execute immediately. **Write requests** (POST/PUT/DELETE) are queued for human approval before execution.
10
+
11
+ ## How It Works
12
+
13
+ ```mermaid
14
+ flowchart LR
15
+ A["🦀 Agent"] -->|read| G["🤖 agentgate"] -->|fetch| S[Services]
16
+ A -->|write| G -->|queue| H["🧑 Human"] -->|approve| S
17
+ ```
18
+
19
+ ## Supported Services
20
+
21
+ - **GitHub** - Repos, issues, PRs, commits
22
+ - **Bluesky** - Timeline, posts, profile (DMs blocked)
23
+ - **Mastodon** - Timeline, notifications, profile (DMs blocked)
24
+ - **Reddit** - Subreddits, posts, comments (DMs blocked)
25
+ - **Google Calendar** - Events, calendars
26
+ - **YouTube** - Channels, videos, subscriptions
27
+ - **LinkedIn** - Profile (messaging blocked)
28
+ - **Jira** - Issues, projects, search
29
+ - **Fitbit** - Activity, sleep, heart rate, profile
30
+
31
+ ## Security Notes
32
+
33
+ > **IMPORTANT: Do NOT run this service on the same machine as your AI agents (clawdbot, moltbot, openclaw, etc.).** If an agent has local access to the agentgate box, it could potentially read the database file directly, bypassing all security controls. Run this gateway on a separate, isolated machine that agents can only reach over the network.
34
+
35
+ - All write operations require human approval via the admin UI
36
+ - Agents cannot approve their own requests
37
+ - DMs/messaging endpoints are blocked for social services
38
+ - Admin UI is password-protected
39
+ - API keys are bcrypt-hashed and only shown once at creation
40
+
41
+ ## Quick Start
42
+
43
+ ```bash
44
+ # Install dependencies
45
+ npm install
46
+
47
+ # Start the server
48
+ npm start
49
+
50
+ # Or with auto-reload for development
51
+ npm run dev
52
+ ```
53
+
54
+ The server runs on port 3050 by default. Set `PORT` environment variable to change it.
55
+
56
+ ## First Time Setup
57
+
58
+ 1. Open http://localhost:3050/ui
59
+ 2. Create an admin password
60
+ 3. Add service accounts (OAuth or API tokens depending on service)
61
+ 4. Create API keys for your agents via CLI
62
+
63
+ ## API Key Management
64
+
65
+ Manage API keys in the admin UI at `/ui/keys`, or via CLI:
66
+
67
+ ```bash
68
+ # List all API keys
69
+ npm run keys list
70
+
71
+ # Create a new key
72
+ npm run keys create <name>
73
+
74
+ # Delete a key
75
+ npm run keys delete <id>
76
+ ```
77
+
78
+ ## Usage
79
+
80
+ Agents make requests with the API key in the Authorization header:
81
+
82
+ ```bash
83
+ # Read requests (immediate)
84
+ curl -H "Authorization: Bearer rms_your_key_here" \
85
+ http://localhost:3050/api/github/personal/repos/owner/repo
86
+
87
+ # Write requests (queued for approval)
88
+ curl -X POST http://localhost:3050/api/queue/github/personal/submit \
89
+ -H "Authorization: Bearer rms_your_key_here" \
90
+ -H "Content-Type: application/json" \
91
+ -d '{"requests":[{"method":"POST","path":"/repos/owner/repo/issues","body":{"title":"Bug"}}],"comment":"Creating issue"}'
92
+ ```
93
+
94
+ ## API Documentation
95
+
96
+ Agents can fetch full API documentation at:
97
+ ```
98
+ GET /api/readme
99
+ Authorization: Bearer rms_your_key_here
100
+ ```
101
+
102
+ ## Self-Hosting
103
+
104
+ ### Running as a systemd Service (Linux)
105
+
106
+ Create `/etc/systemd/system/agentgate.service`:
107
+
108
+ ```ini
109
+ [Unit]
110
+ Description=agentgate API gateway
111
+ After=network.target
112
+
113
+ [Service]
114
+ Type=simple
115
+ User=youruser
116
+ WorkingDirectory=/path/to/agentgate
117
+ ExecStart=/usr/bin/node src/index.js
118
+ Restart=on-failure
119
+ RestartSec=10
120
+ Environment=PORT=3050
121
+ Environment=NODE_ENV=production
122
+
123
+ [Install]
124
+ WantedBy=multi-user.target
125
+ ```
126
+
127
+ Then:
128
+ ```bash
129
+ sudo systemctl daemon-reload
130
+ sudo systemctl enable agentgate
131
+ sudo systemctl start agentgate
132
+ ```
133
+
134
+ ### Running with Docker
135
+
136
+ ```dockerfile
137
+ FROM node:20-slim
138
+
139
+ WORKDIR /app
140
+ COPY package*.json ./
141
+ RUN npm ci --only=production
142
+ COPY . .
143
+
144
+ EXPOSE 3050
145
+ CMD ["node", "src/index.js"]
146
+ ```
147
+
148
+ ```bash
149
+ docker build -t agentgate .
150
+ docker run -d -p 3050:3050 -v ./data.db:/app/data.db agentgate
151
+ ```
152
+
153
+ ### Running with PM2
154
+
155
+ ```bash
156
+ npm install -g pm2
157
+ pm2 start src/index.js --name agentgate
158
+ pm2 save
159
+ pm2 startup
160
+ ```
161
+
162
+ ### Remote Access with hsync
163
+
164
+ The admin UI supports [hsync](https://hsync.tech) for secure remote access without exposing ports. Configure it in the UI under Configuration > hsync.
165
+
166
+ ### Remote Access with Cloudflare Tunnel
167
+
168
+ Use [trycloudflare](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/do-more-with-tunnels/trycloudflare/) for quick, free tunnels without a Cloudflare account:
169
+
170
+ ```bash
171
+ # Install cloudflared
172
+ brew install cloudflared # macOS
173
+ # or download from https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/
174
+
175
+ # Start a tunnel (generates a random *.trycloudflare.com URL)
176
+ cloudflared tunnel --url http://localhost:3050
177
+ ```
178
+
179
+ For persistent tunnels with a custom domain, create a [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).
180
+
181
+ ### Reverse Proxy (nginx)
182
+
183
+ ```nginx
184
+ server {
185
+ listen 443 ssl;
186
+ server_name agentgate.yourdomain.com;
187
+
188
+ ssl_certificate /path/to/cert.pem;
189
+ ssl_certificate_key /path/to/key.pem;
190
+
191
+ location / {
192
+ proxy_pass http://127.0.0.1:3050;
193
+ proxy_http_version 1.1;
194
+ proxy_set_header Host $host;
195
+ proxy_set_header X-Real-IP $remote_addr;
196
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
197
+ proxy_set_header X-Forwarded-Proto $scheme;
198
+ }
199
+ }
200
+ ```
201
+
202
+ Set `BASE_URL` environment variable to your public URL for OAuth callbacks:
203
+ ```bash
204
+ BASE_URL=https://agentgate.yourdomain.com npm start
205
+ ```
206
+
207
+ ## TODO
208
+
209
+ - [ ] Per-agent service access control - different agents can access different services/accounts
210
+
211
+ - [ ] Fine-grained endpoint control per service - whitelist/blacklist individual endpoints (even for read operations)
212
+
213
+ ## License
214
+
215
+ ISC
216
+
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "agentgate",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "API gateway for AI agents with human-in-the-loop write approval",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "agentgate": "src/index.js",
9
+ "agentgate-keys": "src/cli.js"
10
+ },
11
+ "engines": {
12
+ "node": ">=18"
13
+ },
14
+ "files": [
15
+ "src/",
16
+ "public/"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/monteslu/agentgate.git"
21
+ },
22
+ "keywords": [
23
+ "ai",
24
+ "agent",
25
+ "api",
26
+ "gateway",
27
+ "proxy",
28
+ "human-in-the-loop",
29
+ "llm",
30
+ "claude",
31
+ "gpt"
32
+ ],
33
+ "author": "Luis Montes",
34
+ "license": "ISC",
35
+ "bugs": {
36
+ "url": "https://github.com/monteslu/agentgate/issues"
37
+ },
38
+ "homepage": "https://github.com/monteslu/agentgate#readme",
39
+ "scripts": {
40
+ "start": "node src/index.js",
41
+ "dev": "node --watch src/index.js",
42
+ "keys": "node src/cli.js",
43
+ "lint": "eslint .",
44
+ "lint:fix": "eslint . --fix",
45
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
46
+ "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
47
+ "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage"
48
+ },
49
+ "dependencies": {
50
+ "bcrypt": "^6.0.0",
51
+ "better-sqlite3": "^11.0.0",
52
+ "cookie-parser": "^1.4.7",
53
+ "express": "^4.18.2",
54
+ "hsync": "^0.33.0",
55
+ "nanoid": "^5.0.0",
56
+ "socket.io": "^4.8.3"
57
+ },
58
+ "devDependencies": {
59
+ "eslint": "^9.0.0",
60
+ "jest": "^29.7.0",
61
+ "supertest": "^7.0.0"
62
+ }
63
+ }
@@ -0,0 +1,48 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <defs>
3
+ <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#6366f1"/>
5
+ <stop offset="100%" style="stop-color:#8b5cf6"/>
6
+ </linearGradient>
7
+ <linearGradient id="metal" x1="0%" y1="0%" x2="100%" y2="0%">
8
+ <stop offset="0%" style="stop-color:#9ca3af"/>
9
+ <stop offset="50%" style="stop-color:#e5e7eb"/>
10
+ <stop offset="100%" style="stop-color:#9ca3af"/>
11
+ </linearGradient>
12
+ </defs>
13
+
14
+ <!-- Background -->
15
+ <rect x="2" y="2" width="60" height="60" rx="14" fill="url(#grad)"/>
16
+
17
+ <!-- Robot torso/suit -->
18
+ <path d="M16 58 L16 36 L24 30 L40 30 L48 36 L48 58" fill="#374151"/>
19
+
20
+ <!-- Suit lapels -->
21
+ <path d="M24 30 L32 42 L40 30" fill="white"/>
22
+
23
+ <!-- Tie -->
24
+ <path d="M30 42 L32 58 L34 42 L32 38 Z" fill="#dc2626"/>
25
+
26
+ <!-- Robot head -->
27
+ <ellipse cx="32" cy="20" rx="12" ry="14" fill="url(#metal)"/>
28
+
29
+ <!-- Face details -->
30
+ <ellipse cx="27" cy="18" rx="2.5" ry="3" fill="#374151"/>
31
+ <ellipse cx="37" cy="18" rx="2.5" ry="3" fill="#374151"/>
32
+ <path d="M28 26 L36 26" stroke="#374151" stroke-width="1.5" stroke-linecap="round"/>
33
+
34
+ <!-- Robot blocking hand (palm facing out) -->
35
+ <rect x="4" y="28" width="14" height="18" rx="2" fill="url(#metal)" stroke="#6b7280" stroke-width="0.5"/>
36
+ <!-- Fingers -->
37
+ <rect x="5" y="22" width="3" height="8" rx="1" fill="url(#metal)"/>
38
+ <rect x="9" y="20" width="3" height="10" rx="1" fill="url(#metal)"/>
39
+ <rect x="13" y="22" width="3" height="8" rx="1" fill="url(#metal)"/>
40
+
41
+ <!-- Incoming robot arm from bottom left -->
42
+ <rect x="0" y="48" width="28" height="6" rx="2" fill="url(#metal)" transform="rotate(-35 14 51)"/>
43
+
44
+ <!-- Magnifying glass being blocked -->
45
+ <circle cx="22" cy="52" r="8" fill="none" stroke="url(#metal)" stroke-width="3"/>
46
+ <circle cx="22" cy="52" r="5" fill="rgba(255,255,255,0.3)"/>
47
+ <line x1="28" y1="57" x2="34" y2="62" stroke="url(#metal)" stroke-width="3" stroke-linecap="round"/>
48
+ </svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="#0085ff" xmlns="http://www.w3.org/2000/svg"><path d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z"/></svg>
@@ -0,0 +1,16 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#00B0B9">
2
+ <circle cx="12" cy="2.5" r="2"/>
3
+ <circle cx="12" cy="8" r="2.25"/>
4
+ <circle cx="12" cy="14" r="2.5"/>
5
+ <circle cx="12" cy="20" r="2.25"/>
6
+ <circle cx="17.5" cy="5" r="1.75"/>
7
+ <circle cx="17.5" cy="11" r="2"/>
8
+ <circle cx="17.5" cy="17" r="1.75"/>
9
+ <circle cx="6.5" cy="5" r="1.75"/>
10
+ <circle cx="6.5" cy="11" r="2"/>
11
+ <circle cx="6.5" cy="17" r="1.75"/>
12
+ <circle cx="22" cy="8" r="1.25"/>
13
+ <circle cx="22" cy="14" r="1.25"/>
14
+ <circle cx="2" cy="8" r="1.25"/>
15
+ <circle cx="2" cy="14" r="1.25"/>
16
+ </svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="#4285f4" xmlns="http://www.w3.org/2000/svg"><path d="M18.316 5.684H24v12.632h-5.684V5.684zM5.684 24h12.632v-5.684H5.684V24zM18.316 5.684V0H1.895A1.894 1.894 0 0 0 0 1.895v16.421h5.684V5.684h12.632zm-7.207 6.25v-.065c.272-.144.5-.349.687-.617s.279-.595.279-.982c0-.379-.099-.72-.3-1.025a2.05 2.05 0 0 0-.832-.714 2.703 2.703 0 0 0-1.197-.257c-.6 0-1.094.156-1.481.467-.386.311-.65.671-.793 1.078l1.085.452c.086-.249.224-.461.413-.633.189-.172.445-.257.767-.257.33 0 .602.088.816.264a.86.86 0 0 1 .322.703c0 .33-.12.589-.36.778-.24.19-.535.284-.886.284h-.567v1.085h.633c.407 0 .748.109 1.02.327.272.218.407.499.407.843 0 .336-.129.614-.387.832s-.565.327-.924.327c-.351 0-.651-.103-.897-.311-.248-.208-.422-.502-.521-.881l-1.096.452c.178.616.505 1.082.977 1.401.472.319 1.023.478 1.651.478.498 0 .954-.093 1.368-.28.414-.187.745-.451.989-.792.244-.341.365-.743.365-1.207 0-.398-.085-.762-.257-1.092a2.003 2.003 0 0 0-.722-.783zm4.905-2.707l-1.13.452c.097.26.145.509.145.749 0 .427-.125.786-.373 1.076s-.534.493-.856.609v.065c.405.104.749.313 1.033.627.284.313.426.704.426 1.171 0 .381-.097.727-.29 1.037a2.09 2.09 0 0 1-.792.752c-.33.184-.695.276-1.096.276-.6 0-1.094-.157-1.481-.469-.388-.313-.652-.751-.794-1.313l1.096-.452c.13.504.487.756 1.073.756.322 0 .583-.108.782-.323s.299-.493.299-.835c0-.249-.065-.462-.194-.639a1.195 1.195 0 0 0-.519-.407 1.719 1.719 0 0 0-.717-.145h-.452v-1.085h.419c.274 0 .519-.064.735-.194s.383-.295.501-.496a1.23 1.23 0 0 0 .178-.639c0-.291-.089-.528-.268-.712-.178-.184-.414-.276-.707-.276-.277 0-.51.08-.698.24s-.325.391-.41.692l-1.085-.452c.127-.397.349-.739.665-1.025.316-.286.682-.498 1.098-.634a4.017 4.017 0 0 1 1.306-.204c.494 0 .942.097 1.346.291.403.194.724.478.963.852.238.373.357.805.357 1.295 0 .395-.073.745-.218 1.05z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="#0052cc" xmlns="http://www.w3.org/2000/svg"><path d="M11.571 11.513H0a5.218 5.218 0 0 0 5.232 5.215h2.13v2.057A5.215 5.215 0 0 0 12.575 24V12.518a1.005 1.005 0 0 0-1.005-1.005zm5.723-5.756H5.736a5.215 5.215 0 0 0 5.215 5.214h2.129v2.058a5.218 5.218 0 0 0 5.215 5.214V6.758a1.001 1.001 0 0 0-1.001-1.001zM23.013 0H11.455a5.215 5.215 0 0 0 5.215 5.215h2.129v2.057A5.215 5.215 0 0 0 24 12.483V1.005A1.005 1.005 0 0 0 23.013 0z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="#0a66c2" xmlns="http://www.w3.org/2000/svg"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="#6364ff" xmlns="http://www.w3.org/2000/svg"><path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="#ff4500" xmlns="http://www.w3.org/2000/svg"><path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24" fill="#ff0000" xmlns="http://www.w3.org/2000/svg"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
@@ -0,0 +1,52 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 80">
2
+ <defs>
3
+ <linearGradient id="logo-grad" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#6366f1"/>
5
+ <stop offset="100%" style="stop-color:#8b5cf6"/>
6
+ </linearGradient>
7
+ <linearGradient id="metal" x1="0%" y1="0%" x2="100%" y2="0%">
8
+ <stop offset="0%" style="stop-color:#9ca3af"/>
9
+ <stop offset="50%" style="stop-color:#e5e7eb"/>
10
+ <stop offset="100%" style="stop-color:#9ca3af"/>
11
+ </linearGradient>
12
+ </defs>
13
+
14
+ <!-- Icon background -->
15
+ <rect x="4" y="4" width="72" height="72" rx="16" fill="url(#logo-grad)"/>
16
+
17
+ <!-- Robot torso/suit -->
18
+ <path d="M20 72 L20 44 L28 36 L52 36 L60 44 L60 72" fill="#374151"/>
19
+
20
+ <!-- Suit lapels -->
21
+ <path d="M28 36 L40 52 L52 36" fill="white"/>
22
+
23
+ <!-- Tie -->
24
+ <path d="M37 52 L40 72 L43 52 L40 46 Z" fill="#dc2626"/>
25
+
26
+ <!-- Robot head -->
27
+ <ellipse cx="40" cy="22" rx="14" ry="16" fill="url(#metal)"/>
28
+
29
+ <!-- Face details -->
30
+ <ellipse cx="34" cy="20" rx="3" ry="3.5" fill="#374151"/>
31
+ <ellipse cx="46" cy="20" rx="3" ry="3.5" fill="#374151"/>
32
+ <path d="M35 30 L45 30" stroke="#374151" stroke-width="2" stroke-linecap="round"/>
33
+
34
+ <!-- Robot blocking hand (palm facing out) -->
35
+ <rect x="6" y="34" width="16" height="22" rx="3" fill="url(#metal)" stroke="#6b7280" stroke-width="0.5"/>
36
+ <!-- Fingers -->
37
+ <rect x="7" y="26" width="4" height="10" rx="1.5" fill="url(#metal)"/>
38
+ <rect x="12" y="24" width="4" height="12" rx="1.5" fill="url(#metal)"/>
39
+ <rect x="17" y="26" width="4" height="10" rx="1.5" fill="url(#metal)"/>
40
+
41
+ <!-- Incoming robot arm from bottom left -->
42
+ <rect x="2" y="58" width="34" height="7" rx="2" fill="url(#metal)" transform="rotate(-35 18 62)"/>
43
+
44
+ <!-- Magnifying glass being blocked -->
45
+ <circle cx="28" cy="64" r="10" fill="none" stroke="url(#metal)" stroke-width="4"/>
46
+ <circle cx="28" cy="64" r="6" fill="rgba(255,255,255,0.3)"/>
47
+ <line x1="35" y1="70" x2="42" y2="76" stroke="url(#metal)" stroke-width="4" stroke-linecap="round"/>
48
+
49
+ <!-- Text: agentgate -->
50
+ <text x="92" y="54" font-family="system-ui, -apple-system, sans-serif" font-size="38" font-weight="700" fill="#1f2937">agent</text>
51
+ <text x="212" y="54" font-family="system-ui, -apple-system, sans-serif" font-size="38" font-weight="700" fill="url(#logo-grad)">gate</text>
52
+ </svg>