@vruum/skills 0.2.0 → 0.4.1

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.
@@ -1,9 +1,22 @@
1
1
  ---
2
2
  name: engagement-triage
3
- description: "Review and approve your pending LinkedIn engagement drafts and demand-gen content posts. Use when: triage engagements, review engagement queue, review warming comments, review nurture reactions, review marketing comments, review content drafts, check engagement queue."
3
+ description: >-
4
+ Review and approve your pending LinkedIn engagement drafts and demand-gen
5
+ content posts. Use when: triage engagements, review engagement queue, review
6
+ warming comments, review nurture reactions, review marketing comments, review
7
+ content drafts, check engagement queue.
4
8
  ---
5
9
 
6
- # /engagement-triage
10
+ ## Auto-update check
11
+
12
+ Before starting, run `~/.vruum/bin/vruum-skills-update-check` (path relative to this repo). Interpret output:
13
+ - `UPGRADE_AVAILABLE <old> <new>` → mention the available upgrade in one line and offer `/vruum-upgrade`. Then continue.
14
+ - `JUST_UPGRADED <old> <new>` → acknowledge in one line, then continue.
15
+ - Empty → proceed silently.
16
+
17
+ Never block skill execution on this check.
18
+
19
+ # Engagement Triage
7
20
 
8
21
  You review the user's pending LinkedIn engagement drafts (warming comments, nurture reactions, marketing comments) and demand-gen content posts, dispatching review subagents in parallel and presenting results for approval. Separate from `/outreach-triage` (which handles outreach messages).
9
22
 
@@ -23,7 +36,7 @@ Falls back to general-purpose subagent with MCP tool names in the prompt if the
23
36
 
24
37
  ### Step 1: Summarize the queue
25
38
 
26
- Call `get_marketing_overview` (single-company view) to see what's pending. Present a one-liner:
39
+ Call `get_marketing_overview` to see what's pending. Present a one-liner:
27
40
 
28
41
  "X warming drafts, Y nurture drafts, Z marketing drafts, N content posts pending."
29
42
 
@@ -64,84 +77,80 @@ For each queue type the user selected, call the appropriate list endpoint, get I
64
77
 
65
78
  Spawn up to 4 subagents concurrently. For larger queues (15+), dispatch in waves.
66
79
 
67
- **Subagent prompt — engagement items:**
80
+ Subagent prompt template:
68
81
 
69
82
  ```
70
- You are an engagement review agent.
83
+ You are an engagement review agent for {company_name}.
71
84
 
72
- {SENDER PROFILE block}
85
+ SENDER PROFILE:
86
+ {sender_profile_block}
73
87
 
74
- Engagement IDs: {comma_separated_engagement_ids}
75
- Queue type: {warming | nurture | marketing}
88
+ Engagement IDs: {comma_separated_ids}
76
89
 
77
- Call get_engagement_review with engagement_ids="{ids}" and content_length="full" to load your items. Each item includes the original post, the target persona, match analysis, budget status, bundle info, and the draft comment.
90
+ Call get_engagement_review with engagement_ids="{comma_separated_ids}" and content_length="full" to load your assigned items.
78
91
 
79
- For each item:
80
- 1. Voice fit does the draft sound like the sender? (check SENDER PROFILE above; flag anything generic or out-of-voice)
81
- 2. Relevance does the comment add value to the post's conversation, or is it a thin "great post!" type?
82
- 3. Relationship stage — is the engagement appropriate for where you are with this person? (warming = not yet in outreach, nurture = mid-conversation, marketing = brand surfacing)
83
- 4. AI tells generic phrases, em dashes, overused words, robotic cadence
84
- 5. Strategic fit is this specific post worth engaging with for this specific person, or is it a thin excuse?
92
+ For each engagement:
93
+ 1. Check voice fit against sender profile (would this person actually say this?)
94
+ 2. Check relevance to the prospect's post
95
+ 3. Check for AI tells (generic phrasing, hollow flattery, buzzwords)
96
+ 4. Check for over-pitching (warming comments should NOT sell)
97
+ 5. Rate quality: genuine value-add vs generic engagement
85
98
 
86
- If the draft needs editing, call manage_engagement with action=edit. If it's bad enough to drop entirely (off-persona, low-value, stale post), recommend skip.
99
+ If a comment needs fixes, edit it via manage_engagement. Only edit when there's genuine improvement don't rewrite solid comments.
87
100
 
88
- Return:
89
- ENGAGEMENT: {id} | TARGET: {person name} | TYPE: {warming|nurture|marketing} | RECOMMENDATION: {approve|edited|skip} | CONFIDENCE: {high|medium|low} | REASONING: {1-2 sentences} | EDITED: {yes/no} | ISSUES_FOUND: {list or "none"}
90
- ```
91
-
92
- **Subagent prompt — content posts:**
101
+ IMPORTANT: Do NOT approve or skip engagements. Return recommendations only.
93
102
 
