@vruum/skills 0.5.0 → 0.5.2
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 +1 -0
- package/package.json +2 -2
- package/skills/create-content/SKILL.md +89 -0
package/README.md
CHANGED
|
@@ -72,6 +72,7 @@ npx @vruum/skills install --target /path/to/skills/dir
|
|
|
72
72
|
- `/sales-nav-deep-fill` — Sales Nav harness source for /pipeline-fill. Pre-filters Sales Nav profiles via vruum-pipeline-filter, produces a candidate list, hands off to /pipeline-fill for deep research and import. Use when: sales nav with deep research, sales nav harness mode, in-chat sales nav.
|
|
73
73
|
- `/yc-pipeline-fill` — YC harness source for /pipeline-fill. Scrapes YC's public Algolia index, extracts founder LinkedIn URLs, dedups, hands a candidate list to /pipeline-fill for deep research and import. Use when: YC pipeline fill, source from YC, fill segment with YC founders, sales nav dried up, source YC.
|
|
74
74
|
- `/csv-pipeline-fill` — CSV harness source for /pipeline-fill. Reads a CSV, auto-detects headers, maps columns, hands off to /pipeline-fill for harness deep research and import. Use when: import CSV, paste a CSV, csv import, prospect list from CSV, csv harness mode.
|
|
75
|
+
- `/create-content` — Co-produce an on-voice LinkedIn content post — pull your own signal, steer the angle conversationally, draft in your voice, then save as draft, schedule, or publish. Use when: write a post, draft LinkedIn content, create content, post about, content co-production, help me write a post.
|
|
75
76
|
- `/segment-doctor` — Diagnose and fix struggling outreach segments. Use when: fix a segment, diagnose segment, why is my segment not working, segment health, low reply rate, check segments, which segments need help.
|
|
76
77
|
- `/vruum-skills-upgrade` — Upgrade @vruum/skills to the latest npm version and re-sync ~/.vruum/. Use when: upgrade vruum skills, update vruum, pull latest vruum skills, or when the preamble reports UPGRADE_AVAILABLE.
|
|
77
78
|
- `/winback-fill` — Source winback candidates from closed-lost deals or churned customers. Surfaces people who went silent or lost a deal >90 days ago, where the loss reason wasn't 'no_fit'. Use when: winback, win back churned, reactivate, revive cold deals, 90-day silent revival, lost deal recovery, lost customer outreach.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vruum/skills",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Vruum AI skills for Claude Code, Claude Desktop, Codex CLI, and any AI assistant with a skill directory. Slash commands for outreach triage, engagement triage, pipeline filling, prospect enrichment, and reply diagnosis. Pairs with the Vruum MCP server at https://api.vruum.ai/mcp.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"outreach",
|
|
37
37
|
"gtm"
|
|
38
38
|
],
|
|
39
|
-
"contentHash": "
|
|
39
|
+
"contentHash": "e0050f63b3a0e2e8dfd104839324afe1d385046dc74fe0a2347ba37906ddd7b4"
|
|
40
40
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-content
|
|
3
|
+
description: >-
|
|
4
|
+
Co-produce an on-voice LinkedIn content post — pull your own signal, steer the
|
|
5
|
+
angle conversationally, draft in your voice, then save as draft, schedule, or
|
|
6
|
+
publish. Use when: write a post, draft LinkedIn content, create content, post
|
|
7
|
+
about, content co-production, help me write a post.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# /create-content
|
|
11
|
+
|
|
12
|
+
You co-produce a LinkedIn post in the seller's own voice. This is a conversation, not a one-shot generator: you pull the seller's real signal (their calls, posts, notes, knowledge), surface what's there, let them steer the angle, draft on-voice, and then save it the way they want — draft, scheduled, or (only on explicit confirmation) published.
|
|
13
|
+
|
|
14
|
+
The conversation IS the capture. You don't need a form — you need a topic and a back-and-forth.
|
|
15
|
+
|
|
16
|
+
## Step 1: Capture a lightweight topic
|
|
17
|
+
|
|
18
|
+
Open with a single question if the seller hasn't already said what they want to post about:
|
|
19
|
+
|
|
20
|
+
"What do you want to post about? A theme, a recent win, a take you want to put out — even a rough phrase is enough to start."
|
|
21
|
+
|
|
22
|
+
Keep it light. You're not locking a brief yet — you just need a seed string to retrieve relevant signal. Do not call any tool until you have at least a rough topic.
|
|
23
|
+
|
|
24
|
+
## Step 2: Pull the seller's signal
|
|
25
|
+
|
|
26
|
+
Call `get_seller_signal_bundle` with the seller's rough topic as the `draft_brief` argument. The brief drives a semantic re-rank, so the more concrete the topic, the more relevant the returned evidence.
|
|
27
|
+
|
|
28
|
+
**Ground on `formatted_evidence`.** It is the EVIDENCE-wrapped rendering prepared for drafting — the surface you should read, quote, and reason over. The backend scrubs prospect names, emails, phone numbers, and URLs out of *everything* it returns (both `formatted_evidence` and the raw `bundle` text), so you don't have to police that yourself — there is no un-redacted surface on the response. Still prefer `formatted_evidence`: it is the prepared, sectioned grounding surface, where `bundle` is just the structured raw material behind it.
|
|
29
|
+
|
|
30
|
+
`formatted_evidence` can be `null`. Null-check it before using it:
|
|
31
|
+
- If `formatted_evidence` is present → use it as the grounding evidence in Step 3.
|
|
32
|
+
- If `formatted_evidence` is `null` (a `formatted_evidence_skipped_reason` of `bundle_empty` means there was no signal to draw on yet; any other reason means the evidence was withheld and the `bundle` text is redacted to empty too) → say so plainly and fall back to a **profile-only draft**: write from the company voice profile and the seller's stated topic alone, with no evidence grounding.
|
|
33
|
+
|
|
34
|
+
## Step 2.5: Check the calendar (optional)
|
|
35
|
+
|
|
36
|
+
This step is **optional** and **must never gate the loop**. It exists only to make the brief a little smarter, not to add a precondition before drafting. If you skip it, or it returns nothing, or it errors — proceed to Step 3 silently and draft anyway.
|
|
37
|
+
|
|
38
|
+
If a quick read of what's already on the content calendar would help shape the angle, call `get_content_calendar` **once** (the default `days` window is fine — don't loop or page). Treat the returned `posts` (each with `topic_tags`, `status`, and `scheduled_at`/`published_at`) and the `summary` as planning context only, to:
|
|
39
|
+
|
|
40
|
+
- **Avoid theme clustering** — if a recent or upcoming post already covers this `topic_tags` theme, nudge the angle somewhere fresher rather than posting two near-duplicates close together.
|
|
41
|
+
- **Notice cadence gaps** — if the calendar looks thin lately, that's a soft reason to keep this one moving. This is best-effort only: the tool returns posts by recency (it lists what was created recently, not a precise scheduled-window view), so don't promise exact cadence math or specific dates — read it as a rough sense of "busy" vs "quiet," not a schedule.
|
|
42
|
+
- **Adapt a strong recent angle** — if a recent post's theme clearly resonated, consider building on it instead of repeating a weaker one. This is soft: the tool orders by recency, not performance, so treat "recent" as a hint, not proof that an angle worked.
|
|
43
|
+
|
|
44
|
+
Surface anything useful to the seller as a light suggestion ("you posted on this theme last week — want a different angle, or a follow-up?"), never as a blocker. If `posts` is empty, the tool is unavailable, or it errors, say nothing about the calendar and just continue. Do not retry it.
|
|
45
|
+
|
|
46
|
+
## Step 3: Surface the evidence and settle the brief
|
|
47
|
+
|
|
48
|
+
If you have `formatted_evidence`, show the seller the relevant points you found, in plain language:
|
|
49
|
+
|
|
50
|
+
"Here's what I found in your recent signal that fits this topic:
|
|
51
|
+
- [evidence point 1]
|
|
52
|
+
- [evidence point 2]
|
|
53
|
+
- [evidence point 3]
|
|
54
|
+
|
|
55
|
+
Which of these do you want to anchor the post on? And what's the angle — a lesson, a contrarian take, a story, an announcement?"
|
|
56
|
+
|
|
57
|
+
Let the seller refine. Iterate in conversation until the brief is **settled** — you and the seller agree on the angle, the anchor evidence, and the tone. Do not generate a draft while the brief is still moving.
|
|
58
|
+
|
|
59
|
+
## Step 4: Draft on-voice — once
|
|
60
|
+
|
|
61
|
+
**Only once the brief is settled**, call `generate_linkedin_post`, passing the settled brief as the `topic` argument. The backend writes the draft in the seller's voice and grounds it on their seller signal internally — you do not pass the evidence yourself.
|
|
62
|
+
|
|
63
|
+
`generate_linkedin_post` creates a new draft row every time it runs. Call it **once** per post. Show the seller the returned draft.
|
|
64
|
+
|
|
65
|
+
## Step 5: Iterate by editing — never regenerate
|
|
66
|
+
|
|
67
|
+
When the seller wants changes (tighten the hook, change the CTA, fix a line), revise the **existing** draft with `manage_content_post` using `action="edit"`, passing the updated `content`.
|
|
68
|
+
|
|
69
|
+
Never call `generate_linkedin_post` again for a revision — that spawns a duplicate draft row and loses the thread. One post = one draft row, edited in place.
|
|
70
|
+
|
|
71
|
+
## Step 6: Save — draft, schedule, or publish
|
|
72
|
+
|
|
73
|
+
When the seller is happy with the draft, ask how they want to land it. **Default to keeping it as a draft or scheduling it.**
|
|
74
|
+
|
|
75
|
+
- **Keep as draft** — do nothing further; the draft already exists and is visible at `/marketing/content`.
|
|
76
|
+
- **Schedule** — call `manage_content_post` with `action="schedule"` and a `scheduled_at` ISO-8601 timestamp. It auto-publishes when due.
|
|
77
|
+
- **Publish now** — this is destructive and irreversible, and it will fail (marking the draft unusable) if no LinkedIn account is connected. So treat it as a deliberate, confirmed action:
|
|
78
|
+
- Never call publish as a probe or a default.
|
|
79
|
+
- Only call `manage_content_post` with `action="publish"` **after** the seller has explicitly confirmed "publish now."
|
|
80
|
+
- Always offer save-as-draft or schedule as the safer fallback when proposing publish.
|
|
81
|
+
|
|
82
|
+
If the seller asks to reschedule a post that is **already scheduled**, be aware that rescheduling an already-scheduled post is not currently supported and may return a "not in draft status" error. Tell the seller this plainly rather than retrying blindly, and offer to keep the existing schedule.
|
|
83
|
+
|
|
84
|
+
## Notes
|
|
85
|
+
|
|
86
|
+
- Stay conversational. The value of this skill is the steer→draft→schedule loop, not a single generated blob. Surface evidence, let the seller choose the angle, and draft only when the brief is settled.
|
|
87
|
+
- The seller's voice is the product. Ground the post in their real signal (`formatted_evidence`) whenever it's available; only fall back to a profile-only draft when there's genuinely no evidence to draw on.
|
|
88
|
+
- Be honest about gaps. If there was no signal to retrieve, say "I didn't find recent signal on this — here's a draft from your voice profile" rather than inventing specifics.
|
|
89
|
+
- This skill never deletes posts. If the seller wants to discard a draft, point them to `/marketing/content` rather than removing rows on their behalf.
|