@dmsdc-ai/aigentry-deliberation 0.0.4 → 0.0.6

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.
Files changed (2) hide show
  1. package/index.js +65 -11
  2. package/package.json +6 -3
package/index.js CHANGED
@@ -32,7 +32,7 @@ Usage:
32
32
  }
33
33
 
34
34
  /**
35
- * MCP Deliberation Server (Global) — v2.5 Multi-Session + Transport Routing + Cross-Platform + BrowserControlPort
35
+ * MCP Deliberation Server (Global) — Multi-Session + Transport Routing + Cross-Platform + BrowserControlPort
36
36
  *
37
37
  * 모든 프로젝트에서 사용 가능한 AI 간 deliberation 서버.
38
38
  * 동시에 여러 deliberation을 병렬 진행할 수 있다.
@@ -63,6 +63,7 @@ import { z } from "zod";
63
63
  import { execFileSync, spawn } from "child_process";
64
64
  import fs from "fs";
65
65
  import path from "path";
66
+ import { fileURLToPath } from "url";
66
67
  import os from "os";
67
68
  import { OrchestratedBrowserPort } from "./browser-control-port.js";
68
69
 
@@ -125,6 +126,20 @@ const DEFAULT_LLM_DOMAINS = [
125
126
  "notebooklm.google.com",
126
127
  ];
127
128
 
129
+ // Well-known web LLMs — always available as speaker candidates regardless of browser detection.
130
+ // When a matching browser tab is detected, transport upgrades to browser_auto (CDP) or clipboard.
131
+ // When no tab is detected, transport falls back to clipboard (manual paste).
132
+ const DEFAULT_WEB_SPEAKERS = [
133
+ { speaker: "web-chatgpt", provider: "chatgpt", name: "ChatGPT", url: "https://chatgpt.com" },
134
+ { speaker: "web-claude", provider: "claude", name: "Claude", url: "https://claude.ai" },
135
+ { speaker: "web-gemini", provider: "gemini", name: "Gemini", url: "https://gemini.google.com" },
136
+ { speaker: "web-copilot", provider: "copilot", name: "Copilot", url: "https://copilot.microsoft.com" },
137
+ { speaker: "web-perplexity", provider: "perplexity", name: "Perplexity", url: "https://perplexity.ai" },
138
+ { speaker: "web-deepseek", provider: "deepseek", name: "DeepSeek", url: "https://deepseek.com" },
139
+ { speaker: "web-mistral", provider: "mistral", name: "Mistral", url: "https://mistral.ai" },
140
+ { speaker: "web-poe", provider: "poe", name: "Poe", url: "https://poe.com" },
141
+ ];
142
+
128
143
  let _extensionProviderRegistry = null;
129
144
  const __dirnameEsm = path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/, "$1"));
130
145
  function loadExtensionProviderRegistry() {
@@ -1158,12 +1173,33 @@ async function collectSpeakerCandidates({ include_cli = true, include_browser =
1158
1173
  }
1159
1174
  }
1160
1175
 
1176
+ // Auto-register well-known web LLMs that weren't already detected via browser scanning.
1177
+ // This ensures web speakers are ALWAYS available regardless of browser detection success.
1178
+ // If a browser tab for the same provider was already detected, skip auto-registration
1179
+ // to avoid duplicates (e.g., detected "web-chatgpt-1" vs auto-registered "web-chatgpt").
1180
+ const detectedProviders = new Set(
1181
+ candidates.filter(c => c.type === "browser" && !c.auto_registered).map(c => c.provider)
1182
+ );
1183
+ for (const ws of DEFAULT_WEB_SPEAKERS) {
1184
+ if (detectedProviders.has(ws.provider)) continue;
1185
+ add({
1186
+ speaker: ws.speaker,
1187
+ type: "browser",
1188
+ provider: ws.provider,
1189
+ browser: "auto-registered",
1190
+ title: ws.name,
1191
+ url: ws.url,
1192
+ auto_registered: true,
1193
+ });
1194
+ }
1195
+
1161
1196
  return { candidates, browserNote };
1162
1197
  }
1163
1198
 
1164
1199
  function formatSpeakerCandidatesReport({ candidates, browserNote }) {
1165
1200
  const cli = candidates.filter(c => c.type === "cli");
1166
- const browser = candidates.filter(c => c.type === "browser");
1201
+ const detected = candidates.filter(c => c.type === "browser" && !c.auto_registered);
1202
+ const autoReg = candidates.filter(c => c.type === "browser" && c.auto_registered);
1167
1203
 
1168
1204
  let out = "## Selectable Speakers\n\n";
1169
1205
  out += "### CLI\n";
@@ -1173,17 +1209,22 @@ function formatSpeakerCandidatesReport({ candidates, browserNote }) {
1173
1209
  out += `${cli.map(c => `- \`${c.speaker}\` (command: ${c.command})`).join("\n")}\n\n`;
1174
1210
  }
1175
1211
 
1176
- out += "### Browser LLM\n";
1177
- if (browser.length === 0) {
1178
- out += "- (감지된 브라우저 LLM 탭 없음)\n";
1212
+ out += "### Browser LLM (감지됨)\n";
1213
+ if (detected.length === 0) {
1214
+ out += "- (브라우저에서 감지된 LLM 탭 없음)\n";
1179
1215
  } else {
1180
- out += `${browser.map(c => {
1216
+ out += `${detected.map(c => {
1181
1217
  const icon = c.cdp_available ? "⚡자동" : "📋클립보드";
1182
1218
  const extTag = String(c.url || "").startsWith("chrome-extension://") ? " [Extension]" : "";
1183
1219
  return `- \`${c.speaker}\` [${icon}]${extTag} [${c.browser}] ${c.title}\n ${c.url}`;
1184
1220
  }).join("\n")}\n`;
1185
1221
  }
1186
1222
 
1223
+ out += "\n### Web LLM (자동 등록)\n";
1224
+ out += `${autoReg.map(c => {
1225
+ return `- \`${c.speaker}\` — ${c.title} (${c.url})`;
1226
+ }).join("\n")}\n`;
1227
+
1187
1228
  if (browserNote) {
1188
1229
  out += `\n\nℹ️ ${browserNote}`;
1189
1230
  }
@@ -1217,10 +1258,19 @@ function mapParticipantProfiles(speakers, candidates, typeOverrides) {
1217
1258
 
1218
1259
  const candidate = bySpeaker.get(speaker);
1219
1260
  if (!candidate) {
1220
- profiles.push({
1221
- speaker,
1222
- type: "manual",
1223
- });
1261
+ // Force CLI type if the speaker is available as a CLI command in PATH
1262
+ if (commandExistsInPath(speaker)) {
1263
+ profiles.push({
1264
+ speaker,
1265
+ type: "cli",
1266
+ command: speaker,
1267
+ });
1268
+ } else {
1269
+ profiles.push({
1270
+ speaker,
1271
+ type: "manual",
1272
+ });
1273
+ }
1224
1274
  continue;
1225
1275
  }
1226
1276
 
@@ -2134,9 +2184,13 @@ process.on("unhandledRejection", (reason) => {
2134
2184
  }
2135
2185
  });
2136
2186
 
2187
+ // Read version from package.json (single source of truth)
2188
+ const __pkgPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "package.json");
2189
+ const __pkgVersion = JSON.parse(fs.readFileSync(__pkgPath, "utf-8")).version;
2190
+
2137
2191
  const server = new McpServer({
2138
2192
  name: "mcp-deliberation",
2139
- version: "2.4.0",
2193
+ version: __pkgVersion,
2140
2194
  });
2141
2195
 
2142
2196
  server.tool(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmsdc-ai/aigentry-deliberation",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "MCP Deliberation Server — Multi-session AI deliberation with smart speaker ordering and persona roles",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,10 +40,13 @@
40
40
  "README.md"
41
41
  ],
42
42
  "scripts": {
43
- "postinstall": "node install.js || true",
44
43
  "start": "node index.js",
45
44
  "test": "vitest run",
46
- "test:watch": "vitest"
45
+ "test:watch": "vitest",
46
+ "prepublishOnly": "vitest run",
47
+ "release:patch": "npm version patch && git push && git push --tags",
48
+ "release:minor": "npm version minor && git push && git push --tags",
49
+ "release:major": "npm version major && git push && git push --tags"
47
50
  },
48
51
  "dependencies": {
49
52
  "@modelcontextprotocol/sdk": "^1.26.0",