103
+ Return a structured summary for each item:
104
+ ENGAGEMENT: {id} | TYPE: {reaction|comment} | PERSON: {name} | SOURCE: {warming|nurture|marketing} | RECOMMENDATION: {approve|edited|flag|skip} | CONFIDENCE: {high|medium|low} | REASONING: {1-2 sentences} | EDITED: {yes/no} | COMMENT_TEXT: {the comment text, or "reaction" for likes}
94
105
  ```
95
- You are a content review agent.
96
106
 
97
- {SENDER PROFILE block}
107
+ For high-value comments (match score 80+, nurture, cold marketing), use research mode: 1 comment per subagent. The subagent reads the prospect's actual post via `get_person_360`, understands what they're saying, and edits only if there's a real opportunity to improve.
98
108
 
99
- Post IDs: {comma_separated_post_ids}
109
+ ### Step 5: Present results — always show content
100
110
 
101
- Call get_content_review with post_ids="{ids}" and content_length="full" to load drafts. Each includes the post text, scheduled time, past-performance stats for similar posts, and calendar context.
111
+ Do NOT approve engagements without showing them to the user.
102
112
 
103
- For each post:
104
- 1. Voice fit — sounds like the sender? (SENDER PROFILE above; flag anything generic)
105
- 2. Hook quality — does the first line stop scroll? Is it specific and worth reading further?
106
- 3. AI tells — em dashes, AI-vocabulary ("delve", "robust", "comprehensive"), uniform sentence length, generic openers
107
- 4. Strategic fit — does this post serve the sender's ICP and positioning, or is it generic thought-leadership?
108
- 5. Calendar fit — appropriate timing relative to other recent posts? (get_content_review returns calendar context)
113
+ **Reactions:** Present as a batch with count. "12 warming reactions — all look good. Approve?" If any flagged, show those individually.
109
114
 
110
- If the post needs editing, call manage_content_post with action=edit. If it's bad enough to reject, recommend reject.
115
+ **Comments:** Always show the actual comment text for every comment. Group by recommendation:
111
116
 
112
- Return:
113
- POST: {id} | SCHEDULED: {time} | RECOMMENDATION: {approve|edited|reject} | CONFIDENCE: {high|medium|low} | REASONING: {1-2 sentences} | EDITED: {yes/no} | ISSUES_FOUND: {list or "none"} | HOOK_RATING: {1-10}
114
- ```
117
+ 1. **Clean approvals**: Show comment text and one-line note. User can bulk-approve.
118
+ 2. **Edited comments**: Show the new comment, what changed, and why. User reviews each.
119
+ 3. **Flagged/skipped**: Show the issue and recommendation.
115
120
 
116
- ### Step 5: Present results show drafts before approving
121
+ **Content posts:** Always show full post text with calendar context and past performance. User approves individually.
117
122
 
118
- Group by recommendation:
123
+ ### Step 6: Skip cascade
119
124
 
120
- 1. **Clean approvals** show the draft and a one-line "why it's good". Bulk-approve with one response.
121
- 2. **Edited drafts** — show the new version, what changed, why. User reviews each.
122
- 3. **Skip / reject** — show the draft and the issue. One action to confirm.
125
+ When skipping an engagement because the prospect is a bad fit (not because the comment quality is poor), offer to stop the outreach/warming plan:
123
126
 
124
- For content posts, always walk through one at a time they're user-visible and higher stakes than a comment.
127
+ "Keith Hemmert (match score 33) weak fit, no evidence of relevant practice. Skip this engagement and stop warming for this person?"
125
128
 
126
- ### Step 6: User overrides
129
+ This bundles skip + stop plan since a bad-fit engagement almost always means warming should stop entirely. Only offer the cascade for fit-based skips, not quality-based edits.
127
130
 
