@vruum/skills 0.6.50 → 0.6.51
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vruum",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.51",
|
|
4
4
|
"description": "Vruum AI skills + remote MCP server for B2B GTM teams. Slash commands for outreach triage, engagement triage, pipeline filling, prospect enrichment, and reply diagnosis, paired with the full Vruum MCP tool surface over OAuth 2.1.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Vruum AI",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vruum",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.51",
|
|
4
4
|
"description": "Vruum AI skills + remote MCP server for B2B GTM teams. Skills for outreach triage, engagement triage, pipeline filling, prospect enrichment, and reply diagnosis, paired with the full Vruum MCP tool surface over OAuth 2.1.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Vruum AI",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vruum/skills",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.51",
|
|
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": {
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"outreach",
|
|
42
42
|
"gtm"
|
|
43
43
|
],
|
|
44
|
-
"contentHash": "
|
|
44
|
+
"contentHash": "7b005a0d67d55681a74103c681916d07dbaebfc7b86107220ac0f22d7db0a0b9"
|
|
45
45
|
}
|
|
@@ -64,7 +64,7 @@ Once the user says go (or picks a focus area), pull the lightweight message queu
|
|
|
64
64
|
|
|
65
65
|
**Frame by conversation state, not sequence number.** `first_content_touch=true` means this person has NEVER received a content-bearing message — their history is only connection requests (blank or noted). That item is an OPENER no matter its T-number (a T3 email that fell back from a never-accepted LinkedIn connect is still the first thing this person reads from the sender). `first_content_touch=false` means real prior contact exists — follow-up framing is legitimate. If the field is null/absent (rows drafted before this signal shipped, or an older backend), fall back to the sequence_number heuristic: seq 1 = opener, seq ≥2 = follow-up. The full block lives on the `get_outreach_review` item as `conversation_state` (`{v, first_content_touch, prior_context: none|note_only|inbound_only|content, connection_note_text, last_delivered_channel, designed_channel, channel_rewrite_reason, channel_fallback}`) — same absent-block fallback applies when `v` is unrecognized.
|
|
66
66
|
|
|
67
|
-
**Authoring mode (needs_draft items).** The backend no longer writes outreach prose — touches arrive as `needs_draft` items carrying the decision context (channel, touch number, signals) and no content. These are not rewrites; they are blank pages. For each needs_draft item the subagent AUTHORS the message: check the person's research freshness from the review item itself — `person_researched_at` / `company_researched_at` / `research_status` are on the payload, no extra fetch needed (older than ~14 days or missing → research first with WebSearch + the research reads, and persist what you learn via `research` action=save_person with `payload.person_id` set to the review item's person UUID (update-only — the response's `updated_fields` confirms what landed; NEVER pass the UUID as the facade `id` argument), plus action=save_company when you learned something about the company, so it compounds), then write the touch
|
|
67
|
+
**Authoring mode (needs_draft items).** The backend no longer writes outreach prose — touches arrive as `needs_draft` items carrying the decision context (channel, touch number, signals) and no content. These are not rewrites; they are blank pages. The full review item includes `manual_notes`, up to 10 recent person notes, newest first. Each note can contain 4,000 characters, each person can contain 8,000, and a full response can contain 30,000 across repeated items. A cut note ends with `...[truncated]`; never treat that incomplete note as an exact saved draft. Use the notes as seller context. When campaign instructions name a complete saved draft in `manual_notes`, treat that named draft as authoritative instead of replacing it with generic researched copy; preserve its wording unless the actual channel limit requires compression. For each needs_draft item the subagent AUTHORS the message: check the person's research freshness from the review item itself — `person_researched_at` / `company_researched_at` / `research_status` are on the payload, no extra fetch needed (older than ~14 days or missing → research first with WebSearch + the research reads, and persist what you learn via `research` action=save_person with `payload.person_id` set to the review item's person UUID (update-only — the response's `updated_fields` confirms what landed; NEVER pass the UUID as the facade `id` argument), plus action=save_company when you learned something about the company, so it compounds), then write the touch in the seller's voice against the same quality standards as any review, then check it — call `check_prose` with `{item_id: <message id>, item_type: "message", content: <draft>}` and treat the `failures[]` as an advisory checklist: fix what you agree with; severity `block` failures are hard stops that bounce at post time — today: channel character caps (cut to fit) and prior-outreach references on a first content touch (rewrite as an opener) — then submit it via `manage_messages` action=edit with the content and the returned `rules_version` as `client_rules_version` — that transitions the item to a normal draft — and approve only what the user's standing instructions allow. (The edit re-runs the same lint server-side; annotations are recorded to the label corpus, never rejected — a `block`-severity draft bounces with `prose_gate_blocked` + `failures[].fix` and a `span` naming the exact offending text.) Inbound replies also arrive as needs_draft (category inbound_reply, with the conversation attached): author the reply with full thread context. If a prospect turns out to be a bad fit at authoring time, skip the item and say why — authoring is the second qualification gate, not an obligation to write.
|
|
68
68
|
|
|
69
69
|
**Dispatch order within the authoring lane.** Pull the WARM lane directly — `search` type=messages with `warm_only=true, status=needs_draft, sort_by=expiring, fields=compact` returns exactly the LinkedIn follow-ups to accepted connections, nearest sweep deadline first, immune to page-1 truncation (warm rows are old by construction, so the default newest-first sort buries them under the cold backlog). Dispatch that lane first — they accepted the invite and the follow-up is the first real message they read. For the remaining lanes, compact rows carry `connection_status` if you need to spot stragglers, and `sort_by=expiring` works on any needs_draft pull.
|
|
70
70
|
|
|
@@ -131,7 +131,7 @@ You are an outreach review agent.
|
|
|
131
131
|
|
|
132
132
|
Message IDs: {comma_separated_message_ids}
|
|
133
133
|
|
|
134
|
-
Call get_outreach_review with message_ids="{comma_separated_message_ids}" and content_length="full" to load your assigned messages.
|
|
134
|
+
Call get_outreach_review with message_ids="{comma_separated_message_ids}" and content_length="full" to load your assigned messages. Inspect `manual_notes`; when campaign instructions name a saved draft there, treat that note as the authoritative source.
|
|
135
135
|
|
|
136
136
|
For each message:
|
|
137
137
|
1. Check structural compliance (touch sequence, char limits, channel)
|
|
@@ -158,7 +158,7 @@ Prospect: {person_name}, {title} at {company}
|
|
|
158
158
|
Message type: T{sequence_number} — frame by the item's conversation_state, NOT the T-number: first_content_touch=true means this is an OPENER (their history is only connection requests; never reference prior outreach); false means a real follow-up; block absent → treat T{sequence_number}>=2 as follow-up
|
|
159
159
|
|
|
160
160
|
Steps:
|
|
161
|
-
1. Call get_outreach_review with message_ids="{message_id}" and content_length="full" to get the current message, thread context, campaign instructions, and
|
|
161
|
+
1. Call get_outreach_review with message_ids="{message_id}" and content_length="full" to get the current message, thread context, campaign instructions, match analysis, and complete `manual_notes`. When campaign instructions name a saved draft there, treat that note as the authoritative source.
|
|
162
162
|
2. Call fetch with type=person_research plus get_person_360 for this person to get everything we know.
|
|
163
163
|
3. Call fetch with type=company_research to understand the company's product, positioning, and what problems it solves.
|
|
164
164
|
4. Search the web for this prospect and their company to understand what they actually do, what challenges they face, what they post about.
|