Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

ai-workflow-kit

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ai-workflow-kit - npm Package Compare versions

Comparing version
2.2.0-beta.2
to
2.2.0
+212
-32
bin/cli.js

@@ -6,8 +6,12 @@ #!/usr/bin/env node

* Usage:
* npx ai-workflow-kit → interactive selection menu
* npx ai-workflow-kit → interactive (asks IDE, scope, items)
* npx ai-workflow-kit --yes → install everything without prompting
* npx ai-workflow-kit --local → install into .claude/ of the current project
* npx ai-workflow-kit --local → install into .claude/ of current project
* npx ai-workflow-kit --global → install into ~/.claude/ (default)
* npx ai-workflow-kit --skills → all skills and agents only
* npx ai-workflow-kit --hooks → all hooks only
* npx ai-workflow-kit --claude → skip IDE prompt, use Claude Code
* npx ai-workflow-kit --cursor → skip IDE prompt, use Cursor
* npx ai-workflow-kit --copilot → skip IDE prompt, use GitHub Copilot
* npx ai-workflow-kit --antigravity → skip IDE prompt, use Antigravity
* npx ai-workflow-kit --skills → skills and agents only (Claude Code)
* npx ai-workflow-kit --hooks → hooks only (Claude Code)
* npx ai-workflow-kit --uninstall → remove what was installed

@@ -41,10 +45,14 @@ * npx ai-workflow-kit --list → show what would be installed

// ─── Args ────────────────────────────────────────────────────────────────────
const args = process.argv.slice(2)
const SKILLS_ONLY = args.includes('--skills')
const HOOKS_ONLY = args.includes('--hooks')
const YES = args.includes('--yes') || args.includes('-y')
const UNINSTALL = args.includes('--uninstall')
const LIST = args.includes('--list')
const FORCE_LOCAL = args.includes('--local')
const FORCE_GLOBAL = args.includes('--global')
const args = process.argv.slice(2)
const SKILLS_ONLY = args.includes('--skills')
const HOOKS_ONLY = args.includes('--hooks')
const YES = args.includes('--yes') || args.includes('-y')
const UNINSTALL = args.includes('--uninstall')
const LIST = args.includes('--list')
const FORCE_LOCAL = args.includes('--local')
const FORCE_GLOBAL = args.includes('--global')
const FORCE_CLAUDE = args.includes('--claude')
const FORCE_CURSOR = args.includes('--cursor')
const FORCE_COPILOT = args.includes('--copilot')
const FORCE_AG = args.includes('--antigravity')

@@ -70,3 +78,2 @@ // ─── Paths ───────────────────────────────────────────────────────────────────

