@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.
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "open-party",
3
+ "version": "0.1.1",
4
+ "description": "Decentralized Agent communication network for Claude Code"
5
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "mcpServers": {
3
+ "open-party": {
4
+ "type": "stdio",
5
+ "command": "node",
6
+ "args": ["${CLAUDE_PLUGIN_ROOT}/dist/mcp-server.js"]
7
+ }
8
+ }
9
+ }
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" onclick="navigator.clipboard.writeText('' + display.replace(/'/g, "\\'") + '').then(function(){this.querySelector('.copy-hint').textContent='Copied!'}.bind(this))">';
4782
+ html += '<div class="cmd" data-clipboard="' + display.replace(/"/g, '&quot;') + '">';
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 findPluginDist() {
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 ?? ".", "..", "party-server.js"),
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)) return dirname(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 ensureConfigFile(configPath) {
5087
- const dir = dirname(configPath);
5088
- if (!existsSync3(dir)) {
5089
- mkdirSync(dir, { recursive: true });
5090
- }
5091
- if (existsSync3(configPath)) {
5092
- try {
5093
- const content = readFileSync(configPath, "utf-8");
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
- return { mcpServers: {} };
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 writeConfigFile(configPath, config) {
5101
- writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
5155
+ function getMarketplaceDir() {
5156
+ return join3(homedir2(), ".claude", "plugins", "marketplaces", "open-party");
5102
5157
  }
5103
- function getPluginCommand() {
5104
- const distDir = findPluginDist();
5105
- if (distDir) {
5106
- const serverPath = join3(distDir, "mcp-server.js");
5107
- if (existsSync3(serverPath)) {
5108
- return { command: "node", args: [serverPath] };
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
- return { command: "npx", args: ["@feynmanzhang/open-party", "mcp"] };
5112
- }
5113
- function getMcpServerConfig() {
5114
- const cmd = getPluginCommand();
5115
- if (!cmd) return null;
5116
- return {
5117
- type: "stdio",
5118
- command: cmd.command,
5119
- args: cmd.args
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 configPath = join3(homedir2(), ".claude", "settings.json");
5124
- const serverConfig = getMcpServerConfig();
5125
- if (!serverConfig) {
5126
- return { success: false, error: "Could not locate Open Party plugin files" };
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 config = ensureConfigFile(configPath);
5129
- if (!config.mcpServers) config.mcpServers = {};
5130
- config.mcpServers["open-party"] = serverConfig;
5131
- writeConfigFile(configPath, config);
5132
- return { success: true, configPath };
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 serverConfig = getMcpServerConfig();
5137
- if (!serverConfig) {
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"] = serverConfig;
5143
- writeConfigFile(configPath, config);
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 serverConfig = getMcpServerConfig();
5149
- if (!serverConfig) {
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"] = serverConfig;
5155
- writeConfigFile(configPath, config);
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
  }