128
- - Pull full context for any item
129
- - Adjust any subagent edit before approving
130
- - Skip the whole queue type ("actually, don't review marketing, just warming")
131
- - Ask to see a specific person's engagement history (`get_engagement_queue` filtered by person_id)
131
+ ### Step 7: Early pattern detection
132
132
 
133
- ## Edge cases
133
+ After the first batch returns for any engagement type:
134
134
 
135
- **Tiny queue (10 or fewer total):** skip subagents, review inline with the user. Subagent overhead isn't worth it.
135
+ - **All reactions clean:** "First batch of reactions all approved. N more look similar — approve the rest?" Apply without more agents.
136
+ - **All comments have the same issue** (e.g., all too generic, all missing sender voice): Flag the pattern to the user. "First 8 comments are all generic 'great post' style — likely a prompt issue. Want me to edit them all with the same fix, or skip the batch?"
137
+ - **Systematic voice mismatch:** If comments consistently don't sound like the sender, flag it as a segment/prompt config issue rather than fixing each one individually.
136
138
 
137
- **Only warming, no content:** skip Step 4's content-post branch.
139
+ ### Step 8: Summary
138
140
 
139
- **Subagent can't reach Vruum MCP:** fall back to inline review. Tell the user: "Subagents can't reach Vruum MCP — run `claude mcp add --transport http --scope user vruum-local https://api.vruum.ai/mcp` once (OAuth), then retry."
141
+ After all queues are processed, present a summary:
142
+ - Total items reviewed
143
+ - Approved (with user confirmation)
144
+ - Edited and approved
145
+ - Flagged for review
146
+ - Skipped
147
+ - Plans stopped (from skip cascades)
148
+ - Content posts approved/scheduled
140
149
 
141
- **User wants to see past performance before approving content:** `get_content_review` already returns past performance stats per post — reference them in your presentation so the user can calibrate.
150
+ ## Edge cases
142
151
 
143
- ## After triage
152
+ - Queue <= 10 items: skip subagent dispatch, review inline
153
+ - Single item: review directly, no subagents
154
+ - Subagent MCP errors: fall back to inline review
155
+ - **Homogeneous pattern detected**: If first batch all has the same issue, apply fix to remaining without more agents. Confirm with the user first.
144
156
 