// { src, name, isDir } — supports flat <name>.md and <name>/SKILL.md dirs
function listSkills(dir) {

@@ -87,4 +94,2 @@ if (!fs.existsSync(dir)) return []

// { src, name } — supports flat <name>.md and <name>/AGENT.md dirs
// Always installed as flat files to ~/.claude/agents/<name>.md
function listAgents(dir) {

@@ -141,4 +146,35 @@ if (!fs.existsSync(dir)) return []

// ─── Selection — step 1: categories ─────────────────────────────────────────
// ─── IDE Selection ───────────────────────────────────────────────────────────
const IDES = [
{ key: 'claude', label: 'Claude Code', hint: '~/.claude/' },
{ key: 'cursor', label: 'Cursor', hint: '.cursorrules' },
{ key: 'copilot', label: 'GitHub Copilot', hint: '.github/copilot-instructions.md' },
{ key: 'antigravity', label: 'Antigravity', hint: 'GEMINI.md + skills' },
]
async function selectIDE() {
if (FORCE_CLAUDE) return 'claude'
if (FORCE_CURSOR) return 'cursor'
if (FORCE_COPILOT) return 'copilot'
if (FORCE_AG) return 'antigravity'
if (YES || SKILLS_ONLY || HOOKS_ONLY || UNINSTALL) return 'claude'
console.log(` ${c.bold}Which IDE are you using?${c.reset}\n`)
IDES.forEach((ide, i) => {
const n = String(i + 1).padStart(2)
console.log(` ${c.cyan}${n}${c.reset} ${ide.label.padEnd(20)} ${c.dim}${ide.hint}${c.reset}`)
})
console.log()
const input = await prompt(` Enter number ${c.dim}[1-${IDES.length}]${c.reset}: `)
const n = parseInt(input, 10)
if (n >= 1 && n <= IDES.length) return IDES[n - 1].key
warn('Invalid selection, defaulting to Claude Code.')
return 'claude'
}
// ─── Selection — categories ──────────────────────────────────────────────────
async function selectCategories(allSkills, allAgents, allHooks) {

@@ -172,3 +208,3 @@ const skillNames = allSkills.map(s => s.name).join(', ')

// ─── Selection — step 2: items within a category ────────────────────────────
// ─── Selection — items ───────────────────────────────────────────────────────

@@ -233,2 +269,11 @@ async function selectItemsInCategory(items, getName) {

// ─── Antigravity — item selection ────────────────────────────────────────────
async function selectAntigravitySkills(allSkills) {
console.log(`\n${c.bold} Which skills would you like to install?${c.reset}\n`)
console.log(` ${c.dim}Enter numbers separated by spaces, or Enter for all.${c.reset}`)
return selectItemsInCategory(allSkills, s => s.name)
}
// ─── Header ──────────────────────────────────────────────────────────────────

@@ -242,14 +287,26 @@ console.log()

if (LIST) {
const skills = listSkills(path.join(REPO_ROOT, 'skills'))
const agents = listAgents(path.join(REPO_ROOT, 'agents'))
const hooks = listFiles(path.join(REPO_ROOT, 'hooks'), '.sh')
const skills = listSkills(path.join(REPO_ROOT, 'skills'))
const agents = listAgents(path.join(REPO_ROOT, 'agents'))
const hooks = listFiles(path.join(REPO_ROOT, 'hooks'), '.sh')
const agSkills = listSkills(path.join(REPO_ROOT, 'antigravity-skills'))
console.log(`${c.bold}Skills (${skills.length})${c.reset}`)
console.log(`${c.bold}Claude Code${c.reset}`)
console.log(` Skills (${skills.length}):`)
skills.forEach(s => dim(`/${s.name}`))
console.log(`\n${c.bold}Agents (${agents.length})${c.reset}`)
console.log(` Agents (${agents.length}):`)
agents.forEach(a => dim(`/${a.name}`))
console.log(` Hooks (${hooks.length}):`)
hooks.forEach(f => dim(path.basename(f)))
console.log(`\n${c.bold}Hooks (${hooks.length})${c.reset}`)
hooks.forEach(f => dim(path.basename(f)))
console.log(`\n${c.bold}Cursor${c.reset}`)
dim('.cursorrules')
console.log(`\n${c.bold}GitHub Copilot${c.reset}`)
dim('.github/copilot-instructions.md')
console.log(`\n${c.bold}Antigravity${c.reset}`)
console.log(` Skills (${agSkills.length}):`)
agSkills.forEach(s => dim(`@${s.name}`))
dim('GEMINI.md')
console.log()

@@ -259,4 +316,128 @@ process.exit(0)

// ─── Resolve scope (local vs global) ─────────────────────────────────────────
// ─── IDE Selection ────────────────────────────────────────────────────────────
const ide = await selectIDE()
console.log()
// ─── Cursor ──────────────────────────────────────────────────────────────────
if (ide === 'cursor') {
const src = path.join(REPO_ROOT, '.cursorrules')
const dst = path.join(process.cwd(), '.cursorrules')
if (!fs.existsSync(src)) {
warn('.cursorrules file not found in the kit.')
process.exit(1)
}
if (fs.existsSync(dst) && !YES) {
const overwrite = await ask('.cursorrules already exists in this project. Overwrite?')
if (!overwrite) { info('Skipped.'); process.exit(0) }
}
copyFile(src, dst)
console.log()
console.log(`${c.bold} ─────────────────────────────${c.reset}`)
console.log(`${c.bold}${c.green} Installation complete${c.reset}`)
console.log(`${c.bold} ─────────────────────────────${c.reset}`)
console.log()
ok('.cursorrules → ' + dst)
console.log()
process.exit(0)
}
// ─── GitHub Copilot ───────────────────────────────────────────────────────────
if (ide === 'copilot') {
const src = path.join(REPO_ROOT, '.github', 'copilot-instructions.md')
const dst = path.join(process.cwd(), '.github', 'copilot-instructions.md')
if (!fs.existsSync(src)) {
warn('copilot-instructions.md not found in the kit.')
process.exit(1)
}
if (fs.existsSync(dst) && !YES) {
const overwrite = await ask('copilot-instructions.md already exists. Overwrite?')
if (!overwrite) { info('Skipped.'); process.exit(0) }
}
copyFile(src, dst)
console.log()
console.log(`${c.bold} ─────────────────────────────${c.reset}`)
console.log(`${c.bold}${c.green} Installation complete${c.reset}`)
console.log(`${c.bold} ─────────────────────────────${c.reset}`)
console.log()
ok('.github/copilot-instructions.md → ' + dst)
console.log()
process.exit(0)
}
// ─── Antigravity ─────────────────────────────────────────────────────────────
if (ide === 'antigravity') {
const allAgSkills = listSkills(path.join(REPO_ROOT, 'antigravity-skills'))
const geminiSrc = path.join(REPO_ROOT, 'GEMINI.md')
const agentsMdSrc = path.join(REPO_ROOT, 'AGENTS.md')
let selectedSkills = allAgSkills
if (!YES) {
selectedSkills = await selectAntigravitySkills(allAgSkills)
if (selectedSkills.length === 0) {
info('Nothing selected. Exiting.')
console.log()
process.exit(0)
}
}
const agDst = path.join(process.cwd(), 'antigravity-skills')
let installedCount = 0
step('Installing Antigravity skills...')
fs.mkdirSync(agDst, { recursive: true })
for (const skill of selectedSkills) {
const dst = path.join(agDst, skill.name)
if (fs.existsSync(dst) && !YES) {
const overwrite = await ask(`@${skill.name} already exists. Overwrite?`)
if (!overwrite) { info(`Skipped: @${skill.name}`); continue }
}
copyDir(skill.src, dst)
ok(`skill: @${skill.name}`)
installedCount++
}
if (fs.existsSync(geminiSrc)) {
const dst = path.join(process.cwd(), 'GEMINI.md')
if (!fs.existsSync(dst) || YES) {
copyFile(geminiSrc, dst)
ok('GEMINI.md')
installedCount++
} else {
const overwrite = await ask('GEMINI.md already exists. Overwrite?')
if (overwrite) { copyFile(geminiSrc, dst); ok('GEMINI.md'); installedCount++ }
else info('Skipped: GEMINI.md')
}
}
if (fs.existsSync(agentsMdSrc)) {
const dst = path.join(process.cwd(), 'AGENTS.md')
if (!fs.existsSync(dst) || YES) {
copyFile(agentsMdSrc, dst)
ok('AGENTS.md')
installedCount++
}
}
console.log()
console.log(`${c.bold} ─────────────────────────────${c.reset}`)
console.log(`${c.bold}${c.green} Installation complete${c.reset} (${installedCount} items)`)
console.log(`${c.bold} ─────────────────────────────${c.reset}`)
console.log()
console.log(` ${c.dim}Skills:${c.reset} ${selectedSkills.map(s => '@' + s.name).join(' ')}`)
console.log()
process.exit(0)
}
// ─── Claude Code: resolve scope ──────────────────────────────────────────────
let isLocal

@@ -266,11 +447,10 @@

isLocal = true
} else if (FORCE_GLOBAL) {
} else if (FORCE_GLOBAL || YES || SKILLS_ONLY || HOOKS_ONLY || UNINSTALL) {
isLocal = false
} else {
// Interactive scope question
console.log(` ${c.bold}Where do you want to install?${c.reset}`)
console.log(` ${c.bold}Where do you want to install?${c.reset}\n`)
console.log(` ${c.cyan}g${c.reset} Global ${c.dim}~/.claude/ — available in all projects${c.reset}`)
console.log(` ${c.cyan}l${c.reset} Local ${c.dim}.claude/ (here) — this project only${c.reset}`)
console.log()
const scopeAns = YES ? 'g' : await prompt(` ${c.dim}[g/l]${c.reset} `)
const scopeAns = await prompt(` ${c.dim}[g/l]${c.reset} `)
isLocal = scopeAns.toLowerCase() === 'l'

@@ -316,3 +496,3 @@ console.log()

// ─── Resolve selection ────────────────────────────────────────────────────────
// ─── Claude Code: check install ──────────────────────────────────────────────

@@ -355,3 +535,3 @@ const claudeInstalled = spawnSync('claude', ['--version'], { shell: true }).status === 0

// ─── Install ─────────────────────────────────────────────────────────────────
// ─── Install skills ───────────────────────────────────────────────────────────

@@ -358,0 +538,0 @@ let installedCount = 0

@@ -12,2 +12,24 @@ # Changelog

## [2.2.0] - 2026-05-24
### Added
- **cli**: Flags `--claude`, `--cursor`, `--copilot`, `--antigravity` to skip IDE prompt
- **cli**: Local and global installation options (`--local`, `--global`)
- **cli**: Interactive selection menu with improved category and item handling
- Skills: `/commit`, `/debug`, `/memory`, `/plan`, `/pr`, `/review`, `/vibe-audit`
- Agents: `/api`, `/docs`, `/frontend`, `/refactor`, `/test`
- Memory management documentation and changelog guidelines
- Support for Google Antigravity alongside Claude Code, Cursor, and Copilot
### Fixed
- Argument-hint YAML formatting in skill documentation
- CLI scope selection logic for non-interactive modes
- CLI uninstall option included in scope selection
### Changed
- Enhanced CLI skill management with improved listing and copying functions
- Updated project architecture decisions and stack documentation
---
## [2.1.0] - 2026-04-11

@@ -55,3 +77,4 @@

[Unreleased]: https://github.com/bezael/ai-workflow-kit/compare/v2.1.0...HEAD
[Unreleased]: https://github.com/bezael/ai-workflow-kit/compare/v2.2.0...HEAD
[2.2.0]: https://github.com/bezael/ai-workflow-kit/compare/v2.1.0...v2.2.0
[2.1.0]: https://github.com/bezael/ai-workflow-kit/compare/v2.0.0...v2.1.0
+1
-1
{
"name": "ai-workflow-kit",
"version": "2.2.0-beta.2",
"version": "2.2.0",
"description": "Skills, agents & hooks for Claude Code, Cursor, GitHub Copilot, and Google Antigravity",

@@ -5,0 +5,0 @@ "type": "module",

---
name: ak:memory
description: Manage persistent memory across sessions. Subcommands: save [topic] captures session learnings, recall [question] retrieves relevant context before acting, clean removes stale entries.
description: "Manage persistent memory across sessions. Subcommands: save [topic] captures session learnings, recall [question] retrieves relevant context before acting, clean removes stale entries."
argument-hint: <save|recall|clean> [topic or question]

@@ -5,0 +5,0 @@ ---

---
name: ak:review
description: Review code with real engineering criteria — logic bugs, security vulnerabilities, and technical debt. Use when user says /review @file or /review to review current PR changes.
argument-hint: [@file or leave empty for PR diff]
argument-hint: "[@file or leave empty for PR diff]"
context: fork

@@ -6,0 +6,0 @@ agent: Explore

@@ -5,3 +5,3 @@ ---

disable-model-invocation: true
argument-hint: [@folder or leave empty for current project]
argument-hint: "[@folder or leave empty for current project]"
context: fork

@@ -8,0 +8,0 @@ agent: Explore