ai-omni-skills 1.2.21 → 1.2.23

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.2.22] - 2026-06-22
4
+
5
+ ### Added
6
+ - **NVIDIA SkillSpector integration** — security scanning for AI skills
7
+ - `omni-skills security` — check SkillSpector status
8
+ - `omni-skills security scan` — scan skills for 64 vulnerability patterns
9
+ - Setup asks to install SkillSpector (default: yes)
10
+ - Doctor checks SkillSpector installation status
11
+ - README documents SkillSpector with NVIDIA reference
12
+ - **Skill creation wizard** — create skills directly without going through an agent
13
+ - `omni-skills create [name]` — interactive wizard with SKILL.md template
14
+ - `omni-skills create from <file>` — convert existing file to skill
15
+ - **Help hint** — quick-start banner at bottom of `omni-skills help`
16
+
17
+ ### Changed
18
+ - Rename CLI command from `skills` to `omni-skills` (`skills` kept as backward-compatible alias)
19
+ - Update all documentation examples to use `omni-skills`
20
+
3
21
  ## [1.2.20] - 2026-06-22
4
22
 
5
23
  ### Added
package/INDEX.md CHANGED
@@ -1,14 +1,60 @@
1
- # Skills Index
1
+ # Skills index
2
2
 
3
- This file is auto-generated by `omni-skills index`.
3
+ This index lists skills in this repo, ordered by recent usage.
4
4
 
5
- In the toolkit repo, this index is intentionally minimal. Once you set up your private skills store and run `omni-skills index`, this file will populate with your actual skills ordered by recent usage.
6
-
7
- ## Getting Started
8
-
9
- ```bash
10
- omni-skills setup # Configure your private skills directory
11
- omni-skills index # Generate your skills index
12
- ```
13
-
14
- Your private skills index will be created at the root of your configured skills directory.
5
+ | Skill | Description |
6
+ | ----- | ----------- |
7
+ | clean-code | Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments |
8
+ | agents-md-compliance-checker | |
9
+ | agents-md-sync-checker | |
10
+ | agp-9-upgrade | Upgrades, or migrates, an Android project to use Android Gradle Plugin (AGP) version 9. Do not use this skill for migrating Kotlin Multiplatform (KMP) projects. |
11
+ | code-review-checklist | Code review guidelines covering code quality, security, and best practices. |
12
+ | codebase-memory | Use the codebase knowledge graph for structural code queries. Triggers on: explore the codebase, understand the architecture, what functions exist, show me the structure, who calls this function, what does X call, trace the call chain, find callers of, show dependencies, impact analysis, dead code, unused functions, high fan-out, refactor candidates, code quality audit, graph query syntax, Cypher query examples, edge types, how to use search_graph. |
13
+ | commit-suggest | Suggest a commit message for the current changes following this project's commit message guide. Use when asked to suggest, draft, propose, or write a commit message for the staged/unstaged changes. |
14
+ | content-research-writer | Assists in writing high-quality content by conducting research, adding citations, improving hooks, iterating on outlines, and providing real-time feedback on each section. Transforms your writing process from solo effort to collaborative partnership. |
15
+ | docker-expert | Docker containerization expert with deep knowledge of multi-stage builds, image optimization, container security, Docker Compose orchestration, and production deployment patterns. Use PROACTIVELY for Dockerfile optimization, container issues, image size problems, security hardening, networking, and orchestration challenges. |
16
+ | edge-to-edge | Use this skill to migrate your Jetpack Compose app to add adaptive edge-to-edge support and troubleshoot common issues. Use this skill to fix UI components (like buttons or lists) that are obscured by or overlapping with the navigation bar or status bar, fix IME insets, and fix system bar legibility. |
17
+ | finishing-a-development-branch | Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup |
18
+ | flutter-mobile-design | Use when designing, reviewing, critiquing, or improving Flutter mobile UI/UX. Covers widget composition, RTL Arabic typography, performance optimization, accessibility, Material 3 / iOS adaptation, and reading-app specifics. Tuned for Quran/Arabic reading apps built with Clean Architecture, BLoC, and GetIt — Quran content (Uthmani script, Mushaf layout, audio recitation). |
19
+ | lead-research-assistant | Identifies high-quality leads for your product or service by analyzing your business, searching for target companies, and providing actionable contact strategies. Perfect for sales, business development, and marketing professionals. |
20
+ | lint-and-validate | Automatic quality control, linting, and static analysis procedures. Use after every code modification to ensure syntax correctness and project standards. Triggers onKeywords: lint, format, check, validate, types, static analysis. |
21
+ | migrate-xml-views-to-jetpack-compose | Provides a structured workflow for migrating an Android XML View to Jetpack Compose. This skill details the step-by-step process, from planning and dependency setup, to theming and layout migration, validation and XML cleanup. Use this skill when you need to migrate an XML View to Jetpack Compose in an Android project. It solves the problem of converting the UI of a legacy XML View into modern, declarative Compose components while maintaining interoperability. |
22
+ | mmx-cli | Use mmx to generate text, images, video, speech, and music via the MiniMax AI platform. Use when the user wants to create media content, chat with MiniMax models, perform web search, or manage MiniMax API resources from the terminal. |
23
+ | navigation-3 | Learn how to install and migrate to Jetpack Navigation 3, and how to implement features and patterns such as deep links, multiple backstacks, scenes (dialogs, bottom sheets, list-detail, two-pane, supporting pane), conditional navigation (such as logged-in navigation vs anonymous), returning results from flows, integration with Hilt, ViewModel, Kotlin, and view interoperability. |
24
+ | nextjs-best-practices | Next.js App Router principles. Server Components, data fetching, routing patterns. |
25
+ | nodejs-best-practices | Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying. |
26
+ | play-billing-library-version-upgrade | Use this skill when upgrading or migrating an Android project from any legacy Google Play Billing Library (PBL) version to the latest stable version of PBL. |
27
+ | pr-review-rule-extractor | |
28
+ | process-pr-comments | Full PR review workflow for Bitbucket Server (non-GitHub). Use whenever the user wants to process, address, or work through PR review comments — e.g. "process PR comments", "let's address review feedback on PR 123", "apply PR review comments", "work through PR X". Handles branch checkout, fetching updates, scoring unresolved comments, getting user approval per comment, generating an implementation plan, suggesting a commit message, and drafting human-style replies to reviewers where a response is warranted. |
29
+ | r8-analyzer | Analyzes Android build files and R8 keep rules to identify redundancies, broad package-wide rules, and rules that subsume library consumer keep rules. Use when developers want to optimize their app's size, remove redundant or overly broad keep rules, or troubleshoot Proguard configurations. |
30
+ | receiving-code-review | Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation |
31
+ | requesting-code-review | Use when completing tasks, implementing major features, or before merging to verify work meets requirements |
32
+ | skill-seeker | Scan for orphaned skills, unclassified instruction files (AGENTS.md, CLAUDE.md, GEMINI.md, etc.), and newly created agent configurations. Help the user decide whether each should be public or private, and move them to the correct canonical location. Use when the user says "find new skills", "organize my skills", "what skills are not tracked", "classify my agents.md", "seeker", or "sync my skills". |
33
+ | speckit-agent-context-update | Refresh the managed Spec Kit section in the coding agent context file |
34
+ | speckit-analyze | Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation. |
35
+ | speckit-checklist | Generate a custom checklist for the current feature based on user requirements. |
36
+ | speckit-clarify | Identify underspecified areas in the current feature spec by asking up to 5 highly targeted clarification questions and encoding answers back into the spec. |
37
+ | speckit-constitution | Create or update the project constitution from interactive or provided principle inputs, ensuring all dependent templates stay in sync. |
38
+ | speckit-git-commit | Auto-commit changes after a Spec Kit command completes |
39
+ | speckit-git-feature | Create a feature branch with sequential or timestamp numbering |
40
+ | speckit-git-initialize | Initialize a Git repository with an initial commit |
41
+ | speckit-git-remote | Detect Git remote URL for GitHub integration |
42
+ | speckit-git-validate | Validate current branch follows feature branch naming conventions |
43
+ | speckit-implement | Execute the implementation plan by processing and executing all tasks defined in tasks.md |
44
+ | speckit-plan | Execute the implementation planning workflow using the plan template to generate design artifacts. |
45
+ | speckit-specify | Create or update the feature specification from a natural language feature description. |
46
+ | speckit-tasks | Generate an actionable, dependency-ordered tasks.md for the feature based on available design artifacts. |
47
+ | speckit-taskstoissues | Convert existing tasks into actionable, dependency-ordered GitHub issues for the feature based on available design artifacts. |
48
+ | systematic-debugging | Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes |
49
+ | testing-patterns | Jest testing patterns, factory functions, mocking strategies, and TDD workflow. Use when writing unit tests, creating test factories, or following TDD red-green-refactor cycle. |
50
+ | ticket-refinement | Refine a ticket by comparing its acceptance criteria against an existing/legacy implementation and the current codebase, then produce a ready-to-paste Jira/Linear comment flagging only what's contradictory, ambiguous, missing, or genuinely new work. Use when preparing for a refinement/grooming session and you have a ticket's ACs (and optionally designs) to validate before sprint planning. |
51
+ | typescript-expert | TypeScript and JavaScript expert with deep knowledge of type-level programming, performance optimization, monorepo management, migration strategies, and modern tooling. Use PROACTIVELY for any TypeScript/JavaScript issues including complex type gymnastics, build performance, debugging, and architectural decisions. If a specialized expert is a better fit, I will recommend switching and stop. |
52
+ | using-git-worktrees | Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification |
53
+ | vercel-react-best-practices | React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements. |
54
+ | verification-before-completion | Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always |
55
+ | ponytail | Forces the laziest solution that actually works, simplest, shortest, most minimal. Channels a senior dev who has seen everything: question whether the task needs to exist at all (YAGNI), reach for the standard library before custom code, native platform features before dependencies, one line before fifty. Supports intensity levels: lite, full (default), ultra. Use whenever the user says "ponytail", "be lazy", "lazy mode", "simplest solution", "minimal solution", "yagni", "do less", or "shortest path", and whenever they complain about over-engineering, bloat, boilerplate, or unnecessary dependencies. |
56
+ | ponytail-audit | Whole-repo audit for over-engineering. Like ponytail-review, but scans the entire codebase instead of a diff: a ranked list of what to delete, simplify, or replace with stdlib/native equivalents. Use when the user says "audit this codebase", "audit for over-engineering", "what can I delete from this repo", "find bloat", "ponytail-audit", or "/ponytail-audit". One-shot report, does not apply fixes. |
57
+ | ponytail-debt | Harvest every `ponytail:` comment in the codebase into a debt ledger, so the deliberate shortcuts and deferrals ponytail leaves behind get tracked instead of rotting into "later means never". Use when the user says "ponytail debt", "/ponytail-debt", "what did ponytail defer", "list the shortcuts", "ponytail ledger", or "what did we mark to do later". One-shot report, changes nothing. |
58
+ | ponytail-gain | Show ponytail's measured impact as a compact scoreboard: less code, less cost, more speed, from the benchmark medians. One-shot display, not a persistent mode, and not a per-repo number. Trigger: /ponytail-gain, "ponytail gain", "what does ponytail save", "show ponytail impact", "ponytail scoreboard". |
59
+ | ponytail-help | Quick-reference card for all ponytail modes, skills, and commands. One-shot display, not a persistent mode. Trigger: /ponytail-help, "ponytail help", "what ponytail commands", "how do I use ponytail". |
60
+ | ponytail-review | Code review focused exclusively on over-engineering. Finds what to delete: reinvented standard library, unneeded dependencies, speculative abstractions, dead flexibility. One line per finding: location, what to cut, what replaces it. Use when the user says "review for over-engineering", "what can we delete", "is this over-engineered", "simplify review", or invokes /ponytail-review. Complements correctness-focused review, this one only hunts complexity. |
package/README.md CHANGED
@@ -167,6 +167,9 @@ Tools with MCP support get the `skills` MCP server registered automatically. Too
167
167
  | `omni-skills doctor` | Health check: verify symlinks, config, indexes, and skill counts. |
