@feynmanzhang/open-party 0.1.1 → 0.1.2
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/dist/claude-code/open-party-0.1.1/.claude-plugin/plugin.json +5 -0
- package/dist/claude-code/open-party-0.1.1/.mcp.json +9 -0
- package/dist/cli/index.js +216 -61
- package/dist/cli/index.js.map +1 -1
- package/dist/party-server.js +14 -1
- package/dist/party-server.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -4639,6 +4639,19 @@ body::after{
|
|
|
4639
4639
|
fastTimer = setInterval(fastRefresh, 3000);
|
|
4640
4640
|
fullTimer = setInterval(fullRefresh, 5000);
|
|
4641
4641
|
|
|
4642
|
+
// Clipboard click delegation for .cmd elements
|
|
4643
|
+
document.addEventListener('click', function(e) {
|
|
4644
|
+
var cmd = e.target.closest('.cmd');
|
|
4645
|
+
if (!cmd) return;
|
|
4646
|
+
var text = cmd.getAttribute('data-clipboard');
|
|
4647
|
+
if (text) {
|
|
4648
|
+
navigator.clipboard.writeText(text).then(function() {
|
|
4649
|
+
var hint = cmd.querySelector('.copy-hint');
|
|
4650
|
+
if (hint) hint.textContent = 'Copied!';
|
|
4651
|
+
});
|
|
4652
|
+
}
|
|
4653
|
+
});
|
|
4654
|
+
|
|
4642
4655
|
// Update uptime display every second
|
|
4643
4656
|
setInterval(function() {
|
|
4644
4657
|
if (overview && overview.server) {
|
|
@@ -4766,7 +4779,7 @@ body::after{
|
|
|
4766
4779
|
html += '<div style="color:var(--muted);margin-bottom:6px">Install for ' + info.os + ':</div>';
|
|
4767
4780
|
info.commands.forEach(function(cmd) {
|
|
4768
4781
|
const display = info.needs_sudo ? 'sudo ' + cmd : cmd;
|
|
4769
|
-
html += '<div class="cmd"
|
|
4782
|
+
html += '<div class="cmd" data-clipboard="' + display.replace(/"/g, '"') + '">';
|
|
4770
4783
|
html += '<code>' + display + '</code><span class="copy-hint">Click to copy</span></div>';
|
|
4771
4784
|
});
|
|
4772
4785
|
if (info.download_url) {
|
|
@@ -5068,93 +5081,229 @@ function detectAgents() {
|
|
|
5068
5081
|
}
|
|
5069
5082
|
|
|
5070
5083
|
// src/cli/agent-installer.ts
|
|
5071
|
-
import { existsSync as existsSync3, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
5084
|
+
import { existsSync as existsSync3, readFileSync, writeFileSync, mkdirSync, cpSync, rmSync, readdirSync } from "fs";
|
|
5072
5085
|
import { join as join3, dirname, resolve } from "path";
|
|
5073
5086
|
import { homedir as homedir2 } from "os";
|
|
5074
|
-
function
|
|
5087
|
+
function ensureDir(filePath) {
|
|
5088
|
+
const dir = dirname(filePath);
|
|
5089
|
+
if (!existsSync3(dir)) {
|
|
5090
|
+
mkdirSync(dir, { recursive: true });
|
|
5091
|
+
}
|
|
5092
|
+
}
|
|
5093
|
+
function readJsonFile(filePath, fallback) {
|
|
5094
|
+
if (!existsSync3(filePath)) return fallback;
|
|
5095
|
+
try {
|
|
5096
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
5097
|
+
} catch {
|
|
5098
|
+
return fallback;
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
function writeJsonFile(filePath, data) {
|
|
5102
|
+
ensureDir(filePath);
|
|
5103
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
|
|
5104
|
+
}
|
|
5105
|
+
function findPluginDistDir() {
|
|
5106
|
+
const distDir = resolve(import.meta.dirname ?? ".", "..", "claude-code");
|
|
5107
|
+
if (!existsSync3(distDir)) return null;
|
|
5108
|
+
try {
|
|
5109
|
+
const entries = readdirSync(distDir);
|
|
5110
|
+
const dirs = entries.filter((e) => e.startsWith("open-party-"));
|
|
5111
|
+
if (dirs.length === 0) return null;
|
|
5112
|
+
const pluginDir = join3(distDir, dirs[dirs.length - 1]);
|
|
5113
|
+
if (existsSync3(join3(pluginDir, ".claude-plugin", "plugin.json"))) {
|
|
5114
|
+
return pluginDir;
|
|
5115
|
+
}
|
|
5116
|
+
} catch {
|
|
5117
|
+
}
|
|
5118
|
+
return null;
|
|
5119
|
+
}
|
|
5120
|
+
function findDistJsDir() {
|
|
5075
5121
|
const possiblePaths = [
|
|
5076
|
-
// When installed globally: <pkg-root>/dist/cli/index.js → <pkg-root>/dist/
|
|
5077
|
-
resolve(import.meta.dirname ?? ".", ".."
|
|
5078
|
-
// When running from source: <project>/dist/cli/index.js → <project>/dist/
|
|
5079
|
-
resolve(import.meta.dirname ?? ".", "..", "mcp-server.js")
|
|
5122
|
+
// When installed globally via npm: <pkg-root>/dist/cli/index.js → <pkg-root>/dist/
|
|
5123
|
+
resolve(import.meta.dirname ?? ".", "..")
|
|
5080
5124
|
];
|
|
5081
5125
|
for (const p of possiblePaths) {
|
|
5082
|
-
if (existsSync3(p))
|
|
5126
|
+
if (existsSync3(join3(p, "mcp-server.js")) && existsSync3(join3(p, "hook-handler.js"))) {
|
|
5127
|
+
return p;
|
|
5128
|
+
}
|
|
5083
5129
|
}
|
|
5084
5130
|
return null;
|
|
5085
5131
|
}
|
|
5086
|
-
function
|
|
5087
|
-
const
|
|
5088
|
-
if (
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
return JSON.parse(content);
|
|
5095
|
-
} catch {
|
|
5096
|
-
}
|
|
5132
|
+
function getPluginVersion() {
|
|
5133
|
+
const pluginDir = findPluginDistDir();
|
|
5134
|
+
if (pluginDir) {
|
|
5135
|
+
const manifest2 = readJsonFile(
|
|
5136
|
+
join3(pluginDir, ".claude-plugin", "plugin.json"),
|
|
5137
|
+
{}
|
|
5138
|
+
);
|
|
5139
|
+
if (manifest2.version) return manifest2.version;
|
|
5097
5140
|
}
|
|
5098
|
-
|
|
5141
|
+
const sourceManifest = resolve(
|
|
5142
|
+
import.meta.dirname ?? ".",
|
|
5143
|
+
"..",
|
|
5144
|
+
"..",
|
|
5145
|
+
"src",
|
|
5146
|
+
"client",
|
|
5147
|
+
"claude-code",
|
|
5148
|
+
".claude-plugin",
|
|
5149
|
+
"plugin.json"
|
|
5150
|
+
);
|
|
5151
|
+
const manifest = readJsonFile(sourceManifest, {});
|
|
5152
|
+
if (manifest.version) return manifest.version;
|
|
5153
|
+
return "0.1.0";
|
|
5099
5154
|
}
|
|
5100
|
-
function
|
|
5101
|
-
|
|
5155
|
+
function getMarketplaceDir() {
|
|
5156
|
+
return join3(homedir2(), ".claude", "plugins", "marketplaces", "open-party");
|
|
5102
5157
|
}
|
|
5103
|
-
function
|
|
5104
|
-
const
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
}
|
|
5158
|
+
function registerMarketplace(version, pluginDir) {
|
|
5159
|
+
const marketplaceDir = getMarketplaceDir();
|
|
5160
|
+
const pluginSourceDir = join3(marketplaceDir, "plugin");
|
|
5161
|
+
const marketplacePluginDir = join3(marketplaceDir, ".claude-plugin");
|
|
5162
|
+
if (!existsSync3(marketplacePluginDir)) {
|
|
5163
|
+
mkdirSync(marketplacePluginDir, { recursive: true });
|
|
5110
5164
|
}
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5165
|
+
const marketplaceManifest = {
|
|
5166
|
+
name: "open-party",
|
|
5167
|
+
owner: { name: "Feynman Zhang" },
|
|
5168
|
+
metadata: {
|
|
5169
|
+
description: "Decentralized Agent communication network for Claude Code",
|
|
5170
|
+
homepage: "https://github.com/FeynmanZhang/open-party"
|
|
5171
|
+
},
|
|
5172
|
+
plugins: [
|
|
5173
|
+
{
|
|
5174
|
+
name: "open-party",
|
|
5175
|
+
version,
|
|
5176
|
+
source: "./plugin",
|
|
5177
|
+
description: "Decentralized Agent communication network for Claude Code"
|
|
5178
|
+
}
|
|
5179
|
+
]
|
|
5180
|
+
};
|
|
5181
|
+
writeJsonFile(join3(marketplacePluginDir, "marketplace.json"), marketplaceManifest);
|
|
5182
|
+
if (existsSync3(pluginSourceDir)) {
|
|
5183
|
+
rmSync(pluginSourceDir, { recursive: true });
|
|
5184
|
+
}
|
|
5185
|
+
mkdirSync(pluginSourceDir, { recursive: true });
|
|
5186
|
+
cpSync(pluginDir, pluginSourceDir, { recursive: true });
|
|
5187
|
+
const knownMarketplacesPath = join3(homedir2(), ".claude", "plugins", "known_marketplaces.json");
|
|
5188
|
+
const knownMarketplaces = readJsonFile(knownMarketplacesPath, {});
|
|
5189
|
+
knownMarketplaces["open-party"] = {
|
|
5190
|
+
source: {
|
|
5191
|
+
source: "github",
|
|
5192
|
+
repo: "FeynmanZhang/open-party"
|
|
5193
|
+
},
|
|
5194
|
+
installLocation: marketplaceDir,
|
|
5195
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
5120
5196
|
};
|
|
5197
|
+
writeJsonFile(knownMarketplacesPath, knownMarketplaces);
|
|
5121
5198
|
}
|
|
5122
5199
|
function installClaudeCode() {
|
|
5123
|
-
const
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5200
|
+
const pluginDir = findPluginDistDir();
|
|
5201
|
+
if (!pluginDir) {
|
|
5202
|
+
return {
|
|
5203
|
+
success: false,
|
|
5204
|
+
error: 'Plugin package not found. Run "npm run build:plugin" first, or use "claude --plugin-dir" to install manually.'
|
|
5205
|
+
};
|
|
5127
5206
|
}
|
|
5128
|
-
const
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5207
|
+
const version = getPluginVersion();
|
|
5208
|
+
const installDir = join3(homedir2(), ".claude", "plugins", "cache", "open-party", "open-party", version);
|
|
5209
|
+
if (existsSync3(installDir)) {
|
|
5210
|
+
rmSync(installDir, { recursive: true });
|
|
5211
|
+
}
|
|
5212
|
+
mkdirSync(installDir, { recursive: true });
|
|
5213
|
+
cpSync(pluginDir, installDir, { recursive: true });
|
|
5214
|
+
const mcpServerPath = join3(installDir, "dist", "mcp-server.js");
|
|
5215
|
+
if (!existsSync3(mcpServerPath)) {
|
|
5216
|
+
const distJsDir = findDistJsDir();
|
|
5217
|
+
if (distJsDir) {
|
|
5218
|
+
const targetDist = join3(installDir, "dist");
|
|
5219
|
+
if (!existsSync3(targetDist)) mkdirSync(targetDist, { recursive: true });
|
|
5220
|
+
for (const file of ["mcp-server.js", "hook-handler.js", "party-server.js"]) {
|
|
5221
|
+
const src = join3(distJsDir, file);
|
|
5222
|
+
if (existsSync3(src)) {
|
|
5223
|
+
cpSync(src, join3(targetDist, file));
|
|
5224
|
+
}
|
|
5225
|
+
}
|
|
5226
|
+
for (const file of ["mcp-server.js.map", "hook-handler.js.map", "party-server.js.map"]) {
|
|
5227
|
+
const src = join3(distJsDir, file);
|
|
5228
|
+
if (existsSync3(src)) {
|
|
5229
|
+
cpSync(src, join3(targetDist, file));
|
|
5230
|
+
}
|
|
5231
|
+
}
|
|
5232
|
+
}
|
|
5233
|
+
}
|
|
5234
|
+
const orphanedPath = join3(installDir, "dist", ".orphaned_at");
|
|
5235
|
+
if (existsSync3(orphanedPath)) {
|
|
5236
|
+
rmSync(orphanedPath);
|
|
5237
|
+
}
|
|
5238
|
+
registerMarketplace(version, pluginDir);
|
|
5239
|
+
const pluginsJsonPath = join3(homedir2(), ".claude", "plugins", "installed_plugins.json");
|
|
5240
|
+
const pluginsData = readJsonFile(
|
|
5241
|
+
pluginsJsonPath,
|
|
5242
|
+
{ version: 2, plugins: {} }
|
|
5243
|
+
);
|
|
5244
|
+
if (!pluginsData.plugins) pluginsData.plugins = {};
|
|
5245
|
+
if (pluginsData.plugins["open-party@local"]) {
|
|
5246
|
+
delete pluginsData.plugins["open-party@local"];
|
|
5247
|
+
}
|
|
5248
|
+
pluginsData.plugins["open-party@open-party"] = [
|
|
5249
|
+
{
|
|
5250
|
+
scope: "user",
|
|
5251
|
+
installPath: installDir,
|
|
5252
|
+
version,
|
|
5253
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5254
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
5255
|
+
}
|
|
5256
|
+
];
|
|
5257
|
+
writeJsonFile(pluginsJsonPath, pluginsData);
|
|
5258
|
+
const settingsPath = join3(homedir2(), ".claude", "settings.json");
|
|
5259
|
+
const settings = readJsonFile(settingsPath, {});
|
|
5260
|
+
if (settings.mcpServers?.["open-party"]) {
|
|
5261
|
+
delete settings.mcpServers["open-party"];
|
|
5262
|
+
if (Object.keys(settings.mcpServers).length === 0) {
|
|
5263
|
+
delete settings.mcpServers;
|
|
5264
|
+
}
|
|
5265
|
+
}
|
|
5266
|
+
if (!settings.enabledPlugins) {
|
|
5267
|
+
settings.enabledPlugins = {};
|
|
5268
|
+
}
|
|
5269
|
+
if (settings.enabledPlugins["open-party@local"] !== void 0) {
|
|
5270
|
+
delete settings.enabledPlugins["open-party@local"];
|
|
5271
|
+
}
|
|
5272
|
+
settings.enabledPlugins["open-party@open-party"] = true;
|
|
5273
|
+
writeJsonFile(settingsPath, settings);
|
|
5274
|
+
return {
|
|
5275
|
+
success: true,
|
|
5276
|
+
configPath: settingsPath
|
|
5277
|
+
};
|
|
5133
5278
|
}
|
|
5134
5279
|
function installCursor() {
|
|
5135
5280
|
const configPath = join3(homedir2(), ".cursor", "mcp.json");
|
|
5136
|
-
const
|
|
5137
|
-
|
|
5138
|
-
return { success: false, error: "Could not locate Open Party plugin files" };
|
|
5139
|
-
}
|
|
5140
|
-
const config = ensureConfigFile(configPath);
|
|
5281
|
+
const { command: command2, args: args2 } = getPluginCommand();
|
|
5282
|
+
const config = readJsonFile(configPath, {});
|
|
5141
5283
|
if (!config.mcpServers) config.mcpServers = {};
|
|
5142
|
-
config.mcpServers["open-party"] =
|
|
5143
|
-
|
|
5284
|
+
config.mcpServers["open-party"] = { type: "stdio", command: command2, args: args2 };
|
|
5285
|
+
writeJsonFile(configPath, config);
|
|
5144
5286
|
return { success: true, configPath };
|
|
5145
5287
|
}
|
|
5146
5288
|
function installGeminiCli() {
|
|
5147
5289
|
const configPath = join3(homedir2(), ".gemini", "settings.json");
|
|
5148
|
-
const
|
|
5149
|
-
|
|
5150
|
-
return { success: false, error: "Could not locate Open Party plugin files" };
|
|
5151
|
-
}
|
|
5152
|
-
const config = ensureConfigFile(configPath);
|
|
5290
|
+
const { command: command2, args: args2 } = getPluginCommand();
|
|
5291
|
+
const config = readJsonFile(configPath, {});
|
|
5153
5292
|
if (!config.mcpServers) config.mcpServers = {};
|
|
5154
|
-
config.mcpServers["open-party"] =
|
|
5155
|
-
|
|
5293
|
+
config.mcpServers["open-party"] = { type: "stdio", command: command2, args: args2 };
|
|
5294
|
+
writeJsonFile(configPath, config);
|
|
5156
5295
|
return { success: true, configPath };
|
|
5157
5296
|
}
|
|
5297
|
+
function getPluginCommand() {
|
|
5298
|
+
const distDir = findDistJsDir();
|
|
5299
|
+
if (distDir) {
|
|
5300
|
+
const serverPath = join3(distDir, "mcp-server.js");
|
|
5301
|
+
if (existsSync3(serverPath)) {
|
|
5302
|
+
return { command: "node", args: [serverPath] };
|
|
5303
|
+
}
|
|
5304
|
+
}
|
|
5305
|
+
return { command: "npx", args: ["@feynmanzhang/open-party", "mcp"] };
|
|
5306
|
+
}
|
|
5158
5307
|
async function installPluginToAgent(agentType) {
|
|
5159
5308
|
switch (agentType) {
|
|
5160
5309
|
case "claude-code":
|
|
@@ -5352,6 +5501,12 @@ Installing Open Party plugin for ${agent.name}...`);
|
|
|
5352
5501
|
const result = await installPluginToAgent(agent.type);
|
|
5353
5502
|
if (result.success) {
|
|
5354
5503
|
console.log(`${green("\u2705")} Plugin installed for ${agent.name}${result.configPath ? ` (${result.configPath})` : ""}`);
|
|
5504
|
+
if (result.warning) {
|
|
5505
|
+
console.log(` ${yellow("\u26A0\uFE0F")} ${result.warning}`);
|
|
5506
|
+
}
|
|
5507
|
+
if (agent.type === "claude-code") {
|
|
5508
|
+
console.log(` ${bold("Please restart Claude Code")} for changes to take effect.`);
|
|
5509
|
+
}
|
|
5355
5510
|
} else {
|
|
5356
5511
|
console.log(`${red("\u274C")} Failed to install for ${agent.name}: ${result.error}`);
|
|
5357
5512
|
}
|