claude-team-join 1.2.0 → 2.0.0

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
@@ -10,7 +10,7 @@ The team files stay on disk (`~/.claude/teams/`), but no session can lead them a
10
10
 
11
11
  You lose your team setup, prompts, and member configs.
12
12
 
13
- **claude-team-join** is an MCP server that lets Claude Code discover those orphaned teams, take over as lead, and re-spawn the teammates exactly as they were.
13
+ **claude-team-join** installs skills that let Claude Code discover those orphaned teams, take over as lead, and re-spawn the teammates exactly as they were.
14
14
 
15
15
  ## Requirements
16
16
 
@@ -27,7 +27,7 @@ npx claude-team-join --install
27
27
 
28
28
  Then restart Claude Code (close and reopen, or run `claude` again).
29
29
 
30
- That's it. The tools are now available in every Claude Code session.
30
+ That's it. The skills are now available in every Claude Code session.
31
31
 
32
32
  To uninstall:
33
33
 
@@ -37,25 +37,25 @@ npx claude-team-join --uninstall
37
37
 
38
38
  ## What you get
39
39
 
40
- Three tools become available to Claude Code:
40
+ Three skills are installed to `~/.claude/skills/`:
41
41
 
42
- - **`list_teams`** - Shows all teams, their members, and whether the lead session is alive or stale.
42
+ - **`team-join`** - Rejoins an orphaned team by making your current session the new lead.
43
43
 
44
- - **`team_join`** - Makes your current session the new lead of an orphaned team.
44
+ - **`team-list`** - Shows all teams, their members, and whether the lead session is alive or stale.
45
45
 
46
- - **`get_team_members`** - Returns the full config (name, role, prompt, model) for each teammate so they can be re-spawned identically.
46
+ - **`team-members`** - Returns the full config (name, role, prompt, model) for each teammate so they can be re-spawned identically.
47
47
 
48
48
  ## Usage
49
49
 
50
50
  Once installed, just tell Claude Code what you need in plain English:
51
51
 
52
52
  ```
53
- "Show me my orphaned teams"
54
53
  "Rejoin the my-project team"
54
+ "Show me my orphaned teams"
55
55
  "Re-spawn all the teammates from my-project"
56
56
  ```
57
57
 
58
- Claude Code will use the tools automatically.
58
+ Claude Code will match the appropriate skill automatically.
59
59
 
60
60
  ## Contributing
61
61
 
@@ -72,20 +72,14 @@ Run tests:
72
72
  npm test
73
73
  ```
74
74
 
75
- To test locally, point your Claude Code config at the local build:
76
-
77
- ```json
78
- {
79
- "mcpServers": {
80
- "claude-team-join": {
81
- "type": "stdio",
82
- "command": "node",
83
- "args": ["/absolute/path/to/claude-code-agent-teams-join/dist/index.js"]
84
- }
85
- }
86
- }
75
+ To test locally:
76
+
77
+ ```bash
78
+ node dist/index.js --install
87
79
  ```
88
80
 
81
+ Then restart Claude Code and try commands like "rejoin the my-team team".
82
+
89
83
  ## License
90
84
 
91
85
  MIT - see [LICENSE](LICENSE) for details.
