@vruum/skills 0.6.16 → 0.6.18
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.18",
|
|
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.18",
|
|
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/README.md
CHANGED
|
@@ -76,6 +76,7 @@ npx @vruum/skills install --target /path/to/skills/dir
|
|
|
76
76
|
- `/engagement-triage` — 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.
|
|
77
77
|
- `/enrich-prospect` — 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.
|
|
78
78
|
- `/expansion-fill` — Source expansion-ready customers for outreach. Finds closed-won customers >60 days old with no open follow-on deal and surfaces them for an expansion play. Use when: expand customer, find upsell opportunities, NRR play, expansion opportunities, customers ripe for expansion, who can we expand to.
|
|
79
|
+
- `/ingest-meetings` — Pull meeting transcripts from your connected Google Drive into Vruum. Attaches each transcript to the right person and deal as a meeting on their timeline, and turns its action items into tasks that surface in your daily briefing. You review every attach before anything is written; safe to re-run. Use when: ingest meetings, import meeting notes, pull transcripts, log my meetings, action items from meetings, Gemini notes, Read.ai transcripts, turn meetings into tasks.
|
|
79
80
|
- `/outreach-triage` — Review and approve your pending outreach drafts across LinkedIn and email. Use when: triage, review queue, morning review, check messages, approve outreach, what needs review.
|
|
80
81
|
- `/pipeline-fill` — Source-agnostic pipeline orchestrator. Picks a source per segment (Sales Nav / YC / CSV / discovery), runs harness deep research, applies a pre-filter gate, then saves into the segment via the backend authoritative match_score>=70 gate. Use when: fill pipeline, import prospects, daily imports, need more prospects, discover prospects from scratch, deep research before import.
|
|
81
82
|
- `/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.
|
|
@@ -21,7 +21,9 @@ CONFIG_FILE="$STATE_DIR/config.yaml"
|
|
|
21
21
|
REMOTE_URL="${VRUUM_REMOTE_URL:-https://registry.npmjs.org/@vruum/skills/latest}"
|
|
22
22
|
|
|
23
23
|
# Force flag busts cache + snooze (used by /vruum-skills-upgrade directly)
|
|
24
|
+
FORCE=0
|
|
24
25
|
if [ "${1:-}" = "--force" ]; then
|
|
26
|
+
FORCE=1
|
|
25
27
|
rm -f "$CACHE_FILE" "$SNOOZE_FILE"
|
|
26
28
|
fi
|
|
27
29
|
|
|
@@ -75,6 +77,7 @@ if [ -f "$CACHE_FILE" ]; then
|
|
|
75
77
|
case "$CACHED" in
|
|
76
78
|
UP_TO_DATE*) TTL=60 ;;
|
|
77
79
|
UPGRADE_AVAILABLE*) TTL=720 ;;
|
|
80
|
+
CHECK_FAILED*) TTL=30 ;;
|
|
78
81
|
*) TTL=0 ;;
|
|
79
82
|
esac
|
|
80
83
|
STALE=$(find "$CACHE_FILE" -mmin +"$TTL" 2>/dev/null || true)
|
|
@@ -93,6 +96,12 @@ if [ -f "$CACHE_FILE" ]; then
|
|
|
93
96
|
exit 0
|
|
94
97
|
fi
|
|
95
98
|
;;
|
|
99
|
+
CHECK_FAILED*)
|
|
100
|
+
# Recent fetch failure cached — stay quiet and do NOT imply "up to
|
|
101
|
+
# date". Retry once the short TTL expires. A --force run never reaches
|
|
102
|
+
# here (it cleared the cache above), so it always re-fetches.
|
|
103
|
+
exit 0
|
|
104
|
+
;;
|
|
96
105
|
esac
|
|
97
106
|
fi
|
|
98
107
|
fi
|
|
@@ -100,13 +109,24 @@ fi
|
|
|
100
109
|
# Step 5: slow path — fetch latest from npm registry.
|
|
101
110
|
mkdir -p "$STATE_DIR"
|
|
102
111
|
RESP="$(curl -fsSL --max-time 5 "$REMOTE_URL" 2>/dev/null || true)"
|
|
103
|
-
# Extract "version":"X.Y.Z" without jq.
|
|
104
|
-
|
|
112
|
+
# Extract "version":"X.Y.Z" without jq. The trailing `|| true` is load-bearing
|
|
113
|
+
# under `set -euo pipefail`: on a failed/empty fetch the grep matches nothing
|
|
114
|
+
# and (with pipefail) the pipeline exits non-zero, which would errexit the whole
|
|
115
|
+
# script mid-way — the original silent-failure path. Swallow it so REMOTE ends
|
|
116
|
+
# up empty and the unreachable-registry branch below handles it deliberately.
|
|
117
|
+
REMOTE="$(echo "$RESP" | grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' | head -1 | sed -E 's/.*"([^"]+)"$/\1/' || true)"
|
|
105
118
|
REMOTE="$(echo "$REMOTE" | tr -d '[:space:]')"
|
|
106
119
|
|
|
107
|
-
#
|
|
120
|
+
# Registry unreachable or unparseable response. A failed fetch is NOT evidence
|
|
121
|
+
# the local version is current — caching UP_TO_DATE here is the false-positive
|
|
122
|
+
# that pinned a sandboxed client to a stale bundle: its forced check returned
|
|
123
|
+
# nothing, which /vruum-skills-upgrade reads as "already on latest". Cache a
|
|
124
|
+
# short-lived CHECK_FAILED marker so passive checks don't hammer the registry,
|
|
125
|
+
# but never claim current. A forced check surfaces the failure so the user
|
|
126
|
+
# knows it couldn't run (vs. a real up-to-date).
|
|
108
127
|
if ! echo "$REMOTE" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
|
|
109
|
-
echo "
|
|
128
|
+
echo "CHECK_FAILED $LOCAL $(date +%s)" > "$CACHE_FILE"
|
|
129
|
+
if [ "$FORCE" = 1 ]; then echo "CHECK_FAILED $LOCAL"; fi
|
|
110
130
|
exit 0
|
|
111
131
|
fi
|
|
112
132
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vruum/skills",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.18",
|
|
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": {
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"outreach",
|
|
43
43
|
"gtm"
|
|
44
44
|
],
|
|
45
|
-
"contentHash": "
|
|
45
|
+
"contentHash": "c8ff45027670bb35cdb93bdb0301d9ce9faacb739eefcbe7efdf0bc699942051"
|
|
46
46
|
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ingest-meetings
|
|
3
|
+
description: >-
|
|
4
|
+
Pull meeting transcripts from your connected Google Drive into Vruum. Attaches
|
|
5
|
+
each transcript to the right person and deal as a meeting on their timeline,
|
|
6
|
+
and turns its action items into tasks that surface in your daily briefing. You
|
|
7
|
+
review every attach before anything is written; safe to re-run. Use when:
|
|
8
|
+
ingest meetings, import meeting notes, pull transcripts, log my meetings,
|
|
9
|
+
action items from meetings, Gemini notes, Read.ai transcripts, turn meetings
|
|
10
|
+
into tasks.
|
|
11
|
+
---
|
|
12
|
+
# /ingest-meetings
|
|
13
|
+
|
|
14
|
+
Your meeting transcripts (Gemini Meet auto-notes, Read.ai reports) land in Google Drive. With Drive connected to Vruum, those transcripts sync into your knowledge base — but on their own they're just searchable text. This skill turns them into CRM activity: each transcript gets **attached to the right person and deal as a meeting** on their timeline, and its **action items become Vruum tasks** that show up in your daily briefing.
|
|
15
|
+
|
|
16
|
+
This is an analyst's job, not a batch import. The attribution step (which person? which deal?) is where a wrong guess does real damage — a meeting logged on the wrong account misleads whoever reads it next. So **you confirm every attach before anything is written**, the skill never auto-attaches an ambiguous match, and it's **safe to re-run** (already-logged meetings and tasks are skipped, not duplicated).
|
|
17
|
+
|
|
18
|
+
## What this needs
|
|
19
|
+
|
|
20
|
+
- **Drive connected to Vruum.** The transcripts must be syncing into the knowledge base via the connector. If KB search turns up none of your recent meetings, the connection may be down or PDFs may not be admitted — say so and stop; this skill reads what's synced, it doesn't fix the connector.
|
|
21
|
+
- **Vruum MCP** for: `search` (kb + people reads), `get_person_360`, `manage_person` (to log the meeting as a `meeting`-kind interaction), `manage_tasks`, `get_tasks`.
|
|
22
|
+
|
|
23
|
+
### Step 1 — Find the transcripts
|
|
24
|
+
|
|
25
|
+
Search the knowledge base for meeting-shaped documents:
|
|
26
|
+
|
|
27
|
+
- `search` type=kb with `filters={query: "meeting notes transcript", include_content: false}` for a compact catalog (id, name, summary, date).
|
|
28
|
+
- Identify transcripts by their **filename shape**, not just the query — these tools name files predictably:
|
|
29
|
+
- **Gemini:** `… - Notes by Gemini`, `Notes by Gemini for …`, `… - Transcript`, `… - Live Notes`
|
|
30
|
+
- **Read.ai:** `… - Read Meeting Report`, `Read AI …`, `… Smart Notes`
|
|
31
|
+
- Default to a **recent window** (e.g. the last 2 weeks) unless the user asks for more.
|
|
32
|
+
- Present the candidates as a short list: `name · meeting date · one-line summary`. Ask which to process (default: **all that aren't already logged** — Step 5 detects those).
|
|
33
|
+
|
|
34
|
+
> Alternative source: if you have a Google Drive MCP pointed at the same Drive and a transcript hasn't synced into the KB yet, you can read it directly (`search_files` → `read_file_content` for Docs, `download_file_content` for Read.ai PDFs) and feed the text into Step 3. Lead with the KB — it's tenant-scoped and is what the connector already pulled.
|
|
35
|
+
|
|
36
|
+
### Step 2 — Read each chosen transcript in full
|
|
37
|
+
|
|
38
|
+
`search` type=kb with `filters={document_id: "<doc_id>", include_content: true}` returns the full document text. You need the whole transcript (attendees + the discussion), not a search snippet.
|
|
39
|
+
|
|
40
|
+
### Step 3 — Resolve the entity (the careful step)
|
|
41
|
+
|
|
42
|
+
For each transcript, work out **which person** it's with and **which deal** it belongs to. Mis-attribution is worse than no attribution — when in doubt, ask.
|
|
43
|
+
|
|
44
|
+
1. **Pull the attendees** from the transcript text (Gemini and Read.ai both list participants, usually with emails).
|
|
45
|
+
2. **Drop the internal side:** ignore attendees on your own company's email domain (that's you / your team, not the prospect). Ignore bare free-provider addresses (gmail.com, outlook.com, …) unless that's the only handle you have and the name clearly matches.
|
|
46
|
+
3. For each remaining external attendee, resolve against the pipeline:
|
|
47
|
+
- `search` type=people with `query=<attendee email>` (exact email is the strongest key).
|
|
48
|
+
- If email finds nothing, try `query=<full name>` and disambiguate by company.
|
|
49
|
+
4. **Exactly one confident match** → that's the person. Then `get_person_360` on them and pick the **open / most-recent deal** (ignore closed-won/closed-lost). If there's no deal, that's fine — attach to the person only.
|
|
50
|
+
5. **Zero matches, more than one, or low confidence** → **ask the user**: pick from the candidates, create the person (`manage_person` action=create with the attendee's name/email/company), or skip this transcript. **Never auto-attach a guess.**
|
|
51
|
+
|
|
52
|
+
### Step 4 — Extract the recap and action items (your judgment)
|
|
53
|
+
|
|
54
|
+
From the transcript text, produce:
|
|
55
|
+
|
|
56
|
+
- A **1–2 sentence recap** of what the meeting was about and where it landed.
|
|
57
|
+
- **Action items** — only concrete commitments or follow-ups that were actually stated ("send the pricing doc", "intro them to security", "follow up after their board meeting"). Do **not** turn every discussion topic into a task. For each: a short imperative `title`, the `owner` if one was named, a `due` hint if a date/timeframe was said, and a `priority` (low/medium/high). Cap at ~10 to keep signal high. If the meeting had no real follow-ups, that's fine — log the meeting with no tasks.
|
|
58
|
+
|
|
59
|
+
### Step 5 — Review (the approval gate)
|
|
60
|
+
|
|
61
|
+
Per transcript, show the user the complete proposal before writing anything:
|
|
62
|
+
|
|
63
|
+
- **Resolved entity:** person (+ company) and the deal it'll attach to.
|
|
64
|
+
- **Meeting:** the recap + meeting date.
|
|
65
|
+
- **Tasks:** the action-item list.
|
|
66
|
+
|
|
67
|
+
**Idempotency check (do this before writing):** confirm the transcript isn't already logged — in `get_person_360` for the resolved person, scan recent **meeting** activity for the marker `[vruum-meeting:<doc_id>]` in the summary. If it's there, this transcript was already ingested → skip it (don't re-log, don't re-create tasks).
|
|
68
|
+
|
|
69
|
+
The user **approves / edits / drops individual tasks / drops the whole transcript**. Only what they approve gets written.
|
|
70
|
+
|
|
71
|
+
### Step 6 — Write (only the approved items)
|
|
72
|
+
|
|
73
|
+
For each approved transcript:
|
|
74
|
+
|
|
75
|
+
1. **Log the meeting** — call `manage_person` with the action that records a manual interaction/touch (its `interaction_kind: call|email|linkedin|meeting|other` action), with:
|
|
76
|
+
- `person_id` = the resolved person
|
|
77
|
+
- `interaction_kind` = `"meeting"`
|
|
78
|
+
- `direction` = `"outbound"` (or `"inbound"` if the prospect convened it)
|
|
79
|
+
- `occurred_at` = the meeting date as ISO-8601 (from the transcript title/text; fall back to the KB doc's date)
|
|
80
|
+
- `deal_id` = the resolved deal (omit if none)
|
|
81
|
+
- `summary` =
|
|
82
|
+
```
|
|
83
|
+
<1–2 sentence recap>
|
|
84
|
+
|
|
85
|
+
Attendees: <names / emails>
|
|
86
|
+
Source: <transcript filename> — Google Drive [vruum-meeting:<doc_id>]
|
|
87
|
+
```
|
|
88
|
+
The `[vruum-meeting:<doc_id>]` marker is what makes re-runs idempotent (Step 5 scans for it). Keep it verbatim in the summary.
|
|
89
|
+
2. **Create each approved task** — `manage_tasks` action=create with:
|
|
90
|
+
- `title` (the action item), `person_id` (+ `deal_id` if there is one)
|
|
91
|
+
- `priority`, and `due_at` as ISO-8601 **only if** a date was actually parseable (omit otherwise)
|
|
92
|
+
- `assigned_to` = the rep running this (leave to self; only assign a teammate if you know their Vruum user id)
|
|
93
|
+
- `external_id` = `transcript:<doc_id>:task:<n>` — the backend dedups on this, so re-running never duplicates a task.
|
|
94
|
+
|
|
95
|
+
### Step 7 — Confirm
|
|
96
|
+
|
|
97
|
+
Report concisely: **N meetings logged, M tasks created**, and anything **skipped** (already-logged, or unresolved). Note that the tasks will now surface in `get_daily_briefing` (tasks due) and on each person's timeline (`get_person_360`). For any **unresolved** transcripts, list them so the user can create the people and re-run.
|
|
98
|
+
|
|
99
|
+
## Guardrails
|
|
100
|
+
|
|
101
|
+
- **Never attach on an ambiguous or missing match** — ask. Mis-attribution is worse than no attribution.
|
|
102
|
+
- **Never invent action items** — only commitments actually stated in the meeting.
|
|
103
|
+
- **You approve every write.** Nothing is committed without the Step 5 sign-off.
|
|
104
|
+
- **Safe to re-run.** Tasks dedup on `external_id`; meetings dedup on the `[vruum-meeting:<doc_id>]` summary marker. Running this twice on the same Drive is a no-op for already-ingested meetings.
|
|
@@ -67,10 +67,13 @@ Force a fresh check first, then run the flow above starting from Step 2:
|
|
|
67
67
|
~/.vruum/bin/vruum-skills-update-check --force
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Interpret the forced check's output:
|
|
71
|
+
- Returns nothing → genuinely up to date. Report `already on latest (v$(cat ~/.vruum/VERSION))` and exit.
|
|
72
|
+
- `CHECK_FAILED <local>` → the registry could NOT be reached (network/sandbox), so we do **not** know if you're current. Report `upgrade check failed — couldn't reach the npm registry (network/sandbox); not necessarily on latest. Try again later or from an unsandboxed shell.` Do NOT claim "already on latest." (A forced check emits this whenever the fetch fails; a sandbox that blocks the registry is the common cause.)
|
|
73
|
+
- `UPGRADE_AVAILABLE <old> <new>` → run the upgrade flow from Step 2.
|
|
71
74
|
|
|
72
75
|
## When something goes wrong
|
|
73
76
|
|
|
74
77
|
- `npm install` fails with permissions → tell the user to re-run with `sudo` or fix their npm prefix. Don't auto-sudo.
|
|
75
78
|
- `vruum-skills install` reports skipped skills → surface the conflict message verbatim; user needs to remove conflicting files.
|
|
76
|
-
- Network failure on registry lookup →
|
|
79
|
+
- Network failure on registry lookup → the forced check now emits `CHECK_FAILED <local>` (it no longer silently looks up to date). Report `upgrade check failed, try again later` and continue with the original skill (don't block work on a transient fetch error).
|