168
168
  | `omni-skills report [--enhance]` | Usage statistics and heuristic improvement tips. |
169
169
  | `omni-skills init [--dry-run]` | Interactive setup: scan, classify, route, wire. |
170
+ | `omni-skills security [scan]` | Check/install NVIDIA SkillSpector. Scan skills for vulnerabilities. |
171
+ | `omni-skills create [name]` | Create a new skill with interactive wizard. |
172
+ | `omni-skills create from <file>` | Convert an existing file into a skill. |
170
173
  | `omni-skills help` | Show help. |
171
174
 
172
175
  ---
@@ -264,6 +267,70 @@ Workflows live in your private repo under `workflows/` — they are personal, no
264
267
 
265
268
  ---
266
269
 
270
+ ## 🔒 Security Scanning (NVIDIA SkillSpector)
271
+
272
+ Research shows **26.1% of AI skills contain vulnerabilities** and **5.2% show likely malicious intent**. Omni Skills integrates with [NVIDIA SkillSpector](https://github.com/NVIDIA/skillspector) to scan your skills before you install them.
273
+
274
+ SkillSpector detects **64 vulnerability patterns** across **16 categories**:
275
+ - Prompt injection, data exfiltration, privilege escalation
276
+ - Supply chain attacks, malware, credential harvesting
277
+ - Excessive agency, tool misuse, system prompt leakage
278
+
279
+ ### Quick Start
280
+
281
+ ```bash
282
+ # Check SkillSpector status
283
+ omni-skills security
284
+
285
+ # Scan all skills in your canonical store
286
+ omni-skills security scan
287
+
288
+ # Scan without LLM (faster, static analysis only)
289
+ omni-skills security scan --no-llm
290
+
291
+ # Scan a specific skill directory
292
+ omni-skills security scan ~/my-skills-private/clean-code
293
+ ```
294
+
295
+ ### Install SkillSpector
296
+
297
+ ```bash
298
+ git clone https://github.com/NVIDIA/skillspector.git
299
+ cd skillspector
300
+ python3 -m venv .venv && source .venv/bin/activate
301
+ pip install -e .
302
+ ```
303
+
304
+ Or use Docker:
305
+ ```bash
306
+ docker run --rm -v "$PWD:/scan" ghcr.io/nvidia/skillspector scan /scan
307
+ ```
308
+
309
+ ---
310
+
311
+ ## ✨ Creating New Skills
312
+
313
+ Instead of creating skills through an agent and then moving them, create them directly:
314
+
315
+ ```bash
316
+ # Interactive wizard
317
+ omni-skills create
318
+
319
+ # With name and description
320
+ omni-skills create refine-requests "Refine ticket acceptance criteria"
321
+
322
+ # Convert an existing file into a skill
323
+ omni-skills create from ./my-instructions.md
324
+
325
+ # Then index and sync
326
+ omni-skills index
327
+ omni-skills sync all
328
+ ```
329
+
330
+ This creates a `SKILL.md` with proper frontmatter in your private skills store.
331
+
332
+ ---
333
+
267
334
  ## How to Store Your Skills
268
335
 
269
336
  This toolkit is **code only**. Your skills live in a separate repository (or two) that you control.
package/cli.js CHANGED
@@ -68,6 +68,15 @@ Subcommands:
68
68
  Interactive seeker: scan tool skills dirs and known agent locations for
69
69
  new skills, classify them public/private/skip, then sync and index.
70
70
  --dry-run prints recommendations without prompting or writing.
71
+ security [scan [path] [--no-llm]]
72
+ Check security status of NVIDIA SkillSpector.
73
+ Scan skills for vulnerabilities (prompt injection, data exfiltration,
74
+ malware, etc.). Requires SkillSpector installation.
75
+ create [name] [description]
76
+ Create a new skill with interactive wizard.
77
+ Creates SKILL.md template in your private skills store.
78
+ create from <path> [name]
79
+ Convert an existing file into a skill.
71
80
  help Show this help message
72
81
 
73
82
  Config resolves from $SKILLS_CONFIG, then ~/.config/skills/config.json, then the
@@ -181,6 +190,42 @@ async function main() {
181
190
  await initSkills(loadConfig(), { dryRun: flags.dryRun });
182
191
  break;
183
192
  }
193
+ case 'security': {
194
+ const { showSecurityStatus, runSkillSpectorScan, showSecurityBanner } = await import('./lib/security.js');
195
+ const config = loadConfig();
196
+ const subcmd = positional[0];
197
+ if (subcmd === 'scan') {
198
+ const target = positional[1] || config.privatePath || config.publicPath || process.cwd();
199
+ showSecurityBanner();
200
+ const output = runSkillSpectorScan(target, {
201
+ noLLM: rest.includes('--no-llm'),
202
+ format: rest.find(a => a.startsWith('--format='))?.split('=')[1],
203
+ output: rest.find(a => a.startsWith('--output='))?.split('=')[1],
204
+ verbose: rest.includes('-V') || rest.includes('--verbose'),
205
+ });
206
+ if (output) console.log(output);
207
+ } else {
208
+ showSecurityStatus();
209
+ }
210
+ break;
211
+ }
212
+ case 'create': {
213
+ const { createSkill, createSkillFromFile } = await import('./lib/create-skill.js');
214
+ const config = loadConfig();
215
+ const subcmd = positional[0];
216
+ if (subcmd === 'from' && positional[1]) {
217
+ await createSkillFromFile(config, positional[1], {
218
+ name: positional[2],
219
+ });
220
+ } else {
221
+ await createSkill(config, {
222
+ name: positional[0],
223
+ description: positional[1],
224
+ targetDir: flags.privatePath || config.privatePath,
225
+ });
226
+ }
227
+ break;
228
+ }
184
229
  case 'help':
185
230
  case '-h':
186
231
  case undefined:
@@ -0,0 +1,180 @@
1
+ import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import readline from 'node:readline';
4
+
5
+ const SKILL_TEMPLATE = `---
6
+ name: {{NAME}}
7
+ description: {{DESCRIPTION}}
8
+ triggers: {{TRIGGERS}}
9
+ ---
10
+
11
+ # {{NAME}}
12
+
13
+ {{DESCRIPTION}}
14
+
15
+ ## When to Use
16
+
17
+ - Trigger condition 1
18
+ - Trigger condition 2
19
+
20
+ ## Instructions
21
+
22
+ 1. Step one
23
+ 2. Step two
24
+ 3. Step three
25
+
26
+ ## Notes
27
+
28
+ - Add any important notes or edge cases here
29
+ - Keep this section updated as you refine the skill
30
+ `;
31
+
32
+ function ask(rl, question) {
33
+ return new Promise((resolve) => {
34
+ rl.question(question, resolve);
35
+ });
36
+ }
37
+
38
+ export async function createSkill(config, options = {}) {
39
+ const { privatePath } = config;
40
+ if (!privatePath) {
41
+ console.error('❌ No privatePath configured. Run `omni-skills setup` first.');
42
+ process.exit(1);
43
+ }
44
+
45
+ const isTty = process.stdin.isTTY && process.stdout.isTTY;
46
+ const rl = isTty ? readline.createInterface({ input: process.stdin, output: process.stdout }) : null;
47
+
48
+ // Determine target directory
49
+ let targetDir = options.targetDir || privatePath;
50
+ if (!existsSync(targetDir)) {
51
+ console.error(`❌ Target directory does not exist: ${targetDir}`);
52
+ console.log('Run `omni-skills setup` to configure your skills directory.');
53
+ process.exit(1);
54
+ }
55
+
56
+ let skillName = options.name;
57
+ let description = options.description;
58
+ let triggers = options.triggers;
59
+ let openEditor = options.openEditor ?? true;
60
+
61
+ if (isTty && !skillName) {
62
+ skillName = (await ask(rl, 'Skill name (kebab-case, e.g. "refine-requests"): ')).trim();
63
+ }
64
+
65
+ if (!skillName) {
66
+ console.error('❌ Skill name is required.');
67
+ process.exit(1);
68
+ }
69
+
70
+ // Validate skill name
71
+ const validName = /^[a-z0-9-]+$/.test(skillName);
72
+ if (!validName) {
73
+ console.error('❌ Skill name must be kebab-case (lowercase letters, numbers, hyphens only).');
74
+ process.exit(1);
75
+ }
76
+
77
+ const skillDir = join(targetDir, skillName);
78
+ if (existsSync(skillDir)) {
79
+ console.error(`❌ Skill "${skillName}" already exists at ${skillDir}`);
80
+ process.exit(1);
81
+ }
82
+
83
+ if (isTty && !description) {
84
+ description = (await ask(rl, 'Description (one sentence, what this skill does): ')).trim();
85
+ }
86
+
87
+ if (!description) {
88
+ description = `Use this skill when working with ${skillName}.`;
89
+ }
90
+
91
+ if (isTty && !triggers) {
92
+ triggers = (await ask(rl, 'Trigger keywords (comma-separated, e.g. "refine, clarify, review"): ')).trim();
93
+ }
94
+
95
+ if (!triggers) {
96
+ triggers = skillName;
97
+ }
98
+
99
+ // Create skill directory and file
100
+ mkdirSync(skillDir, { recursive: true });
101
+ const skillFile = join(skillDir, 'SKILL.md');
102
+
103
+ const content = SKILL_TEMPLATE
104
+ .replace(/{{NAME}}/g, skillName)
105
+ .replace(/{{DESCRIPTION}}/g, description)
106
+ .replace(/{{TRIGGERS}}/g, triggers);
107
+
108
+ writeFileSync(skillFile, content, 'utf8');
109
+
110
+ console.log(`✅ Created skill: ${skillName}`);
111
+ console.log(` Path: ${skillFile}`);
112
+ console.log('');
113
+ console.log('Next steps:');
114
+ console.log(' 1. Edit SKILL.md to add your instructions');
115
+ console.log(' 2. Run `omni-skills index` to regenerate the skill index');
116
+ console.log(' 3. Run `omni-skills sync all` to wire into all tools');
117
+ console.log('');
118
+
119
+ if (isTty && openEditor) {
120
+ const answer = (await ask(rl, 'Open in editor? [y/n] (default: y): ')).trim().toLowerCase();
121
+ if (answer === '' || answer === 'y' || answer === 'yes') {
122
+ const { execSync } = await import('node:child_process');
123
+ const editor = process.env.EDITOR || 'code';
124
+ try {
125
+ execSync(`${editor} "${skillFile}"`, { stdio: 'inherit' });
126
+ } catch {
127
+ console.log(`Could not open editor. Edit manually: ${skillFile}`);
128
+ }
129
+ }
130
+ }
131
+
132
+ if (rl) rl.close();
133
+ return { skillName, skillDir, skillFile };
134
+ }
135
+
136
+ export async function createSkillFromFile(config, sourcePath, options = {}) {
137
+ if (!existsSync(sourcePath)) {
138
+ console.error(`❌ Source file does not exist: ${sourcePath}`);
139
+ process.exit(1);
140
+ }
141
+
142
+ const { privatePath } = config;
143
+ if (!privatePath) {
144
+ console.error('❌ No privatePath configured. Run `omni-skills setup` first.');
145
+ process.exit(1);
146
+ }
147
+
148
+ const sourceName = sourcePath.split('/').pop().replace(/\.md$/, '');
149
+ const skillName = options.name || sourceName.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
150
+
151
+ const skillDir = join(privatePath, skillName);
152
+ if (existsSync(skillDir)) {
153
+ console.error(`❌ Skill "${skillName}" already exists.`);
154
+ process.exit(1);
155
+ }
156
+
157
+ mkdirSync(skillDir, { recursive: true });
158
+ const skillFile = join(skillDir, 'SKILL.md');
159
+
160
+ let content = readFileSync(sourcePath, 'utf8');
161
+
162
+ // If content doesn't have frontmatter, add it
163
+ if (!content.trim().startsWith('---')) {
164
+ const description = options.description || `Converted from ${sourceName}`;
165
+ content = `---\nname: ${skillName}\ndescription: ${description}\n---\n\n${content}`;
166
+ }
167
+
168
+ writeFileSync(skillFile, content, 'utf8');
169
+
170
+ console.log(`✅ Created skill from file: ${skillName}`);
171
+ console.log(` Source: ${sourcePath}`);
172
+ console.log(` Path: ${skillFile}`);
173
+ console.log('');
174
+ console.log('Next steps:');
175
+ console.log(' 1. Review and edit SKILL.md');
176
+ console.log(' 2. Run `omni-skills index` to regenerate the skill index');
177
+ console.log(' 3. Run `omni-skills sync all` to wire into all tools');
178
+
179
+ return { skillName, skillDir, skillFile };
180
+ }
package/lib/doctor.js CHANGED
@@ -246,6 +246,20 @@ export async function runDoctor(config) {
246
246
  }
247
247
  console.log('');
248
248
 
249
+ // 6. Security check (SkillSpector)
250
+ console.log('[security]');
251
+ const { isSkillSpectorInstalled, findSkillSpector } = await import('./security.js');
252
+ if (isSkillSpectorInstalled()) {
253
+ const path = findSkillSpector();
254
+ console.log(` ✓ NVIDIA SkillSpector installed (${path})`);
255
+ console.log(' Run `omni-skills security scan` to check skills for vulnerabilities');
256
+ } else {
257
+ console.log(' ⚠ NVIDIA SkillSpector not installed (optional)');
258
+ console.log(' Detects 64 vulnerability patterns in AI skills');
259
+ console.log(' Install: https://github.com/NVIDIA/skillspector');
260
+ }
261
+ console.log('');
262
+
249
263
  // Summary
250
264
  if (issues.length === 0) {
251
265
  console.log('✓ All checks passed. The skills ecosystem is healthy.');
@@ -254,6 +268,6 @@ export async function runDoctor(config) {
254
268
  for (const issue of issues) {
255
269
  console.log(issue);
256
270
  }
257
- console.log('\nRun `skills sync all` to fix most symlink issues.');
271
+ console.log('\nRun `omni-skills sync all` to fix most symlink issues.');
258
272
  }
259
273
  }
@@ -0,0 +1,129 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { execSync } from 'node:child_process';
3
+ import { join } from 'node:path';
4
+ import { homedir } from 'node:os';
5
+
6
+ const SKILLSPECTOR_PATHS = [
7
+ 'skillspector',
8
+ join(homedir(), '.local', 'bin', 'skillspector'),
9
+ '/usr/local/bin/skillspector',
10
+ '/usr/bin/skillspector',
11
+ ];
12
+
13
+ export function findSkillSpector() {
14
+ for (const path of SKILLSPECTOR_PATHS) {
15
+ try {
16
+ execSync(`which ${path}`, { stdio: 'ignore' });
17
+ return path;
18
+ } catch {
19
+ continue;
20
+ }
21
+ }
22
+ return null;
23
+ }
24
+
25
+ export function isSkillSpectorInstalled() {
26
+ return findSkillSpector() !== null;
27
+ }
28
+
29
+ export function getSkillSpectorVersion() {
30
+ const path = findSkillSpector();
31
+ if (!path) return null;
32
+ try {
33
+ const output = execSync(`${path} --version`, { encoding: 'utf8', timeout: 5000 });
34
+ return output.trim();
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+
40
+ export function runSkillSpectorScan(targetPath, options = {}) {
41
+ const path = findSkillSpector();
42
+ if (!path) {
43
+ console.error('❌ SkillSpector not found.');
44
+ console.log('');
45
+ console.log('🔒 NVIDIA SkillSpector — Security Scanner for AI Skills');
46
+ console.log(' Detects 64 vulnerability patterns across 16 categories');
47
+ console.log(' (prompt injection, data exfiltration, privilege escalation, etc.)');
48
+ console.log('');
49
+ console.log('Install:');
50
+ console.log(' git clone https://github.com/NVIDIA/skillspector.git');
51
+ console.log(' cd skillspector');
52
+ console.log(' python3 -m venv .venv && source .venv/bin/activate');
53
+ console.log(' pip install -e .');
54
+ console.log('');
55
+ console.log('Or via Docker:');
56
+ console.log(' docker run --rm -v "$PWD:/scan" ghcr.io/nvidia/skillspector scan /scan');
57
+ console.log('');
58
+ console.log('📎 https://github.com/NVIDIA/skillspector');
59
+ return null;
60
+ }
61
+
62
+ const args = ['scan', targetPath];
63
+ if (options.noLLM) args.push('--no-llm');
64
+ if (options.format) args.push('--format', options.format);
65
+ if (options.output) args.push('--output', options.output);
66
+ if (options.verbose) args.push('-V');
67
+
68
+ try {
69
+ const output = execSync(`${path} ${args.join(' ')}`, {
70
+ encoding: 'utf8',
71
+ timeout: 120000,
72
+ stdio: 'pipe',
73
+ });
74
+ return output;
75
+ } catch (err) {
76
+ if (err.stdout) return err.stdout;
77
+ if (err.stderr) return err.stderr;
78
+ return err.message;
79
+ }
80
+ }
81
+
82
+ export function showSecurityStatus() {
83
+ const path = findSkillSpector();
84
+ if (path) {
85
+ const version = getSkillSpectorVersion();
86
+ console.log('✅ NVIDIA SkillSpector is installed');
87
+ if (version) console.log(` Version: ${version}`);
88
+ console.log(` Path: ${path}`);
89
+ console.log('');
90
+ console.log('Usage:');
91
+ console.log(' omni-skills security scan # Scan all skills');
92
+ console.log(' omni-skills security scan --dir ./ # Scan specific directory');
93
+ console.log(' omni-skills security scan --no-llm # Static analysis only (faster)');
94
+ } else {
95
+ console.log('⚠️ NVIDIA SkillSpector is not installed');
96
+ console.log('');
97
+ console.log('🔒 Why install it?');
98
+ console.log(' • Scans AI skills for 64 vulnerability patterns');
99
+ console.log(' • Detects prompt injection, data exfiltration, malware');
100
+ console.log(' • 26.1% of skills contain vulnerabilities (research-backed)');
101
+ console.log('');
102
+ console.log('Install:');
103
+ console.log(' git clone https://github.com/NVIDIA/skillspector.git');
104
+ console.log(' cd skillspector');
105
+ console.log(' python3 -m venv .venv && source .venv/bin/activate');
106
+ console.log(' pip install -e .');
107
+ console.log('');
108
+ console.log('Or use Docker:');
109
+ console.log(' docker run --rm -v "$PWD:/scan" ghcr.io/nvidia/skillspector scan /scan');
110
+ console.log('');
111
+ console.log('📎 https://github.com/NVIDIA/skillspector');
112
+ }
113
+ }
114
+
115
+ export function showSecurityBanner() {
116
+ console.log('');
117
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
118
+ console.log(' 🔒 NVIDIA SkillSpector — Security for AI Skills');
119
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
120
+ console.log('');
121
+ console.log('Research shows 26.1% of skills contain vulnerabilities.');
122
+ console.log('SkillSpector detects 64 patterns across 16 categories:');
123
+ console.log(' • Prompt injection, data exfiltration, privilege escalation');
124
+ console.log(' • Supply chain attacks, malware, credential harvesting');
125
+ console.log(' • Excessive agency, tool misuse, system prompt leakage');
126
+ console.log('');
127
+ console.log('📎 https://github.com/NVIDIA/skillspector');
128
+ console.log('');
129
+ }
package/lib/setup.js CHANGED
@@ -218,7 +218,7 @@ export async function runSetup({ publicPath, privatePath, toolkitDir } = {}) {
218
218
  type: 'stale-template',
219
219
  project: proj.name,
220
220
  count: staleTemplates.length,
221
- action: `skills classify ${proj.path} --dry-run`,
221
+ action: `omni-skills classify ${proj.path} --dry-run`,
222
222
  });
223
223
  }
224
224
  }
