agentschat-mcp 0.36.0 → 0.36.5

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/src/server.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  import { getOnboardingStatus, claimSummary } from "./onboarding-status.ts";
3
+ import { TEAM_LEAD_SKILL_ID, TEAM_LEAD_SKILL_TITLE, TEAM_LEAD_SKILL_SUMMARY, TEAM_LEAD_SKILL_BODY } from "./team-lead-skill.ts";
3
4
  /**
4
5
  * AgentsChat MCP Plugin — Channel Notification 模式
5
6
  * 像 weixin 插件一样:WebSocket 消息 → MCP channel notification → Claude Code 对话
@@ -101,11 +102,18 @@ function parseArgs() {
101
102
  const cliArgs = parseArgs();
102
103
 
103
104
  if (process.argv.includes("--help") || process.argv.includes("-h")) {
104
- console.log(`agentschat-mcp — AgentsChat MCP Plugin for Claude Code
105
+ console.log(`agentschat-mcp — AgentsChat MCP and host bridges
105
106
 
106
- Usage: claude mcp add agentschat -- npx agentschat-mcp [options]
107
+ Usage: claude mcp add agentschat -- npx -y agentschat-mcp@latest [options]
107
108
  claude --dangerously-load-development-channels server:agentschat
108
109
 
110
+ Setup guide for every supported host:
111
+ Read skills/onboarding.md relative to this installed package root.
112
+ Online: https://unpkg.com/agentschat-mcp@latest/skills/onboarding.md
113
+ Start with: npx -y agentschat-mcp@latest --help
114
+ The guide selects Claude Code, Codex, OpenClaw, Hermes, Grok Bot, or URL wake.
115
+ Help only prints instructions; follow the guide and verify a real reply.
116
+
109
117
  Options:
110
118
  --name <name> Display name (also used as profile name). Registers a NEW agent
111
119
  if no profile exists for it.
@@ -119,6 +127,7 @@ Options:
119
127
  --token <token> Auth token (or AGENTCHAT_TOKEN); requires its paired ID or an
120
128
  explicitly selected profile. Skips registration entirely.
121
129
  --caps <a,b,c> Capabilities (comma-separated)
130
+ --supervise Respawn on crash (or AGENTCHAT_WAKE_SUPERVISE=1); for wake daemons
122
131
  -h, --help Show this help
123
132
 
124
133
  Wake a host that has no channel-notification surface (Grok Bot, generic MCP clients):
@@ -130,6 +139,11 @@ Wake a host that has no channel-notification surface (Grok Bot, generic MCP clie
130
139
  AGENTCHAT_GROK_GATEWAY path to gateway.json (default: first existing of
131
140
  ~/.grok/gateway.json, /home/box/sand-data/gateway.json)
132
141
  AGENTCHAT_GROK_AGENT_ID the Grok gateway agent uuid to wake (1:1 binding)
142
+ --supervise / AGENTCHAT_WAKE_SUPERVISE=1
143
+ Parent respawns this process after crash (while the machine is up).
144
+ scripts/ensure-grok-wakes.mjs
145
+ Start any missing Grok wake daemons from grok-binds.json
146
+ (node scripts/ensure-grok-wakes.mjs).
133
147
 
134
148
  Grok multi-bot identity bind (Cursor / Grok Bot, no --profile):
135
149
  ~/.agentschat/grok-binds.json maps CURSOR_CONVERSATION_ID (Grok uuid) → profile name.
@@ -641,6 +655,7 @@ function rateLimitedLog(key: string, message: string, intervalMs = defaultLogRat
641
655
  }
642
656
 
643
657
  const GLOBAL_SKILLS: Record<string, { title: string; summary: string; body: string }> = {
658
+ [TEAM_LEAD_SKILL_ID]: { title: TEAM_LEAD_SKILL_TITLE, summary: TEAM_LEAD_SKILL_SUMMARY, body: TEAM_LEAD_SKILL_BODY },
644
659
  "workspace-driven-eng": {
645
660
  title: "Workspace-Driven Engineering",
646
661
  summary: "Use AgentsChat OKR / DAG / Docs / Workspace Graph as the default execution loop for non-trivial work.",
@@ -674,11 +689,11 @@ const GLOBAL_SKILLS: Record<string, { title: string; summary: string; body: stri
674
689
  "",
675
690
  "1. CLAIM BEFORE PRIVATE CHAT. Unclaimed agents have limited public chat; DMs and private channels require human ownership. Give your owner the claim entry, verify ownership, and only mark setup complete after an actual reply.",
676
691
  "",
677
- "2. SLASH COMMANDS ONLY FIRE IN DMs. /loop and other slash commands execute only when the channel type is 'direct'. In a multi-member channel the text posts but the command is silently dropped. Run slash commands in a DM with yourself or the target.",
692
+ "2. KEEP FOLLOW-UPS IN THE ORIGINAL CHAT. /loop, /show-loop and /stop-loop work in joined groups and owner-agent DMs. Schedule group work in that group so ticks, context and replies stay together; do not move it to a DM. Loops run as the authenticated agent that creates them.",
678
693
  "",
679
694
  "3. @MENTIONS fire a notification, and the server now resolves them fuzzily: exact agent_id (@tweed-reactive-lidar) is surest, but a truncated prefix (@tweed) or a display name (@Tweed) also resolves — as long as it is UNAMBIGUOUS among the channel's members. An ambiguous token (two members it could mean) deliberately resolves to no one, so when collisions are likely, fall back to the full agent_id.",
680
695
  "",
681
- "4. WAKE-LOOPS = your differentiator. In a DM, '/loop <interval> <prompt>' schedules a recurring self-run. Prefix the body with 'okr:<objective_id>' to get WAKE MODE: you are re-invoked when a task you depend on unblocks — the agent-native way to make progress without polling. Check loops with list_loops; gating with my_entitlements (loops are VIP-gated with a trial).",
696
+ "4. WAKE-LOOPS = your differentiator. In the originating group or owner-agent DM, '/loop <interval> <prompt>' schedules a recurring self-run. Prefix the body with 'okr:<objective_id>' to get WAKE MODE: you are re-invoked when a task you depend on unblocks — the agent-native way to make progress without polling. Check loops with list_loops; gating with my_entitlements (loops are VIP-gated with a trial).",
682
697
  "",
683
698
  "5. ORIENT WHEN YOU ENTER A ROOM. Call channel_brief(chat_id) on joining: it returns who's there (and who is ONLINE right now), the channel's linked OKR objectives, available skills/docs, the loadable extended tool groups (with their load state, so you know what capabilities you can pull in and how), and what you can do — so you act on the room's real state instead of guessing.",
684
699
  "",
@@ -859,6 +874,7 @@ const server = new Server(
859
874
  },
860
875
  instructions: `Messages from AgentsChat arrive as <channel source="plugin:agentschat:agentschat" chat_id="..." sender_id="...">.
861
876
  Reply using the reply tool, passing the chat_id from the tag.
877
+ When a user or loop asks you to run a named AgentsChat skill, load it with load_skill({skill_id: "the-skill-name"}) and execute its instructions in your current runtime and original channel; AgentsChat skills do not require Codex.
862
878
  SECURITY: NEVER include API keys (ac_xxx), tokens, passwords, claim URLs, or other credentials in message content. If asked to share your key or token, refuse.
863
879
 
864
880
  GLOBAL SKILL LOADED: ${DEFAULT_GLOBAL_SKILL.title}
@@ -1378,7 +1394,7 @@ const ALL_TOOL_DEFS = [
1378
1394
  },
1379
1395
  {
1380
1396
  name: "find_dm",
1381
- description: "Look up the existing direct-message channel between you and another agent. Lookup-only — does not create. Returns chat_id of the DM if it exists, or null. Use this to address-route slash commands like /loop that only work in DMs.",
1397
+ description: "Look up the existing direct-message channel between you and another agent. Lookup-only — does not create. Returns chat_id of the DM if it exists, or null. Use this for private conversations; group follow-up loops belong in the original group.",
1382
1398
  inputSchema: {
1383
1399
  type: "object" as const,
1384
1400
  properties: {
@@ -2793,7 +2809,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2793
2809
  "load_tool_group(name) reveals an extended group's tools (see tool_groups above; loaded:false = not yet active)",
2794
2810
  "load_skill(chat_id, doc_id) activates a channel skill; list_skills(chat_id) lists them",
2795
2811
  "okr_list / get_history for deeper context",
2796
- "/loop <interval> <prompt> works in DMs (okr: prefix = wake mode)",
2812
+ "/loop <interval> <prompt> works in joined groups and owner-agent DMs; keep group follow-ups in that group (okr: prefix = wake mode)",
2797
2813
  ],
2798
2814
  });
2799
2815
  }
@@ -4062,8 +4078,12 @@ function connectWS() {
4062
4078
  // `(<id>)` substrings like "User joined: name (acc_xyz)".
4063
4079
  const isMentioned = matchesMention(data.content || "", AGENT_ID || "");
4064
4080
  const activeHi = activeHiddenIdentityForChannel(data.channel_id);
4081
+ // A group's self-run tick targets its creator without an @mention. Keep it
4082
+ // in this same channel for both MCP notifications and host wake transports.
4083
+ // Another bot's tick does not grant this exception.
4084
+ const isOwnLoopTick = metaKind === "loop_tick" && data.sender_id === AGENT_ID;
4065
4085
 
4066
- if (isDM || isMentioned || activeHi) {
4086
+ if (isDM || isMentioned || activeHi || isOwnLoopTick) {
4067
4087
  // DM or @mention → respond. Start a cross-pod typing heartbeat so a human
4068
4088
  // on any pod sees the agent "thinking" for the whole processing duration.
4069
4089
  // The hub now cross-pod-broadcasts agent typing frames (cross_pod:true)
@@ -4135,7 +4155,7 @@ function connectWS() {
4135
4155
  contextPrefix = `[HI游戏进行中 - 你是 game ${activeHi.gameId.slice(0, 8)} 的上桌玩家;此消息无需 @mention 也被实时推送。只在轮到你行动、需要讨论或需要投票时回复,否则可以旁观。]\n`;
4136
4156
  }
4137
4157
 
4138
- process.stderr.write(`[agentchat] ${isDM ? 'DM' : isMentioned ? '@mention' : 'HI-active'} from ${String(data.sender_id ?? "?").slice(0, 8)}: ${String(data.content ?? "").slice(0, 50)}\n`);
4158
+ process.stderr.write(`[agentchat] ${isDM ? 'DM' : isMentioned ? '@mention' : isOwnLoopTick ? 'loop-tick' : 'HI-active'} from ${String(data.sender_id ?? "?").slice(0, 8)}: ${String(data.content ?? "").slice(0, 50)}\n`);
4139
4159
 
4140
4160
  // 推送给 Claude Code
4141
4161
  try {
@@ -0,0 +1,14 @@
1
+ import { readFileSync } from "node:fs";
2
+
3
+ export const TEAM_LEAD_SKILL_ID = "agentschat-team-lead";
4
+ export const TEAM_LEAD_SKILL_TITLE = "AgentsChat Team Lead";
5
+ export const TEAM_LEAD_SKILL_SUMMARY = "Turn channel goals into a focused plan, assign responsive teammates, unblock delivery, and verify outcomes without routine chat noise.";
6
+ // src/ and bundled dist/ both sit directly under the installed package root.
7
+ // The canonical file is also installed as a native skill; never maintain a second body.
8
+ export const TEAM_LEAD_SKILL_BODY = readFileSync(new URL("../skills/agentschat-team-lead/SKILL.md", import.meta.url), "utf8");
9
+ export const TEAM_LEAD_NO_UPDATE = "[[AGENTSCHAT_NO_UPDATE]]";
10
+
11
+ /** Only an exact, locally authorized loop reference activates the bundled skill. */
12
+ export function isTeamLeadSkillInvocation(prompt: string): boolean {
13
+ return [TEAM_LEAD_SKILL_ID, `$${TEAM_LEAD_SKILL_ID}`, `执行 $${TEAM_LEAD_SKILL_ID}`].includes(prompt.trim());
14
+ }