claude-code-swarm 0.3.10 → 0.3.11

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,95 +0,0 @@
1
- #!/bin/bash
2
- # Wrapper script to run agent-inbox MCP server
3
- # When the sidecar's inbox socket exists, runs in proxy mode (IPC client).
4
- # Otherwise falls back to standalone mode with its own storage.
5
- # Exits silently if inbox is not enabled or not installed.
6
-
7
- # Check if inbox is enabled in config
8
- ENABLED=false
9
- if [ -f .swarm/claude-swarm/config.json ]; then
10
- ENABLED=$(node -e "
11
- try {
12
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
13
- const envEnabled = (process.env.SWARM_INBOX_ENABLED || '').toLowerCase();
14
- const isEnabled = ['true', '1', 'yes'].includes(envEnabled) || c.inbox?.enabled === true;
15
- process.stdout.write(isEnabled ? 'true' : 'false');
16
- } catch { process.stdout.write('false'); }
17
- " 2>/dev/null || echo "false")
18
- elif [ -n "$SWARM_INBOX_ENABLED" ]; then
19
- case "$(echo "$SWARM_INBOX_ENABLED" | tr '[:upper:]' '[:lower:]')" in
20
- true|1|yes) ENABLED=true ;;
21
- esac
22
- fi
23
-
24
- if [ "$ENABLED" != "true" ]; then
25
- # Not enabled — exit silently so Claude Code doesn't show an error
26
- sleep 0.1
27
- exit 0
28
- fi
29
-
30
- # Read scope from config (defaults to MAP scope or "default")
31
- SCOPE="default"
32
- if [ -f .swarm/claude-swarm/config.json ]; then
33
- CONFIGURED_SCOPE=$(node -e "
34
- try {
35
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
36
- const s = c.inbox?.scope || c.map?.scope || process.env.SWARM_INBOX_SCOPE || '';
37
- if (s) process.stdout.write(s);
38
- } catch {}
39
- " 2>/dev/null)
40
- if [ -n "$CONFIGURED_SCOPE" ]; then
41
- SCOPE="$CONFIGURED_SCOPE"
42
- fi
43
- fi
44
-
45
- if [ -n "$SWARM_INBOX_SCOPE" ]; then
46
- SCOPE="$SWARM_INBOX_SCOPE"
47
- fi
48
-
49
- export INBOX_SCOPE="$SCOPE"
50
-
51
- # Discover sidecar inbox socket for proxy mode
52
- # Check well-known paths: .swarm/claude-swarm/tmp/map/inbox.sock
53
- INBOX_SOCK=""
54
- if [ -S .swarm/claude-swarm/tmp/map/inbox.sock ]; then
55
- INBOX_SOCK=".swarm/claude-swarm/tmp/map/inbox.sock"
56
- fi
57
-
58
- # Also check per-session paths
59
- if [ -z "$INBOX_SOCK" ] && [ -d .swarm/claude-swarm/tmp/map/sessions ]; then
60
- # Find the most recently modified inbox.sock in session dirs
61
- INBOX_SOCK=$(find .swarm/claude-swarm/tmp/map/sessions -name inbox.sock -type s 2>/dev/null | head -1)
62
- fi
63
-
64
- # If inbox socket found, enable proxy mode
65
- if [ -n "$INBOX_SOCK" ]; then
66
- export INBOX_SOCKET_PATH="$INBOX_SOCK"
67
- fi
68
-
69
- # Try to find the agent-inbox module entry point
70
- INBOX_MAIN=""
71
-
72
- # 1. Check global npm root (swarmkit installs here)
73
- GLOBAL_ROOT=$(npm root -g 2>/dev/null)
74
- if [ -n "$GLOBAL_ROOT" ] && [ -f "$GLOBAL_ROOT/agent-inbox/dist/index.js" ]; then
75
- INBOX_MAIN="$GLOBAL_ROOT/agent-inbox/dist/index.js"
76
- fi
77
-
78
- # 2. Check plugin directory's node_modules (dev installs)
79
- if [ -z "$INBOX_MAIN" ] && [ -n "$CLAUDE_PLUGIN_ROOT" ] && [ -f "$CLAUDE_PLUGIN_ROOT/node_modules/agent-inbox/dist/index.js" ]; then
80
- INBOX_MAIN="$CLAUDE_PLUGIN_ROOT/node_modules/agent-inbox/dist/index.js"
81
- fi
82
-
83
- # 3. Fallback: try require.resolve from CWD
84
- if [ -z "$INBOX_MAIN" ]; then
85
- INBOX_MAIN=$(node -e "try { console.log(require.resolve('agent-inbox/dist/index.js')); } catch {}" 2>/dev/null)
86
- fi
87
-
88
- if [ -n "$INBOX_MAIN" ]; then
89
- # Uses proxy mode when INBOX_SOCKET_PATH is set, standalone otherwise
90
- exec node "$INBOX_MAIN" mcp
91
- fi
92
-
93
- # agent-inbox not installed — log to stderr and exit cleanly
94
- echo "[agent-inbox-mcp] agent-inbox not found. Install with: npm install -g agent-inbox or install via swarmkit" >&2
95
- exit 0
@@ -1,98 +0,0 @@
1
- #!/bin/bash
2
- # Wrapper script to run minimem MCP server
3
- # Reads provider and directory from swarm config
4
- # Exits silently if minimem is not enabled or not installed
5
-
6
- # Check if minimem is enabled in config
7
- ENABLED=false
8
- if [ -f .swarm/claude-swarm/config.json ]; then
9
- ENABLED=$(node -e "
10
- try {
11
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
12
- const envEnabled = (process.env.SWARM_MINIMEM_ENABLED || '').toLowerCase();
13
- const isEnabled = ['true', '1', 'yes'].includes(envEnabled) || c.minimem?.enabled === true;
14
- process.stdout.write(isEnabled ? 'true' : 'false');
15
- } catch { process.stdout.write('false'); }
16
- " 2>/dev/null || echo "false")
17
- elif [ -n "$SWARM_MINIMEM_ENABLED" ]; then
18
- case "$(echo "$SWARM_MINIMEM_ENABLED" | tr '[:upper:]' '[:lower:]')" in
19
- true|1|yes) ENABLED=true ;;
20
- esac
21
- fi
22
-
23
- if [ "$ENABLED" != "true" ]; then
24
- # Not enabled — exit silently so Claude Code doesn't show an error
25
- sleep 0.1
26
- exit 0
27
- fi
28
-
29
- # Read provider from config (defaults to "auto")
30
- PROVIDER="auto"
31
- if [ -f .swarm/claude-swarm/config.json ]; then
32
- CONFIGURED_PROVIDER=$(node -e "
33
- try {
34
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
35
- const p = process.env.SWARM_MINIMEM_PROVIDER || c.minimem?.provider || '';
36
- if (p) process.stdout.write(p);
37
- } catch {}
38
- " 2>/dev/null)
39
- if [ -n "$CONFIGURED_PROVIDER" ]; then
40
- PROVIDER="$CONFIGURED_PROVIDER"
41
- fi
42
- fi
43
-
44
- if [ -n "$SWARM_MINIMEM_PROVIDER" ]; then
45
- PROVIDER="$SWARM_MINIMEM_PROVIDER"
46
- fi
47
-
48
- # Discover memory directory: config dir > .swarm/minimem/ > cwd
49
- MEMORY_DIR=""
50
- if [ -f .swarm/claude-swarm/config.json ]; then
51
- CONFIGURED_DIR=$(node -e "
52
- try {
53
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
54
- const d = process.env.SWARM_MINIMEM_DIR || c.minimem?.dir || '';
55
- if (d) process.stdout.write(d);
56
- } catch {}
57
- " 2>/dev/null)
58
- if [ -n "$CONFIGURED_DIR" ]; then
59
- MEMORY_DIR="$CONFIGURED_DIR"
60
- fi
61
- fi
62
-
63
- if [ -n "$SWARM_MINIMEM_DIR" ]; then
64
- MEMORY_DIR="$SWARM_MINIMEM_DIR"
65
- fi
66
-
67
- if [ -z "$MEMORY_DIR" ]; then
68
- if [ -d ".swarm/minimem" ]; then
69
- MEMORY_DIR=".swarm/minimem"
70
- else
71
- MEMORY_DIR="."
72
- fi
73
- fi
74
-
75
- # Check if global memory should also be searched
76
- GLOBAL_ARG=""
77
- if [ -f .swarm/claude-swarm/config.json ]; then
78
- USE_GLOBAL=$(node -e "
79
- try {
80
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
81
- const envGlobal = (process.env.SWARM_MINIMEM_GLOBAL || '').toLowerCase();
82
- const isGlobal = ['true', '1', 'yes'].includes(envGlobal) || c.minimem?.global === true;
83
- process.stdout.write(isGlobal ? 'true' : 'false');
84
- } catch { process.stdout.write('false'); }
85
- " 2>/dev/null || echo "false")
86
- if [ "$USE_GLOBAL" = "true" ]; then
87
- GLOBAL_ARG="--global"
88
- fi
89
- fi
90
-
91
- # Try installed minimem command
92
- if command -v minimem &> /dev/null; then
93
- exec minimem mcp --dir "$MEMORY_DIR" --provider "$PROVIDER" $GLOBAL_ARG
94
- fi
95
-
96
- # minimem not installed — log to stderr and exit cleanly
97
- echo "[minimem-mcp] minimem CLI not found. Install with: npm install -g minimem" >&2
98
- exit 0
@@ -1,65 +0,0 @@
1
- #!/bin/bash
2
- # Wrapper script to run opentasks MCP server
3
- # Reads scope from swarm config, defaults to "tasks"
4
- # Exits silently if opentasks is not enabled or not installed
5
-
6
- # Check if opentasks is enabled in config
7
- ENABLED=false
8
- if [ -f .swarm/claude-swarm/config.json ]; then
9
- ENABLED=$(node -e "
10
- try {
11
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
12
- const envEnabled = (process.env.SWARM_OPENTASKS_ENABLED || '').toLowerCase();
13
- const isEnabled = ['true', '1', 'yes'].includes(envEnabled) || c.opentasks?.enabled === true;
14
- process.stdout.write(isEnabled ? 'true' : 'false');
15
- } catch { process.stdout.write('false'); }
16
- " 2>/dev/null || echo "false")
17
- elif [ -n "$SWARM_OPENTASKS_ENABLED" ]; then
18
- case "$(echo "$SWARM_OPENTASKS_ENABLED" | tr '[:upper:]' '[:lower:]')" in
19
- true|1|yes) ENABLED=true ;;
20
- esac
21
- fi
22
-
23
- if [ "$ENABLED" != "true" ]; then
24
- # Not enabled — exit silently so Claude Code doesn't show an error
25
- # Sleep briefly then exit so the MCP transport doesn't see an immediate close
26
- sleep 0.1
27
- exit 0
28
- fi
29
-
30
- # Read scope from config
31
- SCOPE="tasks"
32
- if [ -f .swarm/claude-swarm/config.json ]; then
33
- CONFIGURED_SCOPE=$(node -e "
34
- try {
35
- const c = JSON.parse(require('fs').readFileSync('.swarm/claude-swarm/config.json', 'utf-8'));
36
- const s = c.opentasks?.scope || process.env.SWARM_OPENTASKS_SCOPE || '';
37
- if (s) process.stdout.write(s);
38
- } catch {}
39
- " 2>/dev/null)
40
- if [ -n "$CONFIGURED_SCOPE" ]; then
41
- SCOPE="$CONFIGURED_SCOPE"
42
- fi
43
- fi
44
-
45
- if [ -n "$SWARM_OPENTASKS_SCOPE" ]; then
46
- SCOPE="$SWARM_OPENTASKS_SCOPE"
47
- fi
48
-
49
- # Build socket path arg if daemon socket exists
50
- SOCKET_ARG=""
51
- for SOCK in .swarm/opentasks/daemon.sock .opentasks/daemon.sock .git/opentasks/daemon.sock; do
52
- if [ -S "$SOCK" ]; then
53
- SOCKET_ARG="--socket $SOCK"
54
- break
55
- fi
56
- done
57
-
58
- # Try installed opentasks command
59
- if command -v opentasks &> /dev/null; then
60
- exec opentasks mcp --scope "$SCOPE" $SOCKET_ARG
61
- fi
62
-
63
- # opentasks not installed — log to stderr and exit cleanly
64
- echo "[opentasks-mcp] opentasks CLI not found. Install with: npm install -g opentasks" >&2
65
- exit 0
@@ -1,179 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * dev-link.mjs — Link/unlink local plugin for development
4
- *
5
- * Replaces the installed plugin cache directory with a symlink to the local
6
- * repo. Claude Code resolves CLAUDE_PLUGIN_ROOT from the original cache path,
7
- * so we must symlink there (editing installed_plugins.json alone doesn't work).
8
- *
9
- * Usage:
10
- * npm run dev:link — replace cache dir with symlink to local repo
11
- * npm run dev:unlink — remove symlink, reinstall from marketplace
12
- * npm run dev:status — check current link state
13
- */
14
-
15
- import fs from "fs";
16
- import path from "path";
17
- import os from "os";
18
- import { execSync } from "child_process";
19
- import { fileURLToPath } from "url";
20
-
21
- const __filename = fileURLToPath(import.meta.url);
22
- const PLUGIN_ROOT = path.resolve(path.dirname(__filename), "..");
23
- const PLUGIN_KEY = "claude-code-swarm@claude-code-swarm";
24
- const MARKETPLACE_KEY = "claude-code-swarm";
25
- const PLUGINS_DIR = path.join(os.homedir(), ".claude", "plugins");
26
- const CACHE_DIR = path.join(PLUGINS_DIR, "cache");
27
- const INSTALLED_PLUGINS_PATH = path.join(PLUGINS_DIR, "installed_plugins.json");
28
- const MARKETPLACES_PATH = path.join(PLUGINS_DIR, "known_marketplaces.json");
29
-
30
- const action = process.argv[2];
31
-
32
- function readJson(filePath) {
33
- try {
34
- return JSON.parse(fs.readFileSync(filePath, "utf-8"));
35
- } catch {
36
- console.error(`Could not read ${filePath}`);
37
- process.exit(1);
38
- }
39
- }
40
-
41
- function getPluginEntry() {
42
- const data = readJson(INSTALLED_PLUGINS_PATH);
43
- const entries = data.plugins?.[PLUGIN_KEY];
44
- if (!entries?.length) {
45
- console.error(`Plugin "${PLUGIN_KEY}" not found in installed_plugins.json`);
46
- process.exit(1);
47
- }
48
- return { data, entry: entries[0] };
49
- }
50
-
51
- function getMarketplacePath() {
52
- const data = readJson(MARKETPLACES_PATH);
53
- const marketplace = data[MARKETPLACE_KEY];
54
- if (!marketplace?.installLocation) {
55
- console.error(`Marketplace "${MARKETPLACE_KEY}" not found in known_marketplaces.json`);
56
- process.exit(1);
57
- }
58
- return marketplace.installLocation;
59
- }
60
-
61
- function isSymlink(p) {
62
- try {
63
- return fs.lstatSync(p).isSymbolicLink();
64
- } catch {
65
- return false;
66
- }
67
- }
68
-
69
- /**
70
- * Get the cache path that Claude Code actually uses for CLAUDE_PLUGIN_ROOT.
71
- * This is the installPath from installed_plugins.json (usually under ~/.claude/plugins/cache/).
72
- */
73
- function getCachePath() {
74
- const { entry } = getPluginEntry();
75
- // If installPath was already changed to local repo, look for the original
76
- if (entry.installPath === PLUGIN_ROOT && entry._originalInstallPath) {
77
- return entry._originalInstallPath;
78
- }
79
- return entry.installPath;
80
- }
81
-
82
- function link() {
83
- const cachePath = getCachePath();
84
-
85
- if (isSymlink(cachePath)) {
86
- const target = fs.readlinkSync(cachePath);
87
- if (target === PLUGIN_ROOT) {
88
- console.log(`Already linked: ${cachePath} → ${PLUGIN_ROOT}`);
89
- return;
90
- }
91
- console.error(`Already symlinked to a different target: ${target}`);
92
- process.exit(1);
93
- }
94
-
95
- // Remove the cached copy
96
- if (fs.existsSync(cachePath)) {
97
- fs.rmSync(cachePath, { recursive: true, force: true });
98
- console.log(`Removed cached copy: ${cachePath}`);
99
- }
100
-
101
- // Ensure parent directory exists
102
- fs.mkdirSync(path.dirname(cachePath), { recursive: true });
103
-
104
- // Create symlink
105
- fs.symlinkSync(PLUGIN_ROOT, cachePath, "dir");
106
- console.log(`Linked: ${cachePath} → ${PLUGIN_ROOT}`);
107
- console.log("\nRestart Claude Code for changes to take effect.");
108
- }
109
-
110
- function unlink() {
111
- const cachePath = getCachePath();
112
-
113
- if (!isSymlink(cachePath)) {
114
- console.log(`Not linked (${cachePath} is not a symlink)`);
115
- return;
116
- }
117
-
118
- // Remove symlink
119
- fs.unlinkSync(cachePath);
120
- console.log(`Removed symlink: ${cachePath}`);
121
-
122
- // Reinstall from marketplace clone
123
- const marketplacePath = getMarketplacePath();
124
- const pluginDir = path.join(marketplacePath, ".claude-plugin");
125
-
126
- if (!fs.existsSync(pluginDir)) {
127
- console.error(`Marketplace clone missing .claude-plugin/ at ${marketplacePath}`);
128
- console.error("Run 'claude plugins update' to reinstall.");
129
- process.exit(1);
130
- }
131
-
132
- // Copy marketplace clone to cache
133
- fs.cpSync(marketplacePath, cachePath, { recursive: true });
134
-
135
- // Install production deps
136
- try {
137
- execSync("npm install --production --ignore-scripts", {
138
- cwd: cachePath,
139
- stdio: ["ignore", "ignore", "pipe"],
140
- });
141
- } catch {
142
- console.warn("Warning: npm install failed, plugin may not work correctly");
143
- }
144
-
145
- const pkgJson = readJson(path.join(cachePath, "package.json"));
146
- console.log(`Unlinked: reinstalled from marketplace at ${cachePath} (v${pkgJson.version})`);
147
- console.log("\nRestart Claude Code for changes to take effect.");
148
- }
149
-
150
- function status() {
151
- const cachePath = getCachePath();
152
-
153
- if (isSymlink(cachePath)) {
154
- const target = fs.readlinkSync(cachePath);
155
- console.log(`LINKED: ${cachePath} → ${target}`);
156
- } else if (fs.existsSync(cachePath)) {
157
- const pkgPath = path.join(cachePath, "package.json");
158
- const version = fs.existsSync(pkgPath) ? readJson(pkgPath).version : "?";
159
- console.log(`NOT LINKED: using cached copy at ${cachePath} (v${version})`);
160
- } else {
161
- console.log(`MISSING: ${cachePath} does not exist`);
162
- console.log(` Run 'npm run dev:link' to create symlink.`);
163
- }
164
- }
165
-
166
- switch (action) {
167
- case "link":
168
- link();
169
- break;
170
- case "unlink":
171
- unlink();
172
- break;
173
- case "status":
174
- status();
175
- break;
176
- default:
177
- console.error("Usage: dev-link.mjs <link|unlink|status>");
178
- process.exit(1);
179
- }