@@ -236,7 +236,7 @@ export async function runSetup({ publicPath, privatePath, toolkitDir } = {}) {
236
236
  suggestions.push({
237
237
  type: 'orphaned-skills',
238
238
  count: orphanedSkills,
239
- action: 'skills check --move --dry-run',
239
+ action: 'omni-skills check --move --dry-run',
240
240
  });
241
241
  }
242
242
 
@@ -291,15 +291,72 @@ export async function runSetup({ publicPath, privatePath, toolkitDir } = {}) {
291
291
  console.log(` ✓ Created example skill in ${resolvedPublic}/example-skill/`);
292
292
  }
293
293
 
294
- // 7. Create SHARED.md
295
- // 7. Create SHARED.md
294
+ // 7. Create SHARED.md with strong omni-skills rule
296
295
  const sharedPath = absPath(join(resolvedPublic, 'SHARED.md'));
297
296
  if (!existsSync(sharedPath)) {
298
- writeFileSync(sharedPath, '# SHARED.md\n\nThis file contains shared instructions that apply to all AI tools.\nIt is automatically symlinked into each tool\'s global instruction file.\n\nAdd your cross-tool rules here.\n');
297
+ writeFileSync(sharedPath, '# Shared Instructions
298
+
299
+ This file contains shared instructions that apply to all AI tools.
300
+ It is automatically symlinked into each tool's global instruction file.
301
+
302
+ ---
303
+
304
+ ## 🔴 CRITICAL: Omni Skills Creation Rule
305
+
306
+ **DO NOT create skills directly in any AI tool's directory.**
307
+ **DO NOT write SKILL.md files to ~/.claude/skills/, ~/.codex/skills/, ~/.kimi/skills/, etc.**
308
+
309
+ When the user wants to create, install, or modify a skill:
310
+
311
+ 1. **STOP** — Do not write the file directly.
312
+ 2. **SAY**: "I'll create that using `omni-skills` so it syncs to all your tools."
313
+ 3. **RUN**: `omni-skills create <skill-name>`
314
+ 4. **THEN**: `omni-skills index && omni-skills sync all`
315
+
316
+ **Why this matters:**
317
+ - Tool directories are **symlinked** from the canonical store. Writing directly creates orphans.
318
+ - Direct creation means other tools won't see the skill. Only `omni-skills sync` wires everything.
319
+ - If you create directly, the next `omni-skills doctor` will flag it as a broken/foreign symlink.
320
+
321
+ **The ONLY way to create a skill is:**
322
+ ```bash
323
+ omni-skills create <name> # Interactive wizard
324
+ omni-skills index # Regenerate index
325
+ omni-skills sync all # Sync to all tools
326
+ omni-skills doctor # Verify
327
+ ```
328
+
329
+ **If the user pastes skill content**, run `omni-skills create from <file>` instead of writing to a tool dir.
330
+
331
+ ---
332
+
333
+ Add your cross-tool rules below.
334
+ ');
299
335
  console.log(` ✓ Created SHARED.md in ${resolvedPublic}/`);
300
336
  }
301
337
 
302
- // 8. Generate config.json
338
+ // 8. Ask about SkillSpector (default: yes)
339
+ let installSkillSpector = true;
340
+ if (process.stdin.isTTY && process.stdout.isTTY) {
341
+ const readline = await import('node:readline');
342
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
343
+ const answer = await new Promise((resolve) => {
344
+ rl.question('\n🔒 NVIDIA SkillSpector — Security Scanner for AI Skills\n Detects 64 vulnerability patterns (prompt injection, data exfiltration, malware)\n Research: 26.1% of skills contain vulnerabilities\n Install? [Y/n] (default: yes): ', resolve);
345
+ });
346
+ rl.close();
347
+ installSkillSpector = answer.trim().toLowerCase() !== 'n' && answer.trim().toLowerCase() !== 'no';
348
+ }
349
+
350
+ if (installSkillSpector) {
351
+ console.log('\n📎 SkillSpector: https://github.com/NVIDIA/skillspector');
352
+ console.log(' Install: git clone https://github.com/NVIDIA/skillspector.git');
353
+ console.log(' cd skillspector && python3 -m venv .venv && source .venv/bin/activate');
354
+ console.log(' pip install -e .');
355
+ console.log(' Then run: omni-skills security scan');
356
+ }
357
+ console.log('');
358
+
359
+ // 9. Generate config.json
303
360
  console.log('\nGenerating config...');
304
361
  const configDir = absPath('~/.config/skills');
305
362
  if (!existsSync(configDir)) {
@@ -329,9 +386,10 @@ export async function runSetup({ publicPath, privatePath, toolkitDir } = {}) {
329
386
  console.log(' 2. Run `skills classify <path>` to sort instruction files');
330
387
  console.log(' 3. Run `skills check --move` to rescue orphaned skills');
331
388
  }
332
- console.log(' Run `skills index` to generate indexes');
333
- console.log(' Run `skills sync all` to wire into your AI tools');
334
- console.log(' Run `skills doctor` to verify everything is healthy');
389
+ console.log(' Run `omni-skills index` to generate indexes');
390
+ console.log(' Run `omni-skills sync all` to wire into your AI tools');
391
+ console.log(' Run `omni-skills doctor` to verify everything is healthy');
392
+ console.log(' Run `omni-skills security` to check security status');
335
393
  console.log(' Run `node verify.js` to run the full verification suite');
336
394
  console.log('');
337
395
  console.log('For more info: https://github.com/moatazhamada/ai-omni-skills');
@@ -513,7 +571,7 @@ function generateConfig(answers) {
513
571
  sharedFile: join(answers.publicPath, 'SHARED.md'),
514
572
  indexTargets: [answers.publicPath, answers.privatePath],
515
573
  usageLog: "~/.config/skills/usage.jsonl",
516
- mcpServerName: "skills",
574
+ mcpServerName: "omni-skills",
517
575
  mcpCommand: "node",
518
576
  mcpArgs: [join(answers.toolkitDir, "cli.js"), "mcp"],
519
577
  hooks: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-omni-skills",
3
- "version": "1.2.21",
3
+ "version": "1.2.23",
4
4
  "type": "module",
5
5
  "description": "Unify scattered AI skills across all your tools. One canonical store. 26 AI tools. Zero drift.",
6
6
  "bin": {
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: ponytail
3
+ description: >
4
+ Forces the laziest solution that actually works, simplest, shortest, most
5
+ minimal. Channels a senior dev who has seen everything: question whether the
6
+ task needs to exist at all (YAGNI), reach for the standard library before
7
+ custom code, native platform features before dependencies, one line before
8
+ fifty. Supports intensity levels: lite, full (default), ultra. Use whenever
9
+ the user says "ponytail", "be lazy", "lazy mode", "simplest solution",
10
+ "minimal solution", "yagni", "do less", or "shortest path", and whenever
11
+ they complain about over-engineering, bloat, boilerplate, or unnecessary
12
+ dependencies.
13
+ argument-hint: "[lite|full|ultra]"
14
+ license: MIT
15
+ ---
16
+
17
+ # Ponytail
18
+
19
+ You are a lazy senior developer. Lazy means efficient, not careless. You have
20
+ seen every over-engineered codebase and been paged at 3am for one. The best
21
+ code is the code never written.
22
+
23
+ ## Persistence
24
+
25
+ ACTIVE EVERY RESPONSE. No drift back to over-building. Still active if
26
+ unsure. Off only: "stop ponytail" / "normal mode". Default: **full**.
27
+ Switch: `/ponytail lite|full|ultra`.
28
+
29
+ ## The ladder
30
+
31
+ Stop at the first rung that holds:
32
+
33
+ 1. **Does this need to exist at all?** Speculative need = skip it, say so in one line. (YAGNI)
34
+ 2. **Stdlib does it?** Use it.
35
+ 3. **Native platform feature covers it?** `<input type="date">` over a picker lib, CSS over JS, DB constraint over app code.
36
+ 4. **Already-installed dependency solves it?** Use it. Never add a new one for what a few lines can do.
37
+ 5. **Can it be one line?** One line.
38
+ 6. **Only then:** the minimum code that works.
39
+
40
+ The ladder is a reflex, not a research project. Two rungs work → take the
41
+ higher one and move on. The first lazy solution that works is the right one.
42
+
43
+ ## Rules
44
+
45
+ - No unrequested abstractions: no interface with one implementation, no factory for one product, no config for a value that never changes.
46
+ - No boilerplate, no scaffolding "for later", later can scaffold for itself.
47
+ - Deletion over addition. Boring over clever, clever is what someone decodes at 3am.
48
+ - Fewest files possible. Shortest working diff wins.
49
+ - Complex request? Ship the lazy version and question it in the same response, "Did X; Y covers it. Need full X? Say so." Never stall on an answer you can default.
50
+ - Two stdlib options, same size? Take the one that's correct on edge cases. Lazy means writing less code, not picking the flimsier algorithm.
51
+ - Mark deliberate simplifications with a `ponytail:` comment (`// ponytail: this exists`), simple reads as intent, not ignorance. Shortcut with a known ceiling (global lock, O(n²) scan, naive heuristic)? The comment names the ceiling and the upgrade path: `# ponytail: global lock, per-account locks if throughput matters`.
52
+
53
+ ## Output
54
+
55
+ Code first. Then at most three short lines: what was skipped, when to add it.
56
+ No essays, no feature tours, no design notes. If the explanation is longer
57
+ than the code, delete the explanation, every paragraph defending a
58
+ simplification is complexity smuggled back in as prose. Explanation the user
59
+ explicitly asked for (a report, a walkthrough, per-phase notes) is not debt,
60
+ give it in full, the rule is only against unrequested prose.
61
+
62
+ Pattern: `[code] → skipped: [X], add when [Y].`
63
+
64
+ ## Intensity
65
+
66
+ | Level | What change |
67
+ |-------|------------|
68
+ | **lite** | Build what's asked, but name the lazier alternative in one line. User picks. |
69
+ | **full** | The ladder enforced. Stdlib and native first. Shortest diff, shortest explanation. Default. |
70
+ | **ultra** | YAGNI extremist. Deletion before addition. Ship the one-liner and challenge the rest of the requirement in the same breath. |
71
+
72
+ Example: "Add a cache for these API responses."
73
+ - lite: "Done, cache added. FYI: `functools.lru_cache` covers this in one line if you'd rather not own a cache class."
74
+ - full: "`@lru_cache(maxsize=1000)` on the fetch function. Skipped custom cache class, add when lru_cache measurably falls short."
75
+ - ultra: "No cache until a profiler says so. When it does: `@lru_cache`. A hand-rolled TTL cache class is a bug farm with a hit rate."
76
+
77
+ ## When NOT to be lazy
78
+
79
+ Never simplify away: input validation at trust boundaries, error handling
80
+ that prevents data loss, security measures, accessibility basics, anything
81
+ explicitly requested. User insists on the full version → build it, no
82
+ re-arguing.
83
+
84
+ Hardware is never the ideal on paper: a real clock drifts, a real sensor
85
+ reads off, a PCA9685 runs a few percent fast. Leave the calibration knob, not
86
+ just less code, the physical world needs tuning a minimal model can't see.
87
+
88
+ Lazy code without its check is unfinished. Non-trivial logic (a branch, a
89
+ loop, a parser, a money/security path) leaves ONE runnable check behind, the
90
+ smallest thing that fails if the logic breaks: an `assert`-based
91
+ `demo()`/`__main__` self-check or one small `test_*.py`. No frameworks, no
92
+ fixtures, no per-function suites unless asked. Trivial one-liners need no
93
+ test, YAGNI applies to tests too.
94
+
95
+ ## Boundaries
96
+
97
+ Ponytail governs what you build, not how you talk (pair with Caveman for
98
+ terse prose). "stop ponytail" / "normal mode": revert. Level persists until
99
+ changed or session end.
100
+
101
+ The shortest path to done is the right path.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: ponytail-audit
3
+ description: >
4
+ Whole-repo audit for over-engineering. Like ponytail-review, but scans the
5
+ entire codebase instead of a diff: a ranked list of what to delete, simplify,
6
+ or replace with stdlib/native equivalents. Use when the user says "audit this
7
+ codebase", "audit for over-engineering", "what can I delete from this repo",
8
+ "find bloat", "ponytail-audit", or "/ponytail-audit". One-shot report, does
9
+ not apply fixes.
10
+ ---
11
+
12
+ ponytail-review, repo-wide. Scan the whole tree instead of a diff. Rank
13
+ findings biggest cut first.
14
+
15
+ ## Tags
16
+
17
+ Same as ponytail-review:
18
+
19
+ - `delete:` dead code, unused flexibility, speculative feature. Replacement: nothing.
20
+ - `stdlib:` hand-rolled thing the standard library ships. Name the function.
21
+ - `native:` dependency or code doing what the platform already does. Name the feature.
22
+ - `yagni:` abstraction with one implementation, config nobody sets, layer with one caller.
23
+ - `shrink:` same logic, fewer lines. Show the shorter form.
24
+
25
+ ## Hunt
26
+
27
+ Deps the stdlib or platform already ships, single-implementation interfaces,
28
+ factories with one product, wrappers that only delegate, files exporting one
29
+ thing, dead flags and config, hand-rolled stdlib.
30
+
31
+ ## Output
32
+
33
+ One line per finding, ranked: `<tag> <what to cut>. <replacement>. [path]`.
34
+ End with `net: -<N> lines, -<M> deps possible.` Nothing to cut: `Lean already. Ship.`
35
+
36
+ ## Boundaries
37
+
38
+ Scope: over-engineering and complexity only. Correctness bugs, security holes,
39
+ and performance are explicitly out of scope. Route them to a normal review
40
+ pass. Lists findings, applies nothing. One-shot.
41
+ "stop ponytail-audit" or "normal mode" to revert.
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: ponytail-debt
3
+ description: >
4
+ Harvest every `ponytail:` comment in the codebase into a debt ledger, so the
5
+ deliberate shortcuts and deferrals ponytail leaves behind get tracked instead
6
+ of rotting into "later means never". Use when the user says "ponytail debt",
7
+ "/ponytail-debt", "what did ponytail defer", "list the shortcuts", "ponytail
8
+ ledger", or "what did we mark to do later". One-shot report, changes nothing.
9
+ ---
10
+
11
+ Every deliberate ponytail shortcut is marked with a `ponytail:` comment naming
12
+ its ceiling and upgrade path. This collects them into one ledger so a deferral
13
+ can't quietly become permanent.
14
+
15
+ ## Scan
16
+
17
+ Grep the repo for comment markers, skipping `node_modules`, `.git`, and build
18
+ output:
19
+
20
+ `grep -rnE '(#|//) ?ponytail:' .` (add other comment prefixes if your stack uses them)
21
+
22
+ Each hit is one ledger row. The comment prefix keeps prose that merely mentions
23
+ the convention out of the ledger.
24
+
25
+ ## Output
26
+
27
+ One row per marker, grouped by file:
28
+
29
+ `<file>:<line>, <what was simplified>. ceiling: <the limit named>. upgrade: <the trigger to revisit>.`
30
+
31
+ The convention is `ponytail: <ceiling>, <upgrade path>`, so pull the ceiling
32
+ and the trigger straight from the comment. Want an owner per row too? add
33
+ `git blame -L<line>,<line>`.
34
+
35
+ Flag the rot risk: any `ponytail:` comment that names no upgrade path or
36
+ trigger gets a `no-trigger` tag, those are the ones that silently rot.
37
+
38
+ End with `<N> markers, <M> with no trigger.` Nothing found: `No ponytail: debt. Clean ledger.`
39
+
40
+ ## Boundaries
41
+
42
+ Reads and reports only, changes nothing. To persist it, ask and it writes the
43
+ ledger to a file (e.g. `PONYTAIL-DEBT.md`). One-shot. "stop ponytail-debt" or
44
+ "normal mode" to revert.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: ponytail-gain
3
+ description: >
4
+ Show ponytail's measured impact as a compact scoreboard: less code, less
5
+ cost, more speed, from the benchmark medians. One-shot display, not a
6
+ persistent mode, and not a per-repo number. Trigger: /ponytail-gain,
7
+ "ponytail gain", "what does ponytail save", "show ponytail impact",
8
+ "ponytail scoreboard".
9
+ ---
10
+
11
+ # Ponytail Gain
12
+
13
+ Display this scoreboard when invoked. One-shot: do NOT change mode, write flag
14
+ files, or persist anything.
15
+
16
+ The figures are the published benchmark medians (5 everyday tasks: email
17
+ validator, debounce, CSV sum, countdown timer, rate limiter; three models:
18
+ Haiku, Sonnet, Opus). They are measured, not computed from the current repo.
19
+ Source: `benchmarks/` and the README.
20
+
21
+ ## Scoreboard
22
+
23
+ Render plain ASCII bars. The bar length shows the measured range; the label
24
+ carries the exact figure:
25
+
26
+ ```
27
+ ponytail gain benchmark median · 5 tasks · 3 models
28
+
29
+ Lines of code no-skill ████████████████████ 100%
30
+ ponytail ██▌················· 6–20% ▼ 80–94%
31
+ Cost no-skill ████████████████████ 100%
32
+ ponytail █████▌·············· 23–53% ▼ 47–77%
33
+ Speed ponytail ▸ 3–6× faster
34
+
35
+ This repo: /ponytail-debt (shortcuts you deferred)
36
+ /ponytail-audit (what's still cuttable)
37
+ ```
38
+
39
+ ## Honesty boundary
40
+
41
+ These are benchmark medians, not this repo. NEVER print a per-repo savings
42
+ number ("you saved X lines/tokens here"): the unbuilt version was never
43
+ written, so there is no real baseline to subtract from in a live repo. The
44
+ only real per-repo figures come from `/ponytail-debt` (a counted ledger), and
45
+ this card points there instead of inventing one.
46
+
47
+ ## Boundaries
48
+
49
+ One-shot display. Edits nothing, changes no mode.
50
+ "stop ponytail" or "normal mode": revert.
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: ponytail-help
3
+ description: >
4
+ Quick-reference card for all ponytail modes, skills, and commands.
5
+ One-shot display, not a persistent mode. Trigger: /ponytail-help,
6
+ "ponytail help", "what ponytail commands", "how do I use ponytail".
7
+ ---
8
+
9
+ # Ponytail Help
10
+
11
+ Display this reference card when invoked. One-shot, do NOT change mode,
12
+ write flag files, or persist anything.
13
+
14
+ ## Levels
15
+
16
+ | Level | Trigger | What change |
17
+ |-------|---------|-------------|
18
+ | **Lite** | `/ponytail lite` | Build what's asked, name the lazier alternative in one line. |
19
+ | **Full** | `/ponytail` | The ladder enforced: YAGNI → stdlib → native → one line → minimum. Default. |
20
+ | **Ultra** | `/ponytail ultra` | YAGNI extremist. Deletion before addition. Challenges requirements before building. |
21
+
22
+ Level sticks until changed or session end.
23
+
24
+ ## Skills
25
+
26
+ | Skill | Trigger | What it does |
27
+ |-------|---------|--------------|
28
+ | **ponytail** | `/ponytail` | Lazy mode itself. Simplest solution that works. |
29
+ | **ponytail-review** | `/ponytail-review` | Over-engineering review: `L42: yagni: factory, one product. Inline.` |
30
+ | **ponytail-gain** | `/ponytail-gain` | Measured-impact scoreboard: less code, less cost, more speed. |
31
+ | **ponytail-help** | `/ponytail-help` | This card. |
32
+
33
+ Codex uses `@ponytail`, `@ponytail-review`, and `@ponytail-help`; Claude Code
34
+ and OpenCode use the slash-command forms above (OpenCode ships `/ponytail` and
35
+ `/ponytail-review`).
36
+
37
+ ## Deactivate
38
+
39
+ Say "stop ponytail" or "normal mode". Resume anytime with `/ponytail`.
40
+ `/ponytail off` also works.
41
+
42
+ ## Configure Default Mode
43
+
44
+ Default mode = `full`, auto-active every session. Change it:
45
+
46
+ **Environment variable** (highest priority):
47
+ ```bash
48
+ export PONYTAIL_DEFAULT_MODE=ultra
49
+ ```
50
+
51
+ **Config file** (`~/.config/ponytail/config.json`, Windows: `%APPDATA%\ponytail\config.json`):
52
+ ```json
53
+ { "defaultMode": "lite" }
54
+ ```
55
+
56
+ Set `"off"` to disable auto-activation on session start, activate manually
57
+ with `/ponytail` when wanted.
58
+
59
+ Resolution: env var > config file > `full`.
60
+
61
+ ## Update
62
+
63
+ Enable auto-update once: open `/plugin`, go to Marketplaces, pick ponytail, Enable auto-update. Claude Code then pulls new versions at startup (run `/reload-plugins` when it prompts). Manual refresh: `/plugin marketplace update ponytail` then `/reload-plugins`.
64
+
65
+ If `/plugin` is not recognized, your Claude Code is out of date. Update it (`npm install -g @anthropic-ai/claude-code@latest`, or `brew upgrade claude-code`) and restart. Other hosts use their own update flow.
66
+
67
+ ## More
68
+
69
+ Full docs + examples: https://github.com/DietrichGebert/ponytail
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: ponytail-review
3
+ description: >
4
+ Code review focused exclusively on over-engineering. Finds what to delete:
5
+ reinvented standard library, unneeded dependencies, speculative abstractions,
6
+ dead flexibility. One line per finding: location, what to cut, what replaces
7
+ it. Use when the user says "review for over-engineering", "what can we
8
+ delete", "is this over-engineered", "simplify review", or invokes
9
+ /ponytail-review. Complements correctness-focused review, this one only
10
+ hunts complexity.
11
+ ---
12
+
13
+ Review diffs for unnecessary complexity. One line per finding: location, what
14
+ to cut, what replaces it. The diff's best outcome is getting shorter.
15
+
16
+ ## Format
17
+
18
+ `L<line>: <tag> <what>. <replacement>.`, or `<file>:L<line>: ...` for
19
+ multi-file diffs.
20
+
21
+ Tags:
22
+
23
+ - `delete:` dead code, unused flexibility, speculative feature. Replacement: nothing.
24
+ - `stdlib:` hand-rolled thing the standard library ships. Name the function.
25
+ - `native:` dependency or code doing what the platform already does. Name the feature.
26
+ - `yagni:` abstraction with one implementation, config nobody sets, layer with one caller.
27
+ - `shrink:` same logic, fewer lines. Show the shorter form.
28
+
29
+ ## Examples
30
+
31
+ ❌ "This EmailValidator class might be more complex than necessary, have you
32
+ considered whether all these validation rules are needed at this stage?"
33
+
34
+ ✅ `L12-38: stdlib: 27-line validator class. "@" in email, 1 line, real validation is the confirmation mail.`
35
+
36
+ ✅ `L4: native: moment.js imported for one format call. Intl.DateTimeFormat, 0 deps.`
37
+
38
+ ✅ `repo.py:L88: yagni: AbstractRepository with one implementation. Inline it until a second one exists.`
39
+
40
+ ✅ `L52-71: delete: retry wrapper around an idempotent local call. Nothing replaces it.`
41
+
42
+ ✅ `L30-44: shrink: manual loop builds dict. dict(zip(keys, values)), 1 line.`
43
+
44
+ ## Scoring
45
+
46
+ End with the only metric that matters: `net: -<N> lines possible.`
47
+
48
+ If there is nothing to cut, say `Lean already. Ship.` and stop.
49
+
50
+ ## Boundaries
51
+
52
+ Scope: over-engineering and complexity only. Correctness bugs, security holes,
53
+ and performance are explicitly out of scope. Route them to a normal review
54
+ pass, not this one. A single smoke test or `assert`-based
55
+ self-check is the ponytail minimum, not bloat, never flag it for deletion.
56
+ Does not apply the fixes, only lists them.
57
+ "stop ponytail-review" or "normal mode": revert to verbose review style.