aiblueprint-cli 1.4.20 → 1.4.21
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/README.md +97 -506
- package/dist/cli.js +239 -133
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,441 +1,155 @@
|
|
|
1
1
|
# AIBlueprint CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Supercharge Claude Code with security hooks, custom commands, intelligent statusline, and workflow automation.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
> If you encounter permission errors when running the commands below, add `sudo` before the command.
|
|
5
|
+
📚 **[Full Documentation](https://codelynx.dev/docs)** | 🎯 [Premium Features](https://mlv.sh/claude-cli)
|
|
7
6
|
|
|
8
7
|
## 🚀 Quick Start
|
|
9
8
|
|
|
10
|
-
### Option 1: Install as Claude Code Plugin (Recommended)
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
# Add the AIBlueprint marketplace
|
|
14
|
-
/plugin marketplace add melvynx/aiblueprint
|
|
15
|
-
|
|
16
|
-
# Install the base plugin
|
|
17
|
-
/plugin install aibp-base@AIBlueprint
|
|
18
|
-
|
|
19
|
-
# Or install directly from GitHub
|
|
20
|
-
/plugin install github:melvynx/aiblueprint
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Option 2: Use the CLI Tool
|
|
24
|
-
|
|
25
9
|
```bash
|
|
26
|
-
# Run
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
# Or install globally and use
|
|
30
|
-
npm install -g aiblueprint-cli
|
|
31
|
-
aiblueprint claude-code setup
|
|
10
|
+
# Run setup (no installation required)
|
|
11
|
+
npx aiblueprint-cli@latest claude-code setup
|
|
32
12
|
```
|
|
33
13
|
|
|
34
|
-
##
|
|
35
|
-
|
|
36
|
-
- [Plugin Installation](#-plugin-installation)
|
|
37
|
-
- [CLI Installation & Usage](#-cli-installation--usage)
|
|
38
|
-
- [Command Reference](#command-reference)
|
|
39
|
-
- [Available Features](#available-features)
|
|
40
|
-
- [Configuration System](#configuration-system)
|
|
41
|
-
- [Templates Catalog](#templates-catalog)
|
|
42
|
-
- [Installation Targets](#installation-targets)
|
|
43
|
-
- [Security Features](#security-features)
|
|
44
|
-
- [Development](#development)
|
|
14
|
+
## ✨ Features
|
|
45
15
|
|
|
46
|
-
|
|
16
|
+
- **🛡️ Security** - Command validation hooks blocking dangerous operations
|
|
17
|
+
- **📊 Statusline** - Git status, cost tracking, and token usage display
|
|
18
|
+
- **🤖 Commands** - 16 pre-configured workflow automation commands
|
|
19
|
+
- **🎭 Agents** - 3 specialized AI agents for codebase exploration
|
|
20
|
+
- **⚡ Scripts** - Built-in utilities for spending reports and usage stats
|
|
47
21
|
|
|
48
|
-
|
|
22
|
+
## 📦 Installation
|
|
49
23
|
|
|
50
|
-
|
|
24
|
+
### Option 1: Plugin (Recommended)
|
|
51
25
|
|
|
52
26
|
```bash
|
|
53
|
-
# Step 1: Add the AIBlueprint marketplace
|
|
54
27
|
/plugin marketplace add melvynx/aiblueprint
|
|
55
|
-
|
|
56
|
-
# Step 2: Install the aibp-base plugin
|
|
57
28
|
/plugin install aibp-base@AIBlueprint
|
|
58
|
-
|
|
59
|
-
# Alternative: Install directly from GitHub
|
|
60
|
-
/plugin install github:melvynx/aiblueprint
|
|
61
29
|
```
|
|
62
30
|
|
|
63
|
-
###
|
|
64
|
-
|
|
65
|
-
The `aibp-base` plugin includes:
|
|
66
|
-
|
|
67
|
-
- ✅ **16 Custom Commands** - `/commit`, `/create-pull-request`, `/deep-code-analysis`, etc.
|
|
68
|
-
- ✅ **3 Specialized Agents** - explore-codebase, Snipper, websearch
|
|
69
|
-
- ✅ **Security Hooks** - Command validation and TypeScript processing
|
|
70
|
-
- ✅ **Custom Statusline** - Git status, cost tracking, and token usage
|
|
71
|
-
- ✅ **Notification Sounds** - Audio alerts for task completion
|
|
72
|
-
|
|
73
|
-
### Plugin Management
|
|
31
|
+
### Option 2: CLI Tool
|
|
74
32
|
|
|
75
33
|
```bash
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
# Update plugin to latest version
|
|
80
|
-
/plugin update aibp-base
|
|
81
|
-
|
|
82
|
-
# Remove plugin
|
|
83
|
-
/plugin uninstall aibp-base
|
|
34
|
+
# Run without installation
|
|
35
|
+
npx aiblueprint-cli@latest claude-code setup
|
|
84
36
|
|
|
85
|
-
#
|
|
86
|
-
|
|
37
|
+
# Or install globally
|
|
38
|
+
npm install -g aiblueprint-cli
|
|
87
39
|
```
|
|
88
40
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
**Plugin Installation (Recommended)**:
|
|
92
|
-
|
|
93
|
-
- ✅ Automatic updates via marketplace
|
|
94
|
-
- ✅ No CLI tool installation needed
|
|
95
|
-
- ✅ Direct integration with Claude Code
|
|
96
|
-
- ✅ Easy to manage and update
|
|
97
|
-
|
|
98
|
-
**CLI Tool Installation**:
|
|
99
|
-
|
|
100
|
-
- ✅ More control over installation
|
|
101
|
-
- ✅ Custom folder locations
|
|
102
|
-
- ✅ Interactive feature selection
|
|
103
|
-
- ✅ Symlink management for other tools
|
|
104
|
-
|
|
105
|
-
## 💾 CLI Installation & Usage
|
|
41
|
+
## 🎯 Usage
|
|
106
42
|
|
|
107
|
-
###
|
|
43
|
+
### Setup
|
|
108
44
|
|
|
109
45
|
```bash
|
|
110
|
-
#
|
|
111
|
-
npm install -g aiblueprint-cli
|
|
112
|
-
bun install -g aiblueprint-cli
|
|
113
|
-
|
|
114
|
-
# Run without installation
|
|
46
|
+
# Interactive setup
|
|
115
47
|
npx aiblueprint-cli@latest claude-code setup
|
|
116
|
-
pnpm dlx aiblueprint-cli@latest claude-code setup
|
|
117
|
-
bunx aiblueprint-cli@latest claude-code setup
|
|
118
|
-
```
|
|
119
48
|
|
|
120
|
-
|
|
49
|
+
# Install all features (no prompts)
|
|
50
|
+
npx aiblueprint-cli@latest claude-code setup --skip
|
|
121
51
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
bunx aiblueprint-cli@latest claude-code setup
|
|
125
|
-
|
|
126
|
-
# Non-interactive setup (install all features)
|
|
127
|
-
bunx aiblueprint-cli@latest claude-code setup --skip
|
|
128
|
-
|
|
129
|
-
# Install to custom directory
|
|
130
|
-
bunx aiblueprint-cli@latest claude-code setup --folder ./custom-claude-config
|
|
131
|
-
|
|
132
|
-
# Install to project directory
|
|
133
|
-
cd your-project
|
|
134
|
-
bunx aiblueprint-cli@latest claude-code setup # Creates .claude/ in project root
|
|
52
|
+
# Custom location
|
|
53
|
+
npx aiblueprint-cli@latest claude-code setup --folder ~/.my-claude
|
|
135
54
|
```
|
|
136
55
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
### Main Commands
|
|
56
|
+
### Statusline Scripts
|
|
140
57
|
|
|
141
|
-
|
|
142
|
-
| ------------------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
143
|
-
| `bunx aiblueprint-cli@latest claude-code setup` | Interactive setup with feature selection | `-f, --folder <path>` (alias for --claudeCodeFolder), `--claudeCodeFolder <path>`, `--codexFolder <path>`, `--openCodeFolder <path>`, `--factoryAiFolder <path>`, `-s, --skip` |
|
|
144
|
-
| `bunx aiblueprint-cli@latest claude-code symlink` | Create symlinks between CLI tools (Codex, OpenCode, FactoryAI) | `--claudeCodeFolder <path>`, `--codexFolder <path>`, `--openCodeFolder <path>`, `--factoryAiFolder <path>` |
|
|
145
|
-
| `bunx aiblueprint-cli@latest claude-code statusline` | Setup custom statusline with git status, costs, and token usage | `-f, --folder <path>` |
|
|
146
|
-
| `bunx aiblueprint-cli@latest claude-code add hook <type>` | Install specific hook | `-f, --folder <path>` |
|
|
147
|
-
| `bunx aiblueprint-cli@latest claude-code add commands [name]` | List or install commands | `-f, --folder <path>` |
|
|
148
|
-
|
|
149
|
-
### Command Examples
|
|
58
|
+
Run utility scripts from anywhere:
|
|
150
59
|
|
|
151
60
|
```bash
|
|
152
|
-
#
|
|
153
|
-
|
|
154
|
-
bunx aiblueprint-cli@latest claude-code setup --folder ~/.my-claude # Custom location
|
|
155
|
-
bunx aiblueprint-cli@latest claude-code setup --claudeCodeFolder ~/.claude --codexFolder ~/.codex # Separate folders
|
|
61
|
+
# List available scripts
|
|
62
|
+
npx aiblueprint-cli@latest claude-code statusline --list
|
|
156
63
|
|
|
157
|
-
#
|
|
158
|
-
|
|
64
|
+
# Today's spending report
|
|
65
|
+
npx aiblueprint-cli@latest claude-code statusline spend:today
|
|
159
66
|
|
|
160
|
-
#
|
|
161
|
-
|
|
162
|
-
bunx aiblueprint-cli@latest claude-code add commands commit # Install commit command
|
|
163
|
-
bunx aiblueprint-cli@latest claude-code add commands deep-code-analysis # Install analysis command
|
|
67
|
+
# Weekly usage analysis
|
|
68
|
+
npx aiblueprint-cli@latest claude-code statusline weekly
|
|
164
69
|
|
|
165
|
-
#
|
|
166
|
-
|
|
167
|
-
bunx aiblueprint-cli@latest claude-code symlink --factoryAiFolder ~/.factory # With custom paths
|
|
168
|
-
|
|
169
|
-
# Setup statusline
|
|
170
|
-
bunx aiblueprint-cli@latest claude-code statusline # Quick statusline setup
|
|
171
|
-
bunx aiblueprint-cli@latest claude-code statusline --folder ~/.my-claude # Custom location
|
|
70
|
+
# Configure statusline
|
|
71
|
+
npx aiblueprint-cli@latest claude-code statusline config
|
|
172
72
|
```
|
|
173
73
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
- `
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
The CLI intelligently determines where to install configurations:
|
|
181
|
-
|
|
182
|
-
1. **Project Local** (`.claude/` in project root) - When run in a Git repository
|
|
183
|
-
2. **Global** (`~/.claude/`) - When not in a Git repository or with custom folder
|
|
184
|
-
3. **Custom Path** - When using `--folder` option
|
|
185
|
-
|
|
186
|
-
## ✨ Available Features
|
|
187
|
-
|
|
188
|
-
### 🛡️ Shell Shortcuts
|
|
189
|
-
|
|
190
|
-
- **`cc`** - Claude Code with permissions skipped (`claude --dangerously-skip-permissions`)
|
|
191
|
-
- **`ccc`** - Claude Code with continue mode (`claude --dangerously-skip-permissions -c`)
|
|
192
|
-
- Platform support: macOS (`.zshenv`), Linux (`.bashrc`/`.zshrc`)
|
|
193
|
-
|
|
194
|
-
### 🔒 Command Validation
|
|
195
|
-
|
|
196
|
-
- **700+ line security system** protecting against dangerous bash commands
|
|
197
|
-
- **Real-time validation** before command execution via PreToolUse hooks
|
|
198
|
-
- **Smart detection** of privilege escalation, destructive operations, and command injection
|
|
199
|
-
- **Comprehensive logging** to `~/.claude/security.log` with severity levels
|
|
200
|
-
|
|
201
|
-
### 📊 Custom Statusline
|
|
202
|
-
|
|
203
|
-
- **Git integration** - Branch status, changes, and repository info
|
|
204
|
-
- **Cost tracking** - Session costs, daily limits, and token usage via ccusage
|
|
205
|
-
- **Real-time updates** - Command-triggered statusline refresh
|
|
206
|
-
- **Colored output** - Visual indicators for different status types
|
|
207
|
-
- **Quick setup** - Install with one command: `pnpm dlx aiblueprint-cli claude-code statusline`
|
|
208
|
-
|
|
209
|
-
### 🤖 AIBlueprint Commands (16 Available)
|
|
210
|
-
|
|
211
|
-
**Development Workflow**
|
|
212
|
-
|
|
213
|
-
- `commit` - Fast conventional commits with immediate push
|
|
214
|
-
- `create-pull-request` - Auto-generated PR creation with templates
|
|
215
|
-
- `fix-pr-comments` - Systematic PR review comment resolution
|
|
216
|
-
- `run-tasks` - Execute GitHub issues with full EPCT workflow
|
|
217
|
-
|
|
218
|
-
**Code Analysis & Research**
|
|
74
|
+
**Available scripts:**
|
|
75
|
+
- `spend:today` / `spend:month` / `spend:project` - Spending reports
|
|
76
|
+
- `stats` - Daily usage statistics
|
|
77
|
+
- `weekly` - Weekly usage analysis
|
|
78
|
+
- `config` - Interactive configuration
|
|
79
|
+
- `migrate` - Migrate to SQLite database
|
|
219
80
|
|
|
220
|
-
|
|
221
|
-
- `explain-architecture` - Pattern analysis with ASCII diagrams
|
|
222
|
-
- `cleanup-context` - Memory optimization and duplicate removal
|
|
81
|
+
### Other Commands
|
|
223
82
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
-
|
|
227
|
-
- `watch-ci` - Automated CI/CD monitoring and failure fixing
|
|
228
|
-
- `prompt-command` / `prompt-agent` - Template creation utilities
|
|
229
|
-
- `epct` - Systematic Explore-Plan-Code-Test methodology
|
|
230
|
-
|
|
231
|
-
### 🎭 AIBlueprint Agents (3 Specialized)
|
|
232
|
-
|
|
233
|
-
- **explore-codebase** (yellow) - Comprehensive code discovery and analysis
|
|
234
|
-
- **Snipper** (blue) - Rapid code modification specialist with minimal output
|
|
235
|
-
- **websearch** (yellow) - Quick web research with authoritative sources
|
|
236
|
-
|
|
237
|
-
### 🔊 Notification Sounds
|
|
238
|
-
|
|
239
|
-
- **Finish sound** - Audio alert for completed operations (macOS afplay)
|
|
240
|
-
- **Need-human sound** - Audio alert for attention requests
|
|
241
|
-
- **Volume control** - Configurable audio levels
|
|
242
|
-
|
|
243
|
-
### 🔗 Symlink Management
|
|
244
|
-
|
|
245
|
-
- **Multi-tool integration** - Create symlinks between Claude Code, Codex, OpenCode, and FactoryAI
|
|
246
|
-
- **Interactive selection** - Choose source, content type (commands/agents), and destinations
|
|
247
|
-
- **Smart validation** - Prevents overwriting non-symlink directories and validates paths
|
|
248
|
-
- **Bidirectional sync** - Sync commands and agents in any direction
|
|
249
|
-
- **Supported tools:**
|
|
250
|
-
- **Claude Code** - Commands + Agents (`~/.claude/`)
|
|
251
|
-
- **Codex** - Commands only (`~/.codex/prompts`)
|
|
252
|
-
- **OpenCode** - Commands only (`~/.config/opencode/command`)
|
|
253
|
-
- **FactoryAI** - Commands + Droids/Agents (`~/.factory/`)
|
|
254
|
-
|
|
255
|
-
## ⚙️ Configuration System
|
|
256
|
-
|
|
257
|
-
### Settings.json Structure
|
|
83
|
+
```bash
|
|
84
|
+
# Add specific hooks
|
|
85
|
+
npx aiblueprint-cli@latest claude-code add hook post-edit-typescript
|
|
258
86
|
|
|
259
|
-
|
|
87
|
+
# Manage commands
|
|
88
|
+
npx aiblueprint-cli@latest claude-code add commands
|
|
89
|
+
npx aiblueprint-cli@latest claude-code add commands commit
|
|
260
90
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
"statusLine": {
|
|
264
|
-
"type": "command",
|
|
265
|
-
"command": "bun ~/.claude/scripts/statusline/src/index.ts",
|
|
266
|
-
"padding": 0
|
|
267
|
-
},
|
|
268
|
-
"hooks": {
|
|
269
|
-
"PreToolUse": [
|
|
270
|
-
{
|
|
271
|
-
"matcher": "Bash",
|
|
272
|
-
"hooks": [
|
|
273
|
-
{
|
|
274
|
-
"type": "command",
|
|
275
|
-
"command": "bun ~/.claude/scripts/validate-command.js"
|
|
276
|
-
}
|
|
277
|
-
]
|
|
278
|
-
}
|
|
279
|
-
]
|
|
280
|
-
}
|
|
281
|
-
}
|
|
91
|
+
# Create symlinks between tools
|
|
92
|
+
npx aiblueprint-cli@latest claude-code symlink
|
|
282
93
|
```
|
|
283
94
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
- **Remote-first approach** - Always downloads latest configurations from GitHub
|
|
287
|
-
- **Automatic fallback** - Uses local files when GitHub is unavailable
|
|
288
|
-
- **Version independence** - Get updates without CLI updates
|
|
289
|
-
- **Rate limiting aware** - Handles GitHub API limitations gracefully
|
|
290
|
-
|
|
291
|
-
## 📚 Templates Catalog
|
|
292
|
-
|
|
293
|
-
### Commands by Category
|
|
294
|
-
|
|
295
|
-
<details>
|
|
296
|
-
<summary><strong>Development Workflow (4 commands)</strong></summary>
|
|
297
|
-
|
|
298
|
-
| Command | Tools | Purpose |
|
|
299
|
-
| --------------------- | ----------------------------- | ---------------------------------------------- |
|
|
300
|
-
| `commit` | `Bash(git :*)` | Quick conventional commits with immediate push |
|
|
301
|
-
| `create-pull-request` | `Bash(git :*)`, `Bash(gh :*)` | PR creation with auto-generated descriptions |
|
|
302
|
-
| `fix-pr-comments` | `Bash(gh :*)`, `Read`, `Edit` | Systematic PR review resolution |
|
|
303
|
-
| `run-tasks` | `Bash(gh :*)`, `Bash(git :*)` | GitHub issue execution with EPCT |
|
|
304
|
-
|
|
305
|
-
</details>
|
|
95
|
+
## 📚 What You Get
|
|
306
96
|
|
|
307
|
-
|
|
308
|
-
<summary><strong>Analysis & Research (2 commands)</strong></summary>
|
|
97
|
+
### Security Hooks
|
|
309
98
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
| `explain-architecture` | `Read`, `Glob`, `Grep`, `Task` | Architectural pattern analysis |
|
|
99
|
+
- **Command validation** - Blocks `rm -rf`, privilege escalation, remote execution
|
|
100
|
+
- **TypeScript processing** - Auto-format and lint after file edits
|
|
101
|
+
- **Security logging** - Tracks all blocked commands to `~/.claude/security.log`
|
|
314
102
|
|
|
315
|
-
|
|
103
|
+
### Custom Statusline
|
|
316
104
|
|
|
317
|
-
|
|
318
|
-
|
|
105
|
+
- Git branch, changes, and repository info
|
|
106
|
+
- Session costs and daily limits via ccusage
|
|
107
|
+
- Real-time token usage tracking
|
|
108
|
+
- Colored visual indicators
|
|
319
109
|
|
|
320
|
-
|
|
321
|
-
| ----------------- | -------------------------------- | ------------------------ |
|
|
322
|
-
| `cleanup-context` | `TodoWrite`, `MultiEdit`, `Glob` | Memory bank optimization |
|
|
323
|
-
| `watch-ci` | `Bash(gh :*)`, `Bash(sleep :*)` | Automated CI monitoring |
|
|
110
|
+
### Commands (16 Available)
|
|
324
111
|
|
|
325
|
-
|
|
112
|
+
**Development:**
|
|
113
|
+
- `commit` - Fast conventional commits
|
|
114
|
+
- `create-pull-request` - Auto-generated PRs
|
|
115
|
+
- `fix-pr-comments` - Resolve PR comments
|
|
116
|
+
- `run-tasks` - Execute GitHub issues
|
|
326
117
|
|
|
327
|
-
|
|
328
|
-
|
|
118
|
+
**Analysis:**
|
|
119
|
+
- `deep-code-analysis` - Comprehensive codebase investigation
|
|
120
|
+
- `explain-architecture` - Pattern analysis with diagrams
|
|
121
|
+
- `cleanup-context` - Memory optimization
|
|
329
122
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
| `prompt-command` | `Read`, `Write`, `Edit` | Command template creation |
|
|
335
|
-
| `prompt-agent` | `Read`, `Write`, `Edit` | Agent template creation |
|
|
123
|
+
**Utilities:**
|
|
124
|
+
- `claude-memory` - CLAUDE.md management
|
|
125
|
+
- `watch-ci` - Automated CI monitoring
|
|
126
|
+
- `epct` - Explore-Plan-Code-Test methodology
|
|
336
127
|
|
|
337
|
-
|
|
128
|
+
### Agents (3 Specialized)
|
|
338
129
|
|
|
339
|
-
|
|
130
|
+
- **explore-codebase** - Code discovery and analysis
|
|
131
|
+
- **Snipper** - Fast code modifications
|
|
132
|
+
- **websearch** - Quick web research
|
|
340
133
|
|
|
341
|
-
|
|
342
|
-
| ---------------------- | -------------- | --------------------------- | ---------------------------------- |
|
|
343
|
-
| `post-edit-typescript` | TypeScript/Bun | File processing after edits | Edit, Write, MultiEdit on .ts/.tsx |
|
|
134
|
+
### Shell Shortcuts
|
|
344
135
|
|
|
345
|
-
|
|
136
|
+
- `cc` - Claude Code with permissions skipped
|
|
137
|
+
- `ccc` - Claude Code with continue mode
|
|
346
138
|
|
|
347
|
-
|
|
348
|
-
| ----------------------- | -------------- | ------------------------------------- |
|
|
349
|
-
| `validate-command.js` | Bun/JavaScript | Security validation for bash commands |
|
|
350
|
-
| `statusline-ccusage.sh` | Bash | Git status and usage tracking display |
|
|
139
|
+
## 💎 Premium
|
|
351
140
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
### Local Project Installation (Recommended)
|
|
355
|
-
|
|
356
|
-
When run in a Git repository, creates `.claude/` in your project root:
|
|
141
|
+
Unlock advanced features at [mlv.sh/claude-cli](https://mlv.sh/claude-cli)
|
|
357
142
|
|
|
358
143
|
```bash
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
# Creates: your-project/.claude/
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
**Benefits:**
|
|
365
|
-
|
|
366
|
-
- Project-specific configurations
|
|
367
|
-
- Team collaboration ready
|
|
368
|
-
- Version control friendly
|
|
369
|
-
- Isolated environments
|
|
144
|
+
# Activate premium
|
|
145
|
+
npx aiblueprint-cli@latest claude-code pro activate YOUR_TOKEN
|
|
370
146
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
When not in a Git repository, uses global directory:
|
|
374
|
-
|
|
375
|
-
```bash
|
|
376
|
-
cd ~/
|
|
377
|
-
bunx aiblueprint-cli@latest claude-code setup
|
|
378
|
-
# Creates: ~/.claude/
|
|
147
|
+
# Setup premium configs
|
|
148
|
+
npx aiblueprint-cli@latest claude-code pro setup
|
|
379
149
|
```
|
|
380
150
|
|
|
381
|
-
**Benefits:**
|
|
382
|
-
|
|
383
|
-
- System-wide configurations
|
|
384
|
-
- Works across all projects
|
|
385
|
-
- Persistent settings
|
|
386
|
-
|
|
387
|
-
### Custom Path Installation
|
|
388
|
-
|
|
389
|
-
Use `--folder` for specific locations:
|
|
390
|
-
|
|
391
|
-
```bash
|
|
392
|
-
bunx aiblueprint-cli@latest claude-code setup --folder ./custom-config
|
|
393
|
-
bunx aiblueprint-cli@latest claude-code setup --folder /opt/claude-config
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
## 🔐 Security Features
|
|
397
|
-
|
|
398
|
-
### Command Validation System
|
|
399
|
-
|
|
400
|
-
The security system protects against dangerous operations:
|
|
401
|
-
|
|
402
|
-
**Critical Commands Blocked:**
|
|
403
|
-
|
|
404
|
-
- `rm -rf` (with path validation)
|
|
405
|
-
- `dd`, `mkfs`, `fdisk` (disk operations)
|
|
406
|
-
- `chmod 777`, `chown -R` (permission changes)
|
|
407
|
-
- `curl | bash`, `wget | sh` (remote execution)
|
|
408
|
-
- `sudo` operations (privilege escalation)
|
|
409
|
-
|
|
410
|
-
**Security Logging:**
|
|
411
|
-
|
|
412
|
-
```json
|
|
413
|
-
{
|
|
414
|
-
"timestamp": "2024-01-15T10:30:00.000Z",
|
|
415
|
-
"command": "rm -rf /",
|
|
416
|
-
"severity": "CRITICAL",
|
|
417
|
-
"action": "BLOCKED",
|
|
418
|
-
"reason": "Destructive command with critical path"
|
|
419
|
-
}
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
**Safe Paths Allowed:**
|
|
423
|
-
|
|
424
|
-
- `./`, `~/`, relative paths
|
|
425
|
-
- `node_modules/`, `.git/`, common safe directories
|
|
426
|
-
- Temporary directories (`/tmp/`, `/var/tmp/`)
|
|
427
|
-
|
|
428
|
-
### Hook-Based Protection
|
|
429
|
-
|
|
430
|
-
- **PreToolUse validation** - Commands checked before execution
|
|
431
|
-
- **Real-time analysis** - Pattern matching and rule evaluation
|
|
432
|
-
- **User confirmation** - Interactive prompts for questionable commands
|
|
433
|
-
- **Comprehensive rules** - 50+ security patterns and checks
|
|
434
|
-
|
|
435
151
|
## 🛠️ Development
|
|
436
152
|
|
|
437
|
-
### Local Development Setup
|
|
438
|
-
|
|
439
153
|
```bash
|
|
440
154
|
# Clone and setup
|
|
441
155
|
git clone <repository>
|
|
@@ -444,81 +158,21 @@ bun install
|
|
|
444
158
|
|
|
445
159
|
# Development mode
|
|
446
160
|
bun run dev claude-code setup
|
|
447
|
-
bun run dev claude-code
|
|
448
|
-
|
|
449
|
-
# Testing
|
|
450
|
-
bun run test:run # Run test suite
|
|
451
|
-
bun run dev-test # Test with temporary config
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
### Build and Release
|
|
455
|
-
|
|
456
|
-
```bash
|
|
457
|
-
# Build for distribution
|
|
458
|
-
bun run build # Compiles to dist/cli.js
|
|
459
|
-
|
|
460
|
-
# Local testing
|
|
461
|
-
bun run test-local # Creates npm link
|
|
462
|
-
aiblueprint claude-code setup # Test globally
|
|
463
|
-
|
|
464
|
-
# Release (automated)
|
|
465
|
-
bun run release # Version bump, build, tag, publish
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
### Project Structure
|
|
161
|
+
bun run dev claude-code statusline --list
|
|
469
162
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
├── cli.ts # Main CLI entry point
|
|
473
|
-
├── commands/
|
|
474
|
-
│ ├── setup.ts # Main setup command
|
|
475
|
-
│ ├── addHook.ts # Hook installation
|
|
476
|
-
│ └── addCommand.ts # Command installation
|
|
477
|
-
└── utils/
|
|
478
|
-
├── claude-config.ts # Configuration utilities
|
|
479
|
-
├── file-installer.ts # GitHub/local fallback
|
|
480
|
-
└── github.ts # GitHub API integration
|
|
481
|
-
|
|
482
|
-
claude-code-config/ # Template repository
|
|
483
|
-
├── commands/ # Command templates
|
|
484
|
-
├── hooks/ # Hook scripts
|
|
485
|
-
├── agents/ # Agent configurations
|
|
486
|
-
├── scripts/ # Utility scripts
|
|
487
|
-
└── song/ # Notification sounds
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
### Testing Commands
|
|
163
|
+
# Run tests
|
|
164
|
+
bun run test:run
|
|
491
165
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
bun run
|
|
495
|
-
bun run dev claude-code add hook post-edit-typescript
|
|
496
|
-
bun run dev claude-code add commands
|
|
497
|
-
bun run dev claude-code add commands commit
|
|
498
|
-
|
|
499
|
-
# Test with custom paths
|
|
500
|
-
bun run dev claude-code setup --folder ./test-config
|
|
166
|
+
# Build and test locally
|
|
167
|
+
bun run build
|
|
168
|
+
bun run test-local
|
|
501
169
|
```
|
|
502
170
|
|
|
503
171
|
## 📋 Requirements
|
|
504
172
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
-
|
|
508
|
-
- **Platform**: macOS (full support), Linux (partial), Windows (limited)
|
|
509
|
-
- **Dependencies**: Git (for repository detection)
|
|
510
|
-
|
|
511
|
-
### Claude Code Requirements
|
|
512
|
-
|
|
513
|
-
- **Claude Code**: Latest version installed
|
|
514
|
-
- **Permissions**: Ability to modify `~/.claude/settings.json`
|
|
515
|
-
|
|
516
|
-
### Optional Dependencies
|
|
517
|
-
|
|
518
|
-
- **bun**: Enhanced script execution and hooks
|
|
519
|
-
- **ccusage**: Advanced statusline with cost tracking
|
|
520
|
-
- **gh CLI**: GitHub integration for PR/issue commands
|
|
521
|
-
- **prettier**, **eslint**: TypeScript hook functionality
|
|
173
|
+
- Node.js 16+ or Bun
|
|
174
|
+
- Claude Code installed
|
|
175
|
+
- Optional: `bun`, `ccusage`, `gh CLI`
|
|
522
176
|
|
|
523
177
|
## 🤝 Contributing
|
|
524
178
|
|
|
@@ -528,75 +182,12 @@ bun run dev claude-code setup --folder ./test-config
|
|
|
528
182
|
4. Run tests: `bun run test:run`
|
|
529
183
|
5. Submit a pull request
|
|
530
184
|
|
|
531
|
-
### Adding New Templates
|
|
532
|
-
|
|
533
|
-
1. Add template files to `claude-code-config/`
|
|
534
|
-
2. Update metadata with YAML frontmatter
|
|
535
|
-
3. Test installation: `bun run dev claude-code add commands <name>`
|
|
536
|
-
4. Document in README
|
|
537
|
-
|
|
538
|
-
## 💎 AIBlueprint CLI Premium
|
|
539
|
-
|
|
540
|
-
Unlock advanced features with **AIBlueprint CLI Premium**:
|
|
541
|
-
|
|
542
|
-
### Premium Features
|
|
543
|
-
|
|
544
|
-
- ✨ **Advanced Statusline** - Enhanced git info, real-time costs, and token usage tracking
|
|
545
|
-
- 🚀 **Premium Commands** - Exclusive workflow automation templates
|
|
546
|
-
- 🤖 **Premium Agents** - Specialized AI agents for complex tasks
|
|
547
|
-
- 📦 **Priority Updates** - Get new features first
|
|
548
|
-
- 💬 **Priority Support** - Direct help when you need it
|
|
549
|
-
|
|
550
|
-
### How to Upgrade
|
|
551
|
-
|
|
552
|
-
```bash
|
|
553
|
-
# 1. Get your premium token at https://mlv.sh/claude-cli
|
|
554
|
-
|
|
555
|
-
# 2. Activate premium
|
|
556
|
-
aiblueprint claude-code pro activate YOUR_TOKEN
|
|
557
|
-
|
|
558
|
-
# 3. Setup premium configs
|
|
559
|
-
aiblueprint claude-code pro setup
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### Premium Commands
|
|
563
|
-
|
|
564
|
-
```bash
|
|
565
|
-
# Check premium status
|
|
566
|
-
aiblueprint claude-code pro status
|
|
567
|
-
|
|
568
|
-
# Update premium configs (overwrites all)
|
|
569
|
-
aiblueprint claude-code pro update
|
|
570
|
-
|
|
571
|
-
# Sync premium configs (selective update)
|
|
572
|
-
aiblueprint claude-code pro sync
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
### Sync Command
|
|
576
|
-
|
|
577
|
-
The `sync` command provides intelligent selective updates:
|
|
578
|
-
|
|
579
|
-
```bash
|
|
580
|
-
aiblueprint claude-code pro sync
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
**Features:**
|
|
584
|
-
|
|
585
|
-
- 🔍 **Diff Analysis** - Compares your local config with the latest premium version
|
|
586
|
-
- 📝 **Categorized Changes** - Shows NEW and MODIFIED items separately
|
|
587
|
-
- ✅ **Selective Update** - Choose exactly which files/folders to update
|
|
588
|
-
- 📁 **Smart Grouping** - Commands and agents shown individually, skills and scripts grouped as folders
|
|
589
|
-
|
|
590
|
-
**Learn more:** https://mlv.sh/claude-cli
|
|
591
|
-
|
|
592
|
-
---
|
|
593
|
-
|
|
594
185
|
## 📄 License
|
|
595
186
|
|
|
596
187
|
MIT License - see [LICENSE](LICENSE) file for details.
|
|
597
188
|
|
|
598
189
|
---
|
|
599
190
|
|
|
600
|
-
**Created by AIBlueprint** -
|
|
191
|
+
**Created by AIBlueprint** - [mlv.sh/claude-cli](https://mlv.sh/claude-cli)
|
|
601
192
|
|
|
602
|
-
Need help? [Open an issue](https://github.com/melvynx/aiblueprint/issues)
|
|
193
|
+
Need help? [Open an issue](https://github.com/melvynx/aiblueprint/issues) | [Documentation](https://codelynx.dev/docs)
|
package/dist/cli.js
CHANGED
|
@@ -33996,63 +33996,6 @@ async function symlinkCommand(params = {}) {
|
|
|
33996
33996
|
}
|
|
33997
33997
|
}
|
|
33998
33998
|
|
|
33999
|
-
// src/commands/statusline.ts
|
|
34000
|
-
var import_fs_extra8 = __toESM(require_lib4(), 1);
|
|
34001
|
-
import path10 from "path";
|
|
34002
|
-
import { homedir } from "os";
|
|
34003
|
-
async function statuslineCommand(options) {
|
|
34004
|
-
const claudeDir = options.folder ? path10.resolve(options.folder) : path10.join(homedir(), ".claude");
|
|
34005
|
-
console.log(source_default.blue(`\uD83D\uDE80 Setting up AIBlueprint Statusline ${source_default.gray(`v${getVersion()}`)}...`));
|
|
34006
|
-
console.log(source_default.gray(` Target: ${claudeDir}
|
|
34007
|
-
`));
|
|
34008
|
-
await import_fs_extra8.default.ensureDir(claudeDir);
|
|
34009
|
-
console.log(source_default.cyan("\uD83D\uDCE6 Checking dependencies..."));
|
|
34010
|
-
await checkAndInstallDependencies();
|
|
34011
|
-
console.log(source_default.cyan(`
|
|
34012
|
-
\uD83D\uDCE5 Cloning configuration repository...`));
|
|
34013
|
-
const repoPath = await cloneRepository();
|
|
34014
|
-
if (!repoPath) {
|
|
34015
|
-
console.log(source_default.red(" Failed to clone repository. Please check your internet connection."));
|
|
34016
|
-
return;
|
|
34017
|
-
}
|
|
34018
|
-
const sourceDir = path10.join(repoPath, "claude-code-config");
|
|
34019
|
-
if (!await import_fs_extra8.default.pathExists(sourceDir)) {
|
|
34020
|
-
await cleanupRepository(repoPath);
|
|
34021
|
-
console.log(source_default.red(" Configuration directory not found in cloned repository"));
|
|
34022
|
-
return;
|
|
34023
|
-
}
|
|
34024
|
-
try {
|
|
34025
|
-
const scriptsDir = path10.join(claudeDir, "scripts");
|
|
34026
|
-
await import_fs_extra8.default.ensureDir(scriptsDir);
|
|
34027
|
-
await import_fs_extra8.default.copy(path10.join(sourceDir, "scripts/statusline"), path10.join(scriptsDir, "statusline"), { overwrite: true });
|
|
34028
|
-
console.log(source_default.cyan(`
|
|
34029
|
-
\uD83D\uDCE6 Installing statusline dependencies...`));
|
|
34030
|
-
await installStatuslineDependencies(claudeDir);
|
|
34031
|
-
console.log(source_default.cyan(`
|
|
34032
|
-
⚙️ Configuring settings.json...`));
|
|
34033
|
-
const settingsPath = path10.join(claudeDir, "settings.json");
|
|
34034
|
-
let settings = {};
|
|
34035
|
-
try {
|
|
34036
|
-
const existingSettings = await import_fs_extra8.default.readFile(settingsPath, "utf-8");
|
|
34037
|
-
settings = JSON.parse(existingSettings);
|
|
34038
|
-
} catch {}
|
|
34039
|
-
settings.statusLine = {
|
|
34040
|
-
type: "command",
|
|
34041
|
-
command: `bun ${path10.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
34042
|
-
padding: 0
|
|
34043
|
-
};
|
|
34044
|
-
await import_fs_extra8.default.writeJson(settingsPath, settings, { spaces: 2 });
|
|
34045
|
-
console.log(source_default.green(`
|
|
34046
|
-
✅ Statusline setup complete!`));
|
|
34047
|
-
console.log(source_default.gray(`
|
|
34048
|
-
Your Claude Code statusline is now configured.`));
|
|
34049
|
-
console.log(source_default.gray(`Restart Claude Code to see the changes.
|
|
34050
|
-
`));
|
|
34051
|
-
} finally {
|
|
34052
|
-
await cleanupRepository(repoPath);
|
|
34053
|
-
}
|
|
34054
|
-
}
|
|
34055
|
-
|
|
34056
33999
|
// node_modules/@clack/core/dist/index.mjs
|
|
34057
34000
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
34058
34001
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -34770,19 +34713,19 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
34770
34713
|
|
|
34771
34714
|
// src/commands/pro.ts
|
|
34772
34715
|
import os13 from "os";
|
|
34773
|
-
import
|
|
34716
|
+
import path12 from "path";
|
|
34774
34717
|
|
|
34775
34718
|
// src/lib/pro-installer.ts
|
|
34776
|
-
var
|
|
34719
|
+
var import_fs_extra8 = __toESM(require_lib4(), 1);
|
|
34777
34720
|
import os11 from "os";
|
|
34778
|
-
import
|
|
34721
|
+
import path10 from "path";
|
|
34779
34722
|
import { exec as exec3 } from "child_process";
|
|
34780
34723
|
import { promisify as promisify2 } from "util";
|
|
34781
34724
|
var execAsync2 = promisify2(exec3);
|
|
34782
34725
|
var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
|
|
34783
34726
|
var PREMIUM_BRANCH = "main";
|
|
34784
34727
|
function getCacheRepoDir() {
|
|
34785
|
-
return
|
|
34728
|
+
return path10.join(os11.homedir(), ".config", "aiblueprint", "pro-repos", "aiblueprint-cli-premium");
|
|
34786
34729
|
}
|
|
34787
34730
|
async function execGitWithAuth(command, token, repoUrl, cwd) {
|
|
34788
34731
|
const authenticatedUrl = `https://x-access-token:${token}@${repoUrl.replace(/^https?:\/\//, "")}`;
|
|
@@ -34796,33 +34739,33 @@ async function execGitWithAuth(command, token, repoUrl, cwd) {
|
|
|
34796
34739
|
async function cloneOrUpdateRepo(token) {
|
|
34797
34740
|
const cacheDir = getCacheRepoDir();
|
|
34798
34741
|
const repoUrl = `https://github.com/${PREMIUM_REPO}.git`;
|
|
34799
|
-
if (await
|
|
34742
|
+
if (await import_fs_extra8.default.pathExists(path10.join(cacheDir, ".git"))) {
|
|
34800
34743
|
try {
|
|
34801
34744
|
await execGitWithAuth("pull", token, repoUrl, cacheDir);
|
|
34802
34745
|
} catch (error) {
|
|
34803
|
-
await
|
|
34804
|
-
await
|
|
34746
|
+
await import_fs_extra8.default.remove(cacheDir);
|
|
34747
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(cacheDir));
|
|
34805
34748
|
await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
34806
34749
|
}
|
|
34807
34750
|
} else {
|
|
34808
|
-
await
|
|
34751
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(cacheDir));
|
|
34809
34752
|
await execGitWithAuth(`clone ${repoUrl} ${cacheDir}`, token, repoUrl);
|
|
34810
34753
|
}
|
|
34811
|
-
return
|
|
34754
|
+
return path10.join(cacheDir, "claude-code-config");
|
|
34812
34755
|
}
|
|
34813
34756
|
async function copyConfigFromCache(cacheConfigDir, targetDir, onProgress) {
|
|
34814
34757
|
const walk = async (dir, baseDir = dir) => {
|
|
34815
|
-
const entries = await
|
|
34758
|
+
const entries = await import_fs_extra8.default.readdir(dir, { withFileTypes: true });
|
|
34816
34759
|
for (const entry of entries) {
|
|
34817
|
-
const sourcePath =
|
|
34818
|
-
const relativePath =
|
|
34819
|
-
const targetPath =
|
|
34760
|
+
const sourcePath = path10.join(dir, entry.name);
|
|
34761
|
+
const relativePath = path10.relative(baseDir, sourcePath);
|
|
34762
|
+
const targetPath = path10.join(targetDir, relativePath);
|
|
34820
34763
|
if (entry.isDirectory()) {
|
|
34821
|
-
await
|
|
34764
|
+
await import_fs_extra8.default.ensureDir(targetPath);
|
|
34822
34765
|
onProgress?.(relativePath, "directory");
|
|
34823
34766
|
await walk(sourcePath, baseDir);
|
|
34824
34767
|
} else {
|
|
34825
|
-
await
|
|
34768
|
+
await import_fs_extra8.default.copy(sourcePath, targetPath, { overwrite: true });
|
|
34826
34769
|
onProgress?.(relativePath, "file");
|
|
34827
34770
|
}
|
|
34828
34771
|
}
|
|
@@ -34843,8 +34786,8 @@ async function downloadFromPrivateGitHub(repo, branch, relativePath, targetPath,
|
|
|
34843
34786
|
return false;
|
|
34844
34787
|
}
|
|
34845
34788
|
const content = await response.arrayBuffer();
|
|
34846
|
-
await
|
|
34847
|
-
await
|
|
34789
|
+
await import_fs_extra8.default.ensureDir(path10.dirname(targetPath));
|
|
34790
|
+
await import_fs_extra8.default.writeFile(targetPath, Buffer.from(content));
|
|
34848
34791
|
return true;
|
|
34849
34792
|
} catch (error) {
|
|
34850
34793
|
console.error(`Error downloading ${relativePath}:`, error);
|
|
@@ -34869,10 +34812,10 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
34869
34812
|
console.error(`Unexpected response for directory ${dirPath}`);
|
|
34870
34813
|
return false;
|
|
34871
34814
|
}
|
|
34872
|
-
await
|
|
34815
|
+
await import_fs_extra8.default.ensureDir(targetDir);
|
|
34873
34816
|
for (const file of files) {
|
|
34874
34817
|
const relativePath = dirPath ? `${dirPath}/${file.name}` : file.name;
|
|
34875
|
-
const targetPath =
|
|
34818
|
+
const targetPath = path10.join(targetDir, file.name);
|
|
34876
34819
|
const displayPath = relativePath.replace("claude-code-config/", "");
|
|
34877
34820
|
if (file.type === "file") {
|
|
34878
34821
|
onProgress?.(displayPath, "file");
|
|
@@ -34889,7 +34832,7 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
34889
34832
|
}
|
|
34890
34833
|
async function installProConfigs(options) {
|
|
34891
34834
|
const { githubToken, claudeCodeFolder, onProgress } = options;
|
|
34892
|
-
const claudeFolder = claudeCodeFolder ||
|
|
34835
|
+
const claudeFolder = claudeCodeFolder || path10.join(os11.homedir(), ".claude");
|
|
34893
34836
|
try {
|
|
34894
34837
|
const cacheConfigDir = await cloneOrUpdateRepo(githubToken);
|
|
34895
34838
|
await copyConfigFromCache(cacheConfigDir, claudeFolder, onProgress);
|
|
@@ -34897,53 +34840,53 @@ async function installProConfigs(options) {
|
|
|
34897
34840
|
} catch (error) {
|
|
34898
34841
|
console.warn("Git caching failed, falling back to API download");
|
|
34899
34842
|
}
|
|
34900
|
-
const tempDir =
|
|
34843
|
+
const tempDir = path10.join(os11.tmpdir(), `aiblueprint-premium-${Date.now()}`);
|
|
34901
34844
|
try {
|
|
34902
34845
|
const success = await downloadDirectoryFromPrivateGitHub(PREMIUM_REPO, PREMIUM_BRANCH, "claude-code-config", tempDir, githubToken, onProgress);
|
|
34903
34846
|
if (!success) {
|
|
34904
34847
|
throw new Error("Failed to download premium configurations");
|
|
34905
34848
|
}
|
|
34906
|
-
await
|
|
34849
|
+
await import_fs_extra8.default.copy(tempDir, claudeFolder, {
|
|
34907
34850
|
overwrite: true
|
|
34908
34851
|
});
|
|
34909
34852
|
} catch (error) {
|
|
34910
34853
|
throw new Error(`Failed to install premium configs: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
34911
34854
|
} finally {
|
|
34912
34855
|
try {
|
|
34913
|
-
await
|
|
34856
|
+
await import_fs_extra8.default.remove(tempDir);
|
|
34914
34857
|
} catch {}
|
|
34915
34858
|
}
|
|
34916
34859
|
}
|
|
34917
34860
|
|
|
34918
34861
|
// src/lib/token-storage.ts
|
|
34919
|
-
var
|
|
34862
|
+
var import_fs_extra9 = __toESM(require_lib4(), 1);
|
|
34920
34863
|
import os12 from "os";
|
|
34921
|
-
import
|
|
34864
|
+
import path11 from "path";
|
|
34922
34865
|
function getConfigDir() {
|
|
34923
34866
|
const platform = os12.platform();
|
|
34924
34867
|
if (platform === "win32") {
|
|
34925
|
-
const appData = process.env.APPDATA ||
|
|
34926
|
-
return
|
|
34868
|
+
const appData = process.env.APPDATA || path11.join(os12.homedir(), "AppData", "Roaming");
|
|
34869
|
+
return path11.join(appData, "aiblueprint");
|
|
34927
34870
|
} else {
|
|
34928
|
-
const configHome = process.env.XDG_CONFIG_HOME ||
|
|
34929
|
-
return
|
|
34871
|
+
const configHome = process.env.XDG_CONFIG_HOME || path11.join(os12.homedir(), ".config");
|
|
34872
|
+
return path11.join(configHome, "aiblueprint");
|
|
34930
34873
|
}
|
|
34931
34874
|
}
|
|
34932
34875
|
function getTokenFilePath() {
|
|
34933
|
-
return
|
|
34876
|
+
return path11.join(getConfigDir(), "token.txt");
|
|
34934
34877
|
}
|
|
34935
34878
|
async function saveToken(githubToken) {
|
|
34936
34879
|
const tokenFile = getTokenFilePath();
|
|
34937
|
-
await
|
|
34938
|
-
await
|
|
34880
|
+
await import_fs_extra9.default.ensureDir(path11.dirname(tokenFile));
|
|
34881
|
+
await import_fs_extra9.default.writeFile(tokenFile, githubToken, { mode: 384 });
|
|
34939
34882
|
}
|
|
34940
34883
|
async function getToken() {
|
|
34941
34884
|
const tokenFile = getTokenFilePath();
|
|
34942
|
-
if (!await
|
|
34885
|
+
if (!await import_fs_extra9.default.pathExists(tokenFile)) {
|
|
34943
34886
|
return null;
|
|
34944
34887
|
}
|
|
34945
34888
|
try {
|
|
34946
|
-
const token = await
|
|
34889
|
+
const token = await import_fs_extra9.default.readFile(tokenFile, "utf-8");
|
|
34947
34890
|
return token.trim();
|
|
34948
34891
|
} catch (error) {
|
|
34949
34892
|
return null;
|
|
@@ -34957,7 +34900,7 @@ function getTokenInfo() {
|
|
|
34957
34900
|
}
|
|
34958
34901
|
|
|
34959
34902
|
// src/commands/pro.ts
|
|
34960
|
-
var
|
|
34903
|
+
var import_fs_extra10 = __toESM(require_lib4(), 1);
|
|
34961
34904
|
var API_URL = "https://codeline.app/api/products";
|
|
34962
34905
|
var PRODUCT_IDS = ["prd_XJVgxVPbGG", "prd_NKabAkdOkw"];
|
|
34963
34906
|
async function countInstalledItems(claudeDir) {
|
|
@@ -34967,29 +34910,29 @@ async function countInstalledItems(claudeDir) {
|
|
|
34967
34910
|
skills: 0
|
|
34968
34911
|
};
|
|
34969
34912
|
try {
|
|
34970
|
-
const commandsDir =
|
|
34971
|
-
if (await
|
|
34972
|
-
const files = await
|
|
34913
|
+
const commandsDir = path12.join(claudeDir, "commands");
|
|
34914
|
+
if (await import_fs_extra10.default.pathExists(commandsDir)) {
|
|
34915
|
+
const files = await import_fs_extra10.default.readdir(commandsDir);
|
|
34973
34916
|
counts.commands = files.filter((f) => f.endsWith(".md")).length;
|
|
34974
34917
|
}
|
|
34975
34918
|
} catch (error) {
|
|
34976
34919
|
console.error("Failed to count commands:", error instanceof Error ? error.message : error);
|
|
34977
34920
|
}
|
|
34978
34921
|
try {
|
|
34979
|
-
const agentsDir =
|
|
34980
|
-
if (await
|
|
34981
|
-
const files = await
|
|
34922
|
+
const agentsDir = path12.join(claudeDir, "agents");
|
|
34923
|
+
if (await import_fs_extra10.default.pathExists(agentsDir)) {
|
|
34924
|
+
const files = await import_fs_extra10.default.readdir(agentsDir);
|
|
34982
34925
|
counts.agents = files.filter((f) => f.endsWith(".md")).length;
|
|
34983
34926
|
}
|
|
34984
34927
|
} catch (error) {
|
|
34985
34928
|
console.error("Failed to count agents:", error instanceof Error ? error.message : error);
|
|
34986
34929
|
}
|
|
34987
34930
|
try {
|
|
34988
|
-
const skillsDir =
|
|
34989
|
-
if (await
|
|
34990
|
-
const items = await
|
|
34931
|
+
const skillsDir = path12.join(claudeDir, "skills");
|
|
34932
|
+
if (await import_fs_extra10.default.pathExists(skillsDir)) {
|
|
34933
|
+
const items = await import_fs_extra10.default.readdir(skillsDir);
|
|
34991
34934
|
const dirs = await Promise.all(items.map(async (item) => {
|
|
34992
|
-
const stat = await
|
|
34935
|
+
const stat = await import_fs_extra10.default.stat(path12.join(skillsDir, item));
|
|
34993
34936
|
return stat.isDirectory();
|
|
34994
34937
|
}));
|
|
34995
34938
|
counts.skills = dirs.filter(Boolean).length;
|
|
@@ -35102,7 +35045,7 @@ async function proSetupCommand(options = {}) {
|
|
|
35102
35045
|
Se(source_default.red("❌ Not activated"));
|
|
35103
35046
|
process.exit(1);
|
|
35104
35047
|
}
|
|
35105
|
-
const claudeDir = options.folder ?
|
|
35048
|
+
const claudeDir = options.folder ? path12.resolve(options.folder) : path12.join(os13.homedir(), ".claude");
|
|
35106
35049
|
const spinner = Y2();
|
|
35107
35050
|
const onProgress = (file, type) => {
|
|
35108
35051
|
spinner.message(`Installing: ${source_default.cyan(file)} ${source_default.gray(`(${type})`)}`);
|
|
@@ -35185,11 +35128,11 @@ async function proUpdateCommand(options = {}) {
|
|
|
35185
35128
|
|
|
35186
35129
|
// src/commands/sync.ts
|
|
35187
35130
|
import os14 from "os";
|
|
35188
|
-
import
|
|
35131
|
+
import path14 from "path";
|
|
35189
35132
|
|
|
35190
35133
|
// src/lib/sync-utils.ts
|
|
35191
|
-
var
|
|
35192
|
-
import
|
|
35134
|
+
var import_fs_extra11 = __toESM(require_lib4(), 1);
|
|
35135
|
+
import path13 from "path";
|
|
35193
35136
|
import crypto from "crypto";
|
|
35194
35137
|
var PREMIUM_REPO2 = "Melvynx/aiblueprint-cli-premium";
|
|
35195
35138
|
var PREMIUM_BRANCH2 = "main";
|
|
@@ -35238,7 +35181,7 @@ async function listRemoteFilesRecursive(dirPath, githubToken, basePath = "") {
|
|
|
35238
35181
|
}
|
|
35239
35182
|
async function computeLocalFileSha(filePath) {
|
|
35240
35183
|
try {
|
|
35241
|
-
const content = await
|
|
35184
|
+
const content = await import_fs_extra11.default.readFile(filePath);
|
|
35242
35185
|
return computeFileSha(content);
|
|
35243
35186
|
} catch {
|
|
35244
35187
|
return null;
|
|
@@ -35246,15 +35189,15 @@ async function computeLocalFileSha(filePath) {
|
|
|
35246
35189
|
}
|
|
35247
35190
|
async function listLocalFiles(dir) {
|
|
35248
35191
|
const files = [];
|
|
35249
|
-
if (!await
|
|
35192
|
+
if (!await import_fs_extra11.default.pathExists(dir)) {
|
|
35250
35193
|
return files;
|
|
35251
35194
|
}
|
|
35252
|
-
const items = await
|
|
35195
|
+
const items = await import_fs_extra11.default.readdir(dir);
|
|
35253
35196
|
for (const item of items) {
|
|
35254
35197
|
if (item === "node_modules" || item === ".DS_Store")
|
|
35255
35198
|
continue;
|
|
35256
|
-
const fullPath =
|
|
35257
|
-
const stat = await
|
|
35199
|
+
const fullPath = path13.join(dir, item);
|
|
35200
|
+
const stat = await import_fs_extra11.default.stat(fullPath);
|
|
35258
35201
|
if (stat.isDirectory()) {
|
|
35259
35202
|
files.push(item);
|
|
35260
35203
|
const subFiles = await listLocalFilesRecursive(fullPath, item);
|
|
@@ -35267,13 +35210,13 @@ async function listLocalFiles(dir) {
|
|
|
35267
35210
|
}
|
|
35268
35211
|
async function listLocalFilesRecursive(dir, basePath) {
|
|
35269
35212
|
const files = [];
|
|
35270
|
-
const items = await
|
|
35213
|
+
const items = await import_fs_extra11.default.readdir(dir);
|
|
35271
35214
|
for (const item of items) {
|
|
35272
35215
|
if (item === "node_modules" || item === ".DS_Store")
|
|
35273
35216
|
continue;
|
|
35274
|
-
const fullPath =
|
|
35217
|
+
const fullPath = path13.join(dir, item);
|
|
35275
35218
|
const relativePath = `${basePath}/${item}`;
|
|
35276
|
-
const stat = await
|
|
35219
|
+
const stat = await import_fs_extra11.default.stat(fullPath);
|
|
35277
35220
|
if (stat.isDirectory()) {
|
|
35278
35221
|
files.push(relativePath);
|
|
35279
35222
|
const subFiles = await listLocalFilesRecursive(fullPath, relativePath);
|
|
@@ -35286,7 +35229,7 @@ async function listLocalFilesRecursive(dir, basePath) {
|
|
|
35286
35229
|
}
|
|
35287
35230
|
async function analyzeCategory(category, claudeDir, githubToken) {
|
|
35288
35231
|
const items = [];
|
|
35289
|
-
const localDir =
|
|
35232
|
+
const localDir = path13.join(claudeDir, category);
|
|
35290
35233
|
const remoteFiles = await listRemoteFilesRecursive(category, githubToken);
|
|
35291
35234
|
const localFiles = await listLocalFiles(localDir);
|
|
35292
35235
|
const remoteSet = new Map;
|
|
@@ -35295,7 +35238,7 @@ async function analyzeCategory(category, claudeDir, githubToken) {
|
|
|
35295
35238
|
}
|
|
35296
35239
|
const localSet = new Set(localFiles);
|
|
35297
35240
|
for (const [remotePath, { sha, isFolder }] of remoteSet) {
|
|
35298
|
-
const localPath =
|
|
35241
|
+
const localPath = path13.join(localDir, remotePath);
|
|
35299
35242
|
if (isFolder) {
|
|
35300
35243
|
continue;
|
|
35301
35244
|
}
|
|
@@ -35338,8 +35281,8 @@ async function analyzeCategory(category, claudeDir, githubToken) {
|
|
|
35338
35281
|
if (parentAlreadyDeleted) {
|
|
35339
35282
|
continue;
|
|
35340
35283
|
}
|
|
35341
|
-
const fullPath =
|
|
35342
|
-
const stat = await
|
|
35284
|
+
const fullPath = path13.join(localDir, localPath);
|
|
35285
|
+
const stat = await import_fs_extra11.default.stat(fullPath).catch(() => null);
|
|
35343
35286
|
if (stat) {
|
|
35344
35287
|
const isFolder = stat.isDirectory();
|
|
35345
35288
|
items.push({
|
|
@@ -35375,9 +35318,9 @@ async function fetchRemoteSettings(githubToken) {
|
|
|
35375
35318
|
}
|
|
35376
35319
|
}
|
|
35377
35320
|
async function getLocalSettings(claudeDir) {
|
|
35378
|
-
const settingsPath =
|
|
35321
|
+
const settingsPath = path13.join(claudeDir, "settings.json");
|
|
35379
35322
|
try {
|
|
35380
|
-
const content = await
|
|
35323
|
+
const content = await import_fs_extra11.default.readFile(settingsPath, "utf-8");
|
|
35381
35324
|
return JSON.parse(content);
|
|
35382
35325
|
} catch {
|
|
35383
35326
|
return {};
|
|
@@ -35459,8 +35402,8 @@ async function downloadFromPrivateGitHub2(relativePath, targetPath, githubToken)
|
|
|
35459
35402
|
return false;
|
|
35460
35403
|
}
|
|
35461
35404
|
const content = await response.arrayBuffer();
|
|
35462
|
-
await
|
|
35463
|
-
await
|
|
35405
|
+
await import_fs_extra11.default.ensureDir(path13.dirname(targetPath));
|
|
35406
|
+
await import_fs_extra11.default.writeFile(targetPath, Buffer.from(content));
|
|
35464
35407
|
return true;
|
|
35465
35408
|
} catch {
|
|
35466
35409
|
return false;
|
|
@@ -35470,10 +35413,10 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
|
|
|
35470
35413
|
if (hooks.length === 0) {
|
|
35471
35414
|
return { success: 0, failed: 0 };
|
|
35472
35415
|
}
|
|
35473
|
-
const settingsPath =
|
|
35416
|
+
const settingsPath = path13.join(claudeDir, "settings.json");
|
|
35474
35417
|
let settings = {};
|
|
35475
35418
|
try {
|
|
35476
|
-
const content = await
|
|
35419
|
+
const content = await import_fs_extra11.default.readFile(settingsPath, "utf-8");
|
|
35477
35420
|
settings = JSON.parse(content);
|
|
35478
35421
|
} catch {
|
|
35479
35422
|
settings = {};
|
|
@@ -35501,7 +35444,7 @@ async function syncSelectedHooks(claudeDir, hooks, onProgress) {
|
|
|
35501
35444
|
failed++;
|
|
35502
35445
|
}
|
|
35503
35446
|
}
|
|
35504
|
-
await
|
|
35447
|
+
await import_fs_extra11.default.writeFile(settingsPath, JSON.stringify(settings, null, 2));
|
|
35505
35448
|
return { success, failed };
|
|
35506
35449
|
}
|
|
35507
35450
|
async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
|
|
@@ -35509,11 +35452,11 @@ async function syncSelectedItems(claudeDir, items, githubToken, onProgress) {
|
|
|
35509
35452
|
let failed = 0;
|
|
35510
35453
|
let deleted = 0;
|
|
35511
35454
|
for (const item of items) {
|
|
35512
|
-
const targetPath =
|
|
35455
|
+
const targetPath = path13.join(claudeDir, item.relativePath);
|
|
35513
35456
|
if (item.status === "deleted") {
|
|
35514
35457
|
onProgress?.(item.relativePath, "deleting");
|
|
35515
35458
|
try {
|
|
35516
|
-
await
|
|
35459
|
+
await import_fs_extra11.default.remove(targetPath);
|
|
35517
35460
|
deleted++;
|
|
35518
35461
|
} catch {
|
|
35519
35462
|
failed++;
|
|
@@ -35665,7 +35608,7 @@ async function proSyncCommand(options = {}) {
|
|
|
35665
35608
|
Se(source_default.red("❌ Not activated"));
|
|
35666
35609
|
process.exit(1);
|
|
35667
35610
|
}
|
|
35668
|
-
const claudeDir = options.folder ?
|
|
35611
|
+
const claudeDir = options.folder ? path14.resolve(options.folder) : path14.join(os14.homedir(), ".claude");
|
|
35669
35612
|
const spinner = Y2();
|
|
35670
35613
|
spinner.start("Analyzing changes...");
|
|
35671
35614
|
const result = await analyzeSyncChanges(claudeDir, githubToken);
|
|
@@ -35893,10 +35836,170 @@ async function proSyncCommand(options = {}) {
|
|
|
35893
35836
|
}
|
|
35894
35837
|
}
|
|
35895
35838
|
|
|
35839
|
+
// src/commands/dynamic-scripts.ts
|
|
35840
|
+
import path17 from "path";
|
|
35841
|
+
import { homedir } from "os";
|
|
35842
|
+
|
|
35843
|
+
// src/lib/script-parser.ts
|
|
35844
|
+
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
35845
|
+
import path15 from "path";
|
|
35846
|
+
var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
|
|
35847
|
+
var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
|
|
35848
|
+
function shouldIncludeScript(scriptName) {
|
|
35849
|
+
if (EXCLUDED_SCRIPTS.includes(scriptName))
|
|
35850
|
+
return false;
|
|
35851
|
+
if (EXCLUDED_SUFFIXES.some((suffix) => scriptName.endsWith(suffix)))
|
|
35852
|
+
return false;
|
|
35853
|
+
return true;
|
|
35854
|
+
}
|
|
35855
|
+
async function readScriptsPackageJson(claudeDir) {
|
|
35856
|
+
const packageJsonPath = path15.join(claudeDir, "scripts", "package.json");
|
|
35857
|
+
try {
|
|
35858
|
+
if (!await import_fs_extra12.default.pathExists(packageJsonPath)) {
|
|
35859
|
+
return null;
|
|
35860
|
+
}
|
|
35861
|
+
const content = await import_fs_extra12.default.readFile(packageJsonPath, "utf-8");
|
|
35862
|
+
const parsed = JSON.parse(content);
|
|
35863
|
+
return parsed.scripts || null;
|
|
35864
|
+
} catch (error) {
|
|
35865
|
+
if (process.env.DEBUG) {
|
|
35866
|
+
console.error("Failed to read scripts package.json:", error);
|
|
35867
|
+
}
|
|
35868
|
+
return null;
|
|
35869
|
+
}
|
|
35870
|
+
}
|
|
35871
|
+
function parseScriptCommands(scripts) {
|
|
35872
|
+
const commands = [];
|
|
35873
|
+
for (const scriptName of Object.keys(scripts)) {
|
|
35874
|
+
if (!shouldIncludeScript(scriptName)) {
|
|
35875
|
+
continue;
|
|
35876
|
+
}
|
|
35877
|
+
if (!scriptName.includes(":")) {
|
|
35878
|
+
continue;
|
|
35879
|
+
}
|
|
35880
|
+
const [prefix, ...actionParts] = scriptName.split(":");
|
|
35881
|
+
const action = actionParts.join(":");
|
|
35882
|
+
if (!action) {
|
|
35883
|
+
continue;
|
|
35884
|
+
}
|
|
35885
|
+
commands.push({
|
|
35886
|
+
prefix,
|
|
35887
|
+
action,
|
|
35888
|
+
fullScriptName: scriptName
|
|
35889
|
+
});
|
|
35890
|
+
}
|
|
35891
|
+
return commands;
|
|
35892
|
+
}
|
|
35893
|
+
function groupScriptsByPrefix(commands) {
|
|
35894
|
+
const groups = {};
|
|
35895
|
+
for (const command of commands) {
|
|
35896
|
+
if (!groups[command.prefix]) {
|
|
35897
|
+
groups[command.prefix] = [];
|
|
35898
|
+
}
|
|
35899
|
+
groups[command.prefix].push(command.action);
|
|
35900
|
+
}
|
|
35901
|
+
return groups;
|
|
35902
|
+
}
|
|
35903
|
+
|
|
35904
|
+
// src/commands/script-runner.ts
|
|
35905
|
+
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
35906
|
+
import { spawn as spawn2 } from "child_process";
|
|
35907
|
+
import { execSync as execSync4 } from "child_process";
|
|
35908
|
+
import path16 from "path";
|
|
35909
|
+
import os15 from "os";
|
|
35910
|
+
function checkCommand(cmd) {
|
|
35911
|
+
try {
|
|
35912
|
+
const isWindows = os15.platform() === "win32";
|
|
35913
|
+
const whichCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
35914
|
+
execSync4(whichCmd, { stdio: "ignore" });
|
|
35915
|
+
return true;
|
|
35916
|
+
} catch {
|
|
35917
|
+
return false;
|
|
35918
|
+
}
|
|
35919
|
+
}
|
|
35920
|
+
function showAvailableActions(prefix, actions) {
|
|
35921
|
+
console.log(source_default.blue(`
|
|
35922
|
+
${prefix.charAt(0).toUpperCase() + prefix.slice(1)} Scripts:`));
|
|
35923
|
+
console.log(source_default.gray(`Run scripts from ~/.claude/scripts
|
|
35924
|
+
`));
|
|
35925
|
+
for (const action of actions) {
|
|
35926
|
+
console.log(source_default.white(` ${prefix} ${action}`));
|
|
35927
|
+
}
|
|
35928
|
+
console.log(source_default.gray(`
|
|
35929
|
+
Usage: aiblueprint ${prefix} <action>`));
|
|
35930
|
+
console.log(source_default.gray(`Example: aiblueprint ${prefix} ${actions[0] || "start"}
|
|
35931
|
+
`));
|
|
35932
|
+
}
|
|
35933
|
+
async function executeScript(scriptName, claudeDir) {
|
|
35934
|
+
if (!checkCommand("bun")) {
|
|
35935
|
+
console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
|
|
35936
|
+
return 1;
|
|
35937
|
+
}
|
|
35938
|
+
const scriptsDir = path16.join(claudeDir, "scripts");
|
|
35939
|
+
if (!await import_fs_extra13.default.pathExists(scriptsDir)) {
|
|
35940
|
+
console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
|
|
35941
|
+
console.log(source_default.gray("Run: aiblueprint claude-code setup"));
|
|
35942
|
+
return 1;
|
|
35943
|
+
}
|
|
35944
|
+
const packageJsonPath = path16.join(scriptsDir, "package.json");
|
|
35945
|
+
if (!await import_fs_extra13.default.pathExists(packageJsonPath)) {
|
|
35946
|
+
console.error(source_default.red(`package.json not found in ${scriptsDir}`));
|
|
35947
|
+
return 1;
|
|
35948
|
+
}
|
|
35949
|
+
const packageJson = await import_fs_extra13.default.readJson(packageJsonPath);
|
|
35950
|
+
if (!packageJson.scripts || !packageJson.scripts[scriptName]) {
|
|
35951
|
+
console.error(source_default.red(`Script "${scriptName}" not found in package.json`));
|
|
35952
|
+
return 1;
|
|
35953
|
+
}
|
|
35954
|
+
return new Promise((resolve) => {
|
|
35955
|
+
const child = spawn2("bun", ["run", scriptName], {
|
|
35956
|
+
cwd: scriptsDir,
|
|
35957
|
+
stdio: "inherit",
|
|
35958
|
+
env: process.env
|
|
35959
|
+
});
|
|
35960
|
+
child.on("close", (code) => {
|
|
35961
|
+
resolve(code || 0);
|
|
35962
|
+
});
|
|
35963
|
+
child.on("error", (error) => {
|
|
35964
|
+
console.error(source_default.red(`Failed to execute script: ${error.message}`));
|
|
35965
|
+
resolve(1);
|
|
35966
|
+
});
|
|
35967
|
+
});
|
|
35968
|
+
}
|
|
35969
|
+
|
|
35970
|
+
// src/commands/dynamic-scripts.ts
|
|
35971
|
+
function getClaudeDir(parentOptions) {
|
|
35972
|
+
return parentOptions.claudeCodeFolder || parentOptions.folder ? path17.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path17.join(homedir(), ".claude");
|
|
35973
|
+
}
|
|
35974
|
+
async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
|
|
35975
|
+
const scripts = await readScriptsPackageJson(claudeDir);
|
|
35976
|
+
if (!scripts) {
|
|
35977
|
+
return;
|
|
35978
|
+
}
|
|
35979
|
+
const commands = parseScriptCommands(scripts);
|
|
35980
|
+
if (commands.length === 0) {
|
|
35981
|
+
return;
|
|
35982
|
+
}
|
|
35983
|
+
const scriptGroups = groupScriptsByPrefix(commands);
|
|
35984
|
+
for (const [prefix, actions] of Object.entries(scriptGroups)) {
|
|
35985
|
+
const command = claudeCodeCmd.command(`${prefix} [action]`).description(`Run ${prefix} scripts from ~/.claude/scripts`).option("-l, --list", "List available actions").action(async (action, options) => {
|
|
35986
|
+
const parentOptions = command.parent?.opts() || {};
|
|
35987
|
+
const resolvedClaudeDir = getClaudeDir(parentOptions);
|
|
35988
|
+
if (options.list || !action) {
|
|
35989
|
+
showAvailableActions(prefix, actions);
|
|
35990
|
+
return;
|
|
35991
|
+
}
|
|
35992
|
+
const exitCode = await executeScript(`${prefix}:${action}`, resolvedClaudeDir);
|
|
35993
|
+
process.exit(exitCode);
|
|
35994
|
+
});
|
|
35995
|
+
}
|
|
35996
|
+
}
|
|
35997
|
+
|
|
35896
35998
|
// src/cli.ts
|
|
35897
35999
|
import { readFileSync as readFileSync3 } from "fs";
|
|
35898
36000
|
import { dirname as dirname3, join as join2 } from "path";
|
|
35899
36001
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
36002
|
+
import { homedir as homedir2 } from "os";
|
|
35900
36003
|
var __dirname3 = dirname3(fileURLToPath3(import.meta.url));
|
|
35901
36004
|
var packageJson = JSON.parse(readFileSync3(join2(__dirname3, "../package.json"), "utf8"));
|
|
35902
36005
|
var program2 = new Command;
|
|
@@ -35927,11 +36030,6 @@ claudeCodeCmd.command("symlink").description("Create symlinks between different
|
|
|
35927
36030
|
factoryAiFolder: parentOptions.factoryAiFolder
|
|
35928
36031
|
});
|
|
35929
36032
|
});
|
|
35930
|
-
claudeCodeCmd.command("statusline").description("Setup custom statusline with git status, costs, and token usage").action((options, command) => {
|
|
35931
|
-
const parentOptions = command.parent.opts();
|
|
35932
|
-
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35933
|
-
statuslineCommand({ folder: claudeCodeFolder });
|
|
35934
|
-
});
|
|
35935
36033
|
var proCmd = claudeCodeCmd.command("pro").description("Manage AIBlueprint CLI Premium features");
|
|
35936
36034
|
proCmd.command("activate [token]").description("Activate AIBlueprint CLI Premium with your access token").action((token) => {
|
|
35937
36035
|
proActivateCommand(token);
|
|
@@ -35954,6 +36052,14 @@ proCmd.command("sync").description("Sync premium configurations with selective u
|
|
|
35954
36052
|
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
35955
36053
|
proSyncCommand({ folder: claudeCodeFolder });
|
|
35956
36054
|
});
|
|
36055
|
+
try {
|
|
36056
|
+
const claudeDir = join2(homedir2(), ".claude");
|
|
36057
|
+
await registerDynamicScriptCommands(claudeCodeCmd, claudeDir);
|
|
36058
|
+
} catch (error) {
|
|
36059
|
+
if (process.env.DEBUG) {
|
|
36060
|
+
console.error("Failed to register dynamic commands:", error);
|
|
36061
|
+
}
|
|
36062
|
+
}
|
|
35957
36063
|
program2.parse(process.argv);
|
|
35958
36064
|
if (!process.argv.slice(2).length) {
|
|
35959
36065
|
console.log(source_default.blue("\uD83D\uDE80 AIBlueprint CLI"));
|