@sellable/install 0.1.158 → 0.1.159
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.
|
@@ -60,9 +60,11 @@ required message reference cannot be loaded through the MCP asset loader, return
|
|
|
60
60
|
`get_subskill_prompt({ subskillName: "generate-messages" })`
|
|
61
61
|
|
|
62
62
|
3. Load every packaged reference asset required by that prompt's Reference Asset
|
|
63
|
-
Loading section with `get_subskill_asset
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
Loading section with `get_subskill_asset`: load the required pre-draft reference pack before
|
|
64
|
+
drafting, load final-pass references before approval, and `ai-tells.md` is part of the required pack
|
|
65
|
+
and never optional. If a required asset cannot
|
|
66
|
+
load through the MCP asset loader, return `blocked` / `retry-needed`; do not draft from
|
|
67
|
+
memory or from the prompt alone.
|
|
66
68
|
4. Build positioning in a compact working note: buyer, pain, product, mechanism,
|
|
67
69
|
proof boundary, source-use rule, and CTA.
|
|
68
70
|
5. Draft 3 distinct first-message options: signal-led, product/mechanism-led,
|
|
@@ -89,6 +91,7 @@ Return the following to the parent thread:
|
|
|
89
91
|
|
|
90
92
|
- proposed first-message template using supported `{{...}}` tokens
|
|
91
93
|
- token fill rules and fallbacks
|
|
94
|
+
- `Reference Asset Loading` note naming which assets were used and why
|
|
92
95
|
- one rendered good-fill sample for a plausible passing campaign-table row
|
|
93
96
|
- message-draft runtime status: `ready`, `blocked`, `retry-needed`, or `stale`
|
|
94
97
|
- approve-or-revise recommendation
|
|
@@ -178,16 +181,33 @@ own revision. The parent renders the revised template and waits for
|
|
|
178
181
|
- Engagement-source personalization is a special case, not the default opener.
|
|
179
182
|
Do not write `saw you {{engagement_context}} on {{post_context}}`, `saw you
|
|
180
183
|
reacted to`, `saw you engaging with`, or equivalent source-citation copy as a
|
|
181
|
-
default hook.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
default hook. Sender-owned post sources are different: if the source post was
|
|
185
|
+
authored by the sender/client and the row proves a reaction/comment, prefer a
|
|
186
|
+
light first-person acknowledgment such as `appreciate you showing some love on
|
|
187
|
+
my post about [topic]` or `thanks for showing support on my [topic] post`.
|
|
188
|
+
Do not name a comment unless the row proves comment text, and do not infer
|
|
189
|
+
buyer intent from the reaction. Follow that acknowledgment with a soft
|
|
190
|
+
relevance bridge before any broad problem or product line. Good:
|
|
191
|
+
`figured this might be relevant if [channel/workflow] is becoming more of a
|
|
192
|
+
[GTM/pipeline/content] channel for [company/team]`. Bad: jumping directly
|
|
193
|
+
from `appreciate you showing some love...` to `a lot of B2B teams...` or
|
|
194
|
+
`most teams...`; that reads stitched together. Every line must make the next
|
|
195
|
+
line feel earned: source/post signal -> relevance bridge -> product/problem
|
|
196
|
+
-> next step. If adjacent lines could be swapped, deleted, or joined with
|
|
197
|
+
`anyway` without changing the meaning, rewrite the bridge or cut the orphan
|
|
198
|
+
line. For third-party LinkedIn-post-sourced
|
|
199
|
+
campaigns, keep the source topic-level. Good: `saw you in a few conversations
|
|
200
|
+
around [topic], so hope this is relevant`, `saw you in a few conversations
|
|
201
|
+
about [topic], so may be off, but this seemed relevant`, `saw you might be
|
|
202
|
+
interested in [topic], so hope this is relevant`, `hope this is relevant if
|
|
203
|
+
[topic] is on your plate`, or `found you in a thread about [topic], so may be
|
|
204
|
+
off, but this seemed relevant`. Only use `saw you raise your hand for [topic],
|
|
205
|
+
so figured this was (hopefully) worth sending` when the source was an explicit
|
|
206
|
+
lead-magnet comment, reply, or opt-in.
|
|
188
207
|
The cheekier `saw you raise your hand for [topic] (creepy to reach out based
|
|
189
208
|
on that, i know) - but this felt too on the nose to ignore` version is also
|
|
190
|
-
allowed
|
|
209
|
+
allowed only for explicit lead-magnet comments, replies, or opt-ins and when the
|
|
210
|
+
sender's voice can carry it. Bad: `you commented on...`, `you reacted
|
|
191
211
|
to...`, `saw you engaging with...`, `your LinkedIn activity...`, `you might
|
|
192
212
|
not remember the thread...`, or `found you through [source] and your role
|
|
193
213
|
looked close...`. Otherwise omit the engagement signal and use role/company/problem context.
|
|
@@ -196,9 +216,9 @@ looked close...`. Otherwise omit the engagement signal and use role/company/prob
|
|
|
196
216
|
topic looked close` are blocked. If the source is too weak, omit it.
|
|
197
217
|
- Do not assert fit from title/company. `Your [role] role at [company] looked
|
|
198
218
|
close to this problem` is blocked. Keep the apologetic uncertainty instead:
|
|
199
|
-
`may be off, but if [workflow] is
|
|
219
|
+
`may be off, but if [workflow] is relevant to what you're working on...`.
|
|
200
220
|
- Low-pressure relevance opt-outs are allowed when they do not defend the
|
|
201
|
-
source: `p.s. if this is
|
|
221
|
+
source: `p.s. if this is not relevant to your outbound workflow, ignore me`.
|
|
202
222
|
- Do not use `Caught` as opener language. It reads unnatural in LinkedIn
|
|
203
223
|
outreach.
|
|
204
224
|
- Do not describe the sender in third person inside the outbound message.
|
package/bin/sellable-install.mjs
CHANGED
|
@@ -1256,8 +1256,8 @@ Desktop, then start a new thread.
|
|
|
1256
1256
|
2. When the canonical prompt asks for \`references/*.md\`, load those files
|
|
1257
1257
|
with \`mcp__sellable__get_subskill_asset({ subskillName: "interview", assetPath: "references/<file>.md" })\`.
|
|
1258
1258
|
3. Follow the canonical prompt exactly. Save local memory only where that prompt
|
|
1259
|
-
directs, under
|
|
1260
|
-
|
|
1259
|
+
directs, under \`~/.sellable/configs/core/**\` and
|
|
1260
|
+
\`~/.sellable/interviews/**\`.
|
|
1261
1261
|
|
|
1262
1262
|
## MCP Prompt Fallback
|
|
1263
1263
|
|
|
@@ -1303,7 +1303,7 @@ Desktop, then start a new thread.
|
|
|
1303
1303
|
If the response has \`hasMore=true\`, continue with \`nextOffset\` until
|
|
1304
1304
|
\`hasMore=false\`.
|
|
1305
1305
|
2. Follow the canonical prompt exactly. Read the relevant
|
|
1306
|
-
|
|
1306
|
+
\`~/.sellable/configs/**\` memory files it names.
|
|
1307
1307
|
3. Apply the loaded memory silently to the user's requested writing or answer.
|
|
1308
1308
|
If the user only asked to load voice, summarize the active rules briefly and
|
|
1309
1309
|
ask what they want drafted, answered, or reviewed.
|
|
@@ -2079,7 +2079,7 @@ function patchClaudeAlwaysLoad(opts) {
|
|
|
2079
2079
|
}
|
|
2080
2080
|
|
|
2081
2081
|
function installCodex(opts) {
|
|
2082
|
-
if (!commandExists("codex")) {
|
|
2082
|
+
if (!opts.dryRun && !commandExists("codex")) {
|
|
2083
2083
|
const message =
|
|
2084
2084
|
"Codex CLI not found. Install/login to Codex, then rerun: sellable --host codex";
|
|
2085
2085
|
if (opts.host === "all") {
|
|
@@ -2088,6 +2088,9 @@ function installCodex(opts) {
|
|
|
2088
2088
|
}
|
|
2089
2089
|
throw new Error(message);
|
|
2090
2090
|
}
|
|
2091
|
+
if (!opts.dryRun) {
|
|
2092
|
+
mkdirSync(codexHome(), { recursive: true, mode: 0o700 });
|
|
2093
|
+
}
|
|
2091
2094
|
if (opts.server === "hosted") {
|
|
2092
2095
|
run("codex", codexMcpAddArgs(opts), opts);
|
|
2093
2096
|
const info = installCodexDesktopPlugin(opts);
|
|
@@ -2654,6 +2657,13 @@ async function main() {
|
|
|
2654
2657
|
process.exit(2);
|
|
2655
2658
|
}
|
|
2656
2659
|
const token = rawArgs[2];
|
|
2660
|
+
const authSetFlags = rawArgs.slice(3);
|
|
2661
|
+
const dryRun = authSetFlags.includes("--dry-run");
|
|
2662
|
+
const unknownAuthSetFlag = authSetFlags.find((arg) => arg !== "--dry-run");
|
|
2663
|
+
if (unknownAuthSetFlag) {
|
|
2664
|
+
console.error(`Unknown auth set option: ${unknownAuthSetFlag}`);
|
|
2665
|
+
process.exit(2);
|
|
2666
|
+
}
|
|
2657
2667
|
if (!token) {
|
|
2658
2668
|
console.error(
|
|
2659
2669
|
"Usage: sellable auth set <token>\n" +
|
|
@@ -2678,9 +2688,13 @@ async function main() {
|
|
|
2678
2688
|
writeJson(
|
|
2679
2689
|
authPath(),
|
|
2680
2690
|
{ token, activeWorkspaceId: null, apiUrl },
|
|
2681
|
-
{ dryRun
|
|
2691
|
+
{ dryRun }
|
|
2682
2692
|
);
|
|
2683
|
-
|
|
2693
|
+
if (dryRun) {
|
|
2694
|
+
console.log(`Dry run: token would be saved to ${authPath()}`);
|
|
2695
|
+
} else {
|
|
2696
|
+
console.log(`✓ Token saved to ${authPath()}`);
|
|
2697
|
+
}
|
|
2684
2698
|
console.log(` apiUrl: ${apiUrl}`);
|
|
2685
2699
|
console.log(` Continue in your agent:`);
|
|
2686
2700
|
console.log(` Claude Code: /sellable:create-campaign`);
|