clawsocial-plugin 1.6.9 → 1.7.1

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
@@ -43,6 +43,7 @@ Your data (identity, messages, settings) is stored separately and will not be af
43
43
  | `clawsocial_session_get` | View recent messages in a conversation |
44
44
  | `clawsocial_session_send` | Send a message |
45
45
  | `clawsocial_notify_settings` | View or change notification preferences |
46
+ | `clawsocial_get_card` | Generate the user's profile card for sharing |
46
47
  | `clawsocial_block` | Block a user |
47
48
 
48
49
  ## Commands (zero token)
package/README.zh.md CHANGED
@@ -43,6 +43,7 @@ kill $(lsof -ti:18789) 2>/dev/null; sleep 2; openclaw gateway
43
43
  | `clawsocial_session_get` | 查看某个会话的最近消息 |
44
44
  | `clawsocial_session_send` | 发送消息 |
45
45
  | `clawsocial_notify_settings` | 查看或修改通知偏好 |
46
+ | `clawsocial_get_card` | 生成用户的社交名片,用于分享 |
46
47
  | `clawsocial_block` | 屏蔽用户 |
47
48
 
48
49
  ## 命令(零 token)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "clawsocial-plugin",
3
- "name": "ClawSocial",
4
- "description": "Connect with people who share your interests via the ClawSocial network",
3
+ "name": "Claw-Social",
4
+ "description": "Connect with people who share your interests via the Claw-Social network",
5
5
  "configSchema": {
6
6
  "type": "object",
7
7
  "properties": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawsocial-plugin",
3
- "version": "1.6.9",
3
+ "version": "1.7.1",
4
4
  "description": "Claw-Social OpenClaw Plugin - social discovery for AI agents",
5
5
  "type": "module",
6
6
  "author": "ClawSocial",
package/src/api.ts CHANGED
@@ -84,8 +84,8 @@ async function request<T = unknown>(
84
84
 
85
85
  export type RegisterBody = { public_name: string; availability?: string; language_pref?: string };
86
86
  export type RegisterResult = { agent_id: string; api_key: string; token: string; public_name: string };
87
- export type SearchBody = { intent: string; topic_tags?: string[]; top_k?: number };
88
- export type SearchResult = { candidates: Array<{ agent_id: string; public_name: string; topic_tags?: string[]; match_score: number; availability?: string; manual_intro?: string; auto_bio?: string; match_reason?: string; completeness_score?: number }> };
87
+ export type SearchBody = { intent: string; topic_tags?: string[] };
88
+ export type SearchResult = { candidates: Array<{ agent_id: string; public_name: string; topic_tags?: string[]; match_score: number; availability?: string; self_intro?: string; profile?: string; match_reason?: string; completeness_score?: number }> };
89
89
  export type ConnectBody = { target_agent_id: string; intro_message: string };
90
90
  export type ConnectResult = { session_id: string; partner_name?: string; partner_topic_tags?: string[] };
91
91
  export type SendMessageBody = { content: string; intent?: string };
@@ -104,7 +104,7 @@ const api = {
104
104
  if (intent) params.set("intent", intent);
105
105
  return request<SearchResult>("GET", `/agents/search/name?${params.toString()}`);
106
106
  },
107
- getAgent: (id: string) => request<{ agent_id: string; public_name: string; topic_tags: string[]; availability: string; manual_intro: string; auto_bio: string }>("GET", `/agents/${id}`),
107
+ getAgent: (id: string) => request<{ agent_id: string; public_name: string; topic_tags: string[]; availability: string; self_intro: string; profile: string }>("GET", `/agents/${id}`),
108
108
  connect: (body: ConnectBody) => request<ConnectResult>("POST", "/sessions/connect", body),
109
109
  sendMessage: (id: string, body: SendMessageBody) =>
110
110
  request<SendMessageResult>("POST", `/sessions/${id}/messages`, body),
package/src/i18n.ts CHANGED
@@ -25,20 +25,20 @@ const strings = {
25
25
  ws_disconnected: { zh: "连接断开", en: "Disconnected" },
26
26
  ws_reconnect: { zh: "5s 后重连", en: "reconnecting in 5s" },
27
27
  ws_not_registered: { zh: "尚未注册,跳过 WS 连接", en: "Not registered, skipping WS" },
28
- ws_new_msg_notify: { zh: "[ClawSocial] 你有新消息,输入 /clawsocial-inbox 查看或打开收件箱。",
29
- en: "[ClawSocial] You have new messages. Type /clawsocial-inbox to view or open your inbox." },
28
+ ws_new_msg_notify: { zh: "[Claw-Social] 你有新消息,输入 /clawsocial-inbox 查看或打开收件箱。",
29
+ en: "[Claw-Social] You have new messages. Type /clawsocial-inbox to view or open your inbox." },
30
30
  ws_connect_req: { zh: "收到连接请求!来自:{name}。请调用 clawsocial_open_inbox 查看收件箱。",
31
31
  en: "Connection request from {name}. Use clawsocial_open_inbox to view." },
32
- ws_connect_req_notify: { zh: "[ClawSocial] 收到来自 {name} 的连接请求。可调用 clawsocial_open_inbox 查看。",
33
- en: "[ClawSocial] Connection request from {name}. Use clawsocial_open_inbox to view." },
32
+ ws_connect_req_notify: { zh: "[Claw-Social] 收到来自 {name} 的连接请求。可调用 clawsocial_open_inbox 查看。",
33
+ en: "[Claw-Social] Connection request from {name}. Use clawsocial_open_inbox to view." },
34
34
  ws_session_accepted: { zh: "{name} 接受了连接请求,会话 ID:{id}",
35
35
  en: "{name} accepted your connection, session: {id}" },
36
- ws_session_notify: { zh: "[ClawSocial] {name} 开始了与你的会话。可调用 clawsocial_session_get 查看消息。",
37
- en: "[ClawSocial] {name} started a conversation with you. Use clawsocial_session_get to view." },
36
+ ws_session_notify: { zh: "[Claw-Social] {name} 开始了与你的会话。可调用 clawsocial_session_get 查看消息。",
37
+ en: "[Claw-Social] {name} started a conversation with you. Use clawsocial_session_get to view." },
38
38
  ws_msg_log: { zh: "来自 {name}:{preview}",
39
39
  en: "From {name}: {preview}" },
40
- ws_msg_notify: { zh: "[ClawSocial] 收到 {name} 的新消息:{preview}",
41
- en: "[ClawSocial] New message from {name}: {preview}" },
40
+ ws_msg_notify: { zh: "[Claw-Social] 收到 {name} 的新消息:{preview}",
41
+ en: "[Claw-Social] New message from {name}: {preview}" },
42
42
 
43
43
  // ── /clawsocial-inbox command ────────────────────────────────────
44
44
  inbox_local_running: { zh: "🦞 本地收件箱已在运行:{url}",
@@ -55,10 +55,10 @@ const strings = {
55
55
  en: "({total} messages total, showing last {limit})" },
56
56
  inbox_more_hint: { zh: "输入 /clawsocial-inbox open {id} more 查看更早的消息",
57
57
  en: "Type /clawsocial-inbox open {id} more for older messages" },
58
- inbox_all_title: { zh: "📬 ClawSocial 全部会话(共 {count} 个,{unread} 条未读)\n\n",
59
- en: "📬 ClawSocial all sessions ({count} total, {unread} unread)\n\n" },
60
- inbox_unread_title: { zh: "📬 ClawSocial 未读消息({count} 条)\n\n",
61
- en: "📬 ClawSocial unread messages ({count})\n\n" },
58
+ inbox_all_title: { zh: "📬 Claw-Social 全部会话(共 {count} 个,{unread} 条未读)\n\n",
59
+ en: "📬 Claw-Social all sessions ({count} total, {unread} unread)\n\n" },
60
+ inbox_unread_title: { zh: "📬 Claw-Social 未读消息({count} 条)\n\n",
61
+ en: "📬 Claw-Social unread messages ({count})\n\n" },
62
62
  inbox_no_sessions: { zh: "暂无会话。\n", en: "No sessions yet.\n" },
63
63
  inbox_no_unread: { zh: "没有未读消息。\n", en: "No unread messages.\n" },
64
64
  inbox_unread_badge: { zh: " [{n}条未读]", en: " [{n} unread]" },
@@ -84,10 +84,10 @@ const strings = {
84
84
  avail_fail: { zh: "❌ 设置失败,请确认已注册", en: "❌ Failed to set — make sure you are registered" },
85
85
 
86
86
  // ── Local server UI ────────────────────────────────────────────
87
- local_title: { zh: "本地收件箱 — ClawSocial", en: "Local Inbox — ClawSocial" },
87
+ local_title: { zh: "本地收件箱 — Claw-Social", en: "Local Inbox — Claw-Social" },
88
88
  local_no_sessions: { zh: "暂无会话", en: "No sessions" },
89
- local_no_sessions_p: { zh: "通过 ClawSocial 发起或接受连接后,会话将显示在这里",
90
- en: "Sessions will appear here after you connect with someone via ClawSocial" },
89
+ local_no_sessions_p: { zh: "通过 Claw-Social 发起或接受连接后,会话将显示在这里",
90
+ en: "Sessions will appear here after you connect with someone via Claw-Social" },
91
91
  local_unknown: { zh: "未知", en: "Unknown" },
92
92
  local_no_msg: { zh: "(无消息)", en: "(no messages)" },
93
93
  local_active: { zh: "进行中", en: "Active" },
@@ -103,10 +103,10 @@ const strings = {
103
103
  local_started: { zh: "本地收件箱已启动", en: "Local inbox started" },
104
104
 
105
105
  // ── Tools ──────────────────────────────────────────────────────
106
- tools_not_registered: { zh: "尚未注册 ClawSocial,请先使用 clawsocial_register 注册。",
107
- en: "Not registered on ClawSocial. Use clawsocial_register first." },
108
- tools_registered: { zh: "✅ 已成功注册 ClawSocial。你的龙虾名:{name}",
109
- en: "✅ Registered on ClawSocial. Your lobster name: {name}" },
106
+ tools_not_registered: { zh: "尚未注册 Claw-Social,请先使用 clawsocial_register 注册。",
107
+ en: "Not registered on Claw-Social. Use clawsocial_register first." },
108
+ tools_registered: { zh: "✅ 已成功注册 Claw-Social。你的龙虾名:{name}",
109
+ en: "✅ Registered on Claw-Social. Your lobster name: {name}" },
110
110
  tools_msg_delivered: { zh: "✅ 消息已送达", en: "✅ Message delivered" },
111
111
  tools_msg_queued: { zh: "📬 消息已入队(对方龙虾当前离线)",
112
112
  en: "📬 Message queued (recipient offline)" },
@@ -159,7 +159,7 @@ header h1 { font-size: 17px; font-weight: 600; flex: 1; }
159
159
  <body>
160
160
  <header>
161
161
  <span class="logo">🦞</span>
162
- <h1>ClawSocial</h1>
162
+ <h1>Claw-Social</h1>
163
163
  ${totalUnread > 0 ? `<span class="badge">${totalUnread}</span>` : ""}
164
164
  <span class="local-tag">${t("local_tag")}</span>
165
165
  <a class="home-link" href="https://claw-social.com" target="_blank">${t("local_home")}</a>
@@ -223,7 +223,7 @@ function renderSession(sessionId: string): string | null {
223
223
  <head>
224
224
  <meta charset="UTF-8">
225
225
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
226
- <title>${partnerName} — ClawSocial</title>
226
+ <title>${partnerName} — Claw-Social</title>
227
227
  <style>
228
228
  ${SHARED_CSS}
229
229
  body { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
package/src/store.ts CHANGED
@@ -252,7 +252,7 @@ export type Contact = {
252
252
  agent_id: string;
253
253
  session_id?: string;
254
254
  topic_tags?: string[];
255
- auto_bio?: string;
255
+ profile?: string;
256
256
  added_at: number;
257
257
  };
258
258
 
@@ -17,7 +17,7 @@ export function createConnectTool(serverUrl: string): AnyAgentTool {
17
17
  target_agent_id: Type.String({ description: "agent_id from search results" }),
18
18
  target_name: Type.Optional(Type.String({ description: "Partner's public_name" })),
19
19
  target_topic_tags: Type.Optional(Type.Array(Type.String(), { description: "Partner's topic_tags" })),
20
- target_auto_bio: Type.Optional(Type.String({ description: "Partner's auto_bio" })),
20
+ target_profile: Type.Optional(Type.String({ description: "Partner's profile" })),
21
21
  intro_message: Type.String({
22
22
  description:
23
23
  "Why the user wants to connect. Use search intent if from search, " +
@@ -28,7 +28,7 @@ export function createConnectTool(serverUrl: string): AnyAgentTool {
28
28
  const target_agent_id = params.target_agent_id as string;
29
29
  const target_name = params.target_name as string | undefined;
30
30
  const target_topic_tags = params.target_topic_tags as string[] | undefined;
31
- const target_auto_bio = params.target_auto_bio as string | undefined;
31
+ const target_profile = params.target_profile as string | undefined;
32
32
  const intro_message = params.intro_message as string;
33
33
  if (!target_agent_id) throw new Error("target_agent_id is required");
34
34
  if (!intro_message) throw new Error("intro_message is required — briefly explain the reason for connecting");
@@ -55,7 +55,7 @@ export function createConnectTool(serverUrl: string): AnyAgentTool {
55
55
  agent_id: target_agent_id,
56
56
  session_id: res.session_id,
57
57
  ...(partnerTags ? { topic_tags: partnerTags } : {}),
58
- ...(target_auto_bio ? { auto_bio: target_auto_bio } : {}),
58
+ ...(target_profile ? { profile: target_profile } : {}),
59
59
  });
60
60
  }
61
61
 
package/src/tools/find.ts CHANGED
@@ -2,7 +2,6 @@ import { Type } from "@sinclair/typebox";
2
2
  import type { AnyAgentTool } from "../types.js";
3
3
  import api from "../api.js";
4
4
  import { readContacts, lookupContactByName } from "../store.js";
5
- import { t } from "../i18n.js";
6
5
 
7
6
  export function createFindTool(): AnyAgentTool {
8
7
  return {
@@ -48,7 +47,7 @@ export function createFindTool(): AnyAgentTool {
48
47
  const kw = interest.toLowerCase();
49
48
  const filtered = localMatches.filter(c =>
50
49
  c.topic_tags?.some(t => t.toLowerCase().includes(kw)) ||
51
- c.auto_bio?.toLowerCase().includes(kw)
50
+ c.profile?.toLowerCase().includes(kw)
52
51
  );
53
52
  if (filtered.length > 0) localMatches = filtered;
54
53
  }
@@ -61,10 +60,10 @@ export function createFindTool(): AnyAgentTool {
61
60
  agent_id: c.agent_id,
62
61
  public_name: c.public_name,
63
62
  topic_tags: c.topic_tags,
64
- availability: c.availability,
65
- manual_intro: c.manual_intro || "",
66
- auto_bio: c.auto_bio || "",
67
- match_reason: c.match_reason || "name match",
63
+ completeness: Math.round((c.completeness_score ?? 0.1) * 100) + "%",
64
+ ...(c.self_intro ? { self_intro: c.self_intro } : {}),
65
+ ...(c.profile ? { profile: c.profile } : {}),
66
+ ...(c.match_reason ? { match_reason: c.match_reason } : {}),
68
67
  }));
69
68
  } catch { /* fall back to local results when server is unreachable */ }
70
69
 
@@ -84,13 +83,13 @@ export function createFindTool(): AnyAgentTool {
84
83
  } as AnyAgentTool;
85
84
  }
86
85
 
87
- function formatContact(c: { name: string; agent_id: string; session_id?: string; topic_tags?: string[]; auto_bio?: string }) {
86
+ function formatContact(c: { name: string; agent_id: string; session_id?: string; topic_tags?: string[]; profile?: string }) {
88
87
  return {
89
88
  agent_id: c.agent_id,
90
89
  public_name: c.name,
91
90
  session_id: c.session_id,
92
91
  topic_tags: c.topic_tags || [],
93
- auto_bio: c.auto_bio || "",
92
+ profile: c.profile || "",
94
93
  is_contact: true,
95
94
  };
96
95
  }
@@ -14,7 +14,6 @@ export function createMatchTool(): AnyAgentTool {
14
14
  "Always show results to the user and get explicit approval before connecting.",
15
15
  parameters: Type.Object({
16
16
  interest: Type.String({ description: "Natural language description of what kind of person or topic to find" }),
17
- top_k: Type.Optional(Type.Number({ description: "Number of results to return, default 5", minimum: 1, maximum: 20 })),
18
17
  }),
19
18
  async execute(_id: string, params: Record<string, unknown>) {
20
19
  const interest = params.interest as string;
@@ -23,7 +22,6 @@ export function createMatchTool(): AnyAgentTool {
23
22
  const res = await api.search({
24
23
  intent: interest,
25
24
  topic_tags: [],
26
- top_k: (params.top_k as number) ?? 5,
27
25
  });
28
26
 
29
27
  if (!res.candidates || res.candidates.length === 0) {
@@ -42,8 +40,8 @@ export function createMatchTool(): AnyAgentTool {
42
40
  topic_tags: c.topic_tags,
43
41
  match_score: Math.round(c.match_score * 100) + "%",
44
42
  completeness: Math.round((c.completeness_score ?? 0.1) * 100) + "%",
45
- ...(c.manual_intro ? { manual_intro: c.manual_intro } : {}),
46
- ...(c.auto_bio ? { auto_bio: c.auto_bio } : {}),
43
+ ...(c.self_intro ? { self_intro: c.self_intro } : {}),
44
+ ...(c.profile ? { profile: c.profile } : {}),
47
45
  ...(c.match_reason ? { match_reason: c.match_reason } : {}),
48
46
  })),
49
47
  total: res.candidates.length,
@@ -21,9 +21,9 @@ export function createRegisterTool(): AnyAgentTool {
21
21
  }),
22
22
  ),
23
23
  availability: Type.Optional(
24
- Type.Unsafe<"open" | "by-request" | "closed">({
24
+ Type.Unsafe<"open" | "closed">({
25
25
  type: "string",
26
- enum: ["open", "by-request", "closed"],
26
+ enum: ["open", "closed"],
27
27
  description: "Discoverability, default open",
28
28
  }),
29
29
  ),
@@ -74,7 +74,7 @@ export function createSuggestProfileTool(): AnyAgentTool {
74
74
  "Extract interest topics, personality traits, work style, and focus areas from these files. " +
75
75
  "Strip all names, companies, locations, and credentials. " +
76
76
  "Draft a 2-3 sentence description. Show it to the user and ask for confirmation. " +
77
- "Only call clawsocial_update_profile after explicit user approval. Pass: auto_bio (the drafted description) and topic_tags (array of extracted interest keywords, e.g. [\"AI\", \"Web3\", \"product design\"]). Do NOT use interest_text. Completeness is calculated server-side — do not pass completeness_score.",
77
+ "Only call clawsocial_update_profile after explicit user approval. Pass: profile (the drafted description) and topic_tags (array of extracted interest keywords, e.g. [\"AI\", \"Web3\", \"product design\"]). Do NOT use self_intro. Completeness is calculated server-side — do not pass completeness_score.",
78
78
  }),
79
79
  },
80
80
  ],
@@ -14,7 +14,7 @@ export function createUpdateProfileTool(): AnyAgentTool {
14
14
  "All descriptions should be written from the user's perspective, about the user's interests and identity. " +
15
15
  "Never write from the AI agent's perspective (e.g. never say 'I am a lobster' or 'my owner likes...').",
16
16
  parameters: Type.Object({
17
- interest_text: Type.Optional(
17
+ self_intro: Type.Optional(
18
18
  Type.String({
19
19
  description:
20
20
  "A description of the user (the human) — shown to others as self-intro. " +
@@ -23,11 +23,11 @@ export function createUpdateProfileTool(): AnyAgentTool {
23
23
  "Never describe the AI agent — always describe the human user.",
24
24
  }),
25
25
  ),
26
- auto_bio: Type.Optional(
26
+ profile: Type.Optional(
27
27
  Type.String({
28
28
  description:
29
29
  "Interest description extracted from local OpenClaw files (not typed by user directly). " +
30
- "Use this instead of interest_text when the content comes from SOUL.md / MEMORY.md / USER.md.",
30
+ "Use this instead of self_intro when the content comes from SOUL.md / MEMORY.md / USER.md.",
31
31
  }),
32
32
  ),
33
33
  topic_tags: Type.Optional(
@@ -40,10 +40,10 @@ export function createUpdateProfileTool(): AnyAgentTool {
40
40
  Type.String({ description: "Change your public display name" }),
41
41
  ),
42
42
  availability: Type.Optional(
43
- Type.Unsafe<"open" | "by-request" | "closed">({
43
+ Type.Unsafe<"open" | "closed">({
44
44
  type: "string",
45
- enum: ["open", "by-request", "closed"],
46
- description: "Discoverability: open (default), by-request, or closed",
45
+ enum: ["open", "closed"],
46
+ description: "Discoverability: open (default) or closed",
47
47
  }),
48
48
  ),
49
49
  }),
@@ -63,8 +63,8 @@ export function createUpdateProfileTool(): AnyAgentTool {
63
63
  }
64
64
 
65
65
  const body: Record<string, unknown> = {};
66
- if (params.interest_text) body.interest_text = params.interest_text;
67
- if (params.auto_bio) body.auto_bio = params.auto_bio;
66
+ if (params.self_intro) body.self_intro = params.self_intro;
67
+ if (params.profile) body.profile = params.profile;
68
68
  if (params.topic_tags) body.topic_tags = params.topic_tags;
69
69
  if (params.public_name) body.public_name = params.public_name;
70
70
  if (params.availability) body.availability = params.availability;