@greennx/sales-mcp 1.1.0 → 1.2.0

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.
@@ -50,6 +50,7 @@ function printHelp() {
50
50
  ${bold("COMMANDS")}
51
51
 
52
52
  ${cyan("setup")} Auto-detect and configure all installed MCP clients
53
+ ${cyan("update")} Update the server bundle to the latest installed version
53
54
  ${cyan("uninstall")} Remove sales-mcp from all detected tools
54
55
 
55
56
  ${bold("OPTIONS")}
@@ -65,6 +66,9 @@ function printHelp() {
65
66
  ${dim("# Use a custom directory for HTML backups")}
66
67
  ${cyan(`npx @greenn/sales-mcp setup --token`)} <your-token> ${cyan("--history-path")} ~/backups/greenn
67
68
 
69
+ ${dim("# Update server to the latest version")}
70
+ ${cyan("npx @greenn/sales-mcp update")}
71
+
68
72
  ${dim("# Remove from all tools")}
69
73
  ${cyan("npx @greenn/sales-mcp uninstall")}
70
74
 
@@ -122,6 +126,12 @@ function resolveConfigPath(tool) {
122
126
  case "claude-code-user":
123
127
  if (IS_WIN) return join(process.env["USERPROFILE"] ?? home, ".claude.json");
124
128
  return join(home, ".claude.json");
129
+ case "gemini-cli":
130
+ if (IS_WIN) return join(process.env["USERPROFILE"] ?? home, ".gemini", "settings.json");
131
+ return join(home, ".gemini", "settings.json");
132
+ case "codex":
133
+ if (IS_WIN) return join(process.env["USERPROFILE"] ?? home, ".codex", "config.toml");
134
+ return join(home, ".codex", "config.toml");
125
135
  default:
126
136
  return null;
127
137
  }
@@ -165,6 +175,51 @@ function removeSalesMcpFromJsonConfig(configPath) {
165
175
  writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
166
176
  return true;
167
177
  }
178
+ function removeSalesMcpTomlSections(content) {
179
+ const lines = content.split("\n");
180
+ const out = [];
181
+ let skip = false;
182
+ for (const line of lines) {
183
+ const trimmed = line.trim();
184
+ if (trimmed === "[mcp_servers.sales-mcp]" || trimmed === "[mcp_servers.sales-mcp.env]") {
185
+ skip = true;
186
+ continue;
187
+ }
188
+ if (skip && trimmed.startsWith("[")) skip = false;
189
+ if (!skip) out.push(line);
190
+ }
191
+ return out.join("\n");
192
+ }
193
+ function patchTomlConfig(configPath, serverPath, mcpContext) {
194
+ let content = "";
195
+ let wasCreated = true;
196
+ if (existsSync(configPath)) {
197
+ content = removeSalesMcpTomlSections(readFileSync(configPath, "utf-8")).trimEnd();
198
+ wasCreated = false;
199
+ } else {
200
+ mkdirSync(dirname(configPath), { recursive: true });
201
+ }
202
+ const entry = [
203
+ "",
204
+ "[mcp_servers.sales-mcp]",
205
+ `command = ${JSON.stringify(process.execPath)}`,
206
+ `args = [${JSON.stringify(serverPath)}]`,
207
+ "",
208
+ "[mcp_servers.sales-mcp.env]",
209
+ `MCP_CONTEXT = ${JSON.stringify(mcpContext)}`,
210
+ ""
211
+ ].join("\n");
212
+ writeFileSync(configPath, content + entry);
213
+ return wasCreated ? "created" : "patched";
214
+ }
215
+ function removeSalesMcpFromTomlConfig(configPath) {
216
+ if (!existsSync(configPath)) return false;
217
+ const original = readFileSync(configPath, "utf-8");
218
+ const updated = removeSalesMcpTomlSections(original).trimEnd() + "\n";
219
+ if (updated === original) return false;
220
+ writeFileSync(configPath, updated);
221
+ return true;
222
+ }
168
223
  var [command, ...rest] = process.argv.slice(2);
169
224
  var hasHelp = rest.includes("--help") || rest.includes("-h");
170
225
  if (!command || command === "--help" || command === "-h") {
@@ -220,7 +275,9 @@ if (command === "setup") {
220
275
  { id: "claude-desktop", name: "Claude Desktop", restart: "Restart Claude Desktop." },
221
276
  { id: "cursor", name: "Cursor", restart: 'Settings > MCP > click "Refresh".' },
222
277
  { id: "antigravity", name: "Antigravity (Windsurf)", restart: 'Manage MCP Servers > click "Refresh".' },
223
- { id: "cline", name: "Cline (VS Code)", restart: 'Cline sidebar > MCP Servers > click "Refresh".' }
278
+ { id: "cline", name: "Cline (VS Code)", restart: 'Cline sidebar > MCP Servers > click "Refresh".' },
279
+ { id: "gemini-cli", name: "Gemini CLI", restart: "Restart Gemini CLI." },
280
+ { id: "codex", name: "Codex CLI", restart: "Restart Codex CLI.", toml: true }
224
281
  ];
225
282
  let configured = 0;
226
283
  for (const tool of tools) {
@@ -234,7 +291,7 @@ if (command === "setup") {
234
291
  continue;
235
292
  }
236
293
  try {
237
- const action = patchJsonConfig(configPath, serverDest, mcpContext);
294
+ const action = tool.toml ? patchTomlConfig(configPath, serverDest, mcpContext) : patchJsonConfig(configPath, serverDest, mcpContext);
238
295
  console.log(` ${green("ok")} ${bold(tool.name)} ${dim(`\u2014 config ${action}.`)}`);
239
296
  console.log(` ${dim("file:")} ${configPath}`);
240
297
  console.log(` ${dim("next:")} ${tool.restart}`);
@@ -284,6 +341,27 @@ if (command === "setup") {
284
341
  console.log(` ${dim("3.")} You should see your Greenn funnels listed \u2014 setup is complete.
285
342
  `);
286
343
  }
344
+ } else if (command === "update") {
345
+ const serverDest = join(DEFAULT_INSTALL_DIR, "server.cjs");
346
+ if (!existsSync(serverDest)) {
347
+ console.error(`
348
+ ${red("error")} sales-mcp is not installed. Run ${cyan('"sales-mcp setup"')} first.
349
+ `);
350
+ process.exit(1);
351
+ }
352
+ if (!existsSync(BUNDLE_SRC)) {
353
+ console.error(`
354
+ ${red("error")} bundle not found at ${BUNDLE_SRC}
355
+ `);
356
+ process.exit(1);
357
+ }
358
+ copyFileSync(BUNDLE_SRC, serverDest);
359
+ console.log(`
360
+ ${bold(green("sales-mcp updated"))} ${dim(`\u2192 v${VERSION}`)}`);
361
+ console.log(` ${dim("server:")} ${serverDest}`);
362
+ console.log(`
363
+ Restart your AI tools to apply the update.
364
+ `);
287
365
  } else if (command === "uninstall") {
288
366
  console.log("");
289
367
  for (const scope of ["user", "project", "local"]) {
@@ -294,14 +372,16 @@ if (command === "setup") {
294
372
  { id: "claude-desktop", name: "Claude Desktop" },
295
373
  { id: "cursor", name: "Cursor" },
296
374
  { id: "antigravity", name: "Antigravity (Windsurf)" },
297
- { id: "cline", name: "Cline (VS Code)" }
375
+ { id: "cline", name: "Cline (VS Code)" },
376
+ { id: "gemini-cli", name: "Gemini CLI" },
377
+ { id: "codex", name: "Codex CLI", toml: true }
298
378
  ];
299
379
  let removed = 0;
300
380
  for (const tool of tools) {
301
381
  const configPath = resolveConfigPath(tool.id);
302
382
  if (!configPath) continue;
303
383
  try {
304
- const ok = removeSalesMcpFromJsonConfig(configPath);
384
+ const ok = tool.toml ? removeSalesMcpFromTomlConfig(configPath) : removeSalesMcpFromJsonConfig(configPath);
305
385
  if (ok) {
306
386
  console.log(` ${green("ok")} ${tool.name} ${dim("\u2014 removed.")}`);
307
387
  removed++;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greennx/sales-mcp",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "MCP server for AI-generated landing pages on the Greenn Sales platform",
5
5
  "type": "module",
6
6
  "bin": {