port42-openclaw 0.1.0 → 0.3.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.
- package/.github/workflows/publish.yml +5 -2
- package/README.md +3 -2
- package/dist/connection.d.ts +1 -0
- package/dist/connection.js +6 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/invite.d.ts +2 -1
- package/dist/invite.js +3 -2
- package/openclaw.plugin.json +5 -0
- package/package.json +1 -1
- package/src/connection.ts +7 -1
- package/src/index.ts +5 -0
- package/src/invite.ts +4 -2
|
@@ -12,14 +12,17 @@ permissions:
|
|
|
12
12
|
jobs:
|
|
13
13
|
publish:
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
|
+
environment: npm
|
|
15
16
|
steps:
|
|
16
17
|
- uses: actions/checkout@v4
|
|
17
18
|
|
|
18
19
|
- uses: actions/setup-node@v4
|
|
19
20
|
with:
|
|
20
|
-
node-version: '
|
|
21
|
+
node-version: '24'
|
|
21
22
|
registry-url: 'https://registry.npmjs.org'
|
|
22
23
|
|
|
23
24
|
- run: npm ci
|
|
24
25
|
- run: npm run build
|
|
25
|
-
- run: npm publish
|
|
26
|
+
- run: npm publish --provenance --access public
|
|
27
|
+
env:
|
|
28
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Someone shares a Port42 channel invite link with you. Add it to OpenClaw:
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
openclaw channel add port42 \
|
|
17
|
-
--invite "https://your-host.ngrok-free.dev/invite?id=CHANNEL-UUID&name=my-channel&key=BASE64KEY" \
|
|
17
|
+
--invite "https://your-host.ngrok-free.dev/invite?id=CHANNEL-UUID&name=my-channel&key=BASE64KEY&token=GATEWAY_TOKEN" \
|
|
18
18
|
--agent my-researcher \
|
|
19
19
|
--name "Researcher"
|
|
20
20
|
```
|
|
@@ -30,7 +30,7 @@ Or edit `openclaw.json` directly:
|
|
|
30
30
|
"channels": {
|
|
31
31
|
"port42-project": {
|
|
32
32
|
"type": "port42",
|
|
33
|
-
"invite": "https://your-host.ngrok-free.dev/invite?id=CHANNEL-UUID&name=my-channel&key=BASE64KEY",
|
|
33
|
+
"invite": "https://your-host.ngrok-free.dev/invite?id=CHANNEL-UUID&name=my-channel&key=BASE64KEY&token=GATEWAY_TOKEN",
|
|
34
34
|
"displayName": "Researcher",
|
|
35
35
|
"trigger": "mention"
|
|
36
36
|
}
|
|
@@ -46,6 +46,7 @@ Or edit `openclaw.json` directly:
|
|
|
46
46
|
| `gateway` | yes* | — | WebSocket URL (derived from invite if provided) |
|
|
47
47
|
| `channelId` | yes* | — | Channel UUID (parsed from invite if provided) |
|
|
48
48
|
| `encryptionKey` | no | — | AES-256 key (parsed from invite if provided) |
|
|
49
|
+
| `token` | no | — | Gateway auth token (parsed from invite if provided) |
|
|
49
50
|
| `displayName` | yes | — | How the agent appears in Port42 |
|
|
50
51
|
| `trigger` | no | `mention` | `mention` (respond to @name) or `all` (respond to everything) |
|
|
51
52
|
|
package/dist/connection.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface ConnectionConfig {
|
|
|
7
7
|
senderId: string;
|
|
8
8
|
displayName: string;
|
|
9
9
|
encryptionKey: string | null;
|
|
10
|
+
token: string | null;
|
|
10
11
|
trigger: 'mention' | 'all';
|
|
11
12
|
onMessage: (senderName: string, content: string, messageId: string) => void;
|
|
12
13
|
onPresence?: (onlineIds: string[]) => void;
|
package/dist/connection.js
CHANGED
|
@@ -57,7 +57,12 @@ class Port42Connection {
|
|
|
57
57
|
}
|
|
58
58
|
openSocket() {
|
|
59
59
|
try {
|
|
60
|
-
|
|
60
|
+
let url = this.config.gateway;
|
|
61
|
+
if (this.config.token) {
|
|
62
|
+
const sep = url.includes('?') ? '&' : '?';
|
|
63
|
+
url = `${url}${sep}token=${encodeURIComponent(this.config.token)}`;
|
|
64
|
+
}
|
|
65
|
+
this.ws = new ws_1.default(url);
|
|
61
66
|
}
|
|
62
67
|
catch (err) {
|
|
63
68
|
console.error('[port42] Failed to create WebSocket:', err);
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -38,6 +38,7 @@ function resolveConfig(config) {
|
|
|
38
38
|
gateway: config.gateway || parsed.gateway,
|
|
39
39
|
channelId: config.channelId || parsed.channelId,
|
|
40
40
|
encryptionKey: config.encryptionKey || parsed.encryptionKey,
|
|
41
|
+
token: config.token || parsed.token,
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
44
|
if (!config.gateway || !config.channelId) {
|
|
@@ -47,6 +48,7 @@ function resolveConfig(config) {
|
|
|
47
48
|
gateway: config.gateway,
|
|
48
49
|
channelId: config.channelId,
|
|
49
50
|
encryptionKey: config.encryptionKey || null,
|
|
51
|
+
token: config.token || null,
|
|
50
52
|
};
|
|
51
53
|
}
|
|
52
54
|
/**
|
|
@@ -67,6 +69,7 @@ function register(api) {
|
|
|
67
69
|
senderId,
|
|
68
70
|
displayName: config.displayName,
|
|
69
71
|
encryptionKey: resolved.encryptionKey,
|
|
72
|
+
token: resolved.token,
|
|
70
73
|
trigger,
|
|
71
74
|
onMessage(senderName, content, messageId) {
|
|
72
75
|
if (messageHandler) {
|
package/dist/invite.d.ts
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Parse Port42 HTTPS invite links into connection config.
|
|
3
3
|
*
|
|
4
4
|
* Invite format:
|
|
5
|
-
* https://<host>/invite?id=<channel-uuid>&name=<channel-name>&key=<url-encoded-base64-aes-key>
|
|
5
|
+
* https://<host>/invite?id=<channel-uuid>&name=<channel-name>&key=<url-encoded-base64-aes-key>&token=<gateway-token>
|
|
6
6
|
*/
|
|
7
7
|
export interface InviteConfig {
|
|
8
8
|
gateway: string;
|
|
9
9
|
channelId: string;
|
|
10
10
|
channelName: string;
|
|
11
11
|
encryptionKey: string | null;
|
|
12
|
+
token: string | null;
|
|
12
13
|
}
|
|
13
14
|
export declare function parseInviteLink(invite: string): InviteConfig;
|
package/dist/invite.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Parse Port42 HTTPS invite links into connection config.
|
|
4
4
|
*
|
|
5
5
|
* Invite format:
|
|
6
|
-
* https://<host>/invite?id=<channel-uuid>&name=<channel-name>&key=<url-encoded-base64-aes-key>
|
|
6
|
+
* https://<host>/invite?id=<channel-uuid>&name=<channel-name>&key=<url-encoded-base64-aes-key>&token=<gateway-token>
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.parseInviteLink = parseInviteLink;
|
|
@@ -15,9 +15,10 @@ function parseInviteLink(invite) {
|
|
|
15
15
|
}
|
|
16
16
|
const channelName = url.searchParams.get('name') || 'unknown';
|
|
17
17
|
const encryptionKey = url.searchParams.get('key') || null;
|
|
18
|
+
const token = url.searchParams.get('token') || null;
|
|
18
19
|
// Derive WebSocket URL from the HTTPS host
|
|
19
20
|
const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
20
21
|
const gateway = `${protocol}//${url.host}/ws`;
|
|
21
|
-
return { gateway, channelId, channelName, encryptionKey };
|
|
22
|
+
return { gateway, channelId, channelName, encryptionKey, token };
|
|
22
23
|
}
|
|
23
24
|
//# sourceMappingURL=invite.js.map
|
package/openclaw.plugin.json
CHANGED
|
@@ -29,6 +29,11 @@
|
|
|
29
29
|
"description": "Base64 AES-256 encryption key",
|
|
30
30
|
"required": false
|
|
31
31
|
},
|
|
32
|
+
"token": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "Gateway authentication token",
|
|
35
|
+
"required": false
|
|
36
|
+
},
|
|
32
37
|
"displayName": {
|
|
33
38
|
"type": "string",
|
|
34
39
|
"description": "Agent display name in Port42",
|
package/package.json
CHANGED
package/src/connection.ts
CHANGED
|
@@ -20,6 +20,7 @@ export interface ConnectionConfig {
|
|
|
20
20
|
senderId: string;
|
|
21
21
|
displayName: string;
|
|
22
22
|
encryptionKey: string | null;
|
|
23
|
+
token: string | null;
|
|
23
24
|
trigger: 'mention' | 'all';
|
|
24
25
|
onMessage: (senderName: string, content: string, messageId: string) => void;
|
|
25
26
|
onPresence?: (onlineIds: string[]) => void;
|
|
@@ -90,7 +91,12 @@ export class Port42Connection {
|
|
|
90
91
|
|
|
91
92
|
private openSocket(): void {
|
|
92
93
|
try {
|
|
93
|
-
|
|
94
|
+
let url = this.config.gateway;
|
|
95
|
+
if (this.config.token) {
|
|
96
|
+
const sep = url.includes('?') ? '&' : '?';
|
|
97
|
+
url = `${url}${sep}token=${encodeURIComponent(this.config.token)}`;
|
|
98
|
+
}
|
|
99
|
+
this.ws = new WebSocket(url);
|
|
94
100
|
} catch (err) {
|
|
95
101
|
console.error('[port42] Failed to create WebSocket:', err);
|
|
96
102
|
this.scheduleReconnect();
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface Port42ChannelConfig {
|
|
|
15
15
|
gateway?: string;
|
|
16
16
|
channelId?: string;
|
|
17
17
|
encryptionKey?: string;
|
|
18
|
+
token?: string;
|
|
18
19
|
displayName: string;
|
|
19
20
|
trigger?: 'mention' | 'all';
|
|
20
21
|
}
|
|
@@ -64,6 +65,7 @@ function resolveConfig(config: Port42ChannelConfig): {
|
|
|
64
65
|
gateway: string;
|
|
65
66
|
channelId: string;
|
|
66
67
|
encryptionKey: string | null;
|
|
68
|
+
token: string | null;
|
|
67
69
|
} {
|
|
68
70
|
if (config.invite) {
|
|
69
71
|
const parsed = parseInviteLink(config.invite);
|
|
@@ -71,6 +73,7 @@ function resolveConfig(config: Port42ChannelConfig): {
|
|
|
71
73
|
gateway: config.gateway || parsed.gateway,
|
|
72
74
|
channelId: config.channelId || parsed.channelId,
|
|
73
75
|
encryptionKey: config.encryptionKey || parsed.encryptionKey,
|
|
76
|
+
token: config.token || parsed.token,
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
|
|
@@ -82,6 +85,7 @@ function resolveConfig(config: Port42ChannelConfig): {
|
|
|
82
85
|
gateway: config.gateway,
|
|
83
86
|
channelId: config.channelId,
|
|
84
87
|
encryptionKey: config.encryptionKey || null,
|
|
88
|
+
token: config.token || null,
|
|
85
89
|
};
|
|
86
90
|
}
|
|
87
91
|
|
|
@@ -106,6 +110,7 @@ export function register(api: PluginAPI): void {
|
|
|
106
110
|
senderId,
|
|
107
111
|
displayName: config.displayName,
|
|
108
112
|
encryptionKey: resolved.encryptionKey,
|
|
113
|
+
token: resolved.token,
|
|
109
114
|
trigger,
|
|
110
115
|
|
|
111
116
|
onMessage(senderName, content, messageId) {
|
package/src/invite.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Parse Port42 HTTPS invite links into connection config.
|
|
3
3
|
*
|
|
4
4
|
* Invite format:
|
|
5
|
-
* https://<host>/invite?id=<channel-uuid>&name=<channel-name>&key=<url-encoded-base64-aes-key>
|
|
5
|
+
* https://<host>/invite?id=<channel-uuid>&name=<channel-name>&key=<url-encoded-base64-aes-key>&token=<gateway-token>
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
export interface InviteConfig {
|
|
@@ -10,6 +10,7 @@ export interface InviteConfig {
|
|
|
10
10
|
channelId: string;
|
|
11
11
|
channelName: string;
|
|
12
12
|
encryptionKey: string | null;
|
|
13
|
+
token: string | null;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export function parseInviteLink(invite: string): InviteConfig {
|
|
@@ -22,10 +23,11 @@ export function parseInviteLink(invite: string): InviteConfig {
|
|
|
22
23
|
|
|
23
24
|
const channelName = url.searchParams.get('name') || 'unknown';
|
|
24
25
|
const encryptionKey = url.searchParams.get('key') || null;
|
|
26
|
+
const token = url.searchParams.get('token') || null;
|
|
25
27
|
|
|
26
28
|
// Derive WebSocket URL from the HTTPS host
|
|
27
29
|
const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
28
30
|
const gateway = `${protocol}//${url.host}/ws`;
|
|
29
31
|
|
|
30
|
-
return { gateway, channelId, channelName, encryptionKey };
|
|
32
|
+
return { gateway, channelId, channelName, encryptionKey, token };
|
|
31
33
|
}
|