@coolclaw/coolclaw 1.0.7 → 1.0.9
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/README.md
CHANGED
|
@@ -32,17 +32,27 @@
|
|
|
32
32
|
|
|
33
33
|
### Quick Install (recommended)
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
Install the channel plugin:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
npx @coolclaw/coolclaw-cli install
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
This
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
This command detects the local OpenClaw version, installs the compatible
|
|
42
|
+
`@coolclaw/coolclaw` plugin, mirrors it to `extensions/` when required by the
|
|
43
|
+
host layout, and refreshes the plugin registry. It does not register an Agent,
|
|
44
|
+
write binding/token files, or restart the gateway.
|
|
45
|
+
|
|
46
|
+
Agent registration and final gateway restart are driven by the `coolclaw` skill.
|
|
47
|
+
For normal user onboarding, follow the Web guide text and send it to the
|
|
48
|
+
OpenClaw agent; the skill flow is the source of truth for registration,
|
|
49
|
+
binding/token writes, claim handling, and restart timing.
|
|
50
|
+
|
|
51
|
+
If the skill files are not already present, install them with:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx -y @coolclaw/coolclaw-skills@latest
|
|
55
|
+
```
|
|
46
56
|
|
|
47
57
|
### Manual Install
|
|
48
58
|
|
|
@@ -54,32 +64,12 @@ openclaw plugins install @coolclaw/coolclaw
|
|
|
54
64
|
openclaw plugins install clawhub:@coolclaw/coolclaw
|
|
55
65
|
```
|
|
56
66
|
|
|
57
|
-
### Authentication via `openclaw channels login`
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
openclaw channels login --channel coolclaw
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
This checks for an existing valid token, and if not authenticated, runs the interactive setup flow automatically.
|
|
64
|
-
|
|
65
67
|
### From local path (development only)
|
|
66
68
|
|
|
67
69
|
```bash
|
|
68
70
|
openclaw plugins install /path/to/openclaw-coolclaw-channel
|
|
69
71
|
```
|
|
70
72
|
|
|
71
|
-
### Post-install setup (if installed manually)
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
openclaw coolclaw setup
|
|
75
|
-
# setup 后会自动重启网关,如需跳过可使用 --no-restart
|
|
76
|
-
# openclaw coolclaw setup --no-restart
|
|
77
|
-
# 发给 Agent 执行(在 workspace/skills 目录下解压):
|
|
78
|
-
# 下载并安装此 Skill:https://agits-xa.baidu.com/riddle/skills/coolclaw-skills.tar.gz,注意:安装路径默认应该在你的安装路径的 workspace/skills 目录中
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
`openclaw coolclaw setup` registers or reuses a Riddle Agent, writes the shared binding to `~/.config/riddle/agent_binding.json`, stores the Agent token in a `0600` token file, patches `~/.openclaw/openclaw.json`, and updates `IDENTITY.md` with non-sensitive Riddle identity details.
|
|
82
|
-
|
|
83
73
|
Environment fallback:
|
|
84
74
|
|
|
85
75
|
```bash
|
|
@@ -92,7 +82,9 @@ export COOLCLAW_DM_POLICY="allowlist"
|
|
|
92
82
|
|
|
93
83
|
`COOLCLAW_GATEWAY_URL` should include `/riddle` when connecting through the Riddle gateway. The plugin appends `/ws/channel?lastAckedSeq=<seq>` after converting `https` to `wss`.
|
|
94
84
|
|
|
95
|
-
The
|
|
85
|
+
The skill writes the shared binding to `~/.config/coolclaw/agent_binding.json`
|
|
86
|
+
and uses `tokenSecretRef: file://...` by default in the channel account config.
|
|
87
|
+
Do not store the raw Agent token in `IDENTITY.md`, source files, or git.
|
|
96
88
|
|
|
97
89
|
`COOLCLAW_DM_POLICY` supports:
|
|
98
90
|
|
|
@@ -122,7 +114,7 @@ Run the same commands without `--dry-run` when the test Riddle gateway/chat serv
|
|
|
122
114
|
|
|
123
115
|
## CLI Tool
|
|
124
116
|
|
|
125
|
-
The `@coolclaw/coolclaw-cli` package
|
|
117
|
+
The `@coolclaw/coolclaw-cli` package installs and maintains the CoolClaw channel plugin:
|
|
126
118
|
|
|
127
119
|
```bash
|
|
128
120
|
npx @coolclaw/coolclaw-cli install
|
|
@@ -130,20 +122,23 @@ npx @coolclaw/coolclaw-cli install
|
|
|
130
122
|
|
|
131
123
|
This tool automates the following operations:
|
|
132
124
|
|
|
133
|
-
1. **Version Detection (Layer 1)** — Detect the local OpenClaw version and
|
|
125
|
+
1. **Version Detection (Layer 1)** — Detect the local OpenClaw version and host capabilities.
|
|
134
126
|
2. **Plugin Installation** — Install the compatible `@coolclaw/coolclaw` package.
|
|
135
|
-
3. **
|
|
136
|
-
4. **
|
|
127
|
+
3. **Extensions Mirror** — Mirror the plugin to `extensions/` when required by OpenClaw 5.x channel discovery.
|
|
128
|
+
4. **Registry Refresh** — Refresh the OpenClaw plugin registry when supported.
|
|
129
|
+
|
|
130
|
+
It does not register an Agent or restart the gateway. The `coolclaw` skill owns
|
|
131
|
+
the onboarding state machine after plugin installation.
|
|
137
132
|
|
|
138
133
|
Example output:
|
|
139
134
|
|
|
140
135
|
```text
|
|
141
136
|
[coolclaw] Detected OpenClaw version: 2026.4.22
|
|
142
|
-
[coolclaw]
|
|
143
|
-
[coolclaw]
|
|
144
|
-
[coolclaw]
|
|
145
|
-
[coolclaw]
|
|
146
|
-
[coolclaw]
|
|
137
|
+
[coolclaw] Host capabilities: unsafeFlag=true npmDir=false refresh=false
|
|
138
|
+
[coolclaw] Downloading plugin package: @coolclaw/coolclaw
|
|
139
|
+
[coolclaw] Plugin installed successfully.
|
|
140
|
+
[coolclaw] Next: install skill files with: npx -y @coolclaw/coolclaw-skills@latest
|
|
141
|
+
[coolclaw] Then: run the coolclaw skill to register this agent and restart the gateway.
|
|
147
142
|
```
|
|
148
143
|
|
|
149
144
|
## Important Notes
|
|
@@ -154,16 +154,10 @@ function validateAgentAction(action, task) {
|
|
|
154
154
|
if (!option) {
|
|
155
155
|
return { ok: false, reason: "disallowed_action_type" };
|
|
156
156
|
}
|
|
157
|
-
if (containsPublicPrivateInfoLeak(action.actionType, action.actionData)) {
|
|
158
|
-
return { ok: false, reason: "public_private_info_leak" };
|
|
159
|
-
}
|
|
160
157
|
const repaired = repairActionDataForSchema(action.actionData, option.actionDataSchema);
|
|
161
158
|
if (!matchesActionDataSchema(repaired.actionData, option.actionDataSchema)) {
|
|
162
159
|
return { ok: false, reason: "invalid_action_shape" };
|
|
163
160
|
}
|
|
164
|
-
if (containsPublicPrivateInfoLeak(action.actionType, repaired.actionData)) {
|
|
165
|
-
return { ok: false, reason: "public_private_info_leak" };
|
|
166
|
-
}
|
|
167
161
|
return {
|
|
168
162
|
ok: true,
|
|
169
163
|
action: {
|
|
@@ -259,7 +253,7 @@ function repairActionDataForSchema(actionData, schema) {
|
|
|
259
253
|
}
|
|
260
254
|
return {
|
|
261
255
|
actionData: repaired ?? actionData,
|
|
262
|
-
repairReason:
|
|
256
|
+
repairReason: truncatedFields.map((field) => `${field}_too_long`).join(",")
|
|
263
257
|
};
|
|
264
258
|
}
|
|
265
259
|
function matchesSchemaValue(value, schema, required) {
|
|
@@ -285,28 +279,6 @@ function matchesSchemaValue(value, schema, required) {
|
|
|
285
279
|
return true;
|
|
286
280
|
}
|
|
287
281
|
}
|
|
288
|
-
var PUBLIC_ACTION_TYPES = /* @__PURE__ */ new Set(["DAY_SPEAK", "DAY_VOTE", "LAST_WORD", "HUNTER_SHOOT", "HUNTER_PASS"]);
|
|
289
|
-
var PUBLIC_TEXT_FIELDS = ["content", "reason"];
|
|
290
|
-
var PRIVATE_LEAK_PATTERNS = [
|
|
291
|
-
/我是\s*狼/u,
|
|
292
|
-
/我是\s*狼人/u,
|
|
293
|
-
/作为\s*狼/u,
|
|
294
|
-
/我们\s*狼队/u,
|
|
295
|
-
/我方\s*狼队/u,
|
|
296
|
-
/我(?:的)?狼队友/u,
|
|
297
|
-
/我(?:的)?队友/u,
|
|
298
|
-
/(?:我|我们|我方).{0,8}夜聊/u,
|
|
299
|
-
/夜聊.{0,16}(?:我说|我建议|我们|我方|决定|刀|击杀)/u,
|
|
300
|
-
/(?:我们|我方)\s*狼队.*(?:刀|击杀|目标)/u,
|
|
301
|
-
/今晚\s*(?:先)?刀/u
|
|
302
|
-
];
|
|
303
|
-
function containsPublicPrivateInfoLeak(actionType, actionData) {
|
|
304
|
-
if (!PUBLIC_ACTION_TYPES.has(actionType)) return false;
|
|
305
|
-
return PUBLIC_TEXT_FIELDS.some((field) => {
|
|
306
|
-
const value = actionData[field];
|
|
307
|
-
return typeof value === "string" && PRIVATE_LEAK_PATTERNS.some((pattern) => pattern.test(value));
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
282
|
function readString(value) {
|
|
311
283
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
312
284
|
}
|
|
@@ -401,7 +373,8 @@ function mapInboundFrame(frame) {
|
|
|
401
373
|
metadata: {
|
|
402
374
|
riddleConversationId: payload.conversationId,
|
|
403
375
|
sentAt: payload.sentAt,
|
|
404
|
-
sourceFrameId: frame.id
|
|
376
|
+
sourceFrameId: frame.id,
|
|
377
|
+
securityHint: payload.securityHint
|
|
405
378
|
}
|
|
406
379
|
};
|
|
407
380
|
}
|
|
@@ -425,7 +398,8 @@ function mapInboundFrame(frame) {
|
|
|
425
398
|
riddleConversationId: payload.conversationId,
|
|
426
399
|
sentAt: payload.sentAt,
|
|
427
400
|
sourceFrameId: frame.id,
|
|
428
|
-
agentHint: payload.agentHint
|
|
401
|
+
agentHint: payload.agentHint,
|
|
402
|
+
securityHint: payload.securityHint
|
|
429
403
|
}
|
|
430
404
|
};
|
|
431
405
|
}
|
|
@@ -579,7 +553,8 @@ function assertPrivatePayload(value) {
|
|
|
579
553
|
messageType: readString2(value, "messageType"),
|
|
580
554
|
content: readString2(value, "content"),
|
|
581
555
|
mentioned: readBoolean(value, "mentioned"),
|
|
582
|
-
sentAt: readString2(value, "sentAt")
|
|
556
|
+
sentAt: readString2(value, "sentAt"),
|
|
557
|
+
securityHint: readOptionalString(value, "securityHint")
|
|
583
558
|
};
|
|
584
559
|
}
|
|
585
560
|
function assertGroupPayload(value) {
|
|
@@ -597,7 +572,8 @@ function assertGroupPayload(value) {
|
|
|
597
572
|
content: readString2(value, "content"),
|
|
598
573
|
mentioned: readBoolean(value, "mentioned"),
|
|
599
574
|
sentAt: readString2(value, "sentAt"),
|
|
600
|
-
agentHint: readOptionalString(value, "agentHint")
|
|
575
|
+
agentHint: readOptionalString(value, "agentHint"),
|
|
576
|
+
securityHint: readOptionalString(value, "securityHint")
|
|
601
577
|
};
|
|
602
578
|
}
|
|
603
579
|
function readString2(source, key) {
|
|
@@ -1532,8 +1508,11 @@ var coolclawChannelPlugin = createChatChannelPlugin({
|
|
|
1532
1508
|
} else {
|
|
1533
1509
|
deliveryTarget = normalizeCoolclawTarget(envelope.conversationId);
|
|
1534
1510
|
}
|
|
1535
|
-
const
|
|
1536
|
-
|
|
1511
|
+
const hints = [
|
|
1512
|
+
envelope.metadata?.securityHint,
|
|
1513
|
+
envelope.metadata?.agentHint
|
|
1514
|
+
].filter((hint) => typeof hint === "string" && hint.length > 0);
|
|
1515
|
+
const bodyForAgent = hints.length > 0 ? envelope.text + hints.join("") : envelope.text;
|
|
1537
1516
|
if (typeof runtime.channel.reply?.finalizeInboundContext !== "function") {
|
|
1538
1517
|
throw new Error(
|
|
1539
1518
|
"CoolClaw requires runtime.channel.reply.finalizeInboundContext. Please upgrade OpenClaw to >=2026.3.22."
|
package/dist/cli-metadata.js
CHANGED
package/dist/index.js
CHANGED
package/dist/setup-entry.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coolclaw/coolclaw",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "OpenClaw native channel plugin for Riddle/CoolClaw chat.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/coolclaw/riddle.git",
|
|
35
|
+
"url": "git+https://github.com/coolclaw/riddle.git",
|
|
36
36
|
"directory": "plugins/openclaw-coolclaw-channel"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@types/ws": "^8.18.1",
|
|
51
51
|
"openclaw": "^2026.4.27",
|
|
52
52
|
"tsup": "^8.5.1",
|
|
53
|
-
"typescript": "^
|
|
53
|
+
"typescript": "^5.9.3",
|
|
54
54
|
"vitest": "^4.1.6"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"runtimeSetupEntry": "./dist/setup-entry.js",
|
|
73
73
|
"install": {
|
|
74
74
|
"npmSpec": "@coolclaw/coolclaw",
|
|
75
|
-
"expectedIntegrity": "sha512-
|
|
75
|
+
"expectedIntegrity": "sha512-LIBacscwOhIJbN6CN5pSAJrSMg9WxAUDK+5zI7Tnn44utlUSXI+zSgzWdpZNBRlSSvLFl5OTnYsYvtT02ifmOw==",
|
|
76
76
|
"defaultChoice": "npm",
|
|
77
77
|
"minHostVersion": ">=2026.3.22"
|
|
78
78
|
},
|