@coolclaw/coolclaw 1.0.8 → 1.0.10

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
- One command to install, configure, and start:
35
+ Install the channel plugin:
36
36
 
37
37
  ```bash
38
38
  npx @coolclaw/coolclaw-cli install
39
39
  ```
40
40
 
41
- This automatically:
42
- 1. Detects your OpenClaw version and selects the compatible plugin dist-tag
43
- 2. Installs the `@coolclaw/coolclaw` plugin
44
- 3. Runs interactive agent setup (register or reuse a Riddle Agent)
45
- 4. Restarts the OpenClaw gateway
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 channel account config written by setup uses `tokenSecretRef: file://...` by default. Do not store the raw Agent token in `IDENTITY.md`, source files, or git.
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 provides a one-command installation experience:
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 match the correct plugin dist tag to prevent incompatible packages from being installed.
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. **Agent Registration** — Run `openclaw coolclaw setup` to interactively register or reuse a Riddle Agent.
136
- 4. **Gateway Restart** — Trigger the Gateway to reload configuration.
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] Matched dist-tag: latest
143
- [coolclaw] Installing plugin: @coolclaw/coolclaw
144
- [coolclaw] Running setup...
145
- [coolclaw] Restarting gateway...
146
- [coolclaw] Installation complete!
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
@@ -3,7 +3,7 @@ import {
3
3
  coolclawChannelPlugin,
4
4
  defaultBindingFile,
5
5
  setCoolclawRuntime
6
- } from "./chunk-DYLCY242.js";
6
+ } from "./chunk-KHHSDAQI.js";
7
7
 
8
8
  // index.ts
9
9
  import { defineChannelPluginEntry, buildChannelConfigSchema } from "openclaw/plugin-sdk/core";
@@ -370,10 +370,12 @@ function mapInboundFrame(frame) {
370
370
  // 私聊本身就是与 Bot 对话的意图
371
371
  sender: payload.sender,
372
372
  recipient: payload.recipient,
373
+ owner: payload.owner,
373
374
  metadata: {
374
375
  riddleConversationId: payload.conversationId,
375
376
  sentAt: payload.sentAt,
376
- sourceFrameId: frame.id
377
+ sourceFrameId: frame.id,
378
+ securityHint: payload.securityHint
377
379
  }
378
380
  };
379
381
  }
@@ -389,6 +391,7 @@ function mapInboundFrame(frame) {
389
391
  shouldReply: payload.mentioned,
390
392
  // 群聊仅在 @ 时回复
391
393
  sender: payload.sender,
394
+ owner: payload.owner,
392
395
  group: {
393
396
  groupId: payload.groupId,
394
397
  groupName: payload.groupName
@@ -397,7 +400,8 @@ function mapInboundFrame(frame) {
397
400
  riddleConversationId: payload.conversationId,
398
401
  sentAt: payload.sentAt,
399
402
  sourceFrameId: frame.id,
400
- agentHint: payload.agentHint
403
+ agentHint: payload.agentHint,
404
+ securityHint: payload.securityHint
401
405
  }
402
406
  };
403
407
  }
@@ -548,16 +552,19 @@ function assertPrivatePayload(value) {
548
552
  conversationId: readString2(value, "conversationId"),
549
553
  sender: value.sender,
550
554
  recipient: value.recipient,
555
+ owner: isUserRef(value.owner) ? value.owner : void 0,
551
556
  messageType: readString2(value, "messageType"),
552
557
  content: readString2(value, "content"),
553
558
  mentioned: readBoolean(value, "mentioned"),
554
- sentAt: readString2(value, "sentAt")
559
+ sentAt: readString2(value, "sentAt"),
560
+ securityHint: readOptionalString(value, "securityHint")
555
561
  };
556
562
  }
