@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.
package/bin/sellable-install.mjs
CHANGED
|
@@ -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
|
@@ -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
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
|
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
|
|
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
|
```
|