package/dist/cli.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export declare function handleInstall(configPath: string): {
1
+ export declare function handleInstall(skillsDir: string): {
2
2
  success: boolean;
3
3
  message: string;
4
4
  };
5
- export declare function handleUninstall(configPath: string): {
5
+ export declare function handleUninstall(skillsDir: string): {
6
6
  success: boolean;
7
7
  message: string;
8
8
  };
package/dist/cli.js CHANGED
@@ -36,62 +36,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.handleInstall = handleInstall;
37
37
  exports.handleUninstall = handleUninstall;
38
38
  const fs = __importStar(require("fs"));
39
- const MCP_SERVER_KEY = "claude-team-join";
40
- function handleInstall(configPath) {
41
- let config;
42
- try {
43
- const raw = fs.readFileSync(configPath, "utf-8");
44
- try {
45
- config = JSON.parse(raw);
46
- }
47
- catch {
48
- // File exists but contains malformed JSON — do NOT overwrite
49
- return {
50
- success: false,
51
- message: `Error: ${configPath} contains malformed JSON. Fix it manually before running --install.`,
52
- };
53
- }
54
- }
55
- catch {
56
- // File doesn't exist — start fresh
57
- config = {};
39
+ const path = __importStar(require("path"));
40
+ const skills_js_1 = require("./skills.js");
41
+ function handleInstall(skillsDir) {
42
+ fs.mkdirSync(skillsDir, { recursive: true });
43
+ const installed = [];
44
+ for (const skill of skills_js_1.SKILLS) {
45
+ const dir = path.join(skillsDir, skill.dirName);
46
+ fs.mkdirSync(dir, { recursive: true });
47
+ fs.writeFileSync(path.join(dir, "SKILL.md"), skill.content, "utf-8");
48
+ installed.push(skill.dirName);
58
49
  }
59
- if (!config.mcpServers)
60
- config.mcpServers = {};
61
- config.mcpServers[MCP_SERVER_KEY] = {
62
- type: "stdio",
63
- command: "npx",
64
- args: ["-y", "claude-team-join"],
65
- };
66
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
67
50
  return {
68
51
  success: true,
69
- message: `Added claude-team-join to ${configPath}\n Restart Claude Code to pick up the new MCP server.`,
52
+ message: `Installed skills to ${skillsDir}: ${installed.join(", ")}\n Restart Claude Code to pick up the new skills.`,
70
53
  };
71
54
  }
72
- function handleUninstall(configPath) {
73
- let config;
74
- try {
75
- const raw = fs.readFileSync(configPath, "utf-8");
76
- config = JSON.parse(raw);
77
- }
78
- catch {
79
- return {
80
- success: true,
81
- message: `claude-team-join is not configured in ${configPath}`,
82
- };
83
- }
84
- if (config.mcpServers?.[MCP_SERVER_KEY]) {
85
- delete config.mcpServers[MCP_SERVER_KEY];
86
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
87
- return {
88
- success: true,
89
- message: `Removed claude-team-join from ${configPath}`,
90
- };
55
+ function handleUninstall(skillsDir) {
56
+ const removed = [];
57
+ for (const skill of skills_js_1.SKILLS) {
58
+ const dir = path.join(skillsDir, skill.dirName);
59
+ if (fs.existsSync(dir)) {
60
+ fs.rmSync(dir, { recursive: true, force: true });
61
+ removed.push(skill.dirName);
62
+ }
91
63
  }
92
64
  return {
93
65
  success: true,
94
- message: `claude-team-join is not configured in ${configPath}`,
66
+ message: removed.length > 0
67
+ ? `Removed skills from ${skillsDir}: ${removed.join(", ")}`
68
+ : `No claude-team-join skills found in ${skillsDir}`,
95
69
  };
96
70
  }
97
71
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,sCAiCC;AAED,0CA0BC;AAjED,uCAAyB;AAEzB,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAE1C,SAAgB,aAAa,CAAC,UAAkB;IAC9C,IAAI,MAA2B,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;YAC7D,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,UAAU,UAAU,qEAAqE;aACnG,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;QACnC,MAAM,GAAG,EAAE,CAAC;IACd,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,UAAU;QAAE,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;IAE/C,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG;QAClC,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,CAAC,IAAI,EAAE,kBAAkB,CAAC;KACjC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAE9E,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,6BAA6B,UAAU,wDAAwD;KACzG,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe,CAAC,UAAkB;IAChD,IAAI,MAA2B,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,yCAAyC,UAAU,EAAE;SAC/D,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;QACxC,OAAO,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QACzC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9E,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,iCAAiC,UAAU,EAAE;SACvD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,yCAAyC,UAAU,EAAE;KAC/D,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,sCAgBC;AAED,0CAiBC;AAvCD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAAqC;AAErC,SAAgB,aAAa,CAAC,SAAiB;IAC7C,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,MAAM,KAAK,IAAI,kBAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,uBAAuB,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,oDAAoD;KACvH,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe,CAAC,SAAiB;IAC/C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,KAAK,IAAI,kBAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC;YACzB,CAAC,CAAC,uBAAuB,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC3D,CAAC,CAAC,uCAAuC,SAAS,EAAE;KACvD,CAAC;AACJ,CAAC"}
package/dist/index.js CHANGED
@@ -34,46 +34,21 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  };
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
- const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
38
- const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
39
- const zod_1 = require("zod");
40
37
  const os = __importStar(require("os"));
41
- const helpers_js_1 = require("./helpers.js");
38
+ const path = __importStar(require("path"));
42
39
  const cli_js_1 = require("./cli.js");
43
- const tools_js_1 = require("./tools.js");
44
- // --- CLI: --install / --uninstall ---
45
- const helpers = (0, helpers_js_1.createHelpers)(os.homedir());
40
+ const skillsDir = path.join(os.homedir(), ".claude", "skills");
46
41
  const arg = process.argv[2];
47
42
  if (arg === "--install" || arg === "install") {
48
- const result = (0, cli_js_1.handleInstall)(helpers.CLAUDE_CONFIG_PATH);
43
+ const result = (0, cli_js_1.handleInstall)(skillsDir);
49
44
  console.log(result.success ? `\u2713 ${result.message}` : result.message);
50
45
  process.exit(result.success ? 0 : 1);
51
46
  }
52
47
  if (arg === "--uninstall" || arg === "uninstall") {
53
- const result = (0, cli_js_1.handleUninstall)(helpers.CLAUDE_CONFIG_PATH);
48
+ const result = (0, cli_js_1.handleUninstall)(skillsDir);
54
49
  console.log(result.success ? `\u2713 ${result.message}` : result.message);
55
50
  process.exit(result.success ? 0 : 1);
56
51
  }
57
- // --- MCP Server ---
58
- const server = new mcp_js_1.McpServer({
59
- name: "claude-team-join",
60
- version: "1.2.0",
61
- });
62
- const toolHandlers = (0, tools_js_1.createToolHandlers)(helpers);
63
- server.tool("list_teams", "List all Claude Code teams with their status, members, and whether the lead session is stale or current", {}, toolHandlers.listTeams);
64
- server.tool("team_join", "Rejoin an existing team by updating its config to point to the current session. This makes you the new team lead.", {
65
- team_name: zod_1.z.string().regex(/^[a-zA-Z0-9_\- ]+$/).describe("Name of the team to rejoin"),
66
- }, toolHandlers.teamJoin);
67
- server.tool("get_team_members", "Get full teammate definitions (name, role, prompt, model) so they can be re-spawned with the Task tool using identical configurations", {
68
- team_name: zod_1.z.string().regex(/^[a-zA-Z0-9_\- ]+$/).describe("Name of the team to get members from"),
69
- }, toolHandlers.getTeamMembers);
70
- // --- Start Server ---
71
- async function main() {
72
- const transport = new stdio_js_1.StdioServerTransport();
73
- await server.connect(transport);
74
- }
75
- main().catch((err) => {
76
- console.error("Fatal error:", err);
77
- process.exit(1);
78
- });
52
+ console.log("Usage: claude-team-join --install | --uninstall");
53
+ process.exit(0);
79
54
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,oEAAoE;AACpE,wEAAiF;AACjF,6BAAwB;AACxB,uCAAyB;AAEzB,6CAA6C;AAC7C,qCAA0D;AAC1D,yCAAgD;AAEhD,uCAAuC;AAEvC,MAAM,OAAO,GAAG,IAAA,0BAAa,EAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;AAE5C,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5B,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAA,sBAAa,EAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AACD,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,IAAA,wBAAe,EAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,qBAAqB;AAErB,MAAM,MAAM,GAAG,IAAI,kBAAS,CAAC;IAC3B,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,IAAA,6BAAkB,EAAC,OAAO,CAAC,CAAC;AAEjD,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,yGAAyG,EACzG,EAAE,EACF,YAAY,CAAC,SAAS,CACvB,CAAC;AAEF,MAAM,CAAC,IAAI,CACT,WAAW,EACX,mHAAmH,EACnH;IACE,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;CACzF,EACD,YAAY,CAAC,QAAQ,CACtB,CAAC;AAEF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,uIAAuI,EACvI;IACE,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;CACnG,EACD,YAAY,CAAC,cAAc,CAC5B,CAAC;AAEF,uBAAuB;AAEvB,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,uCAAyB;AACzB,2CAA6B;AAC7B,qCAA0D;AAE1D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAE5B,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAA,sBAAa,EAAC,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,IAAA,wBAAe,EAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;AAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface SkillDefinition {
2
+ dirName: string;
3
+ content: string;
4
+ }
5
+ export declare const SKILLS: SkillDefinition[];
package/dist/skills.js ADDED
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SKILLS = void 0;
4
+ exports.SKILLS = [
5
+ {
6
+ dirName: "team-join",
7
+ content: `---
8
+ name: team-join
9
+ description: Rejoin an orphaned Claude Code agent team. Use when user says "rejoin team", "join team", "reconnect team", "resume team", "rejoin the <name> team", or wants to become the lead of an existing team.
10
+ allowed-tools: Read, Write, Bash, Glob
11
+ ---
12
+
13
+ # Rejoin an Orphaned Claude Code Team
14
+
15
+ You are helping the user rejoin an orphaned Claude Code agent team. Follow these steps precisely.
16
+
17
+ ## Step 1: Identify the team
18
+
19
+ If the user specified a team name, use that. Otherwise, list available teams:
20
+
21
+ \`\`\`bash
22
+ ls ~/.claude/teams/
23
+ \`\`\`
24
+
25
+ If multiple teams exist and none was specified, show the list and ask the user which team to rejoin.
26
+
27
+ If no teams exist, tell the user there are no teams to rejoin and stop.
28
+
29
+ ## Step 2: Read the team config
30
+
31
+ Read the file \`~/.claude/teams/{team_name}/config.json\`.
32
+
33
+ If it doesn't exist or is unreadable, tell the user and stop.
34
+
35
+ ## Step 3: Get the current session ID
36
+
37
+ Run:
38
+
39
+ \`\`\`bash
40
+ ls -t ~/.claude/session-env/ | head -1
41
+ \`\`\`
42
+
43
+ This returns the most recently modified session directory name, which is the current session ID.
44
+
45
+ If no session is found, tell the user the session could not be detected and stop.
46
+
47
+ ## Step 4: Update the team config
48
+
49
+ Modify the config JSON:
50
+ 1. Set \`leadSessionId\` to the current session ID from step 3
51
+ 2. Set \`leadAgentId\` to \`team-lead@{team_name}\`
52
+ 3. For every entry in the \`members\` array, set \`isActive\` to \`false\`
53
+
54
+ Write the updated JSON back to \`~/.claude/teams/{team_name}/config.json\` (pretty-printed with 4-space indent).
55
+
56
+ ## Step 5: Report the result
57
+
58
+ Tell the user:
59
+ - The team has been rejoined
60
+ - How many teammates were reset to inactive
61
+ - List each non-"team-lead" member by name and role (agentType)
62
+ - Offer to re-spawn the teammates using the Task tool
63
+
64
+ Use the get_team_members skill or read the config directly to get teammate details for re-spawning.
65
+ `,
66
+ },
67
+ {
68
+ dirName: "team-list",
69
+ content: `---
70
+ name: team-list
71
+ description: List all Claude Code agent teams and their status. Use when user says "list teams", "show teams", "my teams", "orphaned teams", "team status".
72
+ allowed-tools: Read, Bash, Glob
73
+ ---
74
+
75
+ # List Claude Code Agent Teams
76
+
77
+ You are listing all Claude Code agent teams and their status. Follow these steps.
78
+
79
+ ## Step 1: Find all teams
80
+
81
+ List directories in \`~/.claude/teams/\`:
82
+
83
+ \`\`\`bash
84
+ ls ~/.claude/teams/
85
+ \`\`\`
86
+
87
+ If the directory doesn't exist or is empty, tell the user there are no teams and stop.
88
+
89
+ ## Step 2: Read each team's config
90
+
91
+ For each team directory, read \`~/.claude/teams/{team_name}/config.json\`.
92
+
93
+ Skip any team whose config is missing or unreadable.
94
+
95
+ ## Step 3: Check session staleness
96
+
97
+ For each team, determine the lead session status:
98
+
99
+ 1. Get the team's \`leadSessionId\` from the config
100
+ 2. Check if that session directory exists and its modification time:
101
+
102
+ \`\`\`bash
103
+ stat -f "%m" ~/.claude/session-env/{leadSessionId}/ 2>/dev/null
104
+ \`\`\`
105
+
106
+ 3. Get the current time:
107
+
108
+ \`\`\`bash
109
+ date +%s
110
+ \`\`\`
111
+
112
+ 4. If the session was modified less than 5 minutes ago (300 seconds), it is **active**. Otherwise it is **stale**.
113
+
114
+ Also determine the current session:
115
+
116
+ \`\`\`bash
117
+ ls -t ~/.claude/session-env/ | head -1
118
+ \`\`\`
119
+
120
+ If the team's \`leadSessionId\` matches the current session, status is **current**. If active but not current, status is **active-other**. Otherwise **stale**.
121
+
122
+ ## Step 4: Present the results
123
+
124
+ For each team, show:
125
+ - **Team name**
126
+ - **Description** (or "no description" if missing)
127
+ - **Created at** (formatted from the \`createdAt\` timestamp)
128
+ - **Member count** and member names with roles
129
+ - **Lead session status**: current, active-other, or stale
130
+
131
+ Format as a clear, readable list. Highlight stale teams as candidates for rejoining.
132
+ `,
133
+ },
134
+ {
135
+ dirName: "team-members",
136
+ content: `---
137
+ name: team-members
138
+ description: Get teammate definitions from a Claude Code team for re-spawning. Use when user says "team members", "show teammates", "re-spawn teammates", "respawn agents".
139
+ allowed-tools: Read, Bash, Glob
140
+ ---
141
+
142
+ # Get Team Member Definitions
143
+
144
+ You are retrieving teammate definitions from a Claude Code team so they can be re-spawned. Follow these steps.
145
+
146
+ ## Step 1: Identify the team
147
+
148
+ If the user specified a team name, use that. Otherwise, list available teams:
149
+
150
+ \`\`\`bash
151
+ ls ~/.claude/teams/
152
+ \`\`\`
153
+
154
+ If multiple teams exist and none was specified, show the list and ask the user which team to inspect.
155
+
156
+ ## Step 2: Read the team config
157
+
158
+ Read \`~/.claude/teams/{team_name}/config.json\`.
159
+
160
+ If it doesn't exist or is unreadable, tell the user and stop.
161
+
162
+ ## Step 3: Extract teammate definitions
163
+
164
+ From the \`members\` array, filter out the entry with \`name\` equal to \`"team-lead"\` (that's the lead agent, not a spawnable teammate).
165
+
166
+ For each remaining member, present:
167
+ - **name**: The teammate's name
168
+ - **agentType**: Their role/subagent type (e.g., "general-purpose", "Explore")
169
+ - **model**: The model they were using (e.g., "sonnet", "opus")
170
+ - **prompt**: Whether they have a prompt defined (show the prompt content)
171
+ - **cwd**: Their working directory
172
+ - **planModeRequired**: Whether they require plan mode (default false)
173
+
174
+ ## Step 4: Offer to re-spawn
175
+
176
+ Ask the user if they'd like to re-spawn these teammates. If yes, use the Task tool to spawn each one with their original configuration:
177
+
178
+ \`\`\`
179
+ Task tool parameters:
180
+ - name: {member.name}
181
+ - subagent_type: {member.agentType}
182
+ - model: {member.model}
183
+ - prompt: {member.prompt}
184
+ - team_name: {team_name}
185
+ - mode: "plan" (if planModeRequired is true)
186
+ \`\`\`
187
+
188
+ Spawn teammates in parallel when possible by making multiple Task tool calls in a single message.
189
+ `,
190
+ },
191
+ ];
192
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":";;;AAKa,QAAA,MAAM,GAAsB;IACvC;QACE,OAAO,EAAE,WAAW;QACpB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DZ;KACE;IACD;QACE,OAAO,EAAE,WAAW;QACpB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+DZ;KACE;IACD;QACE,OAAO,EAAE,cAAc;QACvB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqDZ;KACE;CACF,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "claude-team-join",
3
- "version": "1.2.0",
4
- "description": "MCP server for listing, inspecting, and rejoining orphaned Claude Code teams",
3
+ "version": "2.0.0",
4
+ "description": "Skill package for listing, inspecting, and rejoining orphaned Claude Code teams",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "claude-team-join": "dist/index.js"
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "keywords": [
18
18
  "claude-code",
19
- "mcp",
19
+ "skill",
20
20
  "team",
21
21
  "agent"
22
22
  ],
@@ -30,10 +30,7 @@
30
30
  "bugs": {
31
31
  "url": "https://github.com/shim52/claude-code-agent-teams-join/issues"
32
32
  },
33
- "dependencies": {
34
- "@modelcontextprotocol/sdk": "^1.12.1",
35
- "zod": "^3.23.0"
36
- },
33
+ "dependencies": {},
37
34
  "devDependencies": {
38
35
  "typescript": "^5.7.0",
39
36
  "@types/node": "^22.0.0",
package/dist/helpers.d.ts DELETED
@@ -1,35 +0,0 @@
1
- export interface TeamMember {
2
- agentId: string;
3
- name: string;
4
- agentType: string;
5
- model?: string;
6
- prompt?: string;
7
- color?: string;
8
- planModeRequired?: boolean;
9
- joinedAt: number;
10
- tmuxPaneId?: string;
11
- cwd?: string;
12
- subscriptions?: string[];
13
- backendType?: string;
14
- isActive?: boolean;
15
- }
16
- export interface TeamConfig {
17
- name: string;
18
- description?: string;
19
- createdAt: number;
20
- leadAgentId: string;
21
- leadSessionId: string;
22
- members: TeamMember[];
23
- }
24
- export declare function createHelpers(homeDir: string): {
25
- getTeamNames: () => string[];
26
- readTeamConfig: (teamName: string) => TeamConfig | null;
27
- writeTeamConfig: (teamName: string, config: TeamConfig) => void;
28
- getCurrentSessionId: () => string | null;
29
- isSessionActive: (sessionId: string) => boolean;
30
- formatTimestamp: (ts: number) => string;
31
- CLAUDE_CONFIG_PATH: string;
32
- TEAMS_DIR: string;
33
- SESSION_ENV_DIR: string;
34
- };
35
- export type Helpers = ReturnType<typeof createHelpers>;
package/dist/helpers.js DELETED
@@ -1,133 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.createHelpers = createHelpers;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- function isValidTeamName(name) {
40
- return name.length > 0 && !/[\/\\]|\.\./.test(name);
41
- }
42
- function createHelpers(homeDir) {
43
- const CLAUDE_DIR = path.join(homeDir, ".claude");
44
- const TEAMS_DIR = path.join(CLAUDE_DIR, "teams");
45
- const SESSION_ENV_DIR = path.join(CLAUDE_DIR, "session-env");
46
- const CLAUDE_CONFIG_PATH = path.join(homeDir, ".claude.json");
47
- function getTeamNames() {
48
- try {
49
- return fs
50
- .readdirSync(TEAMS_DIR, { withFileTypes: true })
51
- .filter((d) => d.isDirectory())
52
- .map((d) => d.name);
53
- }
54
- catch {
55
- return [];
56
- }
57
- }
58
- function readTeamConfig(teamName) {
59
- if (!isValidTeamName(teamName)) {
60
- return null;
61
- }
62
- const configPath = path.join(TEAMS_DIR, teamName, "config.json");
63
- try {
64
- const raw = fs.readFileSync(configPath, "utf-8");
65
- const parsed = JSON.parse(raw);
66
- // Validate required fields
67
- if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.members)) {
68
- return null;
69
- }
70
- return parsed;
71
- }
72
- catch (err) {
73
- if (err instanceof Error && "code" in err && err.code === "ENOENT") {
74
- return null;
75
- }
76
- // Log non-ENOENT errors (e.g. permission denied) so they aren't silently lost
77
- process.stderr.write(`Warning: failed to read team config for "${teamName}": ${err instanceof Error ? err.message : String(err)}\n`);
78
- return null;
79
- }
80
- }
81
- function writeTeamConfig(teamName, config) {
82
- if (!isValidTeamName(teamName)) {
83
- throw new Error(`Invalid team name: "${teamName}"`);
84
- }
85
- const configPath = path.join(TEAMS_DIR, teamName, "config.json");
86
- fs.writeFileSync(configPath, JSON.stringify(config, null, 4), "utf-8");
87
- }
88
- function getCurrentSessionId() {
89
- try {
90
- const entries = fs.readdirSync(SESSION_ENV_DIR, { withFileTypes: true });
91
- let newest = null;
92
- for (const entry of entries) {
93
- if (!entry.isDirectory())
94
- continue;
95
- const stat = fs.statSync(path.join(SESSION_ENV_DIR, entry.name));
96
- if (!newest || stat.mtimeMs > newest.mtimeMs) {
97
- newest = { name: entry.name, mtimeMs: stat.mtimeMs };
98
- }
99
- }
100
- return newest?.name ?? null;
101
- }
102
- catch {
103
- return null;
104
- }
105
- }
106
- function isSessionActive(sessionId) {
107
- const sessionDir = path.join(SESSION_ENV_DIR, sessionId);
108
- try {
109
- const stat = fs.statSync(sessionDir);
110
- const ageMs = Date.now() - stat.mtimeMs;
111
- // Consider a session "active" if modified in the last 5 minutes
112
- return ageMs < 5 * 60 * 1000;
113
- }
114
- catch {
115
- return false;
116
- }
117
- }
118
- function formatTimestamp(ts) {
119
- return new Date(ts).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC");
120
- }
121
- return {
122
- getTeamNames,
123
- readTeamConfig,
124
- writeTeamConfig,
125
- getCurrentSessionId,
126
- isSessionActive,
127
- formatTimestamp,
128
- CLAUDE_CONFIG_PATH,
129
- TEAMS_DIR,
130
- SESSION_ENV_DIR,
131
- };
132
- }
133
- //# sourceMappingURL=helpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
package/dist/tools.d.ts DELETED
@@ -1,39 +0,0 @@
1
- import type { Helpers } from "./helpers.js";
2
- export declare function createToolHandlers(helpers: Helpers): {
3
- listTeams: () => Promise<{
4
- content: {
5
- type: "text";
6
- text: string;
7
- }[];
8
- }>;
9
- teamJoin: ({ team_name }: {
10
- team_name: string;
11
- }) => Promise<{
12
- content: {
13
- type: "text";
14
- text: string;
15
- }[];
16
- isError: boolean;
17
- } | {
18
- content: {
19
- type: "text";
20
- text: string;
21
- }[];
22
- isError?: undefined;
23
- }>;
24
- getTeamMembers: ({ team_name }: {
25
- team_name: string;
26
- }) => Promise<{
27
- content: {
28
- type: "text";
29
- text: string;
30
- }[];
31
- isError: boolean;
32
- } | {
33
- content: {
34
- type: "text";
35
- text: string;
36
- }[];
37
- isError?: undefined;
38
- }>;
39
- };
package/dist/tools.js DELETED
@@ -1,164 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createToolHandlers = createToolHandlers;
4
- function createToolHandlers(helpers) {
5
- return {
6
- listTeams: async () => {
7
- const teamNames = helpers.getTeamNames();
8
- if (teamNames.length === 0) {
9
- return {
10
- content: [
11
- {
12
- type: "text",
13
- text: `No teams found in ${helpers.TEAMS_DIR}`,
14
- },
15
- ],
16
- };
17
- }
18
- const currentSessionId = helpers.getCurrentSessionId();
19
- const teams = [];
20
- for (const name of teamNames) {
21
- const config = helpers.readTeamConfig(name);
22
- if (!config)
23
- continue;
24
- const isCurrentSession = config.leadSessionId === currentSessionId;
25
- const isActive = helpers.isSessionActive(config.leadSessionId);
26
- const members = config.members.map((m) => ({
27
- name: m.name,
28
- role: m.agentType,
29
- isActive: m.isActive ?? false,
30
- }));
31
- teams.push({
32
- teamName: name,
33
- description: config.description ?? "(no description)",
34
- createdAt: helpers.formatTimestamp(config.createdAt),
35
- memberCount: config.members.length,
36
- members,
37
- leadSessionId: config.leadSessionId,
38
- leadSessionStatus: isCurrentSession
39
- ? "current"
40
- : isActive
41
- ? "active-other"
42
- : "stale",
43
- });
44
- }
45
- return {
46
- content: [
47
- {
48
- type: "text",
49
- text: JSON.stringify(teams, null, 2),
50
- },
51
- ],
52
- };
53
- },
54
- teamJoin: async ({ team_name }) => {
55
- const config = helpers.readTeamConfig(team_name);
56
- if (!config) {
57
- return {
58
- content: [
59
- {
60
- type: "text",
61
- text: `Error: Team "${team_name}" not found. Use list_teams to see available teams.`,
62
- },
63
- ],
64
- isError: true,
65
- };
66
- }
67
- const currentSessionId = helpers.getCurrentSessionId();
68
- if (!currentSessionId) {
69
- return {
70
- content: [
71
- {
72
- type: "text",
73
- text: `Error: Could not detect current session ID from ${helpers.SESSION_ENV_DIR}`,
74
- },
75
- ],
76
- isError: true,
77
- };
78
- }
79
- const previousSessionId = config.leadSessionId;
80
- // Update the lead session to current
81
- config.leadSessionId = currentSessionId;
82
- config.leadAgentId = `team-lead@${team_name}`;
83
- // Reset all members' isActive to false (they need to be re-spawned)
84
- for (const member of config.members) {
85
- member.isActive = false;
86
- }
87
- try {
88
- helpers.writeTeamConfig(team_name, config);
89
- }
90
- catch (err) {
91
- return {
92
- content: [
93
- {
94
- type: "text",
95
- text: `Error: Failed to write team config: ${err instanceof Error ? err.message : String(err)}`,
96
- },
97
- ],
98
- isError: true,
99
- };
100
- }
101
- const nonLeadMembers = config.members.filter((m) => m.name !== "team-lead");
102
- return {
103
- content: [
104
- {
105
- type: "text",
106
- text: JSON.stringify({
107
- status: "joined",
108
- teamName: team_name,
109
- description: config.description,
110
- previousSessionId,
111
- newSessionId: currentSessionId,
112
- membersResetToInactive: config.members.length,
113
- teammatesReadyToRespawn: nonLeadMembers.map((m) => ({
114
- name: m.name,
115
- role: m.agentType,
116
- hasPrompt: !!m.prompt,
117
- })),
118
- }, null, 2),
119
- },
120
- ],
121
- };
122
- },
123
- getTeamMembers: async ({ team_name }) => {
124
- const config = helpers.readTeamConfig(team_name);
125
- if (!config) {
126
- return {
127
- content: [
128
- {
129
- type: "text",
130
- text: `Error: Team "${team_name}" not found. Use list_teams to see available teams.`,
131
- },
132
- ],
133
- isError: true,
134
- };
135
- }
136
- // Return non-lead members with their full spawn configurations
137
- const teammates = config.members
138
- .filter((m) => m.name !== "team-lead")
139
- .map((m) => ({
140
- name: m.name,
141
- agentType: m.agentType,
142
- model: m.model,
143
- prompt: m.prompt,
144
- color: m.color,
145
- planModeRequired: m.planModeRequired ?? false,
146
- cwd: m.cwd,
147
- previousAgentId: m.agentId,
148
- }));
149
- return {
150
- content: [
151
- {
152
- type: "text",
153
- text: JSON.stringify({
154
- teamName: team_name,
155
- description: config.description,
156
- teammates,
157
- }, null, 2),
158
- },
159
- ],
160
- };
161
- },
162
- };
163
- }
164
- //# sourceMappingURL=tools.js.map
package/dist/tools.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}