@sellable/install 0.1.149 → 0.1.151
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.
|
@@ -37,17 +37,22 @@ the branch input.
|
|
|
37
37
|
|
|
38
38
|
## Required First Steps
|
|
39
39
|
|
|
40
|
-
1. Load the
|
|
41
|
-
|
|
42
|
-
`get_subskill_prompt({ subskillName: "generate-messages
|
|
43
|
-
|
|
44
|
-
2. Use that prompt as the drafting contract.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
1. Load the full normal-path message prompt:
|
|
41
|
+
|
|
42
|
+
`get_subskill_prompt({ subskillName: "generate-messages" })`
|
|
43
|
+
|
|
44
|
+
2. Use that prompt as the drafting contract. Do not use any alternate prompt,
|
|
45
|
+
examples-only shortcut, or create-campaign safety/checklist instructions as a
|
|
46
|
+
substitute for the full message prompt.
|
|
47
|
+
3. Follow the prompt's `Reference Asset Loading` section: load the required
|
|
48
|
+
pre-draft reference pack before drafting, load final-pass references before
|
|
49
|
+
approval, and report which assets were used and why. If those required
|
|
50
|
+
assets cannot be loaded, return `blocked` / `retry-needed`; do not draft from
|
|
51
|
+
the prompt alone. `ai-tells.md` is part of the required pack and is never
|
|
52
|
+
optional.
|
|
53
|
+
4. Draft only from the campaign brief, selected source context, and initial
|
|
49
54
|
campaign-table execution slice rows supplied by the parent.
|
|
50
|
-
|
|
55
|
+
5. Keep the work provisional until the user chooses `Use Template` in Messages.
|
|
51
56
|
|
|
52
57
|
## Owned Output
|
|
53
58
|
|
|
@@ -55,10 +60,12 @@ Return the following to the parent thread:
|
|
|
55
60
|
|
|
56
61
|
- proposed first-message template using supported `{{...}}` tokens
|
|
57
62
|
- token fill rules and fallbacks
|
|
63
|
+
- `Reference Asset Loading` note naming the required and conditional assets used
|
|
64
|
+
and why each was used
|
|
58
65
|
- one rendered good-fill sample for a plausible passing campaign-table row
|
|
59
66
|
- one omit/fallback sample when the row signal is not safe
|
|
60
|
-
- pass/fail notes against the generate-messages
|
|
61
|
-
-
|
|
67
|
+
- pass/fail notes against the generate-messages quality gates
|
|
68
|
+
- message-draft runtime status: `ready`, `blocked`, `retry-needed`, or `stale`
|
|
62
69
|
- basis token containing campaign revision/updatedAt, brief hash,
|
|
63
70
|
`selectedLeadListId`, `workflowTableId`, execution-slice row ids/hash, filter
|
|
64
71
|
choice, and rubric/filter basis when present
|
|
@@ -78,7 +85,7 @@ When reporting branch runtime proof, use this shape under
|
|
|
78
85
|
- `runId` or `fallbackId`
|
|
79
86
|
- `startedAt` and `updatedAt`
|
|
80
87
|
- `basisToken` and `basis`
|
|
81
|
-
- optional `
|
|
88
|
+
- optional `messageDraftOutputRef`, `messageDraftOutput`, and `error`
|
|
82
89
|
|
|
83
90
|
Do not tell the UI to show Message Draft Builder as running unless this proof
|
|
84
91
|
exists and points at the current non-empty campaign-table execution slice.
|
|
@@ -120,11 +127,33 @@ blocker.
|
|
|
120
127
|
- Engagement-source personalization is a special case, not the default opener.
|
|
121
128
|
Do not write `saw you {{engagement_context}} on {{post_context}}`, `saw you
|
|
122
129
|
reacted to`, `saw you engaging with`, or equivalent source-citation copy as a
|
|
123
|
-
default hook.
|
|
124
|
-
|
|
125
|
-
you
|
|
126
|
-
|
|
127
|
-
|
|
130
|
+
default hook. For LinkedIn-post-sourced campaigns, you may reference the
|
|
131
|
+
source when it explains why the note exists, but keep it topic-level, not
|
|
132
|
+
activity-log-level. Good: `saw you in a few conversations around [topic], so
|
|
133
|
+
hope this is relevant`, `saw you in a few conversations about [topic], so
|
|
134
|
+
may be off, but this seemed relevant`, `saw you might be interested in [topic],
|
|
135
|
+
so hope this is relevant`, `hope this is relevant if [topic] is on your plate`,
|
|
136
|
+
or `found you in a thread about [topic], so may be off, but this seemed relevant`.
|
|
137
|
+
Only use `saw you raise your hand for [topic], so figured this was (hopefully)
|
|
138
|
+
worth sending` when the source was an explicit lead-magnet comment, reply, or
|
|
139
|
+
opt-in.
|
|
140
|
+
The cheekier `saw you raise your hand for [topic] (creepy to reach out based
|
|
141
|
+
on that, i know) - but this felt too on the nose to ignore` version is also
|
|
142
|
+
allowed only for explicit lead-magnet comments, replies, or opt-ins and when the
|
|
143
|
+
sender's voice can carry it. Bad: `you commented on...`, `you reacted
|
|
144
|
+
to...`, `saw you engaging with...`, `your LinkedIn activity...`, `you might
|
|
145
|
+
not remember the thread...`, or `found you through [source] and your role
|
|
146
|
+
looked close...`. Otherwise omit the engagement signal and use role/company/problem context.
|
|
147
|
+
- Do not use a PS to defend the source. Lines like `p.s. if the source thread
|
|
148
|
+
was just casual reading, ignore me` or `only reaching out where the role and
|
|
149
|
+
topic looked close` are blocked. If the source is too weak, omit it.
|
|
150
|
+
- Do not assert fit from title/company. `Your [role] role at [company] looked
|
|
151
|
+
close to this problem` is blocked. Keep the apologetic uncertainty instead:
|
|
152
|
+
`may be off, but if [workflow] is anywhere near your lane...`.
|
|
153
|
+
- Low-pressure relevance opt-outs are allowed when they do not defend the
|
|
154
|
+
source: `p.s. if this is nowhere near your outbound workflow, ignore me`.
|
|
155
|
+
- Do not use `Caught` as opener language. It reads unnatural in LinkedIn
|
|
156
|
+
outreach.
|
|
128
157
|
- Do not describe the sender in third person inside the outbound message.
|
|
129
158
|
Lines like `p.s. Saju's angle is...`, `Christian's angle is...`, or
|
|
130
159
|
`[sender]'s approach is...` are internal notes leaking into copy. If the point
|
|
@@ -137,7 +166,7 @@ enablement`, or omit it.
|
|
|
137
166
|
|
|
138
167
|
Return a concise status with:
|
|
139
168
|
|
|
140
|
-
- prompt basis loaded: `generate-messages
|
|
169
|
+
- prompt basis loaded: `generate-messages`
|
|
141
170
|
- live campaign basis used
|
|
142
171
|
- proposed template
|
|
143
172
|
- token fill rules/fallbacks
|
|
@@ -43,7 +43,7 @@ sales Claude`; do not treat broad anchor-only lanes like `Claude Code`, `MCP`,
|
|
|
43
43
|
5. Promote the first narrow sample set when campaign-attached. If a
|
|
44
44
|
`campaignOfferId` was supplied, call `select_promising_posts({
|
|
45
45
|
campaignOfferId, selectionMode: "replace", selections, headlineICPCriteria,
|
|
46
|
-
currentStep: "signal-discovery" })` before sampling so the watched Signal
|
|
46
|
+
scrapePlanMode: "all-selected", currentStep: "signal-discovery" })` before sampling so the watched Signal
|
|
47
47
|
Discovery table shows the promoted posts and the exact posts being tested.
|
|
48
48
|
Do not move the campaign to `confirm-lead-list`; `import_leads` owns that
|
|
49
49
|
visible transition after source approval.
|
package/bin/sellable-install.mjs
CHANGED
|
@@ -1110,8 +1110,8 @@ updates.
|
|
|
1110
1110
|
3. Follow that prompt and workflow config exactly.
|
|
1111
1111
|
4. For message generation, use the \`post-find-leads-message-scout\` agent when
|
|
1112
1112
|
available. The worker and parent-thread fallback must load
|
|
1113
|
-
\`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages
|
|
1114
|
-
|
|
1113
|
+
\`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages" })\`.
|
|
1114
|
+
Do not use any alternate or examples-only message prompt. Message review requires Message Draft Builder output:
|
|
1115
1115
|
do not draft from a checklist, local markdown artifact, or parent-thread
|
|
1116
1116
|
intuition. Use campaign state, campaign brief content, selected source state,
|
|
1117
1117
|
and initial campaign-table execution slice rows as the source of truth; do not read stale
|
|
@@ -1244,8 +1244,8 @@ Desktop, then start a new thread.
|
|
|
1244
1244
|
2. When the canonical prompt asks for \`references/*.md\`, load those files
|
|
1245
1245
|
with \`mcp__sellable__get_subskill_asset({ subskillName: "interview", assetPath: "references/<file>.md" })\`.
|
|
1246
1246
|
3. Follow the canonical prompt exactly. Save local memory only where that prompt
|
|
1247
|
-
directs, under
|
|
1248
|
-
|
|
1247
|
+
directs, under \`~/.sellable/configs/core/**\` and
|
|
1248
|
+
\`~/.sellable/interviews/**\`.
|
|
1249
1249
|
|
|
1250
1250
|
## MCP Prompt Fallback
|
|
1251
1251
|
|
|
@@ -1291,7 +1291,7 @@ Desktop, then start a new thread.
|
|
|
1291
1291
|
If the response has \`hasMore=true\`, continue with \`nextOffset\` until
|
|
1292
1292
|
\`hasMore=false\`.
|
|
1293
1293
|
2. Follow the canonical prompt exactly. Read the relevant
|
|
1294
|
-
|
|
1294
|
+
\`~/.sellable/configs/**\` memory files it names.
|
|
1295
1295
|
3. Apply the loaded memory silently to the user's requested writing or answer.
|
|
1296
1296
|
If the user only asked to load voice, summarize the active rules briefly and
|
|
1297
1297
|
ask what they want drafted, answered, or reviewed.
|
|
@@ -2044,7 +2044,7 @@ function patchClaudeAlwaysLoad(opts) {
|
|
|
2044
2044
|
}
|
|
2045
2045
|
|
|
2046
2046
|
function installCodex(opts) {
|
|
2047
|
-
if (!commandExists("codex")) {
|
|
2047
|
+
if (!opts.dryRun && !commandExists("codex")) {
|
|
2048
2048
|
const message =
|
|
2049
2049
|
"Codex CLI not found. Install/login to Codex, then rerun: sellable --host codex";
|
|
2050
2050
|
if (opts.host === "all") {
|
|
@@ -2053,6 +2053,9 @@ function installCodex(opts) {
|
|
|
2053
2053
|
}
|
|
2054
2054
|
throw new Error(message);
|
|
2055
2055
|
}
|
|
2056
|
+
if (!opts.dryRun) {
|
|
2057
|
+
mkdirSync(codexHome(), { recursive: true, mode: 0o700 });
|
|
2058
|
+
}
|
|
2056
2059
|
if (opts.server === "hosted") {
|
|
2057
2060
|
run("codex", codexMcpAddArgs(opts), opts);
|
|
2058
2061
|
const info = installCodexDesktopPlugin(opts);
|
|
@@ -2619,6 +2622,13 @@ async function main() {
|
|
|
2619
2622
|
process.exit(2);
|
|
2620
2623
|
}
|
|
2621
2624
|
const token = rawArgs[2];
|
|
2625
|
+
const authSetFlags = rawArgs.slice(3);
|
|
2626
|
+
const dryRun = authSetFlags.includes("--dry-run");
|
|
2627
|
+
const unknownAuthSetFlag = authSetFlags.find((arg) => arg !== "--dry-run");
|
|
2628
|
+
if (unknownAuthSetFlag) {
|
|
2629
|
+
console.error(`Unknown auth set option: ${unknownAuthSetFlag}`);
|
|
2630
|
+
process.exit(2);
|
|
2631
|
+
}
|
|
2622
2632
|
if (!token) {
|
|
2623
2633
|
console.error(
|
|
2624
2634
|
"Usage: sellable auth set <token>\n" +
|
|
@@ -2643,9 +2653,13 @@ async function main() {
|
|
|
2643
2653
|
writeJson(
|
|
2644
2654
|
authPath(),
|
|
2645
2655
|
{ token, activeWorkspaceId: null, apiUrl },
|
|
2646
|
-
{ dryRun
|
|
2656
|
+
{ dryRun }
|
|
2647
2657
|
);
|
|
2648
|
-
|
|
2658
|
+
if (dryRun) {
|
|
2659
|
+
console.log(`Dry run: token would be saved to ${authPath()}`);
|
|
2660
|
+
} else {
|
|
2661
|
+
console.log(`✓ Token saved to ${authPath()}`);
|
|
2662
|
+
}
|
|
2649
2663
|
console.log(` apiUrl: ${apiUrl}`);
|
|
2650
2664
|
console.log(` Continue in your agent:`);
|
|
2651
2665
|
console.log(` Claude Code: /sellable:create-campaign`);
|
package/package.json
CHANGED
|
@@ -270,8 +270,13 @@ only an internal approval proof.
|
|
|
270
270
|
|
|
271
271
|
For campaign-attached Signal Discovery sampling, promote/select the exact posts
|
|
272
272
|
with `select_promising_posts` before `fetch_post_engagers` so the user can see
|
|
273
|
-
which posts are being sampled in the watched app.
|
|
274
|
-
|
|
273
|
+
which posts are being sampled in the watched app. Use
|
|
274
|
+
`selectionMode: "replace"` for a fresh absolute promoted set and
|
|
275
|
+
`selectionMode: "add"` only when intentionally expanding existing promoted
|
|
276
|
+
posts. Use `scrapePlanMode: "all-selected"` when the approval/import should use
|
|
277
|
+
every promoted post; use `scrapePlanMode: "capacity-target"` only when source
|
|
278
|
+
math should import the smallest set that covers a target. The watch guide should
|
|
279
|
+
say that we are checking people from these posts to confirm the right people are
|
|
275
280
|
actually engaging and the source is viable.
|
|
276
281
|
|
|
277
282
|
After confirmed source rows exist in the campaign table, use the same registry pattern for
|
|
@@ -755,8 +760,8 @@ updates.
|
|
|
755
760
|
3. Follow that prompt and workflow config exactly.
|
|
756
761
|
4. For message generation, use the `post-find-leads-message-scout` agent when
|
|
757
762
|
available. The worker and parent-thread fallback must load
|
|
758
|
-
`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages
|
|
759
|
-
|
|
763
|
+
`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages" })`.
|
|
764
|
+
Do not use any alternate or examples-only message prompt. Message review requires Message Draft Builder output:
|
|
760
765
|
do not draft from a checklist, local markdown artifact, or parent-thread
|
|
761
766
|
intuition. Use campaign state, campaign brief content, selected source state, and
|
|
762
767
|
initial campaign-table execution slice rows as the source of truth; do not read stale local
|