@sellable/install 0.1.44 → 0.1.46

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.
@@ -1295,9 +1295,62 @@ function installClaude(opts) {
1295
1295
  ["mcp", "add", "--transport", "stdio", "sellable", "--", command, ...args],
1296
1296
  opts
1297
1297
  );
1298
+ // Patch ~/.claude.json to add `alwaysLoad: true` so Claude Code v2.1.121+
1299
+ // pre-loads all mcp__sellable__* tool schemas instead of deferring them
1300
+ // behind ToolSearch (saves 2 round trips per `/sellable:create-campaign`
1301
+ // session). Older Claude Code versions ignore the field — no harm.
1302
+ patchClaudeAlwaysLoad(opts);
1298
1303
  return true;
1299
1304
  }
1300
1305
 
1306
+ function patchClaudeAlwaysLoad(opts) {
1307
+ if (opts.dryRun) {
1308
+ logVerbose(
1309
+ `${C.grey}+ would set alwaysLoad: true on sellable MCP server in ~/.claude.json${C.reset}`
1310
+ );
1311
+ return;
1312
+ }
1313
+ const claudeJsonPath = join(homedir(), ".claude.json");
1314
+ if (!existsSync(claudeJsonPath)) {
1315
+ logVerbose(
1316
+ `${C.grey}+ ~/.claude.json missing — skipping alwaysLoad patch (claude mcp add should have created it)${C.reset}`
1317
+ );
1318
+ return;
1319
+ }
1320
+ try {
1321
+ const raw = readFileSync(claudeJsonPath, "utf8");
1322
+ const config = JSON.parse(raw);
1323
+ let touched = false;
1324
+ // Top-level mcpServers.sellable (older claude versions)
1325
+ if (config.mcpServers?.sellable) {
1326
+ if (config.mcpServers.sellable.alwaysLoad !== true) {
1327
+ config.mcpServers.sellable.alwaysLoad = true;
1328
+ touched = true;
1329
+ }
1330
+ }
1331
+ // Per-project mcpServers.sellable (current claude default)
1332
+ for (const projectPath of Object.keys(config.projects || {})) {
1333
+ const projServers = config.projects[projectPath]?.mcpServers;
1334
+ if (projServers?.sellable && projServers.sellable.alwaysLoad !== true) {
1335
+ projServers.sellable.alwaysLoad = true;
1336
+ touched = true;
1337
+ }
1338
+ }
1339
+ if (touched) {
1340
+ writeFileSync(claudeJsonPath, JSON.stringify(config, null, 2), {
1341
+ mode: 0o600,
1342
+ });
1343
+ logVerbose(
1344
+ `${C.grey}+ patched ${claudeJsonPath} sellable.alwaysLoad = true${C.reset}`
1345
+ );
1346
+ }
1347
+ } catch (err) {
1348
+ logVerbose(
1349
+ `${C.grey}+ could not patch alwaysLoad: ${err instanceof Error ? err.message : String(err)} (non-fatal)${C.reset}`
1350
+ );
1351
+ }
1352
+ }
1353
+
1301
1354
  function installCodex(opts) {
1302
1355
  if (!commandExists("codex")) {
1303
1356
  const message =
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code and Codex",
6
6
  "bin": {
@@ -253,10 +253,18 @@ Cool — I have this campaign as {company}. Who should the LinkedIn messages sen
253
253
  Sender options should include connected sender names if available, `same as
254
254
  me`, `I’ll paste a different sender profile`, and `Other / custom`.
255
255
 
256
- After the user confirms the subject and sender, run one lightweight company
257
- lookup if it has not already run, then ask the campaign setup questions. The
258
- setup questions should use the confirmed company context so they do not feel
259
- generic.
256
+ After the user confirms the subject and sender, run one bounded lightweight
257
+ company-context pass before asking the campaign setup questions. A sender
258
+ LinkedIn profile lookup is not enough by itself unless it clearly includes the
259
+ company's website, product category, customer, and offer context. If the host can
260
+ run tools in parallel, use one parallel batch with at most 2-3 cheap lookups:
261
+ `mcp__sellable__fetch_company` on a LinkedIn company URL from the profile when
262
+ available; `WebFetch` for the company website/domain when available; otherwise
263
+ one `WebSearch` for `{company} official website` or `{company} product`. If
264
+ parallel tool calls are unavailable, do the single highest-confidence lookup
265
+ first and continue. Do not run full company research, source discovery, Sales
266
+ Nav, Prospeo, Signals, or multi-query browsing here. The goal is a fast 15-30
267
+ second context read so the four setup questions feel specific.
260
268
 
261
269
  Before the identity gate, use this customer-facing shape:
262
270
 
@@ -400,7 +408,7 @@ updates.
400
408
  ```text
401
409
  You're in — {activeWorkspaceName} workspace, ready to roll.
402
410
 
403
- Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you (the founder), or whoever's voice the messages should sound like.
411
+ Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you, or whoever's voice the messages should sound like.
404
412
 
405
413
  e.g. https://www.linkedin.com/in/your-handle
406
414
  ```
@@ -411,7 +419,7 @@ updates.
411
419
  ```text
412
420
  You're set up — your {activeWorkspaceName} workspace is ready.
413
421
 
414
- Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you (the founder), or whoever's voice the messages should sound like.
422
+ Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you, or whoever's voice the messages should sound like.
415
423
 
416
424
  e.g. https://www.linkedin.com/in/your-handle
417
425
  ```