145
- Offer:
146
- - "Want to review your outreach queue next?" (runs `/outreach-triage`)
147
- - "Check your marketing overview?" (calls `get_marketing_overview` for a recap)
@@ -0,0 +1,59 @@
1
+ # Subagent Instructions: Content Post Review Agent
2
+
3
+ You are reviewing LinkedIn post drafts before they go to a human operator for approval. These posts are public and brand-facing. Quality bar is higher than engagement comments.
4
+
5
+ ## Step 1: Load your posts
6
+
7
+ Call `get_content_review`. This returns for each post:
8
+ - The draft content, type, tags, status, scheduled date
9
+ - Past performance stats (avg engagement for same content type)
10
+ - Calendar neighbors (other posts within 3 days)
11
+ - Tone instructions from company settings
12
+
13
+ ## Step 2: Review each post
14
+
15
+ ### 2a. Topic freshness
16
+ Check calendar neighbors. If a similar topic was published or scheduled within the last 2 weeks, flag: "similar topic covered recently: [post_id]".
17
+
18
+ ### 2b. Post structure
19
+ LinkedIn posts that perform well:
20
+ - Strong hook in first line (no more than 8 words)
21
+ - White space aggressively used, short paragraphs or single-line statements
22
+ - Ends with a question or clear takeaway, never a CTA to buy
23
+ - No more than 1-2 hashtags
24
+ - No bullet-point overload (3 max)
25
+
26
+ Flag if: generic opening line, one dense text block, 3+ hashtags, direct product pitch.
27
+
28
+ ### 2c. Brand voice
29
+ Check against `content_tone_instructions`. Common failures:
30
+ - Uses first-person plural ("we've seen") when instructions say first-person singular
31
+ - Too formal when brand voice calls for conversational
32
+ - Uses banned words (moreover, furthermore, additionally, etc.)
33
+
34
+ ### 2d. Factual claims
35
+ If the post makes specific claims (statistics, market sizes), flag as "unverified claim: [the claim]". Do not verify, let the human decide.
36
+
37
+ ## Step 3: Edit if needed
38
+
39
+ For structural issues (no line breaks, weak hook), use `manage_content_post` with action="edit". For brand voice and factual issues, FLAG rather than edit.
40
+
41
+ ## Step 4: Return structured summary
42
+
43
+ ```
44
+ POST: {post_id}
45
+ CONTENT_TYPE: {original|repost_commentary|video_script}
46
+ SCHEDULED: {scheduled_at or "unscheduled"}
47
+ RECOMMENDATION: {approve | edited | flag | reject}
48
+ CONFIDENCE: {high | medium | low}
49
+ REASONING: {1-2 sentences}
50
+ EDITED: {yes/no}
51
+ ISSUES_FOUND: {comma-separated or "none"}
52
+ ---
53
+ ```
54
+
55
+ ## Confidence Guide
56
+
57
+ **HIGH**: Well-structured, on-brand, no duplicate topics, no suspicious claims.
58
+ **MEDIUM**: Needed structural fixes, or topic is adjacent to a recent post but different enough.
59
+ **LOW**: Topic repetition, factual claims to verify, or brand voice issues.
@@ -0,0 +1,79 @@
1
+ # Subagent Instructions: Engagement Review Agent
2
+
3
+ You are reviewing AI-generated LinkedIn engagement items (comments, reactions, reposts) before they go to a human operator for approval.
4
+
5
+ ## Step 1: Load your items
6
+
7
+ Call `get_engagement_review` with your assigned `engagement_ids`, `content_length="full"`. This returns for each item:
8
+ - The draft comment text (if comment or repost_commentary)
9
+ - The reaction type (if reaction)
10
+ - The target post text (what the prospect posted)
11
+ - Person info: name, title, match score, segment, outreach plan status
12
+ - Warming/nurture progress: e.g. "2/4 warming engagements sent"
13
+ - Source: warming, nurture, or marketing
14
+ - ICP match reasoning
15
+ - Budget status for the sender account
16
+
17
+ ## Step 2: Review each item
18
+
19
+ ### 2a. Relevance check
20
+ Does the comment address something specific in the post? A comment that could apply to any post fails.
21
+ - Bad: "Great insights here. Definitely something to think about."
22
+ - Good: "The stat on ramp time resonating, we've seen similar patterns when hiring reps with zero SDR background"
23
+
24
+ ### 2b. AI tell detection
25
+ Comments are short (under 300 chars). They fail fast if robotic.
26
+ Check for:
27
+ - Generic opener ("Great post!", "Loved this!", "So true!")
28
+ - Transition words: moreover, furthermore, additionally
29
+ - Emoji overuse (one is fine, three or more is a tell)
30
+ - Round numbers that feel fabricated ("100% agree")
31
+ - Commenting on something not in the post text (hallucination)
32
+ - Em dashes (banned)
33
+
34
+ ### 2c. Relationship stage fit
35
+ - **Warming**: purely value-add, never reference the outreach company's services. Read like a thoughtful peer.
36
+ - **Nurture**: slightly warmer but still not salesy. Reference shared context only if genuinely relevant.
37
+ - **Marketing**: professional and non-salesy. Represents the sender's professional brand.
38
+
39
+ ### 2d. Reactions
40
+ If engagement_type = reaction, confirm the reaction_type fits:
41
+ - like/thumbs_up: most posts
42
+ - celebrate: milestones/announcements
43
+ - support: challenges/difficulties
44
+ Flag if the reaction type seems wrong for the post context.
45
+
46
+ ### 2e. Budget check
47
+ If `budget_status` shows the sender account is near daily limits, note it in REASONING.
48
+
49
+ ## Step 3: Edit if needed
50
+
51
+ Use `manage_engagement` with action="edit" and the engagement_id to update content.
52
+ - Keep to 1-3 sentences max
53
+ - Make it specific to the post
54
+ - Sound like a real person's quick reaction
55
+ - No em dashes
56
+ - Vary sentence rhythm
57
+
58
+ ## Step 4: Return structured summary
59
+
60
+ For each item:
61
+ ```
62
+ ENGAGEMENT: {engagement_id}
63
+ PERSON: {person_name} ({person_title})
64
+ TYPE: {comment|reaction|repost_commentary}
65
+ SOURCE: {warming|nurture|marketing}
66
+ RECOMMENDATION: {approve | edited | flag | reject}
67
+ CONFIDENCE: {high | medium | low}
68
+ REASONING: {1 sentence}
69
+ EDITED: {yes/no}
70
+ NEW_CONTENT: {if edited}
71
+ ISSUES_FOUND: {comma-separated or "none"}
72
+ ---
73
+ ```
74
+
75
+ ## Confidence Guide
76
+
77
+ **HIGH**: Specific, human-sounding, correctly staged. No edits or minor word changes only.
78
+ **MEDIUM**: Acceptable but substantive edits made, or relationship stage fit is uncertain.
79
+ **LOW**: References things not in the post, clearly generic, or stage fit is wrong. Flag for human.
@@ -0,0 +1,45 @@
1
+ # Engagement Comment Quality Standards
2
+
3
+ These apply to LinkedIn comments and reposts in the engagement queue.
4
+
5
+ ## Universal rules
6
+
7
+ - Never generic: a comment that could apply to any post fails immediately
8
+ - Under 300 characters, hard limit
9
+ - No em dashes, ever
10
+ - No "Great post!", "Love this!", or any pure agreement opener without substance
11
+ - One emoji maximum. Zero is fine.
12
+ - Reference something specific from the post: a number, an example, a named decision
13
+ - No transition words: moreover, furthermore, additionally
14
+ - No AI vocabulary: delve, crucial, robust, comprehensive, nuanced, pivotal
15
+ - Vary sentence rhythm even in short comments
16
+ - Sound like typing fast, not crafting a message
17
+
18
+ ## Warming-specific
19
+
20
+ - Zero product or service references, ever
21
+ - Read like a thoughtful industry peer, not a vendor
22
+ - Never reference the sender's company by name
23
+ - Never imply prior familiarity unless there is actual history
24
+
25
+ ## Nurture-specific
26
+
27
+ - Can be slightly warmer than warming
28
+ - May reference shared context only if genuinely relevant
29
+ - Still not salesy. No pitch. No ask.
30
+
31
+ ## Marketing-specific
32
+
33
+ - Professional and non-salesy
34
+ - Represents the sender's professional brand
35
+ - Can express opinions and takes
36
+ - Can share relevant experience from the sender's domain
37
+
38
+ ## Content post standards
39
+
40
+ - Strong hook (first line, under 8 words)
41
+ - White space: short paragraphs, single-line punchy statements
42
+ - Ends with a question or clear takeaway, never a CTA to buy
43
+ - 1-2 hashtags maximum
44
+ - No bullet-point overload (3 max)
45
+ - Must match content_tone_instructions from company settings
@@ -1,6 +1,10 @@
1
1
  ---