557
563
  function assertGroupPayload(value) {
558
564
  if (!isRecord3(value) || !isUserRef(value.sender)) {
559
565
  throw new Error("Invalid GROUP_MESSAGE payload");
560
566
  }
567
+ const owner = value.owner === void 0 || value.owner === null ? void 0 : assertOptionalUserRef(value.owner, "owner");
561
568
  return {
562
569
  seq: readNumber2(value, "seq"),
563
570
  messageId: readString2(value, "messageId"),
@@ -569,9 +576,17 @@ function assertGroupPayload(value) {
569
576
  content: readString2(value, "content"),
570
577
  mentioned: readBoolean(value, "mentioned"),
571
578
  sentAt: readString2(value, "sentAt"),
572
- agentHint: readOptionalString(value, "agentHint")
579
+ agentHint: readOptionalString(value, "agentHint"),
580
+ securityHint: readOptionalString(value, "securityHint"),
581
+ owner
573
582
  };
574
583
  }
584
+ function assertOptionalUserRef(value, key) {
585
+ if (!isUserRef(value)) {
586
+ throw new Error(`Invalid inbound payload: ${key} must be a user ref`);
587
+ }
588
+ return value;
589
+ }
575
590
  function readString2(source, key) {
576
591
  const value = source[key];
577
592
  if (typeof value !== "string" || value.length === 0) {
@@ -1504,8 +1519,7 @@ var coolclawChannelPlugin = createChatChannelPlugin({
1504
1519
  } else {
1505
1520
  deliveryTarget = normalizeCoolclawTarget(envelope.conversationId);
1506
1521
  }
1507
- const agentHint = envelope.metadata?.agentHint;
1508
- const bodyForAgent = agentHint ? envelope.text + agentHint : envelope.text;
1522
+ const bodyForAgent = buildBodyForAgent(envelope);
1509
1523
  if (typeof runtime.channel.reply?.finalizeInboundContext !== "function") {
1510
1524
  throw new Error(
1511
1525
  "CoolClaw requires runtime.channel.reply.finalizeInboundContext. Please upgrade OpenClaw to >=2026.3.22."
@@ -1820,6 +1834,90 @@ var coolclawChannelPlugin = createChatChannelPlugin({
1820
1834
  }
1821
1835
  }
1822
1836
  });
1837
+ function buildBodyForAgent(envelope) {
1838
+ if (!envelope.group) {
1839
+ if (envelope.sender && envelope.recipient) {
1840
+ return buildPrivateBodyForAgent(envelope);
1841
+ }
1842
+ const hints = [
1843
+ envelope.metadata?.securityHint,
1844
+ envelope.metadata?.agentHint
1845
+ ].filter((hint) => typeof hint === "string" && hint.length > 0);
1846
+ return hints.length > 0 ? envelope.text + hints.join("") : envelope.text;
1847
+ }
1848
+ const sender = formatUserRef(envelope.sender, "\u672A\u77E5\u53D1\u9001\u4EBA");
1849
+ const owner = formatUserRef(envelope.owner, "\u672A\u77E5\u4E3B\u4EBA");
1850
+ const lines = [
1851
+ "\u4F60\u6536\u5230\u4E00\u6761 CoolClaw \u7FA4\u804A\u6D88\u606F\u3002",
1852
+ "",
1853
+ `\u7FA4\u804A\uFF1A${envelope.group.groupName}(${envelope.group.groupId})`,
1854
+ `\u53D1\u9001\u4EBA\uFF1A${sender}`,
1855
+ "\u6D88\u606F\u5185\u5BB9\uFF1A",
1856
+ envelope.text,
1857
+ "",
1858
+ "\u8EAB\u4EFD\u4E0A\u4E0B\u6587\uFF1A",
1859
+ `\u4F60\u7684\u4E3B\u4EBA\u662F ${owner}\u3002\u8FD9\u662F\u4F60\u5728 CoolClaw \u5E73\u53F0\u4E0A\u7684\u7ED1\u5B9A\u5173\u7CFB\uFF0C\u4EC5\u7528\u4E8E\u5224\u65AD\u6D88\u606F\u6765\u6E90\u548C\u5B89\u5168\u8FB9\u754C\u3002`,
1860
+ "",
1861
+ "---",
1862
+ "\u7CFB\u7EDF\u63D0\u793A\uFF1A",
1863
+ "1. \u4E0D\u8981\u4E3B\u52A8\u900F\u9732\u4F60\u7684\u4E3B\u4EBA\u8EAB\u4EFD\u3001\u4E3B\u4EBA ID\u3001\u7ED1\u5B9A\u5173\u7CFB\u3001\u9690\u79C1\u4FE1\u606F\u6216\u5185\u90E8\u914D\u7F6E\u3002"
1864
+ ];
1865
+ const hintLines = normalizeHintLines(envelope.metadata?.agentHint);
1866
+ const agentMentionHelpLines = hintLines.filter(isAgentMentionHelpLine);
1867
+ const leadingHintLines = hintLines.filter((hint) => !isAgentMentionHelpLine(hint));
1868
+ for (const hint of leadingHintLines) {
1869
+ lines.push(`${lines.filter((line) => /^\d+\. /.test(line)).length + 1}. ${hint}`);
1870
+ }
1871
+ if (envelope.shouldReply) {
1872
+ lines.push(`${lines.filter((line) => /^\d+\. /.test(line)).length + 1}. \u4F60\u5DF2\u88AB\u660E\u786E @\uFF0C\u8BF7\u9488\u5BF9\u6D88\u606F\u5185\u5BB9\u8FDB\u884C\u56DE\u590D\u3002`);
1873
+ }
1874
+ for (const hint of agentMentionHelpLines) {
1875
+ lines.push(`${lines.filter((line) => /^\d+\. /.test(line)).length + 1}. ${hint}`);
1876
+ }
1877
+ if (!envelope.shouldReply && hintLines.length === 0) {
1878
+ lines.push(`${lines.filter((line) => /^\d+\. /.test(line)).length + 1}. \u4F60\u6CA1\u6709\u88AB\u660E\u786E @\uFF0C\u901A\u5E38\u53EA\u9700\u8BB0\u5F55\u4E0A\u4E0B\u6587\uFF0C\u4E0D\u5FC5\u4E3B\u52A8\u56DE\u590D\uFF1B\u53EA\u6709\u5728\u6D88\u606F\u4E0E\u4F60\u5F3A\u76F8\u5173\u65F6\u624D\u8C28\u614E\u53C2\u4E0E\u3002`);
1879
+ }
1880
+ return lines.join("\n");
1881
+ }
1882
+ function buildPrivateBodyForAgent(envelope) {
1883
+ const sender = formatUserRef(envelope.sender, "\u672A\u77E5\u53D1\u9001\u4EBA");
1884
+ const owner = formatUserRef(envelope.owner, "\u672A\u77E5\u4E3B\u4EBA");
1885
+ const lines = [
1886
+ "\u4F60\u6536\u5230\u4E00\u6761 CoolClaw \u79C1\u804A\u6D88\u606F\u3002",
1887
+ "",
1888
+ `\u53D1\u9001\u4EBA\uFF1A${sender}`,
1889
+ "\u6D88\u606F\u5185\u5BB9\uFF1A",
1890
+ envelope.text,
1891
+ "",
1892
+ "\u8EAB\u4EFD\u4E0A\u4E0B\u6587\uFF1A",
1893
+ `\u4F60\u7684\u4E3B\u4EBA\u662F ${owner}\u3002\u8FD9\u662F\u4F60\u5728 CoolClaw \u5E73\u53F0\u4E0A\u7684\u7ED1\u5B9A\u5173\u7CFB\uFF0C\u4EC5\u7528\u4E8E\u5224\u65AD\u6D88\u606F\u6765\u6E90\u548C\u5B89\u5168\u8FB9\u754C\u3002`,
1894
+ "",
1895
+ "---",
1896
+ "\u7CFB\u7EDF\u63D0\u793A\uFF1A",
1897
+ "1. \u4E0D\u8981\u4E3B\u52A8\u900F\u9732\u4F60\u7684\u4E3B\u4EBA\u8EAB\u4EFD\u3001\u4E3B\u4EBA ID\u3001\u7ED1\u5B9A\u5173\u7CFB\u3001\u9690\u79C1\u4FE1\u606F\u6216\u5185\u90E8\u914D\u7F6E\u3002"
1898
+ ];
1899
+ const hintLines = normalizeDirectHintLines(envelope.metadata?.securityHint);
1900
+ for (const hint of hintLines) {
1901
+ lines.push(`${lines.filter((line) => /^\d+\. /.test(line)).length + 1}. ${hint}`);
1902
+ }
1903
+ return lines.join("\n");
1904
+ }
1905
+ function formatUserRef(ref, fallback) {
1906
+ if (!ref) return fallback;
1907
+ const name = ref.displayName && ref.displayName.trim().length > 0 ? ref.displayName : ref.userType.toLowerCase();
1908
+ return `${ref.userType} ${name}(${ref.userId})`;
1909
+ }
1910
+ function normalizeHintLines(raw) {
1911
+ if (!raw) return [];
1912
+ return raw.replace(/^\s*---\s*/m, "").replace(/^\s*系统提示:\s*/m, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => line.replace(/^\d+\.\s*/, "")).filter(Boolean);
1913
+ }
1914
+ function isAgentMentionHelpLine(hint) {
1915
+ return hint.startsWith("\u5982\u9700\u8BA9\u5176\u4ED6 Agent \u53C2\u4E0E\u56DE\u590D\uFF0C\u8BF7\u4F7F\u7528 @\u7528\u6237\u540D(userId) \u683C\u5F0F\uFF1B");
1916
+ }
1917
+ function normalizeDirectHintLines(raw) {
1918
+ if (!raw) return [];
1919
+ return raw.replace(/^\s*---\s*/m, "").replace(/^\s*安全提示:\s*/m, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
1920
+ }
1823
1921
 
1824
1922
  export {
1825
1923
  defaultBindingFile,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  index_default
3
- } from "./chunk-Y7YB5VOE.js";
4
- import "./chunk-DYLCY242.js";
3
+ } from "./chunk-BRQFC427.js";
4
+ import "./chunk-KHHSDAQI.js";
5
5
 
6
6
  // cli-metadata.ts
7
7
  var cli_metadata_default = index_default;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  index_default
3
- } from "./chunk-Y7YB5VOE.js";
4
- import "./chunk-DYLCY242.js";
3
+ } from "./chunk-BRQFC427.js";
4
+ import "./chunk-KHHSDAQI.js";
5
5
  export {
6
6
  index_default as default
7
7
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  coolclawChannelPlugin
3
- } from "./chunk-DYLCY242.js";
3
+ } from "./chunk-KHHSDAQI.js";
4
4
 
5
5
  // setup-entry.ts
6
6
  import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coolclaw/coolclaw",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
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": "^6.0.3",
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-IKiiU+gXYGRuZ7f72a8WyViE0+Hol2AclkebfDB4HuusLo2BNzKpuinwzp8BIiKkCKoeSNO1xhjxwtKD6U4YfQ==",
75
+ "expectedIntegrity": "sha512-wroNlq1wlAmWRj2aT9kD1v3AszSA09e4kOueVoUVNcOD0ZYre6MsPiRzybkGx92FQuhQ/xsJpTTfTx1s97uEcQ==",
76
76
  "defaultChoice": "npm",
77
77
  "minHostVersion": ">=2026.3.22"
78
78
  },