sophhub 0.4.63 → 0.4.65

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.
@@ -1,10 +1,68 @@
1
1
  {
2
- "version": "1.0.10",
2
+ "version": "1.0.11",
3
3
  "agent_id": "ai-cs-qa",
4
4
  "description": "智能客服,通过 bot API 为客户提供服务",
5
5
  "bot_api_enabled": true,
6
6
  "workspace": "/home/node/.openclaw/workspace-knowledge/workspace-qa",
7
7
  "agent_dependencies": ["ai-cs-admin"],
8
+ "install": {
9
+ "bot_api": {
10
+ "commands": {
11
+ "text": false
12
+ },
13
+ "exec": {
14
+ "induceCommandStarters": [
15
+ "uv run",
16
+ "python",
17
+ "python3",
18
+ "node",
19
+ "bash",
20
+ "curl",
21
+ "kubectl",
22
+ "ls",
23
+ "env",
24
+ "cat",
25
+ "head",
26
+ "tail",
27
+ "find",
28
+ "grep"
29
+ ],
30
+ "commandContentDeny": [
31
+ "sophnet_tools",
32
+ "get_api_key",
33
+ "get-api-key",
34
+ "getApiKey",
35
+ "openclaw.json",
36
+ "models.providers",
37
+ "apiSecret",
38
+ "api_secret",
39
+ "apiKey",
40
+ "api_key",
41
+ ".base.json"
42
+ ],
43
+ "networkDenyTools": [
44
+ "curl",
45
+ "wget",
46
+ "ncat",
47
+ "nc",
48
+ "ssh"
49
+ ],
50
+ "networkDenyCode": [
51
+ "requests.",
52
+ "httpx",
53
+ "urllib",
54
+ "fetch(",
55
+ "http.client"
56
+ ],
57
+ "networkDetectUrls": true,
58
+ "networkAllowHosts": [
59
+ "sophnet.com",
60
+ "www.sophnet.com"
61
+ ],
62
+ "blockUnlistedNetwork": true
63
+ }
64
+ }
65
+ },
8
66
  "post_install": [
9
67
  {
10
68
  "name": "setup-links",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sophhub",
3
- "version": "0.4.63",
3
+ "version": "0.4.65",
4
4
  "description": "SophHub CLI - Manage and download AI Agent skills and agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "agent-install",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "types": [
5
5
  "store"
6
6
  ],
7
7
  "displayName": "Agent安装",
8
8
  "description": "安装或升级 Sophclaw Agent(含占位替换、备份、post_install 脚本与自动安装 skill)。",
9
9
  "changelog": [
10
+ {
11
+ "changes": [
12
+ "bot-api 账号安装透传 commands/exec,升级改 deep-merge 保留已有黑名单,修复升级清空 exec 的 BUG"
13
+ ],
14
+ "date": "2026-07-24",
15
+ "version": "0.1.16"
16
+ },
10
17
  {
11
18
  "changes": [
12
19
  "修复 update_openclaw.py 新建实例时覆盖原实例的严重 BUG:改为按目标 openclaw_id 定位条目,新建时追加、不覆盖同源原实例"
@@ -103,5 +110,5 @@
103
110
  }
104
111
  ],
105
112
  "createdAt": "2026-04-21",
106
- "updatedAt": "2026-07-09"
113
+ "updatedAt": "2026-07-24"
107
114
  }
@@ -354,12 +354,19 @@ def build_bot_api_account(
354
354
  account_name = bot_api.get("account_name") or resolved_name or identity_name_str or agent_label_str or source_agent_id
355
355
  enabled = bot_api.get("enabled", True)
356
356
 
357
- return account_id, {
357
+ account: dict[str, Any] = {
358
358
  "agentId": agent_id,
359
359
  "name": account_name,
360
360
  "apiSecret": existing_secret or secrets.token_hex(32),
361
361
  "enabled": enabled,
362
362
  }
363
+ commands = bot_api.get("commands")
364
+ if isinstance(commands, dict):
365
+ account["commands"] = commands
366
+ exec_config = bot_api.get("exec")
367
+ if isinstance(exec_config, dict):
368
+ account["exec"] = exec_config
369
+ return account_id, account
363
370
 
364
371
 
365
372
  def load_openclaw_config(config_path: Path) -> dict[str, Any]:
@@ -141,7 +141,11 @@ def ensure_bot_api(
141
141
  bot_api = channels.setdefault("bot-api", {})
142
142
  accounts = bot_api.setdefault("accounts", {})
143
143
  action = "updated" if account_id in accounts else "created"
144
- accounts[account_id] = account
144
+ existing_account = accounts.get(account_id, {})
145
+ if isinstance(existing_account, dict):
146
+ accounts[account_id] = deep_merge_dict(existing_account, account)
147
+ else:
148
+ accounts[account_id] = account
145
149
 
146
150
  return {
147
151
  "account_id": account_id,
@@ -0,0 +1,116 @@
1
+ """验证 bot-api 账号的 commands/exec 黑名单能从 .config.json 透传进 openclaw.json,
2
+ 且升级时不会覆盖已有黑名单。"""
3
+
4
+ from __future__ import annotations
5
+
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ SCRIPTS = Path(__file__).resolve().parent.parent / "scripts"
10
+ sys.path.insert(0, str(SCRIPTS))
11
+
12
+ from common import build_bot_api_account, deep_merge_dict # noqa: E402
13
+ from update_openclaw import ensure_bot_api # noqa: E402
14
+
15
+
16
+ def _agent_def(bot_api: dict | None = None) -> dict:
17
+ d = {"agent_id": "ai-cs-qa", "bot_api_enabled": True}
18
+ if bot_api is not None:
19
+ d["install"] = {"bot_api": bot_api}
20
+ return d
21
+
22
+
23
+ def test_commands_and_exec_propagated():
24
+ bot_api = {
25
+ "commands": {"text": False},
26
+ "exec": {"commandContentDeny": ["apiSecret", "openclaw.json"]},
27
+ }
28
+ _, account = build_bot_api_account(_agent_def(bot_api))
29
+ assert account["commands"] == {"text": False}
30
+ assert account["exec"]["commandContentDeny"] == ["apiSecret", "openclaw.json"]
31
+ assert {"agentId", "name", "apiSecret", "enabled", "commands", "exec"} == set(account)
32
+
33
+
34
+ def test_omitted_commands_exec_not_added():
35
+ _, account = build_bot_api_account(_agent_def())
36
+ assert "commands" not in account
37
+ assert "exec" not in account
38
+
39
+
40
+ def test_upgrade_preserves_existing_exec_not_in_config():
41
+ """配置里没声明 exec 时,升级不得清掉 openclaw.json 已有 exec。"""
42
+ config = {
43
+ "channels": {
44
+ "bot-api": {
45
+ "accounts": {
46
+ "ai-cs-qa": {
47
+ "agentId": "ai-cs-qa",
48
+ "name": "ai-cs-qa",
49
+ "apiSecret": "old-secret",
50
+ "enabled": True,
51
+ "exec": {"commandContentDeny": ["hand-added"]},
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ ensure_bot_api(config, _agent_def(), target_agent_id="ai-cs-qa")
58
+ account = config["channels"]["bot-api"]["accounts"]["ai-cs-qa"]
59
+ assert account["exec"]["commandContentDeny"] == ["hand-added"]
60
+ assert account["apiSecret"] == "old-secret" # 复用旧密钥
61
+
62
+
63
+ def test_upgrade_exec_in_config_overrides_existing():
64
+ """配置里声明了 exec,则以配置为准(source of truth),替换而非追加。"""
65
+ config = {
66
+ "channels": {
67
+ "bot-api": {
68
+ "accounts": {
69
+ "ai-cs-qa": {
70
+ "agentId": "ai-cs-qa",
71
+ "name": "old-name",
72
+ "apiSecret": "old-secret",
73
+ "enabled": True,
74
+ "exec": {"commandContentDeny": ["hand-added"], "networkDenyTools": ["curl"]},
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ bot_api = {"exec": {"commandContentDeny": ["apiSecret", "openclaw.json"]}}
81
+ ensure_bot_api(config, _agent_def(bot_api), target_agent_id="ai-cs-qa")
82
+ account = config["channels"]["bot-api"]["accounts"]["ai-cs-qa"]
83
+ # 配置声明的列表整体替换
84
+ assert account["exec"]["commandContentDeny"] == ["apiSecret", "openclaw.json"]
85
+ # 配置未声明的子键保留
86
+ assert account["exec"]["networkDenyTools"] == ["curl"]
87
+ assert account["apiSecret"] == "old-secret"
88
+
89
+
90
+ def test_deep_merge_lists_replace():
91
+ assert deep_merge_dict({"a": [1, 2]}, {"a": [3]}) == {"a": [3]}
92
+
93
+
94
+ def test_corrupt_non_dict_account_does_not_crash():
95
+ """旧账号被写成 null/非 dict 时,退化为整体覆盖,不崩。"""
96
+ for bad in (None, "x", 0):
97
+ config = {"channels": {"bot-api": {"accounts": {"ai-cs-qa": bad}}}}
98
+ ensure_bot_api(config, _agent_def(), target_agent_id="ai-cs-qa")
99
+ account = config["channels"]["bot-api"]["accounts"]["ai-cs-qa"]
100
+ assert isinstance(account, dict)
101
+ assert {"agentId", "name", "apiSecret", "enabled"} <= set(account)
102
+
103
+
104
+ def test_old_agent_without_install_bot_api_unchanged_shape():
105
+ """没有 install.bot_api 的老 agent,账号仍只有原四字段。"""
106
+ config = {"channels": {"bot-api": {"accounts": {}}}}
107
+ ensure_bot_api(config, _agent_def(), target_agent_id="ai-cs-qa")
108
+ account = config["channels"]["bot-api"]["accounts"]["ai-cs-qa"]
109
+ assert set(account) == {"agentId", "name", "apiSecret", "enabled"}
110
+
111
+
112
+ if __name__ == "__main__":
113
+ for name, fn in list(globals().items()):
114
+ if name.startswith("test_") and callable(fn):
115
+ fn()
116
+ print(f"ok: {name}")
@@ -1,10 +1,24 @@
1
1
  {
2
2
  "name": "claw-agent-get-send",
3
- "version": "1.2.0",
3
+ "version": "2.0.0",
4
4
  "types": ["store"],
5
- "displayName": "Claw Agent Get/Send",
6
- "description": "Appia(IM 即时通讯)侧 claw.agent.groups.get / claw.agent.message.send:查询机器人在哪些群聊、向群发纯文本或 Markdown、发送文件附件;脚本封装 + HTTP/curl 参考(JWT、msg/md、错误码)",
5
+ "displayName": "Claw Agent 全量能力",
6
+ "description": "Appia(IM)Claw Agent 全量能力:群聊收发/读历史/公告/撤回/退群,扩展(scopes/搜人/通知/待办/搜频道/纪要/总览/建群/改待办);脚本封装 + HTTP/curl 参考",
7
7
  "changelog": [
8
+ {
9
+ "version": "2.0.0",
10
+ "date": "2026-07-23",
11
+ "changes": [
12
+ "appia_claw.py:新增 get-messages / get-announcements / fetch-file / recall / leave 五个入群子命令(既有 groups/verify-target/send/send-md/send-file 不变)",
13
+ "appia_claw.py:send / send-md 新增 --mention(-m),经 agent.users.search 把显示名解析为 @username 前置到正文,可选按频道成员校验是否在群",
14
+ "新增 appia_common.py:共享凭证 + JWT + 通用 GET/POST/multipart/raw helper",
15
+ "新增 appia_extensions.py:scopes/scopes-request/users-search/notifications/todos/unread/channels-search/channel-info/channel-messages/channel-messages-search/channel-members/channel-attachments/channel-announcements/file-metadata/meeting-minutes/meeting-minutes-ingest/overview-resolve/overview-links/todos-update/channels-create/tool-invoke(21 子命令)",
16
+ "新增 references/ 目录:auth/creator-delegate-api/query-api/write-api/rooms-api/overview-api/session-flow",
17
+ "reference-http.md:追加 messages.get/announcements.get/file.fetch/recall/group.leave 章节与 references 指引",
18
+ "SKILL.md:重写为全量能力用法(入群/扩展)+ 文档地图 + --mention 说明;description 扩触发词",
19
+ "skill.json / pyproject.toml:bump 2.0.0;displayName 改为「Claw Agent 全量能力」"
20
+ ]
21
+ },
8
22
  {
9
23
  "version": "1.2.0",
10
24
  "date": "2026-07-06",
@@ -49,5 +63,5 @@
49
63
  }
50
64
  ],
51
65
  "createdAt": "2026-04-28",
52
- "updatedAt": "2026-07-06"
66
+ "updatedAt": "2026-07-23"
53
67
  }
@@ -1,49 +1,125 @@
1
1
  ---
2
2
  name: claw-agent-get-send
3
- description: On Appia (an IM / team chat platform), list which group chats the bot agent is in (rid + name), or send plaintext or Markdown to a group via Appia Claw. Use when the user asks for group list / 群列表 / Appia 群聊 / rid, or to message a group / 向群发消息 / IM 通知;claw、agent.groups.get、agent.message.send。
3
+ description: AppiaIMClaw Agent 全量能力:群聊收发/读历史/公告/撤回/退群,扩展(scopes/搜人/通知/待办/搜频道/纪要/总览/建群/改待办)。当用户要求 Appia/Claw 群聊收发、查历史公告、撤回、搜人/频道、待办通知、建群、scopes 授权时使用。
4
4
  ---
5
5
 
6
- # Appia 即时通讯(IM)· Claw 群列表与发消息
6
+ # Appia 即时通讯(IM)· Claw Agent 全量能力
7
7
 
8
- Appia 为 IM(即时通讯)工具中的群聊/会话场景。脚本 `{baseDir}/scripts/appia_claw.py` 通过 Claw HTTP API 拉取机器人所在群并发消息。`{baseDir}` 与本 `SKILL.md` 同级(安装根下一般有 `scripts/`)。
8
+ Appia 为 IM(即时通讯)工具中的群聊/会话场景。操作者始终是机器人,凭证只有 JWT + `agentId` + 创建者 `userId`(JWT `sub` 须等于 `userId`);用户 `authToken` 永不给 Agent,写权限通过 scopes 授权。
9
9
 
10
- ## 用法
10
+ 脚本位于 `{baseDir}/scripts/`,用 `uv run` 启动。`{baseDir}` 与本 `SKILL.md` 同级。
11
+
12
+ ## 鉴权与授权
13
+
14
+ - 凭证:`--cred-file /path/to.cred.json`(或 `-c`)JSON 文件,非空字段优先于环境变量;不用凭证文件时设 `CLAW_JWT`、`APP_AGENT_ID`、`CLAW_USER_ID`(新脚本也接受 `MCP_JWT`)。
15
+ - 缺写权限:服务端返回 `SCOPE_DENIED` → `appia_extensions.py scopes-request` → 用户在 myAgent 点「授权」→ `scopes` 或重试。不要向用户要 authToken。
16
+ - 详情:[auth.md](references/auth.md) · [session-flow.md](references/session-flow.md)
17
+
18
+ ## 1. 入群能力(bot 须在频道)— `appia_claw.py`
19
+
20
+ 子命令前可加 `--cred-file /path/to.cred.json`(或 `-c`)、`--timeout 秒`。查群与收发:
21
+
22
+ ```bash
23
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json groups
24
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json groups --json
25
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json verify-target
26
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send --text "正文" --rid "<rid>"
27
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send --text "正文" --rid "<rid>" --mention "黄志举,李迅"
28
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send --file /tmp/body.txt --rid "<rid>"
29
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-md --text "正文" --rid "<rid>"
30
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-md --text "正文" --rid "<rid>" --mention "黄志举"
31
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-md --md-file /tmp/md.json --rid "<rid>"
32
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-file report.pdf --rid "<rid>" --text "请查收"
33
+ ```
34
+
35
+ 读历史/公告、下载附件、撤回、退群:
36
+
37
+ ```bash
38
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json get-messages --rid "<rid>" --count 20
39
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json get-messages --rid "<rid>" --latest "<nextLatest>"
40
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json get-announcements --rid "<rid>"
41
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json fetch-file --file-id "<fid>" --rid "<rid>" -o ./attachment.pdf
42
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json recall --message-id "<msgId>"
43
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json leave --rid "<rid>"
44
+ ```
45
+
46
+ ## 2. 扩展能力(同一机器人 + scopes)— `appia_extensions.py`
47
+
48
+ 授权与人员/通知/待办:
49
+
50
+ ```bash
51
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json scopes
52
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json scopes-request --scopes "channels:write" --reason "建群"
53
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json users-search --q "张三" --limit 20
54
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json notifications --limit 20
55
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json todos --limit 20
56
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json unread
57
+ ```
58
+
59
+ 频道发现与消息:
11
60
 
12
61
  ```bash
13
- # 子命令前可加:--cred-file /path/to.cred.json(或 -c)、--timeout 秒;凭证与路径示例见 docs/claw-agent-get-send.md
62
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channels-search --name "产品周会"
63
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-info --rid "<rid>"
64
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-messages --rid "<rid>" --limit 20
65
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-messages-search --rid "<rid>" --keyword "上线"
66
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-members --rid "<rid>"
67
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-attachments --rid "<rid>"
68
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-announcements --rid "<rid>"
69
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json file-metadata --file-id "<fid>"
70
+ ```
14
71
 
15
- # 1. 列出当前 agent 已加入的群(rid、群名)
16
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json groups
72
+ 会议纪要 / 总览元数据:
17
73
 
18
- # 2. 同上,输出接口原始 JSON(便于复制 rid)
19
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json groups --json
74
+ ```bash
75
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json meeting-minutes --limit 20
76
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json meeting-minutes-ingest --limit 20
77
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json overview-resolve --url "https://projects.appia.vip/<id>?doc=<docKey>"
78
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json overview-links --rid "<rid>"
79
+ ```
80
+
81
+ 写操作(需对应 `:write` scope,缺则 `scopes-request`)与聚合调用:
20
82
 
21
- # 3. 双因子校验:凭证或环境里已配置 TARGET_RID、TARGET_GROUP_NAME
22
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json verify-target
83
+ ```bash
84
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json todos-update --id "<todoId>" --status "done"
85
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channels-create --name "产品周会群" --members-json '["zhangsan","lisi"]'
86
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json tool-invoke --tool "appia.todos.list" --args-json '{"limit":5}'
87
+ ```
23
88
 
24
- # 4. 向指定 rid 发纯文本(--rid 可换成本地凭证里的 target_rid)
25
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send --text "正文" --rid "<rid>"
89
+ ## 文档地图
26
90
 
27
- # 5. 长文本从 UTF-8 文件发送
28
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send --file /tmp/body.txt --rid "<rid>"
91
+ | 文件 | 内容 |
92
+ |------|------|
93
+ | [reference-http.md](reference-http.md) | 入群端点 curl 参考(groups/messages/announcements/file.fetch/upload/send/recall/leave) |
94
+ | [references/auth.md](references/auth.md) | 鉴权 + scopes 授权 |
95
+ | [references/creator-delegate-api.md](references/creator-delegate-api.md) | 扩展能力端点表 |
96
+ | [references/query-api.md](references/query-api.md) / [write-api.md](references/write-api.md) | 读 / 写补充 |
97
+ | [references/rooms-api.md](references/rooms-api.md) | 建频道 |
98
+ | [references/overview-api.md](references/overview-api.md) | 总览 |
99
+ | [references/session-flow.md](references/session-flow.md) | 启动与轮询 |
29
100
 
30
- # 6. 发 Markdown AST:一段纯文本自动包成 md
31
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-md --text "正文" --rid "<rid>"
101
+ ## @提及(--mention)
32
102
 
33
- # 7. JSON 文件读 md 数组
34
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-md --md-file /tmp/md.json --rid "<rid>"
103
+ `send` 和 `send-md` 均支持 `--mention`(`-m`),接收显示名称或 username,逗号分隔。脚本会先通过 `agent.users.search` API 查询用户名,精确匹配 name/username 优先,否则取搜索结果第一条,再拼成 `@username` 前缀。
35
104
 
36
- # 8. 发送文件到群聊(一步到位:内部自动 upload + send,支持一个或多个文件)
37
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-file report.pdf --rid "<rid>" --text "请查收附件"
38
- # 多文件 + 无正文:
39
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-file a.pdf b.pdf --rid "<rid>"
105
+ ```bash
106
+ # 单个 @
107
+ uv run {baseDir}/scripts/appia_claw.py -c cred.json send --text "请查收" --rid "<rid>" --mention "黄志举"
108
+ # 多个 @
109
+ uv run {baseDir}/scripts/appia_claw.py -c cred.json send --text "开会了" --rid "<rid>" --mention "黄志举,李迅"
110
+ # 也可直接用 username
111
+ uv run {baseDir}/scripts/appia_claw.py -c cred.json send-md --text "请确认" --rid "<rid>" --mention "zhiju.huang"
40
112
  ```
41
113
 
42
- 不用凭证文件时,可在环境中设置 `CLAW_JWT`、`APP_AGENT_ID`、`CLAW_USER_ID`(及场景需要的 `TARGET_RID` 等),命令相同,省略 `--cred-file …` 即可。
114
+ ⚠️ 必须先查用户再 @,不要猜测 username。
43
115
 
44
116
  ## 注意事项
45
117
 
46
- - 最小凭证字段(JSON 或环境变量):JWT、机器人 `agentId`、创建者 `userId`;勿将填好真实值的文件提交 Git。
118
+ - 最小凭证字段:JWT、机器人 `agentId`、创建者 `userId`;勿将填好真实值的凭证文件提交 Git。
47
119
  - 未设置 `APPIA_BASE_URL` 时,脚本默认 `https://sophgo.appia.cn`。
48
- - HTTP / curl / 错误码:技能根目录 **`../reference-http.md`**(相对本文件)。
49
- - 发送文件用 `send-file` 一步完成(内部自动 upload + send);不存在单独的 `upload` 子命令,避免"只上传不发消息"的失败。
120
+ - 入群能力须 bot 已在频道;扩展能力看 scopes。
121
+ - 不猜 rid / username:入群 `groups`;按名 `channels-search`;人名 `users-search`。
122
+ - 附件两步:`send-file` 一步完成(内部 upload → send);下载用 `fetch-file`。
123
+ - 建频道 `members` 用 username,不要默认把 Claw 创建者塞进去。
124
+ - 总览行数据未落地,只用 `overview-resolve` / `overview-links`,勿调 `overview.read`。
125
+ - 写操作先向用户确认。
@@ -1,5 +1,5 @@
1
1
  [project]
2
2
  name = "claw-agent-get-send"
3
- version = "1.0.1"
4
- description = "Appia Claw groups.get / message.send helper"
3
+ version = "2.0.0"
4
+ description = "Appia Claw Agent 全量能力:入群收发 + 扩展(scopes)"
5
5
  requires-python = ">=3.10"