@sellable/install 0.1.70 → 0.1.72
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/README.md +5 -3
- package/agents/registry.json +63 -21
- package/bin/sellable-install.mjs +50 -15
- package/package.json +1 -1
- package/skill-templates/create-campaign.md +6 -3
- /package/agents/{linkedin-engagement-scout.md → source-scout-linkedin-engagement.md} +0 -0
- /package/agents/{prospeo-contact-scout.md → source-scout-prospeo-contact.md} +0 -0
- /package/agents/{sales-nav-scout.md → source-scout-sales-nav.md} +0 -0
package/README.md
CHANGED
|
@@ -35,9 +35,11 @@ Auth is stored once at:
|
|
|
35
35
|
|
|
36
36
|
Claude Code and Codex are configured to launch the same packaged MCP server. The
|
|
37
37
|
installer also writes Sellable source-scout agents for both hosts from the
|
|
38
|
-
packaged `agents/` registry: Claude Code gets `
|
|
39
|
-
Codex gets `
|
|
40
|
-
`
|
|
38
|
+
packaged `agents/` registry: Claude Code gets `source-scout-*` subagents, and
|
|
39
|
+
Codex gets `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
40
|
+
`source-scout-prospeo-contact`. The MCP exposes the same list through
|
|
41
|
+
`get_source_scout_registry`, so adding a future scout starts in one registry
|
|
42
|
+
entry instead of scattered prompt edits.
|
|
41
43
|
|
|
42
44
|
## Names
|
|
43
45
|
|
package/agents/registry.json
CHANGED
|
@@ -2,14 +2,30 @@
|
|
|
2
2
|
"version": 1,
|
|
3
3
|
"agents": [
|
|
4
4
|
{
|
|
5
|
-
"id": "linkedin-engagement
|
|
6
|
-
"
|
|
5
|
+
"id": "linkedin-engagement",
|
|
6
|
+
"name": "source-scout-linkedin-engagement",
|
|
7
|
+
"promptFile": "source-scout-linkedin-engagement.md",
|
|
7
8
|
"displayName": "LinkedIn Engagement Scout",
|
|
9
|
+
"provider": "signal-discovery",
|
|
10
|
+
"lane": "linkedin-engagement",
|
|
11
|
+
"legacy": {
|
|
12
|
+
"codex": [
|
|
13
|
+
{
|
|
14
|
+
"name": "linkedin_engagement_scout",
|
|
15
|
+
"filename": "linkedin-engagement-scout.toml"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"claude": [
|
|
19
|
+
{
|
|
20
|
+
"name": "lead-explorer-signals",
|
|
21
|
+
"filename": "lead-explorer-signals.md"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
8
25
|
"codex": {
|
|
9
|
-
"name": "linkedin_engagement_scout",
|
|
10
|
-
"filename": "linkedin-engagement-scout.toml",
|
|
11
26
|
"description": "Sellable lead-source scout for LinkedIn post engagement and active conversation signals.",
|
|
12
|
-
"
|
|
27
|
+
"model": "gpt-5.5",
|
|
28
|
+
"modelReasoningEffort": "high",
|
|
13
29
|
"sandboxMode": "read-only",
|
|
14
30
|
"nicknameCandidates": [
|
|
15
31
|
"LinkedIn Engagement Scout",
|
|
@@ -18,8 +34,6 @@
|
|
|
18
34
|
]
|
|
19
35
|
},
|
|
20
36
|
"claude": {
|
|
21
|
-
"name": "lead-explorer-signals",
|
|
22
|
-
"filename": "lead-explorer-signals.md",
|
|
23
37
|
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs LinkedIn post engagement, Signals, or active conversation evidence.",
|
|
24
38
|
"model": "inherit",
|
|
25
39
|
"background": true,
|
|
@@ -36,14 +50,30 @@
|
|
|
36
50
|
}
|
|
37
51
|
},
|
|
38
52
|
{
|
|
39
|
-
"id": "sales-nav
|
|
40
|
-
"
|
|
53
|
+
"id": "sales-nav",
|
|
54
|
+
"name": "source-scout-sales-nav",
|
|
55
|
+
"promptFile": "source-scout-sales-nav.md",
|
|
41
56
|
"displayName": "Sales Nav Scout",
|
|
57
|
+
"provider": "sales-nav",
|
|
58
|
+
"lane": "sales-nav",
|
|
59
|
+
"legacy": {
|
|
60
|
+
"codex": [
|
|
61
|
+
{
|
|
62
|
+
"name": "sales_nav_scout",
|
|
63
|
+
"filename": "sales-nav-scout.toml"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"claude": [
|
|
67
|
+
{
|
|
68
|
+
"name": "lead-explorer-sales-nav",
|
|
69
|
+
"filename": "lead-explorer-sales-nav.md"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
42
73
|
"codex": {
|
|
43
|
-
"name": "sales_nav_scout",
|
|
44
|
-
"filename": "sales-nav-scout.toml",
|
|
45
74
|
"description": "Sellable lead-source scout for Sales Navigator role, company, and activity filters.",
|
|
46
|
-
"
|
|
75
|
+
"model": "gpt-5.5",
|
|
76
|
+
"modelReasoningEffort": "high",
|
|
47
77
|
"sandboxMode": "read-only",
|
|
48
78
|
"nicknameCandidates": [
|
|
49
79
|
"Sales Nav Scout",
|
|
@@ -52,8 +82,6 @@
|
|
|
52
82
|
]
|
|
53
83
|
},
|
|
54
84
|
"claude": {
|
|
55
|
-
"name": "lead-explorer-sales-nav",
|
|
56
|
-
"filename": "lead-explorer-sales-nav.md",
|
|
57
85
|
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs Sales Navigator title, company, geography, or activity-filter evidence.",
|
|
58
86
|
"model": "inherit",
|
|
59
87
|
"background": true,
|
|
@@ -70,14 +98,30 @@
|
|
|
70
98
|
}
|
|
71
99
|
},
|
|
72
100
|
{
|
|
73
|
-
"id": "prospeo-contact
|
|
74
|
-
"
|
|
101
|
+
"id": "prospeo-contact",
|
|
102
|
+
"name": "source-scout-prospeo-contact",
|
|
103
|
+
"promptFile": "source-scout-prospeo-contact.md",
|
|
75
104
|
"displayName": "Prospeo Contact Scout",
|
|
105
|
+
"provider": "prospeo",
|
|
106
|
+
"lane": "prospeo-contact",
|
|
107
|
+
"legacy": {
|
|
108
|
+
"codex": [
|
|
109
|
+
{
|
|
110
|
+
"name": "prospeo_contact_scout",
|
|
111
|
+
"filename": "prospeo-contact-scout.toml"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"claude": [
|
|
115
|
+
{
|
|
116
|
+
"name": "lead-explorer-prospeo",
|
|
117
|
+
"filename": "lead-explorer-prospeo.md"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
76
121
|
"codex": {
|
|
77
|
-
"name": "prospeo_contact_scout",
|
|
78
|
-
"filename": "prospeo-contact-scout.toml",
|
|
79
122
|
"description": "Sellable lead-source scout for Prospeo account/domain and broad contact expansion.",
|
|
80
|
-
"
|
|
123
|
+
"model": "gpt-5.5",
|
|
124
|
+
"modelReasoningEffort": "high",
|
|
81
125
|
"sandboxMode": "read-only",
|
|
82
126
|
"nicknameCandidates": [
|
|
83
127
|
"Prospeo Contact Scout",
|
|
@@ -86,8 +130,6 @@
|
|
|
86
130
|
]
|
|
87
131
|
},
|
|
88
132
|
"claude": {
|
|
89
|
-
"name": "lead-explorer-prospeo",
|
|
90
|
-
"filename": "lead-explorer-prospeo.md",
|
|
91
133
|
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs Prospeo account, domain-list, CSV-domain, or verified-contact evidence.",
|
|
92
134
|
"model": "inherit",
|
|
93
135
|
"background": true,
|
package/bin/sellable-install.mjs
CHANGED
|
@@ -465,6 +465,7 @@ const CREATE_CAMPAIGN_ALLOWED_TOOLS = [
|
|
|
465
465
|
"mcp__sellable__get_subskill_asset",
|
|
466
466
|
"mcp__sellable__search_subskill_prompts",
|
|
467
467
|
"mcp__sellable__get_provider_prompt",
|
|
468
|
+
"mcp__sellable__get_source_scout_registry",
|
|
468
469
|
"mcp__sellable__get_message_prompt",
|
|
469
470
|
"mcp__sellable__get_active_workspace",
|
|
470
471
|
"mcp__sellable__list_senders",
|
|
@@ -1124,14 +1125,18 @@ function loadCanonicalAgents() {
|
|
|
1124
1125
|
|
|
1125
1126
|
return registry.agents.map((agent) => {
|
|
1126
1127
|
const promptPath = join(root, agent.promptFile || "");
|
|
1127
|
-
if (!agent.id || !agent.promptFile || !existsSync(promptPath)) {
|
|
1128
|
+
if (!agent.id || !agent.name || !agent.promptFile || !existsSync(promptPath)) {
|
|
1128
1129
|
throw new Error(`Invalid Sellable agent registry entry: ${agent.id || "unknown"}`);
|
|
1129
1130
|
}
|
|
1130
|
-
if (
|
|
1131
|
-
throw new Error(
|
|
1131
|
+
if (agent.codex?.name && agent.codex.name !== agent.name) {
|
|
1132
|
+
throw new Error(
|
|
1133
|
+
`Sellable agent ${agent.id} has divergent Codex name ${agent.codex.name}; use canonical name ${agent.name}.`
|
|
1134
|
+
);
|
|
1132
1135
|
}
|
|
1133
|
-
if (
|
|
1134
|
-
throw new Error(
|
|
1136
|
+
if (agent.claude?.name && agent.claude.name !== agent.name) {
|
|
1137
|
+
throw new Error(
|
|
1138
|
+
`Sellable agent ${agent.id} has divergent Claude name ${agent.claude.name}; use canonical name ${agent.name}.`
|
|
1139
|
+
);
|
|
1135
1140
|
}
|
|
1136
1141
|
|
|
1137
1142
|
return {
|
|
@@ -1141,6 +1146,22 @@ function loadCanonicalAgents() {
|
|
|
1141
1146
|
});
|
|
1142
1147
|
}
|
|
1143
1148
|
|
|
1149
|
+
function codexAgentFilename(agent) {
|
|
1150
|
+
return agent.codex?.filename || `${agent.name}.toml`;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
function claudeAgentFilename(agent) {
|
|
1154
|
+
return agent.claude?.filename || `${agent.name}.md`;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
function legacyCodexCustomAgents() {
|
|
1158
|
+
return loadCanonicalAgents().flatMap((agent) => agent.legacy?.codex || []);
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
function legacyClaudeCustomAgents() {
|
|
1162
|
+
return loadCanonicalAgents().flatMap((agent) => agent.legacy?.claude || []);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1144
1165
|
function tomlArray(values) {
|
|
1145
1166
|
return `[${values.map((value) => quoteToml(value)).join(", ")}]`;
|
|
1146
1167
|
}
|
|
@@ -1152,9 +1173,10 @@ function tomlMultilineString(value) {
|
|
|
1152
1173
|
|
|
1153
1174
|
function generateCodexAgentToml(agent) {
|
|
1154
1175
|
const codex = agent.codex;
|
|
1155
|
-
return `name = ${quoteToml(
|
|
1176
|
+
return `name = ${quoteToml(agent.name)}
|
|
1156
1177
|
description = ${quoteToml(codex.description)}
|
|
1157
|
-
|
|
1178
|
+
model = ${quoteToml(codex.model || "gpt-5.5")}
|
|
1179
|
+
model_reasoning_effort = ${quoteToml(codex.modelReasoningEffort || "high")}
|
|
1158
1180
|
sandbox_mode = ${quoteToml(codex.sandboxMode || "read-only")}
|
|
1159
1181
|
nickname_candidates = ${tomlArray(codex.nicknameCandidates || [agent.displayName])}
|
|
1160
1182
|
developer_instructions = ${tomlMultilineString(agent.prompt)}
|
|
@@ -1163,8 +1185,8 @@ developer_instructions = ${tomlMultilineString(agent.prompt)}
|
|
|
1163
1185
|
|
|
1164
1186
|
function codexCustomAgents() {
|
|
1165
1187
|
return loadCanonicalAgents().map((agent) => ({
|
|
1166
|
-
name: agent.
|
|
1167
|
-
filename: agent
|
|
1188
|
+
name: agent.name,
|
|
1189
|
+
filename: codexAgentFilename(agent),
|
|
1168
1190
|
content: generateCodexAgentToml(agent),
|
|
1169
1191
|
}));
|
|
1170
1192
|
}
|
|
@@ -1172,7 +1194,7 @@ function codexCustomAgents() {
|
|
|
1172
1194
|
function generateClaudeAgentMd(agent) {
|
|
1173
1195
|
const claude = agent.claude;
|
|
1174
1196
|
return `---
|
|
1175
|
-
name: ${
|
|
1197
|
+
name: ${agent.name}
|
|
1176
1198
|
description: ${JSON.stringify(claude.description)}
|
|
1177
1199
|
tools: ${(claude.tools || []).join(", ")}
|
|
1178
1200
|
model: ${claude.model || "inherit"}
|
|
@@ -1187,8 +1209,8 @@ ${agent.prompt}
|
|
|
1187
1209
|
|
|
1188
1210
|
function claudeCustomAgents() {
|
|
1189
1211
|
return loadCanonicalAgents().map((agent) => ({
|
|
1190
|
-
name: agent.
|
|
1191
|
-
filename: agent
|
|
1212
|
+
name: agent.name,
|
|
1213
|
+
filename: claudeAgentFilename(agent),
|
|
1192
1214
|
tools: agent.claude.tools || [],
|
|
1193
1215
|
content: generateClaudeAgentMd(agent),
|
|
1194
1216
|
}));
|
|
@@ -1213,6 +1235,11 @@ function writeCodexCustomAgents(home, opts) {
|
|
|
1213
1235
|
for (const agent of codexCustomAgents()) {
|
|
1214
1236
|
writeFile(join(home, "agents", agent.filename), agent.content, opts);
|
|
1215
1237
|
}
|
|
1238
|
+
for (const agent of legacyCodexCustomAgents()) {
|
|
1239
|
+
const legacyPath = join(home, "agents", agent.filename);
|
|
1240
|
+
logVerbose(`${C.grey}Removing legacy Codex scout agent ${legacyPath}${C.reset}`);
|
|
1241
|
+
if (!opts.dryRun) rmSync(legacyPath, { force: true });
|
|
1242
|
+
}
|
|
1216
1243
|
}
|
|
1217
1244
|
|
|
1218
1245
|
function claudeHome() {
|
|
@@ -1224,6 +1251,11 @@ function writeClaudeCustomAgents(opts) {
|
|
|
1224
1251
|
for (const agent of claudeCustomAgents()) {
|
|
1225
1252
|
writeFile(join(home, "agents", agent.filename), agent.content, opts);
|
|
1226
1253
|
}
|
|
1254
|
+
for (const agent of legacyClaudeCustomAgents()) {
|
|
1255
|
+
const legacyPath = join(home, "agents", agent.filename);
|
|
1256
|
+
logVerbose(`${C.grey}Removing legacy Claude scout agent ${legacyPath}${C.reset}`);
|
|
1257
|
+
if (!opts.dryRun) rmSync(legacyPath, { force: true });
|
|
1258
|
+
}
|
|
1227
1259
|
}
|
|
1228
1260
|
|
|
1229
1261
|
function installCodexDesktopPlugin(opts) {
|
|
@@ -1339,6 +1371,9 @@ enabled = false`
|
|
|
1339
1371
|
max_threads = 6
|
|
1340
1372
|
max_depth = 1`
|
|
1341
1373
|
);
|
|
1374
|
+
for (const agent of legacyCodexCustomAgents()) {
|
|
1375
|
+
content = removeTomlSection(content, `agents.${agent.name}`);
|
|
1376
|
+
}
|
|
1342
1377
|
for (const agent of codexCustomAgents()) {
|
|
1343
1378
|
content = upsertTomlTable(
|
|
1344
1379
|
content,
|
|
@@ -1861,7 +1896,7 @@ function runUninstall() {
|
|
|
1861
1896
|
after = removeTomlSection(after, "marketplaces.sellable");
|
|
1862
1897
|
after = removeTomlSection(after, 'plugins."sellable@sellable"');
|
|
1863
1898
|
after = removeTomlSection(after, 'plugins."sellable@sellable-local"');
|
|
1864
|
-
for (const agent of codexCustomAgents()) {
|
|
1899
|
+
for (const agent of [...codexCustomAgents(), ...legacyCodexCustomAgents()]) {
|
|
1865
1900
|
after = removeTomlSection(after, `agents.${agent.name}`);
|
|
1866
1901
|
}
|
|
1867
1902
|
// Collapse 3+ blank lines that the removals may leave behind.
|
|
@@ -1884,7 +1919,7 @@ function runUninstall() {
|
|
|
1884
1919
|
skipped.push(`Codex config not found at ${codexConfigPath}`);
|
|
1885
1920
|
}
|
|
1886
1921
|
|
|
1887
|
-
for (const agent of codexCustomAgents()) {
|
|
1922
|
+
for (const agent of [...codexCustomAgents(), ...legacyCodexCustomAgents()]) {
|
|
1888
1923
|
const agentPath = join(codexHome(), "agents", agent.filename);
|
|
1889
1924
|
if (!existsSync(agentPath)) continue;
|
|
1890
1925
|
try {
|
|
@@ -1911,7 +1946,7 @@ function runUninstall() {
|
|
|
1911
1946
|
skipped.push(`Claude Code CLI not found`);
|
|
1912
1947
|
}
|
|
1913
1948
|
|
|
1914
|
-
for (const agent of claudeCustomAgents()) {
|
|
1949
|
+
for (const agent of [...claudeCustomAgents(), ...legacyClaudeCustomAgents()]) {
|
|
1915
1950
|
const agentPath = join(claudeHome(), "agents", agent.filename);
|
|
1916
1951
|
if (!existsSync(agentPath)) continue;
|
|
1917
1952
|
try {
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ allowed-tools:
|
|
|
11
11
|
- mcp__sellable__get_subskill_asset
|
|
12
12
|
- mcp__sellable__search_subskill_prompts
|
|
13
13
|
- mcp__sellable__get_provider_prompt
|
|
14
|
+
- mcp__sellable__get_source_scout_registry
|
|
14
15
|
- mcp__sellable__get_message_prompt
|
|
15
16
|
- mcp__sellable__get_active_workspace
|
|
16
17
|
- mcp__sellable__list_senders
|
|
@@ -102,12 +103,14 @@ scout those angles as independent branches when the host can actually do it:
|
|
|
102
103
|
LinkedIn Engagement / active post engagers (internal `signal-discovery`
|
|
103
104
|
provider prompt), Sales Nav / title + company filters, and Prospeo Contact /
|
|
104
105
|
domains only when relevant. In Codex, explicitly spawn the named custom scouts
|
|
105
|
-
`
|
|
106
|
+
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and `source-scout-prospeo-contact` for
|
|
106
107
|
the credible lanes; Codex does not infer subagent fan-out from generic source
|
|
107
|
-
comparison wording. In Claude Code, invoke the generated `
|
|
108
|
+
comparison wording. In Claude Code, invoke the generated `source-scout-*`
|
|
108
109
|
Task/Agent subagents for all credible lanes in one assistant message; the
|
|
109
110
|
installer writes them from the same canonical Sellable agent registry with
|
|
110
|
-
explicit Sellable MCP tool allowlists.
|
|
111
|
+
explicit Sellable MCP tool allowlists. The create-campaign-v2 subskill calls
|
|
112
|
+
`get_source_scout_registry` before dispatch so the current registry, not this
|
|
113
|
+
copy, is the runtime source of truth. If the host runs them sequentially, do not
|
|
111
114
|
claim they ran in parallel. In chat, call the downstream copy stage `message generation`;
|
|
112
115
|
`message-validation.md` is only an internal proof artifact.
|
|
113
116
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|