@firstperson/firstperson 2026.1.33
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/.claude/settings.local.json +16 -0
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +81 -0
- package/index.ts +18 -0
- package/openclaw.plugin.json +9 -0
- package/package.json +56 -0
- package/src/channel.test.ts +650 -0
- package/src/channel.ts +742 -0
- package/src/config-schema.test.ts +81 -0
- package/src/config-schema.ts +13 -0
- package/src/relay-client.test.ts +452 -0
- package/src/relay-client.ts +266 -0
- package/src/runtime.ts +14 -0
- package/src/types.ts +32 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +20 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(ls:*)",
|
|
5
|
+
"Bash(node -e:*)",
|
|
6
|
+
"Bash(find /Users/andrewgierke/Developer/firstperson-openclaw/node_modules -name \"package.json\" -path \"*zod*\" ! -path \"*/zod/node_modules/*\" -exec sh -c 'echo \"\"=== $1 ===\"\"; cat \"\"$1\"\" | grep '\"''\"'\"\"version\"\"'\"''\"'' _ {} ;)",
|
|
7
|
+
"Bash(node:*)",
|
|
8
|
+
"Bash(npm ls:*)",
|
|
9
|
+
"Bash(npx tsx:*)",
|
|
10
|
+
"Bash(npm install:*)",
|
|
11
|
+
"Bash(npm run build:*)",
|
|
12
|
+
"Bash(npx tsc:*)",
|
|
13
|
+
"Bash(npm run:*)"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2026.1.33
|
|
4
|
+
|
|
5
|
+
- Fix npm package name to `@firstperson/firstperson` (must match plugin ID)
|
|
6
|
+
|
|
7
|
+
## 2026.1.32
|
|
8
|
+
|
|
9
|
+
- Fix npm package name to `@firstperson/openclaw`
|
|
10
|
+
|
|
11
|
+
## 2026.1.31
|
|
12
|
+
|
|
13
|
+
Initial release of the First Person iOS channel plugin for OpenClaw.
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
- WebSocket relay-based communication with First Person iOS app
|
|
18
|
+
- Pairing-first security model with device approval workflow
|
|
19
|
+
- Support for `pairing`, `allowlist`, `open`, and `disabled` DM policies
|
|
20
|
+
- Automatic reconnection with exponential backoff
|
|
21
|
+
- Environment variable support (`FIRSTPERSON_TOKEN`)
|
|
22
|
+
- Full integration with OpenClaw's channel plugin system
|
|
23
|
+
|
|
24
|
+
### Channel Capabilities
|
|
25
|
+
|
|
26
|
+
- Direct messages only (no group support)
|
|
27
|
+
- Media support
|
|
28
|
+
- No reactions, threads, or polls
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 First Person Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# First Person OpenClaw Plugin
|
|
2
|
+
|
|
3
|
+
Connect your [First Person iOS app](https://apps.apple.com/app/first-person-ai/id123456789) to [OpenClaw](https://openclaw.ai) - your personal AI assistant.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### 1. Install OpenClaw (if you haven't already)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
curl -fsSL https://openclaw.ai/install.sh | bash
|
|
11
|
+
openclaw onboard
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 2. Install the First Person plugin
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
openclaw plugins install firstperson
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 3. Download the First Person iOS app
|
|
21
|
+
|
|
22
|
+
Download from the [App Store](https://apps.apple.com/app/first-person-ai/id123456789) and open the app.
|
|
23
|
+
|
|
24
|
+
### 4. Connect your app to OpenClaw
|
|
25
|
+
|
|
26
|
+
In the First Person iOS app:
|
|
27
|
+
1. Go to **Settings** (gear icon)
|
|
28
|
+
2. Tap **OpenClaw Connection**
|
|
29
|
+
3. Copy your **relay token**
|
|
30
|
+
|
|
31
|
+
Then in your terminal:
|
|
32
|
+
```bash
|
|
33
|
+
openclaw channels add --channel firstperson
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Paste your relay token when prompted. The CLI handles all configuration automatically.
|
|
37
|
+
|
|
38
|
+
### 5. Start the gateway
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
openclaw gateway restart
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 6. Pair your device
|
|
45
|
+
|
|
46
|
+
1. **Send any message** from the First Person iOS app
|
|
47
|
+
2. **You'll receive a pairing code** in the app
|
|
48
|
+
3. **Approve on your server:**
|
|
49
|
+
```bash
|
|
50
|
+
openclaw pairing approve firstperson <CODE>
|
|
51
|
+
```
|
|
52
|
+
4. **Done!** Send another message and your AI will respond.
|
|
53
|
+
|
|
54
|
+
## How It Works
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
┌─────────────────┐ ┌─────────────────────┐ ┌─────────────────┐
|
|
58
|
+
│ First Person │◄───────►│ Cloudflare Relay │◄───────►│ OpenClaw │
|
|
59
|
+
│ iOS App │ WSS │ chat.firstperson.ai│ WSS │ Gateway │
|
|
60
|
+
└─────────────────┘ └─────────────────────┘ └─────────────────┘
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Your messages are relayed securely through our Cloudflare Worker. The pairing system ensures only your approved devices can communicate with your AI.
|
|
64
|
+
|
|
65
|
+
## Troubleshooting
|
|
66
|
+
|
|
67
|
+
**Not receiving pairing code?**
|
|
68
|
+
```bash
|
|
69
|
+
openclaw channels status --probe
|
|
70
|
+
openclaw logs --follow
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Need to re-pair?**
|
|
74
|
+
```bash
|
|
75
|
+
openclaw pairing list firstperson
|
|
76
|
+
openclaw pairing approve firstperson <CODE>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
MIT
|
package/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
2
|
+
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
3
|
+
|
|
4
|
+
import { firstPersonPlugin } from "./src/channel.js";
|
|
5
|
+
import { setFirstPersonRuntime } from "./src/runtime.js";
|
|
6
|
+
|
|
7
|
+
const plugin = {
|
|
8
|
+
id: "firstperson",
|
|
9
|
+
name: "First Person",
|
|
10
|
+
description: "First Person iOS app channel plugin",
|
|
11
|
+
configSchema: emptyPluginConfigSchema(),
|
|
12
|
+
register(api: OpenClawPluginApi) {
|
|
13
|
+
setFirstPersonRuntime(api.runtime);
|
|
14
|
+
api.registerChannel({ plugin: firstPersonPlugin });
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default plugin;
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@firstperson/firstperson",
|
|
3
|
+
"version": "2026.1.33",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "OpenClaw channel plugin for the First Person iOS app",
|
|
6
|
+
"main": "index.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/firstperson-labs/firstperson-openclaw.git"
|
|
10
|
+
},
|
|
11
|
+
"author": "First Person Labs",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"openclaw",
|
|
15
|
+
"firstperson",
|
|
16
|
+
"ios",
|
|
17
|
+
"channel",
|
|
18
|
+
"plugin",
|
|
19
|
+
"ai-assistant"
|
|
20
|
+
],
|
|
21
|
+
"openclaw": {
|
|
22
|
+
"extensions": ["./index.ts"],
|
|
23
|
+
"channel": {
|
|
24
|
+
"id": "firstperson",
|
|
25
|
+
"label": "First Person",
|
|
26
|
+
"selectionLabel": "First Person (iOS)",
|
|
27
|
+
"docsPath": "/channels/firstperson",
|
|
28
|
+
"docsLabel": "firstperson",
|
|
29
|
+
"blurb": "iOS app channel via WebSocket relay.",
|
|
30
|
+
"order": 80,
|
|
31
|
+
"quickstartAllowFrom": false
|
|
32
|
+
},
|
|
33
|
+
"install": {
|
|
34
|
+
"npmSpec": "@firstperson/firstperson",
|
|
35
|
+
"localPath": ".",
|
|
36
|
+
"defaultChoice": "npm"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"ws": "^8.16.0",
|
|
41
|
+
"zod": "^4.0.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/ws": "^8.5.10",
|
|
45
|
+
"openclaw": "*",
|
|
46
|
+
"typescript": "^5.0.0",
|
|
47
|
+
"vitest": "^3.0.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"openclaw": "*"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"test": "vitest run",
|
|
54
|
+
"test:watch": "vitest"
|
|
55
|
+
}
|
|
56
|
+
}
|