agent-skill-manager 1.0.0 → 1.1.0

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.
@@ -46,7 +46,7 @@ an individual is officially representing the community in public spaces.
46
46
 
47
47
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
48
48
  reported to the project maintainers via
49
- [GitHub Issues](https://github.com/luongnv89/skill-manager/issues).
49
+ [GitHub Issues](https://github.com/luongnv89/agent-skill-manager/issues).
50
50
 
51
51
  All complaints will be reviewed and investigated promptly and fairly.
52
52
 
package/CONTRIBUTING.md CHANGED
@@ -1,4 +1,4 @@
1
- # Contributing to skill-manager
1
+ # Contributing to agent-skill-manager
2
2
 
3
3
  Thanks for your interest in contributing! This guide will help you get started.
4
4
 
@@ -12,8 +12,8 @@ Thanks for your interest in contributing! This guide will help you get started.
12
12
  ### Development Setup
13
13
 
14
14
  ```bash
15
- git clone https://github.com/luongnv89/skill-manager.git
16
- cd skill-manager
15
+ git clone https://github.com/luongnv89/agent-skill-manager.git
16
+ cd agent-skill-manager
17
17
  bun install
18
18
  bun run start # Launch the TUI
19
19
  ```
@@ -29,7 +29,7 @@ bun run typecheck # Type-check without emitting
29
29
 
30
30
  ### Reporting Bugs
31
31
 
32
- Open a [bug report](https://github.com/luongnv89/skill-manager/issues/new?template=bug_report.md) with:
32
+ Open a [bug report](https://github.com/luongnv89/agent-skill-manager/issues/new?template=bug_report.md) with:
33
33
 
34
34
  - Steps to reproduce
35
35
  - Expected vs. actual behavior
@@ -37,7 +37,7 @@ Open a [bug report](https://github.com/luongnv89/skill-manager/issues/new?templa
37
37
 
38
38
  ### Suggesting Features
39
39
 
40
- Open a [feature request](https://github.com/luongnv89/skill-manager/issues/new?template=feature_request.md) describing the problem and your proposed solution.
40
+ Open a [feature request](https://github.com/luongnv89/agent-skill-manager/issues/new?template=feature_request.md) describing the problem and your proposed solution.
41
41
 
42
42
  ### Submitting Code
43
43
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <picture>
3
3
  <source media="(prefers-color-scheme: dark)" srcset="assets/logo/logo-full.svg" />
4
4
  <source media="(prefers-color-scheme: light)" srcset="assets/logo/logo-black.svg" />
5
- <img src="assets/logo/logo-full.svg" alt="skill-manager" width="480" />
5
+ <img src="assets/logo/logo-full.svg" alt="agent-skill-manager" width="560" />
6
6
  </picture>
7
7
  </p>
8
8
 
@@ -25,12 +25,16 @@
25
25
 
26
26
  ---
27
27
 
28
- **skill-manager** is an interactive terminal UI for managing installed skills across AI coding agents — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Codex](https://github.com/openai/codex), [OpenClaw](https://github.com/openclaw), and more. Built with [OpenTUI](https://github.com/nicholasgasior/opentui) and [Bun](https://bun.sh).
28
+ **agent-skill-manager** is an interactive terminal UI for managing installed skills across AI coding agents — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Codex](https://github.com/openai/codex), [OpenClaw](https://github.com/openclaw), and more. Built with [OpenTUI](https://github.com/nicholasgasior/opentui) and [Bun](https://bun.sh).
29
+
30
+ <p align="center">
31
+ <img src="assets/screenshots/agent-skill-manager.png" alt="agent-skill-manager TUI dashboard" width="800" />
32
+ </p>
29
33
 
30
34
  ## Features
31
35
 
32
36
  - **Multi-agent support** — Manage skills for Claude Code, Codex, OpenClaw, and custom agent tools from one TUI
33
- - **Configurable providers** — Define which agent tool directories to scan via `~/.config/skill-manager/config.json`
37
+ - **Configurable providers** — Define which agent tool directories to scan via `~/.config/agent-skill-manager/config.json`
34
38
  - **Global & project scopes** — Filter skills by global (`~/.<tool>/skills/`) or project-level (`./<tool>/skills/`)
35
39
  - **Real-time search** — Filter skills by name, description, or provider
36
40
  - **Sort** — By name, version, or location
@@ -40,27 +44,52 @@
40
44
 
41
45
  ## Install
42
46
 
47
+ ### Quick Install (one command)
48
+
49
+ ```bash
50
+ curl -sSL https://raw.githubusercontent.com/luongnv89/agent-skill-manager/main/install.sh | bash
51
+ ```
52
+
53
+ Or with wget:
54
+
55
+ ```bash
56
+ wget -qO- https://raw.githubusercontent.com/luongnv89/agent-skill-manager/main/install.sh | bash
57
+ ```
58
+
59
+ This will automatically install [Bun](https://bun.sh) (if not already installed) and then install `agent-skill-manager` globally.
60
+
61
+ ### Manual Install
62
+
43
63
  **Prerequisites:** [Bun](https://bun.sh) >= 1.0.0
44
64
 
45
65
  ```bash
46
66
  bun install -g agent-skill-manager
47
67
  ```
48
68
 
49
- Or run directly from source:
69
+ ### From Source
50
70
 
51
71
  ```bash
52
- git clone https://github.com/luongnv89/skill-manager.git
53
- cd skill-manager
72
+ git clone https://github.com/luongnv89/agent-skill-manager.git
73
+ cd agent-skill-manager
54
74
  bun install
55
75
  bun run start
56
76
  ```
57
77
 
78
+ ### Advanced Options
79
+
80
+ ```bash
81
+ # Download and inspect before running
82
+ curl -sSL https://raw.githubusercontent.com/luongnv89/agent-skill-manager/main/install.sh -o install.sh
83
+ less install.sh # review the script
84
+ bash install.sh
85
+ ```
86
+
58
87
  ## Usage
59
88
 
60
89
  ```bash
61
- skill-manager # Launch the interactive TUI
62
- skill-manager --help # Show help
63
- skill-manager --version # Show version
90
+ agent-skill-manager # Launch the interactive TUI
91
+ agent-skill-manager --help # Show help
92
+ agent-skill-manager --version # Show version
64
93
  ```
65
94
 
66
95
  ## Keyboard Shortcuts
@@ -81,7 +110,7 @@ skill-manager --version # Show version
81
110
 
82
111
  ## Configuration
83
112
 
84
- On first run, a config file is created at `~/.config/skill-manager/config.json` with default providers:
113
+ On first run, a config file is created at `~/.config/agent-skill-manager/config.json` with default providers:
85
114
 
86
115
  ```json
87
116
  {
@@ -145,9 +174,9 @@ Additional tools can be added via the config file.
145
174
  ## Project Structure
146
175
 
147
176
  ```
148
- skill-manager/
177
+ agent-skill-manager/
149
178
  ├── bin/ # CLI entry point
150
- │ └── skill-manager.ts
179
+ │ └── agent-skill-manager.ts
151
180
  ├── src/
152
181
  │ ├── index.ts # App bootstrap & keyboard handling
153
182
  │ ├── config.ts # Config loading & saving
package/RELEASE_NOTES.md CHANGED
@@ -1,31 +1,22 @@
1
- ## v1.0.0 — 2025-03-11
2
-
3
- Initial release of **skill-manager** — the universal skill manager for AI coding agents.
1
+ ## v1.1.0 — 2026-03-11
4
2
 
5
3
  ### Features
6
4
 
7
- - Interactive TUI dashboard built with OpenTUI and Bun
8
- - Multi-agent support: Claude Code, Codex, OpenClaw, and generic Agents
9
- - Configurable providers via `~/.config/skill-manager/config.json`
10
- - Global and project scope filtering with Tab cycling
11
- - Real-time search and sort (by name, version, location)
12
- - Detailed skill view with SKILL.md frontmatter metadata
13
- - Safe uninstall with confirmation dialog and full removal plan
14
- - In-TUI config editor — toggle providers on/off or open in `$EDITOR`
15
- - CLI entry point with `--help` and `--version` flags
16
- - Neon green logo suite and brand kit
5
+ - Add one-command install script for `curl | bash` usage (dee8bb2)
6
+ - Add non-interactive CLI mode with `asm` shorthand command (3904bdc)
7
+ - Rebrand project to agent-skill-manager across all files (944c877)
8
+ - Rename package to agent-skill-manager and add version info to help (5fe6ed3)
17
9
 
18
- ### Infrastructure
10
+ ### Bug Fixes
19
11
 
20
- - Pre-commit hooks (Prettier, TypeScript type-checking)
21
- - GitHub Actions CI pipeline (type-check + tests)
22
- - 63 unit tests covering config, scanner, uninstaller, and frontmatter modules
23
- - OSS-ready: LICENSE, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, issue/PR templates
12
+ - Handle Bun global bin PATH and create asm/agent-skill-manager aliases in installer (268c2bd)
13
+ - Remove external font import from SVGs for GitHub rendering (c75a985)
24
14
 
25
- ### Install
15
+ ### Other Changes
26
16
 
27
- ```bash
28
- bun install -g agent-skill-manager
29
- ```
17
+ - Rename bin entry point to agent-skill-manager.ts (8ac0ae1)
18
+ - Add .npmignore to exclude unnecessary files from npm package (8339a45)
19
+ - Add TUI screenshot to README and update logo width (339eb04)
20
+ - Remove obsolete RELEASE_NOTES.md and CLI_PLAN.md (ec0d9a9)
30
21
 
31
- **Full Changelog**: https://github.com/luongnv89/skill-manager/commits/v1.0.0
22
+ **Full Changelog**: https://github.com/luongnv89/agent-skill-manager/compare/v1.0.0...v1.1.0
package/SECURITY.md CHANGED
@@ -13,7 +13,7 @@ We take security vulnerabilities seriously. If you discover a security issue, pl
13
13
  ### How to Report
14
14
 
15
15
  1. **Do NOT** open a public GitHub issue for security vulnerabilities
16
- 2. Open a [private security advisory](https://github.com/luongnv89/skill-manager/security/advisories/new) on GitHub
16
+ 2. Open a [private security advisory](https://github.com/luongnv89/agent-skill-manager/security/advisories/new) on GitHub
17
17
  3. Include detailed steps to reproduce the vulnerability
18
18
  4. Allow up to 48 hours for an initial response
19
19
 
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { isCLIMode, runCLI } from "../src/cli";
4
+
5
+ if (isCLIMode(process.argv)) {
6
+ await runCLI(process.argv);
7
+ } else {
8
+ // No args — launch interactive TUI
9
+ await import("../src/index.ts");
10
+ }
11
+
12
+ export {};
@@ -2,11 +2,11 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- skill-manager is a terminal UI application that scans, displays, and manages skills installed for various AI coding agents. It follows a simple layered architecture: CLI entry → app bootstrap → core modules → TUI views.
5
+ agent-skill-manager is a terminal UI application that scans, displays, and manages skills installed for various AI coding agents. It follows a simple layered architecture: CLI entry → app bootstrap → core modules → TUI views.
6
6
 
7
7
  ## Components
8
8
 
9
- ### CLI Entry (`bin/skill-manager.ts`)
9
+ ### CLI Entry (`bin/agent-skill-manager.ts`)
10
10
 
11
11
  Handles `--help` and `--version` flags, then delegates to the main app entry point.
12
12
 
@@ -16,11 +16,11 @@ Initializes the OpenTUI renderer, wires up keyboard handlers, and manages view s
16
16
 
17
17
  ### Core Modules
18
18
 
19
- | Module | Responsibility |
20
- | -------------------- | ----------------------------------------------------------- |
21
- | `src/config.ts` | Load/save config from `~/.config/skill-manager/config.json` |
22
- | `src/scanner.ts` | Walk provider directories, parse SKILL.md, filter & sort |
23
- | `src/uninstaller.ts` | Build removal plans and execute safe deletions |
19
+ | Module | Responsibility |
20
+ | -------------------- | ----------------------------------------------------------------- |
21
+ | `src/config.ts` | Load/save config from `~/.config/agent-skill-manager/config.json` |
22
+ | `src/scanner.ts` | Walk provider directories, parse SKILL.md, filter & sort |
23
+ | `src/uninstaller.ts` | Build removal plans and execute safe deletions |
24
24
 
25
25
  ### Views (`src/views/`)
26
26
 
package/docs/CHANGELOG.md CHANGED
@@ -4,13 +4,37 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [1.1.0] - 2026-03-11
8
+
9
+ ### Added
10
+
11
+ - One-command install script (`curl | bash`) with automatic Bun installation
12
+ - Non-interactive CLI mode with `asm` shorthand command
13
+ - .npmignore to exclude unnecessary files from npm package
14
+ - TUI screenshot in README
15
+
16
+ ### Fixed
17
+
18
+ - Bun global bin PATH handling and asm/agent-skill-manager alias creation in installer
19
+ - External font import in SVGs for GitHub rendering
20
+
21
+ ### Changed
22
+
23
+ - Rebranded project to agent-skill-manager across all files
24
+ - Renamed bin entry point to `agent-skill-manager.ts` to match package name
25
+ - Renamed package to agent-skill-manager with version info in help output
26
+
27
+ ### Removed
28
+
29
+ - Obsolete CLI_PLAN.md
30
+
7
31
  ## [1.0.0] - 2025-03-11
8
32
 
9
33
  ### Added
10
34
 
11
35
  - Interactive TUI dashboard with OpenTUI
12
36
  - Multi-agent support: Claude Code, Codex, OpenClaw, and generic Agents
13
- - Configurable providers via `~/.config/skill-manager/config.json`
37
+ - Configurable providers via `~/.config/agent-skill-manager/config.json`
14
38
  - Global and project scope filtering
15
39
  - Real-time search and sort (by name, version, location)
16
40
  - Detailed skill view with SKILL.md frontmatter metadata
@@ -2,14 +2,14 @@
2
2
 
3
3
  ## Publishing to npm (via Bun)
4
4
 
5
- skill-manager is distributed as a global CLI package.
5
+ agent-skill-manager is distributed as a global CLI package.
6
6
 
7
7
  ### 1. Bump the version
8
8
 
9
9
  Update the version in both files:
10
10
 
11
11
  - `package.json` → `"version"`
12
- - `bin/skill-manager.ts` → `VERSION` constant
12
+ - `bin/agent-skill-manager.ts` → `VERSION` constant
13
13
 
14
14
  ### 2. Build and publish
15
15
 
@@ -36,8 +36,8 @@ bun install -g agent-skill-manager
36
36
  For development or CI environments:
37
37
 
38
38
  ```bash
39
- git clone https://github.com/luongnv89/skill-manager.git
40
- cd skill-manager
39
+ git clone https://github.com/luongnv89/agent-skill-manager.git
40
+ cd agent-skill-manager
41
41
  bun install
42
42
  bun run start
43
43
  ```
@@ -8,8 +8,8 @@
8
8
  ## Setup
9
9
 
10
10
  ```bash
11
- git clone https://github.com/luongnv89/skill-manager.git
12
- cd skill-manager
11
+ git clone https://github.com/luongnv89/agent-skill-manager.git
12
+ cd agent-skill-manager
13
13
  bun install
14
14
  ```
15
15
 
package/install.sh ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # ============================================================================
5
+ # agent-skill-manager Installer
6
+ # The universal skill manager for AI coding agents.
7
+ #
8
+ # Usage:
9
+ # curl -sSL https://raw.githubusercontent.com/luongnv89/agent-skill-manager/main/install.sh | bash
10
+ # wget -qO- https://raw.githubusercontent.com/luongnv89/agent-skill-manager/main/install.sh | bash
11
+ # ============================================================================
12
+
13
+ TOOL_NAME="agent-skill-manager"
14
+ REPO_OWNER="luongnv89"
15
+ REPO_NAME="agent-skill-manager"
16
+ BUN_MIN_VERSION="1.0.0"
17
+
18
+ # --- Color Output ---
19
+ RED='\033[0;31m'
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ BLUE='\033[0;34m'
23
+ NC='\033[0m'
24
+
25
+ info() { printf "${BLUE}[INFO]${NC} %s\n" "$*"; }
26
+ ok() { printf "${GREEN}[ OK ]${NC} %s\n" "$*"; }
27
+ warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$*"; }
28
+ err() { printf "${RED}[ERR ]${NC} %s\n" "$*" >&2; }
29
+ die() { err "$@"; exit 1; }
30
+
31
+ # --- OS / Arch Detection ---
32
+ detect_os() {
33
+ local os
34
+ os="$(uname -s | tr '[:upper:]' '[:lower:]')"
35
+ case "$os" in
36
+ linux*) echo "linux" ;;
37
+ darwin*) echo "macos" ;;
38
+ mingw*|msys*|cygwin*) echo "windows" ;;
39
+ *) die "Unsupported operating system: $os" ;;
40
+ esac
41
+ }
42
+
43
+ detect_arch() {
44
+ local arch
45
+ arch="$(uname -m)"
46
+ case "$arch" in
47
+ x86_64|amd64) echo "x86_64" ;;
48
+ aarch64|arm64) echo "arm64" ;;
49
+ armv7l) echo "armv7" ;;
50
+ *) die "Unsupported architecture: $arch" ;;
51
+ esac
52
+ }
53
+
54
+ # --- Version Comparison ---
55
+ # Returns 0 if $1 >= $2 (semver)
56
+ version_gte() {
57
+ local IFS=.
58
+ local i ver1=($1) ver2=($2)
59
+ for ((i=0; i<${#ver2[@]}; i++)); do
60
+ local v1="${ver1[i]:-0}"
61
+ local v2="${ver2[i]:-0}"
62
+ if ((v1 > v2)); then return 0; fi
63
+ if ((v1 < v2)); then return 1; fi
64
+ done
65
+ return 0
66
+ }
67
+
68
+ # --- Bun Detection & Installation ---
69
+ check_bun() {
70
+ if command -v bun &>/dev/null; then
71
+ local bun_version
72
+ bun_version="$(bun --version 2>/dev/null || echo "0.0.0")"
73
+ if version_gte "$bun_version" "$BUN_MIN_VERSION"; then
74
+ ok "Bun $bun_version found (>= $BUN_MIN_VERSION required)"
75
+ return 0
76
+ else
77
+ warn "Bun $bun_version found but >= $BUN_MIN_VERSION is required"
78
+ return 1
79
+ fi
80
+ else
81
+ return 1
82
+ fi
83
+ }
84
+
85
+ install_bun() {
86
+ info "Installing Bun..."
87
+ if command -v curl &>/dev/null; then
88
+ curl -fsSL https://bun.sh/install | bash
89
+ elif command -v wget &>/dev/null; then
90
+ wget -qO- https://bun.sh/install | bash
91
+ else
92
+ die "Neither curl nor wget found. Please install one of them first."
93
+ fi
94
+
95
+ # Source bun into current shell
96
+ local bun_install="${BUN_INSTALL:-$HOME/.bun}"
97
+ if [ -f "$bun_install/bin/bun" ]; then
98
+ export BUN_INSTALL="$bun_install"
99
+ export PATH="$bun_install/bin:$PATH"
100
+ fi
101
+
102
+ if ! command -v bun &>/dev/null; then
103
+ die "Bun installation completed but 'bun' is not in PATH. Please restart your shell and re-run this script."
104
+ fi
105
+
106
+ ok "Bun $(bun --version) installed"
107
+ }
108
+
109
+ # --- Ensure Bun global bin is in PATH ---
110
+ ensure_bun_in_path() {
111
+ local bun_bin="${BUN_INSTALL:-$HOME/.bun}/bin"
112
+ if [[ ":$PATH:" != *":$bun_bin:"* ]]; then
113
+ export PATH="$bun_bin:$PATH"
114
+ info "Added $bun_bin to PATH for this session"
115
+ fi
116
+ }
117
+
118
+ # --- Install agent-skill-manager ---
119
+ install_asm() {
120
+ info "Installing $TOOL_NAME globally via Bun..."
121
+ bun install -g "$TOOL_NAME"
122
+ ok "$TOOL_NAME installed globally"
123
+ }
124
+
125
+ # --- Create command aliases ---
126
+ create_aliases() {
127
+ local bun_bin="${BUN_INSTALL:-$HOME/.bun}/bin"
128
+ local bin_target=""
129
+
130
+ # Find the actual installed binary (could be skill-manager or agent-skill-manager)
131
+ for name in skill-manager agent-skill-manager; do
132
+ if [ -f "$bun_bin/$name" ] || [ -L "$bun_bin/$name" ]; then
133
+ bin_target="$bun_bin/$name"
134
+ break
135
+ fi
136
+ done
137
+
138
+ if [ -z "$bin_target" ]; then
139
+ warn "Could not find installed binary in $bun_bin"
140
+ return 1
141
+ fi
142
+
143
+ # Create symlinks for all expected command names
144
+ for alias_name in agent-skill-manager asm; do
145
+ local alias_path="$bun_bin/$alias_name"
146
+ if [ ! -f "$alias_path" ] && [ ! -L "$alias_path" ]; then
147
+ ln -s "$bin_target" "$alias_path"
148
+ ok "Created alias: $alias_name"
149
+ fi
150
+ done
151
+ }
152
+
153
+ # --- Verification ---
154
+ verify_installation() {
155
+ info "Verifying installation..."
156
+ local found=false
157
+
158
+ for cmd in agent-skill-manager asm skill-manager; do
159
+ if command -v "$cmd" &>/dev/null; then
160
+ ok "$cmd is available"
161
+ found=true
162
+ fi
163
+ done
164
+
165
+ if [ "$found" = false ]; then
166
+ warn "No commands found in PATH"
167
+ warn "Add Bun's global bin to your PATH by adding this to your shell profile:"
168
+ warn " export PATH=\"\$HOME/.bun/bin:\$PATH\""
169
+ return 1
170
+ fi
171
+
172
+ return 0
173
+ }
174
+
175
+ # --- Entry Point ---
176
+ main() {
177
+ echo ""
178
+ info "============================================"
179
+ info " $TOOL_NAME Installer"
180
+ info "============================================"
181
+ echo ""
182
+
183
+ local os arch
184
+ os="$(detect_os)"
185
+ arch="$(detect_arch)"
186
+ info "OS: $os | Arch: $arch"
187
+ echo ""
188
+
189
+ # Step 1: Ensure Bun is installed
190
+ if ! check_bun; then
191
+ install_bun
192
+ fi
193
+ echo ""
194
+
195
+ # Step 2: Ensure Bun global bin is in PATH
196
+ ensure_bun_in_path
197
+
198
+ # Step 3: Install agent-skill-manager
199
+ install_asm
200
+ echo ""
201
+
202
+ # Step 4: Create aliases (agent-skill-manager, asm)
203
+ create_aliases
204
+ echo ""
205
+
206
+ # Step 5: Verify
207
+ if verify_installation; then
208
+ echo ""
209
+ info "============================================"
210
+ ok "Installation complete!"
211
+ info "============================================"
212
+ echo ""
213
+ info "Get started:"
214
+ info " asm # Launch interactive TUI (shorthand)"
215
+ info " agent-skill-manager # Launch interactive TUI"
216
+ info " asm --help # Show help"
217
+ echo ""
218
+ else
219
+ echo ""
220
+ warn "Installation finished but verification had warnings."
221
+ warn "Try restarting your terminal, then run: agent-skill-manager"
222
+ echo ""
223
+ fi
224
+ }
225
+
226
+ main "$@"
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "agent-skill-manager",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Interactive TUI for managing installed skills for AI coding agents (Claude Code, Codex, OpenClaw, and more)",
5
5
  "type": "module",
6
6
  "bin": {
7
- "skill-manager": "bin/skill-manager.ts"
7
+ "agent-skill-manager": "bin/agent-skill-manager.ts",
8
+ "asm": "bin/agent-skill-manager.ts"
8
9
  },
9
10
  "scripts": {
10
11
  "start": "bun run src/index.ts",
@@ -19,7 +20,7 @@
19
20
  "bun": ">=1.0.0"
20
21
  },
21
22
  "keywords": [
22
- "skill-manager",
23
+ "agent-skill-manager",
23
24
  "tui",
24
25
  "cli",
25
26
  "ai-agents",
@@ -30,13 +31,13 @@
30
31
  ],
31
32
  "author": "luongnv89",
32
33
  "license": "MIT",
33
- "homepage": "https://github.com/luongnv89/skill-manager#readme",
34
+ "homepage": "https://github.com/luongnv89/agent-skill-manager#readme",
34
35
  "repository": {
35
36
  "type": "git",
36
- "url": "git+https://github.com/luongnv89/skill-manager.git"
37
+ "url": "git+https://github.com/luongnv89/agent-skill-manager.git"
37
38
  },
38
39
  "bugs": {
39
- "url": "https://github.com/luongnv89/skill-manager/issues"
40
+ "url": "https://github.com/luongnv89/agent-skill-manager/issues"
40
41
  },
41
42
  "devDependencies": {
42
43
  "bun-types": "^1.3.10"
package/src/cli.ts ADDED
@@ -0,0 +1,488 @@
1
+ import {
2
+ loadConfig,
3
+ getConfigPath,
4
+ getDefaultConfig,
5
+ saveConfig,
6
+ } from "./config";
7
+ import { scanAllSkills, searchSkills, sortSkills } from "./scanner";
8
+ import {
9
+ buildFullRemovalPlan,
10
+ executeRemoval,
11
+ getExistingTargets,
12
+ } from "./uninstaller";
13
+ import {
14
+ formatSkillTable,
15
+ formatSkillDetail,
16
+ formatJSON,
17
+ ansi,
18
+ } from "./formatter";
19
+ import { VERSION_STRING } from "./utils/version";
20
+ import type { Scope, SortBy } from "./utils/types";
21
+
22
+ // ─── Arg Parser ─────────────────────────────────────────────────────────────
23
+
24
+ interface ParsedArgs {
25
+ command: string | null;
26
+ subcommand: string | null;
27
+ positional: string[];
28
+ flags: {
29
+ help: boolean;
30
+ version: boolean;
31
+ json: boolean;
32
+ yes: boolean;
33
+ noColor: boolean;
34
+ scope: Scope;
35
+ sort: SortBy;
36
+ };
37
+ }
38
+
39
+ export function parseArgs(argv: string[]): ParsedArgs {
40
+ const args = argv.slice(2); // skip bun and script path
41
+
42
+ const result: ParsedArgs = {
43
+ command: null,
44
+ subcommand: null,
45
+ positional: [],
46
+ flags: {
47
+ help: false,
48
+ version: false,
49
+ json: false,
50
+ yes: false,
51
+ noColor: false,
52
+ scope: "both",
53
+ sort: "name",
54
+ },
55
+ };
56
+
57
+ let i = 0;
58
+ while (i < args.length) {
59
+ const arg = args[i];
60
+
61
+ // Flags
62
+ if (arg === "--help" || arg === "-h") {
63
+ result.flags.help = true;
64
+ } else if (arg === "--version" || arg === "-v") {
65
+ result.flags.version = true;
66
+ } else if (arg === "--json") {
67
+ result.flags.json = true;
68
+ } else if (arg === "--yes" || arg === "-y") {
69
+ result.flags.yes = true;
70
+ } else if (arg === "--no-color") {
71
+ result.flags.noColor = true;
72
+ } else if (arg === "--scope" || arg === "-s") {
73
+ i++;
74
+ const val = args[i];
75
+ if (val === "global" || val === "project" || val === "both") {
76
+ result.flags.scope = val;
77
+ } else {
78
+ error(`Invalid scope: "${val}". Must be global, project, or both.`);
79
+ process.exit(2);
80
+ }
81
+ } else if (arg === "--sort") {
82
+ i++;
83
+ const val = args[i];
84
+ if (val === "name" || val === "version" || val === "location") {
85
+ result.flags.sort = val;
86
+ } else {
87
+ error(`Invalid sort: "${val}". Must be name, version, or location.`);
88
+ process.exit(2);
89
+ }
90
+ } else if (arg.startsWith("-")) {
91
+ error(`Unknown option: ${arg}`);
92
+ console.error(`Run "asm --help" for usage.`);
93
+ process.exit(2);
94
+ } else {
95
+ // Positional: first is command, second is subcommand, rest are positional args
96
+ if (!result.command) {
97
+ result.command = arg;
98
+ } else if (!result.subcommand) {
99
+ result.subcommand = arg;
100
+ } else {
101
+ result.positional.push(arg);
102
+ }
103
+ }
104
+
105
+ i++;
106
+ }
107
+
108
+ return result;
109
+ }
110
+
111
+ // ─── Output helpers ─────────────────────────────────────────────────────────
112
+
113
+ function error(msg: string) {
114
+ console.error(ansi.red(`Error: ${msg}`));
115
+ }
116
+
117
+ // ─── Help text ──────────────────────────────────────────────────────────────
118
+
119
+ function printMainHelp() {
120
+ console.log(`${ansi.blueBold("agent-skill-manager")} (${ansi.bold("asm")}) ${VERSION_STRING}
121
+
122
+ Interactive TUI and CLI for managing installed skills for AI coding agents.
123
+
124
+ ${ansi.bold("Usage:")}
125
+ asm Launch interactive TUI
126
+ asm <command> [options] Run a CLI command
127
+
128
+ ${ansi.bold("Commands:")}
129
+ list List all discovered skills
130
+ search <query> Search skills by name/description/provider
131
+ inspect <skill-name> Show detailed info for a skill
132
+ uninstall <skill-name> Remove a skill (with confirmation)
133
+ config show Print current config
134
+ config path Print config file path
135
+ config reset Reset config to defaults
136
+ config edit Open config in $EDITOR
137
+
138
+ ${ansi.bold("Global Options:")}
139
+ -h, --help Show help for any command
140
+ -v, --version Print version and exit
141
+ --json Output as JSON (list, search, inspect)
142
+ -s, --scope <scope> Filter: global, project, or both (default: both)
143
+ --no-color Disable ANSI colors
144
+ --sort <field> Sort by: name, version, or location (default: name)
145
+ -y, --yes Skip confirmation prompts`);
146
+ }
147
+
148
+ function printListHelp() {
149
+ console.log(`${ansi.bold("Usage:")} asm list [options]
150
+
151
+ List all discovered skills.
152
+
153
+ ${ansi.bold("Options:")}
154
+ --sort <field> Sort by: name, version, or location (default: name)
155
+ -s, --scope <s> Filter: global, project, or both (default: both)
156
+ --json Output as JSON array
157
+ --no-color Disable ANSI colors`);
158
+ }
159
+
160
+ function printSearchHelp() {
161
+ console.log(`${ansi.bold("Usage:")} asm search <query> [options]
162
+
163
+ Search skills by name, description, or provider.
164
+
165
+ ${ansi.bold("Options:")}
166
+ --sort <field> Sort by: name, version, or location (default: name)
167
+ -s, --scope <s> Filter: global, project, or both (default: both)
168
+ --json Output as JSON array
169
+ --no-color Disable ANSI colors`);
170
+ }
171
+
172
+ function printInspectHelp() {
173
+ console.log(`${ansi.bold("Usage:")} asm inspect <skill-name> [options]
174
+
175
+ Show detailed information for a skill. The <skill-name> is the directory name.
176
+
177
+ ${ansi.bold("Options:")}
178
+ -s, --scope <s> Filter: global, project, or both (default: both)
179
+ --json Output as JSON object
180
+ --no-color Disable ANSI colors`);
181
+ }
182
+
183
+ function printUninstallHelp() {
184
+ console.log(`${ansi.bold("Usage:")} asm uninstall <skill-name> [options]
185
+
186
+ Remove a skill and its associated rule files.
187
+
188
+ ${ansi.bold("Options:")}
189
+ -y, --yes Skip confirmation prompt
190
+ -s, --scope <s> Filter: global, project, or both (default: both)
191
+ --no-color Disable ANSI colors`);
192
+ }
193
+
194
+ function printConfigHelp() {
195
+ console.log(`${ansi.bold("Usage:")} asm config <subcommand>
196
+
197
+ Manage configuration.
198
+
199
+ ${ansi.bold("Subcommands:")}
200
+ show Print current config as JSON
201
+ path Print config file path
202
+ reset Reset config to defaults (with confirmation)
203
+ edit Open config in $EDITOR`);
204
+ }
205
+
206
+ // ─── Command Handlers ───────────────────────────────────────────────────────
207
+
208
+ async function cmdList(args: ParsedArgs) {
209
+ if (args.flags.help) {
210
+ printListHelp();
211
+ return;
212
+ }
213
+
214
+ const config = await loadConfig();
215
+ const allSkills = await scanAllSkills(config, args.flags.scope);
216
+ const sorted = sortSkills(allSkills, args.flags.sort);
217
+
218
+ if (args.flags.json) {
219
+ console.log(formatJSON(sorted));
220
+ } else {
221
+ console.log(formatSkillTable(sorted));
222
+ }
223
+ }
224
+
225
+ async function cmdSearch(args: ParsedArgs) {
226
+ if (args.flags.help) {
227
+ printSearchHelp();
228
+ return;
229
+ }
230
+
231
+ const query = args.subcommand;
232
+ if (!query) {
233
+ error("Missing required argument: <query>");
234
+ console.error(`Run "asm search --help" for usage.`);
235
+ process.exit(2);
236
+ }
237
+
238
+ const config = await loadConfig();
239
+ const allSkills = await scanAllSkills(config, args.flags.scope);
240
+ const filtered = searchSkills(allSkills, query);
241
+ const sorted = sortSkills(filtered, args.flags.sort);
242
+
243
+ if (args.flags.json) {
244
+ console.log(formatJSON(sorted));
245
+ } else {
246
+ console.log(formatSkillTable(sorted));
247
+ }
248
+ }
249
+
250
+ async function cmdInspect(args: ParsedArgs) {
251
+ if (args.flags.help) {
252
+ printInspectHelp();
253
+ return;
254
+ }
255
+
256
+ const skillName = args.subcommand;
257
+ if (!skillName) {
258
+ error("Missing required argument: <skill-name>");
259
+ console.error(`Run "asm inspect --help" for usage.`);
260
+ process.exit(2);
261
+ }
262
+
263
+ const config = await loadConfig();
264
+ const allSkills = await scanAllSkills(config, args.flags.scope);
265
+ const matches = allSkills.filter((s) => s.dirName === skillName);
266
+
267
+ if (matches.length === 0) {
268
+ error(`Skill "${skillName}" not found.`);
269
+ process.exit(1);
270
+ }
271
+
272
+ if (args.flags.json) {
273
+ console.log(formatJSON(matches.length === 1 ? matches[0] : matches));
274
+ } else {
275
+ for (let i = 0; i < matches.length; i++) {
276
+ if (i > 0) console.log("\n" + "─".repeat(40) + "\n");
277
+ console.log(formatSkillDetail(matches[i]));
278
+ }
279
+ }
280
+ }
281
+
282
+ async function cmdUninstall(args: ParsedArgs) {
283
+ if (args.flags.help) {
284
+ printUninstallHelp();
285
+ return;
286
+ }
287
+
288
+ const skillName = args.subcommand;
289
+ if (!skillName) {
290
+ error("Missing required argument: <skill-name>");
291
+ console.error(`Run "asm uninstall --help" for usage.`);
292
+ process.exit(2);
293
+ }
294
+
295
+ const config = await loadConfig();
296
+ const allSkills = await scanAllSkills(config, args.flags.scope);
297
+ const plan = buildFullRemovalPlan(skillName, allSkills, config);
298
+
299
+ const existing = await getExistingTargets(plan);
300
+ if (existing.length === 0) {
301
+ error(`Skill "${skillName}" not found or nothing to remove.`);
302
+ process.exit(1);
303
+ }
304
+
305
+ // Show removal plan
306
+ console.error(ansi.bold("Removal plan:"));
307
+ for (const target of existing) {
308
+ console.error(` ${ansi.red("•")} ${target}`);
309
+ }
310
+
311
+ if (!args.flags.yes) {
312
+ // Interactive confirmation
313
+ if (!process.stdin.isTTY) {
314
+ error(
315
+ "Cannot prompt for confirmation in non-interactive mode. Use --yes to skip.",
316
+ );
317
+ process.exit(2);
318
+ }
319
+ process.stderr.write(`\n${ansi.bold("Proceed with removal?")} [y/N] `);
320
+ const answer = await readLine();
321
+ if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
322
+ console.error("Aborted.");
323
+ process.exit(0);
324
+ }
325
+ }
326
+
327
+ const log = await executeRemoval(plan);
328
+ for (const entry of log) {
329
+ console.error(entry);
330
+ }
331
+ console.error(ansi.green("\nDone."));
332
+ }
333
+
334
+ function readLine(): Promise<string> {
335
+ return new Promise((resolve) => {
336
+ let data = "";
337
+ process.stdin.setEncoding("utf-8");
338
+ process.stdin.on("data", (chunk: string) => {
339
+ data += chunk;
340
+ if (data.includes("\n")) {
341
+ process.stdin.removeAllListeners("data");
342
+ resolve(data.trim());
343
+ }
344
+ });
345
+ process.stdin.resume();
346
+ });
347
+ }
348
+
349
+ async function cmdConfig(args: ParsedArgs) {
350
+ if (args.flags.help) {
351
+ printConfigHelp();
352
+ return;
353
+ }
354
+
355
+ const sub = args.subcommand;
356
+
357
+ if (!sub) {
358
+ error("Missing subcommand. Use: show, path, reset, or edit.");
359
+ console.error(`Run "asm config --help" for usage.`);
360
+ process.exit(2);
361
+ }
362
+
363
+ switch (sub) {
364
+ case "show": {
365
+ const config = await loadConfig();
366
+ console.log(formatJSON(config));
367
+ break;
368
+ }
369
+ case "path": {
370
+ console.log(getConfigPath());
371
+ break;
372
+ }
373
+ case "reset": {
374
+ if (!args.flags.yes) {
375
+ if (!process.stdin.isTTY) {
376
+ error(
377
+ "Cannot prompt for confirmation in non-interactive mode. Use --yes to skip.",
378
+ );
379
+ process.exit(2);
380
+ }
381
+ process.stderr.write(
382
+ `${ansi.bold("Reset config to defaults?")} [y/N] `,
383
+ );
384
+ const answer = await readLine();
385
+ if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
386
+ console.error("Aborted.");
387
+ process.exit(0);
388
+ }
389
+ }
390
+ const defaults = getDefaultConfig();
391
+ await saveConfig(defaults);
392
+ console.error(ansi.green("Config reset to defaults."));
393
+ break;
394
+ }
395
+ case "edit": {
396
+ const editor = process.env.VISUAL || process.env.EDITOR || "vi";
397
+ const configPath = getConfigPath();
398
+ // Ensure config file exists
399
+ await loadConfig();
400
+ const proc = Bun.spawn([editor, configPath], {
401
+ stdin: "inherit",
402
+ stdout: "inherit",
403
+ stderr: "inherit",
404
+ });
405
+ await proc.exited;
406
+ break;
407
+ }
408
+ default: {
409
+ error(
410
+ `Unknown config subcommand: "${sub}". Use: show, path, reset, or edit.`,
411
+ );
412
+ process.exit(2);
413
+ }
414
+ }
415
+ }
416
+
417
+ // ─── Main CLI dispatcher ────────────────────────────────────────────────────
418
+
419
+ export async function runCLI(argv: string[]): Promise<void> {
420
+ const args = parseArgs(argv);
421
+
422
+ // Apply --no-color
423
+ if (args.flags.noColor) {
424
+ (globalThis as any).__CLI_NO_COLOR = true;
425
+ }
426
+
427
+ // --version at top level
428
+ if (args.flags.version) {
429
+ console.log(`asm ${VERSION_STRING}`);
430
+ return;
431
+ }
432
+
433
+ // --help at top level (no command)
434
+ if (!args.command && args.flags.help) {
435
+ printMainHelp();
436
+ return;
437
+ }
438
+
439
+ // No command → return null to signal TUI launch
440
+ if (!args.command) {
441
+ return;
442
+ }
443
+
444
+ switch (args.command) {
445
+ case "list":
446
+ await cmdList(args);
447
+ break;
448
+ case "search":
449
+ await cmdSearch(args);
450
+ break;
451
+ case "inspect":
452
+ await cmdInspect(args);
453
+ break;
454
+ case "uninstall":
455
+ await cmdUninstall(args);
456
+ break;
457
+ case "config":
458
+ await cmdConfig(args);
459
+ break;
460
+ default:
461
+ error(`Unknown command: "${args.command}"`);
462
+ console.error(`Run "asm --help" for usage.`);
463
+ process.exit(2);
464
+ }
465
+ }
466
+
467
+ // ─── Check if CLI mode should run ──────────────────────────────────────────
468
+
469
+ export function isCLIMode(argv: string[]): boolean {
470
+ const args = argv.slice(2);
471
+ if (args.length === 0) return false;
472
+
473
+ // Known commands
474
+ const commands = ["list", "search", "inspect", "uninstall", "config"];
475
+ const first = args[0];
476
+
477
+ // If the first arg is a known command, it's CLI mode
478
+ if (commands.includes(first)) return true;
479
+
480
+ // --help and --version are handled in CLI mode too
481
+ if (first === "--help" || first === "-h") return true;
482
+ if (first === "--version" || first === "-v") return true;
483
+
484
+ // Unknown flags/commands → CLI mode (will show error)
485
+ if (first.startsWith("-") || first.length > 0) return true;
486
+
487
+ return false;
488
+ }
package/src/config.ts CHANGED
@@ -4,7 +4,7 @@ import { homedir } from "os";
4
4
  import type { AppConfig, ProviderConfig } from "./utils/types";
5
5
 
6
6
  const HOME = homedir();
7
- const CONFIG_DIR = join(HOME, ".config", "skill-manager");
7
+ const CONFIG_DIR = join(HOME, ".config", "agent-skill-manager");
8
8
  const CONFIG_PATH = join(CONFIG_DIR, "config.json");
9
9
 
10
10
  const DEFAULT_PROVIDERS: ProviderConfig[] = [
@@ -0,0 +1,92 @@
1
+ import type { SkillInfo } from "./utils/types";
2
+
3
+ // ─── Color helpers ──────────────────────────────────────────────────────────
4
+
5
+ const useColor = (): boolean => {
6
+ if (process.env.NO_COLOR !== undefined) return false;
7
+ if ((globalThis as any).__CLI_NO_COLOR) return false;
8
+ if (!process.stdout.isTTY) return false;
9
+ return true;
10
+ };
11
+
12
+ const ansi = {
13
+ bold: (s: string) => (useColor() ? `\x1b[1m${s}\x1b[0m` : s),
14
+ cyan: (s: string) => (useColor() ? `\x1b[36m${s}\x1b[0m` : s),
15
+ green: (s: string) => (useColor() ? `\x1b[32m${s}\x1b[0m` : s),
16
+ yellow: (s: string) => (useColor() ? `\x1b[33m${s}\x1b[0m` : s),
17
+ dim: (s: string) => (useColor() ? `\x1b[2m${s}\x1b[0m` : s),
18
+ red: (s: string) => (useColor() ? `\x1b[31m${s}\x1b[0m` : s),
19
+ blueBold: (s: string) => (useColor() ? `\x1b[1m\x1b[34m${s}\x1b[0m` : s),
20
+ };
21
+
22
+ export { ansi };
23
+
24
+ // ─── Table formatter ────────────────────────────────────────────────────────
25
+
26
+ export function formatSkillTable(skills: SkillInfo[]): string {
27
+ if (skills.length === 0) {
28
+ return "No skills found.";
29
+ }
30
+
31
+ const headers = ["Name", "Version", "Provider", "Scope", "Type", "Path"];
32
+
33
+ const rows = skills.map((s) => [
34
+ s.name,
35
+ s.version,
36
+ s.providerLabel,
37
+ s.scope,
38
+ s.isSymlink ? "symlink" : "directory",
39
+ s.path,
40
+ ]);
41
+
42
+ // Calculate column widths
43
+ const widths = headers.map((h, i) =>
44
+ Math.max(h.length, ...rows.map((r) => r[i].length)),
45
+ );
46
+
47
+ const pad = (str: string, width: number) => str.padEnd(width);
48
+
49
+ const headerLine = headers.map((h, i) => pad(h, widths[i])).join(" ");
50
+ const separator = widths.map((w) => "─".repeat(w)).join("──");
51
+ const dataLines = rows.map((row) =>
52
+ row.map((cell, i) => pad(cell, widths[i])).join(" "),
53
+ );
54
+
55
+ return [
56
+ useColor() ? ansi.bold(headerLine) : headerLine,
57
+ separator,
58
+ ...dataLines,
59
+ ].join("\n");
60
+ }
61
+
62
+ // ─── Detail formatter ───────────────────────────────────────────────────────
63
+
64
+ export function formatSkillDetail(skill: SkillInfo): string {
65
+ const lines: string[] = [];
66
+ const label = (key: string, value: string) =>
67
+ `${useColor() ? ansi.bold(key + ":") : key + ":"} ${value}`;
68
+
69
+ lines.push(label("Name", skill.name));
70
+ lines.push(label("Version", skill.version));
71
+ lines.push(label("Provider", skill.providerLabel));
72
+ lines.push(label("Scope", skill.scope));
73
+ lines.push(label("Location", skill.location));
74
+ lines.push(label("Path", skill.path));
75
+ lines.push(label("Type", skill.isSymlink ? "symlink" : "directory"));
76
+ if (skill.isSymlink && skill.symlinkTarget) {
77
+ lines.push(label("Symlink Target", skill.symlinkTarget));
78
+ }
79
+ lines.push(label("File Count", String(skill.fileCount)));
80
+ if (skill.description) {
81
+ lines.push("");
82
+ lines.push(label("Description", skill.description));
83
+ }
84
+
85
+ return lines.join("\n");
86
+ }
87
+
88
+ // ─── JSON formatter ─────────────────────────────────────────────────────────
89
+
90
+ export function formatJSON(data: unknown): string {
91
+ return JSON.stringify(data, null, 2);
92
+ }
@@ -122,7 +122,7 @@ async function removeAgentsMdBlock(
122
122
  let content = await readFile(filePath, "utf-8");
123
123
 
124
124
  // Try both new and old marker formats for backward compatibility
125
- for (const prefix of ["skill-manager", "pskills"]) {
125
+ for (const prefix of ["agent-skill-manager", "skill-manager", "pskills"]) {
126
126
  const startMarker = `<!-- ${prefix}: ${skillName} -->`;
127
127
  const endMarker = `<!-- /${prefix}: ${skillName} -->`;
128
128
 
@@ -213,6 +213,7 @@ export async function getExistingTargets(plan: RemovalPlan): Promise<string[]> {
213
213
  const content = await readFile(block.file, "utf-8");
214
214
  // Check both new and old marker formats
215
215
  if (
216
+ content.includes(`<!-- agent-skill-manager: ${block.skillName} -->`) ||
216
217
  content.includes(`<!-- skill-manager: ${block.skillName} -->`) ||
217
218
  content.includes(`<!-- pskills: ${block.skillName} -->`)
218
219
  ) {
@@ -52,7 +52,7 @@ export function createDashboard(
52
52
  // ASCII banner
53
53
  const banner = new ASCIIFontRenderable(ctx, {
54
54
  id: "banner",
55
- text: "skill-manager",
55
+ text: "agent-skill-manager",
56
56
  color: theme.accent,
57
57
  });
58
58
  root.add(banner);
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import { VERSION, VERSION_STRING } from "../src/utils/version";
4
-
5
- const arg = process.argv[2];
6
-
7
- if (arg === "--help" || arg === "-h") {
8
- console.log(`\x1b[1m\x1b[36mskill-manager\x1b[0m ${VERSION_STRING}
9
-
10
- Interactive TUI for managing installed skills for AI coding agents (Claude Code, Codex, OpenClaw, and more).
11
-
12
- \x1b[1mUsage:\x1b[0m
13
- skill-manager Launch the interactive TUI dashboard
14
- skill-manager --help Show this help message
15
- skill-manager --version Show version
16
-
17
- \x1b[1mRequirements:\x1b[0m
18
- Bun >= 1.0.0 (https://bun.sh)
19
-
20
- \x1b[1mConfig:\x1b[0m
21
- ~/.config/skill-manager/config.json
22
-
23
- \x1b[1mTUI Keybindings:\x1b[0m
24
- ↑/↓ or j/k Navigate skill list
25
- Enter View skill details
26
- d Uninstall selected skill
27
- / Search / filter skills
28
- Esc Back / clear filter / close dialog
29
- Tab Cycle scope: Global → Project → Both
30
- s Cycle sort: Name → Version → Location
31
- r Refresh / rescan skills
32
- c Open configuration
33
- q Quit
34
- ? Toggle help overlay`);
35
- process.exit(0);
36
- }
37
-
38
- if (arg === "--version" || arg === "-v") {
39
- console.log(`skill-manager ${VERSION_STRING}`);
40
- process.exit(0);
41
- }
42
-
43
- // Launch the TUI
44
- await import("../src/index.ts");
45
-
46
- export {};