2
2
  name: enrich-prospect
3
- description: "Deep prospect diarization — synthesize everything known about a person into a structured intelligence profile. Use when: enrich prospect, deep research, profile this person, who is this person, research prospect, diarize prospect, prospect briefing."
3
+ description: >-
4
+ Deep prospect diarization — synthesize everything known about a person into a
5
+ structured intelligence profile. Use when: enrich prospect, deep research,
6
+ profile this person, who is this person, research prospect, diarize prospect,
7
+ prospect briefing.
4
8
  ---
5
9
 
6
10
  # /enrich-prospect
@@ -11,7 +15,7 @@ This is not a database lookup. This is an analyst's brief.
11
15
 
12
16
  ## Step 1: Gather all sources
13
17
 
14
- Call these in parallel with `for_company`:
18
+ Call these in parallel:
15
19
  - `get_person_360` — profile, match analysis, research, activity, outreach plan, deal
16
20
  - `get_person_research` — structured research data (if exists)
17
21
  - `get_company_research` — company intelligence
@@ -19,7 +23,7 @@ Call these in parallel with `for_company`:
19
23
  If research is thin (no person_research, or match_analysis is null):
20
24
  - `fetch_linkedin_data` — pull their recent posts and profile
21
25
  - WebSearch for "[person name] [company name]" — recent news, talks, publications
22
- - `search_knowledge_base` with `for_company` — relevant sales docs
26
+ - `search_knowledge_base` — relevant sales docs
23
27
 
24
28
  ## Step 2: Diarize
25
29