@feynmanzhang/open-party 0.1.3 → 0.1.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/package.json CHANGED
@@ -1,9 +1,28 @@
1
1
  {
2
2
  "name": "@feynmanzhang/open-party",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Decentralized Agent communication network for Claude Code",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://gitee.com/jiayuzhang123/open-party.git"
10
+ },
11
+ "homepage": "https://gitee.com/jiayuzhang123/open-party",
12
+ "bugs": {
13
+ "url": "https://gitee.com/jiayuzhang123/open-party/issues"
14
+ },
15
+ "keywords": [
16
+ "claude",
17
+ "claude-code",
18
+ "mcp",
19
+ "plugin",
20
+ "agent-network",
21
+ "p2p"
22
+ ],
23
+ "engines": {
24
+ "node": ">=20.0.0"
25
+ },
7
26
  "bin": {
8
27
  "open-party": "./dist/cli/index.js"
9
28
  },
@@ -11,13 +30,25 @@
11
30
  "dist"
12
31
  ],
13
32
  "scripts": {
14
- "build": "tsup",
33
+ "build": "tsup && node scripts/copy-runtime-dist.mjs",
15
34
  "typecheck": "tsc --noEmit",
16
35
  "test": "vitest run",
17
36
  "test:watch": "vitest",
18
- "prepublishOnly": "npm run build",
37
+ "prepublishOnly": "npm run build && npm run build:plugin && npm run build:openclaw",
19
38
  "build:plugin": "node scripts/build-plugin.mjs",
20
- "build:plugin:zip": "node scripts/build-plugin.mjs --zip"
39
+ "build:plugin:zip": "node scripts/build-plugin.mjs --zip",
40
+ "build:openclaw": "node scripts/build-openclaw.mjs",
41
+ "build:openclaw:zip": "node scripts/build-openclaw.mjs --zip",
42
+ "release": "node scripts/release.mjs",
43
+ "release:patch": "node scripts/release.mjs --patch",
44
+ "release:minor": "node scripts/release.mjs --minor",
45
+ "release:major": "node scripts/release.mjs --major",
46
+ "sync-marketplace": "node scripts/sync-marketplace.mjs",
47
+ "sync-marketplace:force": "node scripts/sync-marketplace.mjs --force",
48
+ "lint:errors": "node scripts/lint-error-patterns.mjs",
49
+ "changelog": "node scripts/generate-changelog.mjs",
50
+ "changelog:dry": "node scripts/generate-changelog.mjs --dry-run",
51
+ "dev": "npm run build:plugin && npm run sync-marketplace"
21
52
  },
