vunor 0.1.0 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vunor",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "bin": {
5
5
  "setup-skills": "./scripts/setup-skills.js"
6
6
  },
@@ -184,7 +184,8 @@
184
184
  "type-check": "vue-tsc --build --force",
185
185
  "test": "vitest run && playwright test",
186
186
  "test:e2e": "playwright test",
187
- "setup-skills": "node ./scripts/setup-skills.js"
187
+ "setup-skills": "node ./scripts/setup-skills.js",
188
+ "postinstall": "node ./scripts/setup-skills.js --postinstall"
188
189
  },
189
190
  "dependencies": {
190
191
  "@internationalized/date": "^3.11.0",
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- 'use strict'
2
+ /* prettier-ignore */
3
+ import fs from 'fs'
4
+ import path from 'path'
5
+ import os from 'os'
6
+ import { fileURLToPath } from 'url'
3
7
 
4
- const fs = require('fs')
5
- const path = require('path')
6
- const os = require('os')
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
7
9
 
8
10
  const SKILL_NAME = 'vunor'
9
-
10
- // Source skill folder ships inside this package
11
11
  const SKILL_SRC = path.join(__dirname, '..', 'skills', SKILL_NAME)
12
12
 
13
13
  if (!fs.existsSync(SKILL_SRC)) {
@@ -16,54 +16,63 @@ if (!fs.existsSync(SKILL_SRC)) {
16
16
  process.exit(1)
17
17
  }
18
18
 
19
- // Known agent skill directories (project-relative and global)
20
19
  const AGENTS = {
21
- 'Claude Code': { dir: '.claude/skills', global: path.join(os.homedir(), '.claude', 'skills') },
22
- 'Cursor': { dir: '.cursor/skills', global: path.join(os.homedir(), '.cursor', 'skills') },
23
- 'Windsurf': { dir: '.windsurf/skills', global: path.join(os.homedir(), '.windsurf', 'skills') },
24
- 'Codex': { dir: '.codex/skills', global: path.join(os.homedir(), '.codex', 'skills') },
25
- 'OpenCode': { dir: '.opencode/skills', global: path.join(os.homedir(), '.opencode', 'skills') },
20
+ 'Claude Code': { dir: '.claude/skills', global: path.join(os.homedir(), '.claude', 'skills') },
21
+ 'Cursor': { dir: '.cursor/skills', global: path.join(os.homedir(), '.cursor', 'skills') },
22
+ 'Windsurf': { dir: '.windsurf/skills', global: path.join(os.homedir(), '.windsurf', 'skills') },
23
+ 'Codex': { dir: '.codex/skills', global: path.join(os.homedir(), '.codex', 'skills') },
24
+ 'OpenCode': { dir: '.opencode/skills', global: path.join(os.homedir(), '.opencode', 'skills') },
26
25
  }
27
26
 
28
27
  const args = process.argv.slice(2)
29
28
  const isGlobal = args.includes('--global') || args.includes('-g')
30
-
31
- let installed = 0
32
- let skipped = 0
29
+ const isPostinstall = args.includes('--postinstall')
30
+ let installed = 0, skipped = 0
31
+ const installedDirs = []
33
32
 
34
33
  for (const [agentName, cfg] of Object.entries(AGENTS)) {
35
34
  const targetBase = isGlobal ? cfg.global : path.join(process.cwd(), cfg.dir)
36
- const dest = path.join(targetBase, SKILL_NAME)
35
+ const agentRootDir = path.dirname(cfg.global) // Check if the agent has ever been installed globally
37
36
 
38
- // For global installs, only write if the agent's home dir already exists
39
- // (meaning the agent is actually installed on this machine)
40
- if (isGlobal) {
41
- const agentHome = path.dirname(cfg.global)
42
- if (!fs.existsSync(agentHome)) {
43
- skipped++
44
- continue
45
- }
37
+ // In postinstall mode: silently skip agents that aren't set up globally
38
+ if (isPostinstall || isGlobal) {
39
+ if (!fs.existsSync(agentRootDir)) { skipped++; continue }
46
40
  }
47
41
 
42
+ const dest = path.join(targetBase, SKILL_NAME)
48
43
  try {
49
44
  fs.mkdirSync(dest, { recursive: true })
50
45
  fs.cpSync(SKILL_SRC, dest, { recursive: true })
51
- console.log(`\u2705 ${agentName}: installed to ${dest}`)
46
+ console.log(`✅ ${agentName}: installed to ${dest}`)
52
47
  installed++
48
+ if (!isGlobal) installedDirs.push(cfg.dir + '/' + SKILL_NAME)
53
49
  } catch (err) {
54
- console.warn(`\u26a0\ufe0f ${agentName}: failed \u2014 ${err.message}`)
50
+ console.warn(`⚠️ ${agentName}: failed ${err.message}`)
55
51
  }
56
52
  }
57
53
 
58
- if (installed === 0 && skipped === Object.keys(AGENTS).length) {
59
- console.log('No agent directories detected on this machine.')
60
- console.log('Try --global after installing an agent, or run without --global for project-local install.')
54
+ // Add locally-installed skill dirs to .gitignore
55
+ if (!isGlobal && installedDirs.length > 0) {
56
+ const gitignorePath = path.join(process.cwd(), '.gitignore')
57
+ let gitignoreContent = ''
58
+ try { gitignoreContent = fs.readFileSync(gitignorePath, 'utf8') } catch {}
59
+ const linesToAdd = installedDirs.filter(d => !gitignoreContent.includes(d))
60
+ if (linesToAdd.length > 0) {
61
+ const hasHeader = gitignoreContent.includes('# AI agent skills')
62
+ const block = (gitignoreContent && !gitignoreContent.endsWith('\n') ? '\n' : '')
63
+ + (hasHeader ? '' : '\n# AI agent skills (auto-generated by setup-skills)\n')
64
+ + linesToAdd.join('\n') + '\n'
65
+ fs.appendFileSync(gitignorePath, block)
66
+ console.log(`📝 Added ${linesToAdd.length} entries to .gitignore`)
67
+ }
68
+ }
69
+
70
+ if (installed === 0 && isPostinstall) {
71
+ // Silence is fine — no agents present, nothing to do
72
+ } else if (installed === 0 && skipped === Object.keys(AGENTS).length) {
73
+ console.log('No agent directories detected. Try --global or run without it for project-local install.')
61
74
  } else if (installed === 0) {
62
75
  console.log('Nothing installed. Run without --global to install project-locally.')
63
76
  } else {
64
- console.log(`\n\u2728 Done! Restart your AI agent to pick up the "${SKILL_NAME}" skill.`)
65
- if (!isGlobal) {
66
- console.log('Tip: commit the generated .*/skills/ directories to share skills with your team.')
67
- console.log(' Or add them to .gitignore if you prefer each developer to opt in.')
68
- }
77
+ console.log(`\n Done! Restart your AI agent to pick up the "${SKILL_NAME}" skill.`)
69
78
  }