@vruum/skills 0.6.44 → 0.6.46

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.44",
3
+ "version": "0.6.46",
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.44",
3
+ "version": "0.6.46",
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
@@ -4,7 +4,11 @@ Vruum AI skills for Claude Code, Codex CLI, and any AI assistant with a skill di
4
4
 
5
5
  Once installed, run `/vruum-guide` in your harness — it takes you from an empty account to your first reviewed outreach draft, then keeps recommending the next most valuable action.
6
6
 
7
- Pairs with the Vruum MCP server at [https://api.vruum.ai/mcp](https://api.vruum.ai/mcp). The MCP server exposes the `skill` tool (action=invoke to run a skill, action=publish to publish one), with `search` type=skills and `fetch` type=skill for discovery, so any connected client can run these skills. Skills themselves are distributed via the Claude Code plugin / marketplace; this npm package installs them into the agent-standard skills directory for harnesses without plugin support (Codex CLI, ChatGPT, Windsurf).
7
+ Pairs with the Vruum MCP server at [https://api.vruum.ai/mcp](https://api.vruum.ai/mcp). The MCP server exposes the `skill` tool (action=invoke to run a skill, action=publish to publish one), with `search` type=skills and `fetch` type=skill for discovery, so any connected client can run these skills. This package installs Vruum-shipped skills into the standard skill directories used by Claude Code, Codex CLI, and other compatible harnesses.
8
+
9
+ You do not need `@vruum/cli` to use Vruum. Connect the Vruum MCP and install
10
+ this skills package; the CLI is optional for local files, scripting, CI, auth
11
+ debugging, and the convenience `vruum init` command.
8
12
 
9
13
  ## Install
10
14
 
@@ -20,7 +24,15 @@ Add to `~/.claude.json`:
20
24
  }
21
25
  ```
22
26
 
23
- Install the skills via the Claude Code plugin / marketplace (below); the MCP server provides the `skill` tool (action=invoke). You don't need this npm package for Claude Code.
27
+ Install through the Claude Code plugin / marketplace when available. Otherwise
28
+ install the skills directly:
29
+
30
+ ```sh
31
+ npx --yes @vruum/skills@latest install
32
+ ```
33
+
34
+ Restart Claude Code afterward. On Windows, the installer uses directory
35
+ junctions and does not require Administrator access or Developer Mode.
24
36
 
25
37
  ### Codex CLI
26
38
 
@@ -41,8 +53,8 @@ url = "https://api.vruum.ai/mcp"
41
53
  ```
42
54
 
43
55
  ```bash
44
- npx @vruum/skills install # detects ~/.agents/skills/
45
- npx @vruum/skills install --target /path/to/skills/dir # any other harness
56
+ npx --yes @vruum/skills@latest install # detects ~/.agents/skills/
57
+ npx --yes @vruum/skills@latest install --target /path/to/skills/dir # any other harness
46
58
  ```
47
59
 
48
60
  ### Cursor / VS Code Copilot / Cline
@@ -60,7 +72,7 @@ Download and upload via **Settings → Customize → Plugins → "+"**.
60
72
  ### ChatGPT / Windsurf / other harnesses without plugin support
61
73
 
62
74
  ```bash
63
- npx @vruum/skills install --target /path/to/skills/dir
75
+ npx --yes @vruum/skills@latest install --target /path/to/skills/dir
64
76
  ```
65
77
 
66
78
  ## Coexisting with operator skills
@@ -99,16 +111,16 @@ the public skill instead of leaving a broken link.
99
111
  Skills auto-prompt to upgrade via the preamble. To upgrade explicitly:
100
112
 
101
113
  ```bash
102
- npx @vruum/skills install
114
+ npx --yes @vruum/skills@latest install
103
115
  ```
104
116
 
105
117
  ## Uninstall
106
118
 
107
119
  ```bash
108
- npx @vruum/skills uninstall
120
+ npx --yes @vruum/skills@latest uninstall
109
121
  ```
110
122
 
111
- Removes all symlinks this installer created. Does not touch `~/.vruum/auth.json` or other co-resident tool state.
123
+ Removes all links or Windows junctions this installer created. Does not touch `~/.vruum/auth.json` or other co-resident tool state.
112
124
 
113
125
  ## Links
114
126
 
package/install.js CHANGED
@@ -119,15 +119,15 @@ function printHelp() {
119
119
  console.log(`@vruum/skills v${VERSION}
120
120
 
121
121
  Usage:
122
- npx @vruum/skills install Install into every detected harness
123
- npx @vruum/skills install --target <dir> Add an extra target (repeatable)
124
- npx @vruum/skills install --dry-run Preview changes, don't touch disk
125
- npx @vruum/skills uninstall Remove previously-installed symlinks
126
- npx @vruum/skills list Show detected targets + what's installed
122
+ npx --yes @vruum/skills@latest install Install into every detected harness
123
+ npx --yes @vruum/skills@latest install --target <dir> Add an extra target (repeatable)
124
+ npx --yes @vruum/skills@latest install --dry-run Preview changes, don't touch disk
125
+ npx --yes @vruum/skills@latest uninstall Remove installed links or junctions
126
+ npx --yes @vruum/skills@latest list Show detected targets + what's installed
127
127
 
128
128
  Pairs with the Vruum MCP server at https://api.vruum.ai/mcp, which provides
129
- the invoke_skill tool. This installer puts the SKILL.md files into a harness's
130
- local skill directory so the skills are available there too.
129
+ the skill tool (action=invoke). This installer puts the SKILL.md files into a
130
+ harness's local skill directory so the skills are available there too.
131
131
 
132
132
  Supported auto-detection:
133
133
  - Claude Code ~/.claude/skills/
@@ -135,10 +135,9 @@ Supported auto-detection:
135
135
 
136
136
  Any other harness: pass --target <its skills directory>.
137
137
 
138
- Note: for Claude Code, install the skills via the Vruum plugin / marketplace
139
- instead of this installer. This installer is for Codex CLI, ChatGPT, Windsurf,
140
- and other assistants without plugin support. In every case the MCP server's
141
- invoke_skill tool can run a skill on demand.`);
138
+ For Claude Code, prefer the Vruum plugin / marketplace when available;
139
+ otherwise this installer auto-detects ~/.claude/skills. The Vruum CLI is not
140
+ required. Restart the harness after installation so it discovers the skills.`);
142
141
  }
143
142
 
144
143
  function listAvailableSkills() {
@@ -196,6 +195,45 @@ function syncVruumRoot({ dryRun }) {
196
195
  return rows;
197
196
  }
198
197
 
198
+ function pathApiFor(platform) {
199
+ return platform === 'win32' ? path.win32 : path.posix;
200
+ }
201
+
202
+ function normalizePathForComparison(value, platform = process.platform) {
203
+ const pathApi = pathApiFor(platform);
204
+ let normalized = pathApi.resolve(value);
205
+ if (platform === 'win32') {
206
+ // Junction readlink results may use a \\?\ namespace prefix and different
207
+ // casing from os.homedir(). Normalize both forms for identity/ownership.
208
+ normalized = pathApi.toNamespacedPath(normalized).toLowerCase();
209
+ }
210
+ const root = pathApi.parse(normalized).root;
211
+ while (normalized.length > root.length && normalized.endsWith(pathApi.sep)) {
212
+ normalized = normalized.slice(0, -1);
213
+ }
214
+ return normalized;
215
+ }
216
+
217
+ function pathsEqual(left, right, platform = process.platform) {
218
+ return normalizePathForComparison(left, platform)
219
+ === normalizePathForComparison(right, platform);
220
+ }
221
+
222
+ function pathIsWithin(candidate, root, platform = process.platform) {
223
+ const pathApi = pathApiFor(platform);
224
+ const normalizedCandidate = normalizePathForComparison(candidate, platform);
225
+ const normalizedRoot = normalizePathForComparison(root, platform);
226
+ return normalizedCandidate === normalizedRoot
227
+ || normalizedCandidate.startsWith(normalizedRoot + pathApi.sep);
228
+ }
229
+
230
+ function resolveLinkTarget(dst, linkTarget, platform = process.platform) {
231
+ const pathApi = pathApiFor(platform);
232
+ return pathApi.isAbsolute(linkTarget)
233
+ ? pathApi.resolve(linkTarget)
234
+ : pathApi.resolve(pathApi.dirname(dst), linkTarget);
235
+ }
236
+
199
237
  // A symlink is "ours" if its target resolves into ~/.vruum/skills/. Resolve
200
238
  // textually from the readlink string (relative links against the link's own
201
239
  // dir) — never realpathSync, which THROWS on a dangling link, i.e. exactly the
@@ -204,21 +242,14 @@ function syncVruumRoot({ dryRun }) {
204
242
  // ~/.vruum/skills-operator, so a bare startsWith would wrongly claim the
205
243
  // operator installer's links. Equality covers a link straight at the dir.
206
244
  function isOurLink(dst, linkTarget) {
207
- const resolved = path.isAbsolute(linkTarget)
208
- ? path.resolve(linkTarget)
209
- : path.resolve(path.dirname(dst), linkTarget);
210
- return resolved === VRUUM_SKILLS || resolved.startsWith(VRUUM_SKILLS + path.sep);
245
+ return pathIsWithin(resolveLinkTarget(dst, linkTarget), VRUUM_SKILLS);
211
246
  }
212
247
 
213
248
  // Operator skills are a strict superset with multi-company scoping. When both
214
249
  // installers are present, operator links win for overlapping names regardless
215
250
  // of install order. Public-only names still link normally.
216
251
  function isOperatorLink(dst, linkTarget) {
217
- const resolved = path.isAbsolute(linkTarget)
218
- ? path.resolve(linkTarget)
219
- : path.resolve(path.dirname(dst), linkTarget);
220
- return resolved === VRUUM_OPERATOR_ROOT
221
- || resolved.startsWith(VRUUM_OPERATOR_ROOT + path.sep);
252
+ return pathIsWithin(resolveLinkTarget(dst, linkTarget), VRUUM_OPERATOR_ROOT);
222
253
  }
223
254
 
224
255
  function hasSkillFile(dir) {
@@ -297,14 +328,12 @@ function linkSkill({ name, srcAbs, target, dryRun }) {
297
328
  if (err.code !== 'ENOENT') throw err;
298
329
  }
299
330
 
300
- if (existing?.kind === 'symlink' && existing.target === srcAbs) {
301
- return { name, target, action: 'already-linked' };
302
- }
303
331
  const resolvedExistingTarget = existing?.kind === 'symlink'
304
- ? (path.isAbsolute(existing.target)
305
- ? path.resolve(existing.target)
306
- : path.resolve(path.dirname(dst), existing.target))
332
+ ? resolveLinkTarget(dst, existing.target)
307
333
  : null;
334
+ if (resolvedExistingTarget && pathsEqual(resolvedExistingTarget, srcAbs)) {
335
+ return { name, target, action: 'already-linked' };
336
+ }
308
337
  const operatorSkillIsUsable = resolvedExistingTarget
309
338
  && isOperatorLink(dst, existing.target)
310
339
  && hasSkillFile(resolvedExistingTarget);
@@ -330,7 +359,9 @@ function linkSkill({ name, srcAbs, target, dryRun }) {
330
359
  if (existing?.kind === 'symlink') {
331
360
  fs.unlinkSync(dst);
332
361
  }
333
- fs.symlinkSync(srcAbs, dst, 'dir');
362
+ // Windows directory symlinks require Developer Mode or elevation. Directory
363
+ // junctions work for this absolute, same-machine target without either.
364
+ fs.symlinkSync(srcAbs, dst, process.platform === 'win32' ? 'junction' : 'dir');
334
365
  return { name, target, action: existing ? 'relinked' : 'linked' };
335
366
  }
336
367
 
@@ -545,7 +576,7 @@ function commandList({ targets: extraTargets }) {
545
576
  const lstat = fs.lstatSync(dst);
546
577
  if (lstat.isSymbolicLink()) {
547
578
  const linkTarget = fs.readlinkSync(dst);
548
- const match = linkTarget === srcAbs;
579
+ const match = pathsEqual(resolveLinkTarget(dst, linkTarget), srcAbs);
549
580
  console.log(` ${match ? 'installed' : 'other-link'.padEnd(10)} ${skillName}${match ? '' : ` -> ${linkTarget}`}`);
550
581
  } else {
551
582
  console.log(` present ${skillName} (not our symlink)`);
@@ -598,6 +629,8 @@ if (require.main === module) main();
598
629
  module.exports = {
599
630
  parseArgs,
600
631
  listAvailableSkills,
632
+ pathsEqual,
633
+ pathIsWithin,
601
634
  linkSkill,
602
635
  isOurLink,
603
636
  isOperatorLink,
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@vruum/skills",
3
- "version": "0.6.44",
3
+ "version": "0.6.46",
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": {
7
7
  "type": "git",
8
- "url": "https://github.com/vruum-gtm/vruum_ai.git",
9
- "directory": ".agents"
8
+ "url": "git+https://github.com/vruum-gtm/skills.git"
10
9
  },
11
10
  "homepage": "https://vruum.ai",
12
11
  "bugs": {
@@ -42,5 +41,5 @@
42
41
  "outreach",
43
42
  "gtm"
44
43
  ],
45
- "contentHash": "dd7363b37525cb10ffce653db525fa540f3877c2fa6e72727e26b6c56e041df3"
44
+ "contentHash": "642c88b2d663edb9fc50184409cd7f569f412bc8e64bed2961c1802e85d19246"
46
45
  }