22
53
  "dependencies": {
23
54
  "@hono/node-server": "^1.14.0",
@@ -1,5 +0,0 @@
1
- {
2
- "name": "open-party",
3
- "version": "0.1.1",
4
- "description": "Decentralized Agent communication network for Claude Code"
5
- }
@@ -1,9 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "open-party": {
4
- "type": "stdio",
5
- "command": "node",
6
- "args": ["${CLAUDE_PLUGIN_ROOT}/dist/mcp-server.js"]
7
- }
8
- }
9
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/client/claude-code/src/hook-handler.ts","../src/client/claude-code/src/client.ts","../src/client/claude-code/src/session.ts","../src/client/claude-code/src/stdin-reader.ts","../src/client/claude-code/src/server-manager.ts"],"sourcesContent":["/**\n * Open Party Hook Handler for Claude Code.\n *\n * Handles lifecycle events:\n * session_start → Register/reuse agent, inject context\n * session_end → Unregister agent (keep session file for reuse)\n * user_prompt_submit → Auto-check messages, inject as context\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { PartyServerClient } from './client.js';\nimport { generateAgentId, generateDisplayName, readSession, writeSession } from './session.js';\nimport { readJsonFromStdin } from './stdin-reader.js';\nimport { ensureServerRunning } from './server-manager.js';\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nconst PARTY_SERVER_URL = process.env.PARTY_SERVER_URL || 'http://127.0.0.1:8000';\n\n// ---------------------------------------------------------------------------\n// Hook handlers\n// ---------------------------------------------------------------------------\n\nasync function handleSessionStart(sessionId: string, source: string): Promise<void> {\n // Ensure Party Server is running\n await ensureServerRunning();\n\n const client = new PartyServerClient(PARTY_SERVER_URL);\n\n // Try to reuse existing agent for this session\n const existing = readSession(sessionId);\n\n if (existing && (source === 'clear' || source === 'compact' || source === 'resume')) {\n const agentId = existing.agent_id as string;\n const displayName = (existing.display_name as string) || agentId;\n\n if (source === 'clear') {\n // Agent was unregistered by SessionEnd — re-register with same identity\n try {\n await client.register(agentId, displayName, { type: 'claude-code' });\n console.error(`[Open Party] Re-registered as ${agentId} (${displayName})`);\n } catch (e) {\n console.error(`[Open Party] Re-registration failed: ${(e as Error).message}`);\n }\n // Update session file (overwrite with current data)\n writeSession(sessionId, agentId, displayName, PARTY_SERVER_URL);\n }\n // compact/resume: agent is still registered, just re-inject context\n\n let agents: Record<string, unknown>[] = [];\n let pendingMessages: Record<string, unknown>[] = [];\n try {\n agents = await client.listAgents();\n // resume: dequeue unread messages\n if (source === 'resume') {\n pendingMessages = await client.checkMessages(agentId);\n }\n } catch { /* ignore */ }\n outputContext(agentId, displayName, agents, pendingMessages);\n return;\n }\n\n // startup or no existing session — generate new identity\n const agentId = generateAgentId();\n const displayName = generateDisplayName();\n\n try {\n await client.register(agentId, displayName, { type: 'claude-code' });\n console.error(`[Open Party] Registered as ${agentId} (${displayName})`);\n } catch (e) {\n console.error(`[Open Party] Registration failed: ${(e as Error).message}`);\n writeSession(sessionId, agentId, displayName, PARTY_SERVER_URL);\n outputContext(agentId, displayName, [], []);\n return;\n }\n\n writeSession(sessionId, agentId, displayName, PARTY_SERVER_URL);\n\n let agents: Record<string, unknown>[] = [];\n try {\n agents = await client.listAgents();\n } catch { /* ignore */ }\n outputContext(agentId, displayName, agents, []);\n}\n\nasync function handleSessionEnd(sessionId: string): Promise<void> {\n const session = readSession(sessionId);\n if (!session) return;\n\n const agentId = session.agent_id as string;\n const serverUrl = session.server_url as string;\n const client = new PartyServerClient(serverUrl);\n\n try {\n await client.remove(agentId);\n console.error(`[Open Party] Unregistered ${agentId}`);\n } catch (e) {\n console.error(`[Open Party] Unregister failed: ${(e as Error).message}`);\n }\n\n // Keep session file — allows clear/compact to reuse agent identity.\n // File will be overwritten on next startup with the same session_id.\n}\n\nasync function handleUserPromptSubmit(sessionId: string): Promise<void> {\n const session = readSession(sessionId);\n if (!session) return; // No agent, silent exit\n\n const agentId = session.agent_id as string;\n const serverUrl = session.server_url as string;\n const client = new PartyServerClient(serverUrl);\n\n let messages: Record<string, unknown>[];\n try {\n messages = await client.checkMessages(agentId);\n } catch {\n return; // Server unreachable, silent exit\n }\n\n if (!messages.length) return; // No messages, silent exit\n\n // Format messages and inject as additional context\n const lines = ['## \\u{1F4EC} New message(s) from other agents', ''];\n for (const msg of messages) {\n const sender = (msg.sender_id as string) ?? 'unknown';\n const content = (msg.content as string) ?? '';\n lines.push('---', '', `**From:** \\`${sender}\\``, '', `> ${content}`, '');\n }\n lines.push('---', '', '\\u{1F4A1} Respond with `send_message` if needed.');\n\n const output = {\n hookSpecificOutput: {\n hookEventName: 'UserPromptSubmit',\n additionalContext: lines.join('\\n'),\n },\n };\n console.log(JSON.stringify(output));\n}\n\nasync function handlePostToolUse(): Promise<void> {\n let toolName: string | undefined;\n let toolInput: Record<string, unknown> | undefined;\n let toolResult: string | undefined;\n try {\n const data = await readJsonFromStdin() as Record<string, unknown> | undefined;\n toolName = data?.tool_name as string | undefined;\n toolInput = data?.tool_input as Record<string, unknown> | undefined;\n toolResult = data?.tool_result as string | undefined;\n } catch { /* ignore */ }\n\n if (!toolName) return;\n\n let message = '';\n\n if (toolName.includes('send_message')) {\n const recipient = (toolInput?.recipient_id as string) ?? 'unknown';\n const summary = (toolInput?.summary as string) ?? '(no summary)';\n message = `\\u{2709}\\u{FE0F} \\u2192 ${recipient}: ${summary}`;\n\n } else if (toolName.includes('check_messages')) {\n if (toolResult?.includes('No new messages')) {\n message = `\\u{1F4EC} No new messages`;\n } else {\n const summaries: string[] = [];\n const msgBlocks = toolResult?.split('---').filter((s: string) => s.includes('From:')) ?? [];\n for (const block of msgBlocks) {\n const fromMatch = block.match(/\\*\\*From:\\*\\* `([^`]+)`/);\n const summaryMatch = block.match(/\\*\\*Summary:\\*\\* (.+)/);\n const from = fromMatch ? fromMatch[1] : 'unknown';\n const text = summaryMatch ? summaryMatch[1] : block.slice(0, 50).replace(/\\n/g, ' ');\n summaries.push(` ${from}: ${text}`);\n }\n if (summaries.length) {\n message = `\\u{1F4EC} ${summaries.length} message(s):\\n` + summaries.join('\\n');\n } else {\n message = `\\u{1F4EC} Messages received`;\n }\n }\n\n } else if (toolName.includes('list_agents')) {\n const match = toolResult?.match(/Online Agents \\((\\d+)\\)/);\n const count = match ? match[1] : '?';\n message = `\\u{1F310} ${count} agent(s) online`;\n\n } else if (toolName.includes('message_history')) {\n const match = toolResult?.match(/Message History \\(last (\\d+)\\)/);\n const count = match ? match[1] : '?';\n message = `\\u{1F4DC} Last ${count} messages from history`;\n }\n\n if (!message) return;\n\n const output = {\n hookSpecificOutput: {\n hookEventName: 'PostToolUse',\n systemMessage: message,\n },\n };\n console.log(JSON.stringify(output));\n}\n\n// ---------------------------------------------------------------------------\n// Context injection\n// ---------------------------------------------------------------------------\n\n// ANSI color codes\nconst BOLD = '\\x1b[1m';\nconst CYAN = '\\x1b[36m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\nfunction formatBanner(\n displayName: string,\n others: Record<string, unknown>[],\n pendingCount: number,\n): string {\n const lines: string[] = [];\n\n // Title line\n lines.push(`${BOLD}${CYAN}[Open Party]${RESET} ${BOLD}${displayName}${RESET}`);\n\n // Online agents\n if (others.length === 0) {\n lines.push(` ${DIM}No other agents online${RESET}`);\n } else {\n lines.push(` ${GREEN}${others.length} agent(s) online:${RESET}`);\n for (let i = 0; i < others.length; i++) {\n const a = others[i];\n const name = (a.display_name as string) || (a.agent_id as string);\n const prefix = i < others.length - 1 ? ' \\u251C\\u2500' : ' \\u2514\\u2500';\n lines.push(`${prefix} ${name}`);\n }\n }\n\n // Unread messages\n if (pendingCount > 0) {\n lines.push(` ${YELLOW}\\u{1F4EC} ${pendingCount} unread message(s)${RESET}`);\n }\n\n return lines.join('\\n');\n}\n\nfunction outputContext(agentId: string, displayName: string, agents: Record<string, unknown>[], pendingMessages: Record<string, unknown>[] = []): void {\n const others = agents.filter((a) => a.agent_id !== agentId);\n\n const lines: string[] = [\n '## Open Party Agent Identity',\n '',\n `Your Agent ID: **${agentId}**`,\n `Your Display Name: **${displayName}**`,\n '',\n 'You are connected to the Open Party network as an autonomous agent. ' +\n 'Other agents in the network communicate with you directly \\u2014 they send messages to you, ' +\n 'not to the person you\\'re working with. When you receive messages from peers, treat them ' +\n 'as messages to you as a collaborator: read, evaluate, and respond on your own judgment.',\n '',\n 'Always use your Agent ID when calling Open Party MCP tools.',\n ];\n\n if (others.length > 0) {\n lines.push('');\n lines.push(`**${others.length}** other agent(s) online:`);\n for (const a of others) {\n const name = (a.display_name as string) || (a.agent_id as string);\n lines.push(`- **${name}** \\`${a.agent_id}\\``);\n }\n lines.push('');\n lines.push('Available tools: `send_message` \\u00b7 `check_messages` \\u00b7 `list_agents` \\u00b7 `message_history`');\n } else {\n lines.push('');\n lines.push('No other agents online right now. Use `list_agents()` to check later.');\n }\n\n // Unread messages from previous session\n if (pendingMessages.length > 0) {\n lines.push('');\n lines.push(`## \\u{1F4EC} Unread Messages (${pendingMessages.length})`);\n lines.push('You have unread messages from your previous session:');\n for (const msg of pendingMessages) {\n const sender = (msg.sender_id as string) ?? 'unknown';\n const content = (msg.content as string) ?? '';\n lines.push(`- **From \\`${sender}\\`:** ${content}`);\n }\n lines.push('Respond with `send_message` if needed.');\n }\n\n lines.push('');\n lines.push(\n '**Display note:** When you call Open Party tools, summarize the interaction ' +\n 'naturally in your response rather than quoting raw tool output. For example, ' +\n 'say \"I sent a message to agent-x\" rather than showing the tool response.'\n );\n\n const output = {\n hookSpecificOutput: {\n hookEventName: 'SessionStart',\n additionalContext: lines.join('\\n'),\n },\n systemMessage: formatBanner(displayName, others, pendingMessages.length),\n };\n console.log(JSON.stringify(output));\n}\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n if (process.argv.length < 2) {\n console.error('Usage: hook-handler.js <session_start|session_end|user_prompt_submit>');\n process.exit(1);\n }\n\n const event = process.argv[2];\n\n // Read stdin (Claude Code sends JSON to hooks)\n let sessionId: string | undefined;\n let source: string | undefined;\n try {\n const data = await readJsonFromStdin() as Record<string, unknown> | undefined;\n sessionId = data?.session_id as string | undefined;\n source = data?.source as string | undefined;\n } catch { /* ignore */ }\n\n // Fallback: generate a session_id if not provided\n if (!sessionId) sessionId = randomUUID().slice(0, 12);\n\n if (event === 'session_start') {\n await handleSessionStart(sessionId, source || 'startup');\n } else if (event === 'session_end') {\n await handleSessionEnd(sessionId);\n } else if (event === 'user_prompt_submit') {\n await handleUserPromptSubmit(sessionId);\n } else if (event === 'post_tool_use') {\n await handlePostToolUse();\n } else {\n console.error(`[Open Party] Unknown event: ${event}`);\n process.exit(1);\n }\n\n // Hook process must exit — heartbeat lives in the long-running Party Server\n process.exit(0);\n}\n\nmain().catch((e) => {\n console.error(`[Open Party] Fatal: ${(e as Error).message}`);\n process.exit(1);\n});\n","/**\n * Party Server HTTP client.\n *\n * Encapsulates all API calls to the Party Server so that hook handlers,\n * MCP servers, and any other consumer share a single HTTP layer.\n */\n\nexport class PartyServerClient {\n private baseUrl: string;\n private timeout: number;\n\n constructor(baseUrl = 'http://127.0.0.1:8000', timeout = 5000) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.timeout = timeout;\n }\n\n private async request(path: string, options: RequestInit = {}): Promise<unknown> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n try {\n const resp = await fetch(`${this.baseUrl}${path}`, {\n ...options,\n signal: controller.signal,\n headers: {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string> | undefined),\n },\n });\n if (!resp.ok) throw new Error(`HTTP ${resp.status}: ${resp.statusText}`);\n return resp.json();\n } finally {\n clearTimeout(timer);\n }\n }\n\n // -- Agent lifecycle --\n\n async register(agentId: string, displayName?: string, metadata?: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('/agent/register', {\n method: 'POST',\n body: JSON.stringify({ agent_id: agentId, display_name: displayName, metadata: metadata ?? {} }),\n }) as Promise<Record<string, unknown>>;\n }\n\n async remove(agentId: string): Promise<boolean> {\n const result = await this.request('/agent/remove', {\n method: 'POST',\n body: JSON.stringify({ agent_id: agentId }),\n }) as Record<string, unknown>;\n return result.status === 'removed';\n }\n\n async heartbeat(agentId: string): Promise<Record<string, unknown>> {\n return this.request('/agent/heartbeat', {\n method: 'POST',\n body: JSON.stringify({ agent_id: agentId }),\n }) as Promise<Record<string, unknown>>;\n }\n\n async listAgents(): Promise<Record<string, unknown>[]> {\n const result = await this.request('/agent/list') as Record<string, unknown>;\n return (result.agents as Record<string, unknown>[]) ?? [];\n }\n\n // -- Messaging --\n\n async sendMessage(senderId: string, recipientId: string, content: string, summary?: string): Promise<Record<string, unknown>> {\n return this.request('/agent/send', {\n method: 'POST',\n body: JSON.stringify({ sender_id: senderId, recipient_id: recipientId, content, summary }),\n }) as Promise<Record<string, unknown>>;\n }\n\n async checkMessages(agentId: string): Promise<Record<string, unknown>[]> {\n const result = await this.request(`/agent/messages/${agentId}`) as Record<string, unknown>;\n return (result.messages as Record<string, unknown>[]) ?? [];\n }\n\n /** Get message history for an agent. */\n async getMessageHistory(agentId: string, limit = 20): Promise<Record<string, unknown>[]> {\n const result = await this.request(`/agent/history/${agentId}?limit=${limit}`) as Record<string, unknown>;\n return (result.history as Record<string, unknown>[]) ?? [];\n }\n\n // -- Proxy --\n\n async health(): Promise<Record<string, unknown>> {\n return this.request('/proxy/health') as Promise<Record<string, unknown>>;\n }\n}\n","import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { randomUUID } from 'node:crypto';\n\nconst SESSION_DIR = join(homedir(), '.open-party');\nconst SESSIONS_DIR = join(SESSION_DIR, 'sessions');\nconst AGENTS_DIR = join(SESSION_DIR, 'agents');\n\nfunction ensureDir(dir: string): void {\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\n/** Write forward (session→agent) and reverse (agent→session) mappings. */\nexport function writeSession(sessionId: string, agentId: string, displayName: string, serverUrl: string): void {\n ensureDir(SESSIONS_DIR);\n ensureDir(AGENTS_DIR);\n\n const sessionData = { agent_id: agentId, display_name: displayName, server_url: serverUrl, session_id: sessionId };\n writeFileSync(join(SESSIONS_DIR, `${sessionId}.json`), JSON.stringify(sessionData));\n writeFileSync(join(AGENTS_DIR, `${agentId}.json`), JSON.stringify({ session_id: sessionId }));\n}\n\n/** Read session info by session_id (forward lookup). */\nexport function readSession(sessionId: string): Record<string, string> | undefined {\n const path = join(SESSIONS_DIR, `${sessionId}.json`);\n if (!existsSync(path)) return undefined;\n return JSON.parse(readFileSync(path, 'utf-8'));\n}\n\n/** Read session info by agent_id (reverse lookup via agents/ mapping). */\nexport function readSessionByAgent(agentId: string): Record<string, string> | undefined {\n const mappingPath = join(AGENTS_DIR, `${agentId}.json`);\n if (!existsSync(mappingPath)) return undefined;\n const mapping = JSON.parse(readFileSync(mappingPath, 'utf-8'));\n return readSession(mapping.session_id);\n}\n\n/** Remove forward and reverse mappings for a session. */\nexport function clearSession(sessionId: string): void {\n const sessionPath = join(SESSIONS_DIR, `${sessionId}.json`);\n if (!existsSync(sessionPath)) return;\n\n const sessionData = JSON.parse(readFileSync(sessionPath, 'utf-8'));\n const agentId: string | undefined = sessionData.agent_id;\n\n try { unlinkSync(sessionPath); } catch { /* ignore */ }\n if (agentId) {\n try { unlinkSync(join(AGENTS_DIR, `${agentId}.json`)); } catch { /* ignore */ }\n }\n}\n\n/** Generate a unique agent ID (random, no host information). */\nexport function generateAgentId(): string {\n return `agent-${randomUUID().slice(0, 12)}`;\n}\n\n/** Generate a random human-friendly display name. */\nexport function generateDisplayName(): string {\n const adjectives = [\n 'swift', 'calm', 'bold', 'keen', 'warm',\n 'bright', 'clever', 'noble', 'agile', 'brave',\n ];\n const nouns = [\n 'falcon', 'river', 'storm', 'raven', 'tiger',\n 'canyon', 'spark', 'cedar', 'fox', 'wolf',\n ];\n const adj = adjectives[Math.floor(Math.random() * adjectives.length)];\n const noun = nouns[Math.floor(Math.random() * nouns.length)];\n const num = Math.floor(Math.random() * 100);\n return `${adj}-${noun}-${num}`;\n}\n","/**\n * Stdin reading utility for Claude Code hooks.\n *\n * Claude Code doesn't close stdin after writing hook input,\n * so stdin 'end' never fires. Solution: detect complete JSON\n * by attempting to parse after each chunk.\n */\n\nconst SAFETY_TIMEOUT_MS = 30000;\nconst PARSE_DELAY_MS = 50;\n\nfunction isStdinAvailable(): boolean {\n try {\n const stdin = process.stdin;\n if (stdin.isTTY) return false;\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n stdin.readable;\n return true;\n } catch {\n return false;\n }\n}\n\nfunction tryParseJson(input: string): { success: true; value: unknown } | { success: false } {\n const trimmed = input.trim();\n if (!trimmed) return { success: false };\n try {\n return { success: true, value: JSON.parse(trimmed) };\n } catch {\n return { success: false };\n }\n}\n\nexport async function readJsonFromStdin(): Promise<unknown> {\n if (!isStdinAvailable()) return undefined;\n\n return new Promise((resolve) => {\n let input = '';\n let resolved = false;\n let parseDelayId: ReturnType<typeof setTimeout> | null = null;\n\n const cleanup = () => {\n try {\n process.stdin.removeAllListeners('data');\n process.stdin.removeAllListeners('end');\n process.stdin.removeAllListeners('error');\n } catch { /* ignore */ }\n };\n\n const resolveWith = (value: unknown) => {\n if (resolved) return;\n resolved = true;\n if (parseDelayId) clearTimeout(parseDelayId);\n clearTimeout(safetyTimeoutId);\n cleanup();\n resolve(value);\n };\n\n const tryResolveWithJson = (): boolean => {\n const result = tryParseJson(input);\n if (result.success) {\n resolveWith(result.value);\n return true;\n }\n return false;\n };\n\n const safetyTimeoutId = setTimeout(() => {\n if (!resolved) {\n if (!tryResolveWithJson()) {\n resolveWith(input.trim() ? undefined : undefined);\n }\n }\n }, SAFETY_TIMEOUT_MS);\n\n try {\n process.stdin.on('data', (chunk: Buffer) => {\n input += chunk.toString();\n if (parseDelayId) { clearTimeout(parseDelayId); parseDelayId = null; }\n if (tryResolveWithJson()) return;\n parseDelayId = setTimeout(() => tryResolveWithJson(), PARSE_DELAY_MS);\n });\n\n process.stdin.on('end', () => {\n if (!resolved) tryResolveWithJson();\n });\n\n process.stdin.on('error', () => {\n if (!resolved) resolveWith(undefined);\n });\n } catch {\n resolved = true;\n clearTimeout(safetyTimeoutId);\n cleanup();\n resolve(undefined);\n }\n });\n}\n","/**\r\n * Manage the Party Server lifecycle for plugin integration.\r\n *\r\n * Detects if the server is already running, starts it if not, and\r\n * tracks the PID for cleanup.\r\n */\r\n\r\nimport { spawn, execSync } from 'node:child_process';\r\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, openSync } from 'node:fs';\r\nimport { join, resolve, dirname } from 'node:path';\r\nimport { homedir } from 'node:os';\r\nimport { fileURLToPath } from 'node:url';\r\n\r\nconst __dirname = dirname(fileURLToPath(import.meta.url));\r\n\r\nconst DEFAULT_PORT = parseInt(process.env.PARTY_PORT || '8000', 10);\r\nconst HEALTH_URL = `http://127.0.0.1:${DEFAULT_PORT}/proxy/health`;\r\nconst STARTUP_TIMEOUT = 10_000; // ms\r\n\r\nfunction pidFile(): string {\r\n const pluginData = process.env.CLAUDE_PLUGIN_DATA || '';\r\n if (pluginData) return join(pluginData, 'server.pid');\r\n return join(homedir(), '.open-party', 'server.pid');\r\n}\r\n\r\nfunction logFile(): string {\r\n const pluginData = process.env.CLAUDE_PLUGIN_DATA || '';\r\n if (pluginData) return join(pluginData, 'server.log');\r\n return join(homedir(), '.open-party', 'server.log');\r\n}\r\n\r\nfunction pluginRoot(): string {\r\n // CLAUDE_PLUGIN_ROOT is set by Claude Code at runtime\r\n if (process.env.CLAUDE_PLUGIN_ROOT) return process.env.CLAUDE_PLUGIN_ROOT;\r\n // Fallback: this file is at <pkg-root>/dist/hook-handler.js, so plugin root is <pkg-root>/\r\n // But when bundled into mcp-server.js, it's at <pkg-root>/dist/mcp-server.js\r\n // Check both locations\r\n const fromHere = resolve(__dirname, '..');\r\n if (existsSync(join(fromHere, 'dist', 'party-server.js'))) {\r\n return fromHere;\r\n }\r\n // When running from npm global install: we're in dist/ itself\r\n if (existsSync(join(fromHere, 'party-server.js'))) {\r\n return fromHere;\r\n }\r\n return resolve(__dirname, '..');\r\n}\r\n\r\nasync function isRunning(): Promise<boolean> {\r\n try {\r\n const controller = new AbortController();\r\n const timer = setTimeout(() => controller.abort(), 2000);\r\n const resp = await fetch(HEALTH_URL, { signal: controller.signal });\r\n clearTimeout(timer);\r\n return resp.status === 200;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nfunction readPid(): number | null {\r\n const path = pidFile();\r\n if (!existsSync(path)) return null;\r\n try {\r\n return parseInt(readFileSync(path, 'utf-8').trim(), 10);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction writePid(pid: number): void {\r\n const path = pidFile();\r\n const dir = dirname(path);\r\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\r\n writeFileSync(path, String(pid));\r\n}\r\n\r\nasync function sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport async function ensureServerRunning(): Promise<void> {\r\n if (await isRunning()) return;\r\n\r\n const serverScript = join(pluginRoot(), 'dist', 'party-server.js');\r\n if (!existsSync(serverScript)) {\r\n console.error(`[Open Party] Server script not found: ${serverScript}`);\r\n return;\r\n }\r\n\r\n // Redirect stdout/stderr to log file so we can debug crashes\r\n const logPath = logFile();\r\n mkdirSync(dirname(logPath), { recursive: true });\r\n const logFd = openSync(logPath, 'a');\r\n\r\n const proc = spawn(process.execPath, [serverScript], {\r\n stdio: ['ignore', logFd, logFd],\r\n detached: true,\r\n windowsHide: true,\r\n });\r\n proc.unref();\r\n writePid(proc.pid!);\r\n\r\n // Handle spawn errors\r\n proc.on('error', (err) => {\r\n console.error(`[Open Party] Failed to start server: ${err.message}`);\r\n });\r\n\r\n // Wait for server to become healthy\r\n const deadline = Date.now() + STARTUP_TIMEOUT;\r\n while (Date.now() < deadline) {\r\n if (await isRunning()) return;\r\n await sleep(500);\r\n }\r\n\r\n // Check if process is still alive\r\n try {\r\n process.kill(proc.pid!, 0);\r\n } catch {\r\n console.error(`[Open Party] Server crashed during startup. Check log: ${logPath}`);\r\n }\r\n}\r\n\r\nfunction stopServer(): void {\r\n const pid = readPid();\r\n if (pid === null) return;\r\n\r\n try {\r\n if (process.platform === 'win32') {\r\n execSync(`taskkill /F /T /PID ${pid}`, { stdio: 'ignore', windowsHide: true });\r\n } else {\r\n process.kill(pid, 'SIGTERM');\r\n }\r\n } catch { /* process already gone */ }\r\n\r\n try { unlinkSync(pidFile()); } catch { /* ignore */ }\r\n}\r\n\r\nexport async function main(): Promise<void> {\r\n if (process.argv.length > 2 && process.argv[2] === 'stop') {\r\n stopServer();\r\n console.log('Server stopped.');\r\n } else {\r\n await ensureServerRunning();\r\n }\r\n}\r\n"],"mappings":"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","names":["randomUUID","resolve","existsSync","readFileSync","writeFileSync","unlinkSync","mkdirSync","join","homedir","existsSync","mkdirSync","writeFileSync","resolve","join","agentId","displayName","agents","randomUUID"]}