aiblueprint-cli 1.4.24 → 1.4.25
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/claude-code-config/skills/workflow-apex-free/SKILL.md +261 -0
- package/claude-code-config/skills/workflow-apex-free/scripts/setup-templates.sh +100 -0
- package/claude-code-config/skills/workflow-apex-free/scripts/update-progress.sh +80 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-00-init.md +267 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-00b-branch.md +126 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-00b-economy.md +244 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-00b-interactive.md +153 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-01-analyze.md +361 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-02-plan.md +264 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-03-execute.md +239 -0
- package/claude-code-config/skills/workflow-apex-free/steps/step-04-validate.md +251 -0
- package/claude-code-config/skills/workflow-apex-free/templates/00-context.md +43 -0
- package/claude-code-config/skills/workflow-apex-free/templates/01-analyze.md +10 -0
- package/claude-code-config/skills/workflow-apex-free/templates/02-plan.md +10 -0
- package/claude-code-config/skills/workflow-apex-free/templates/03-execute.md +10 -0
- package/claude-code-config/skills/workflow-apex-free/templates/04-validate.md +10 -0
- package/claude-code-config/skills/workflow-apex-free/templates/README.md +176 -0
- package/claude-code-config/skills/workflow-apex-free/templates/step-complete.md +7 -0
- package/dist/cli.js +146 -9
- package/package.json +1 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# APEX Template System
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This directory contains template files used to initialize APEX workflow outputs when save mode (`-s`) is enabled. This template system significantly reduces token usage by moving repetitive content out of step files.
|
|
6
|
+
|
|
7
|
+
## Template Files
|
|
8
|
+
|
|
9
|
+
| Template | Purpose | Created When |
|
|
10
|
+
|----------|---------|--------------|
|
|
11
|
+
| `00-context.md` | Workflow configuration and progress tracking | Always (if save_mode) |
|
|
12
|
+
| `01-analyze.md` | Analysis findings | Always (if save_mode) |
|
|
13
|
+
| `02-plan.md` | Implementation plan | Always (if save_mode) |
|
|
14
|
+
| `03-execute.md` | Implementation log | Always (if save_mode) |
|
|
15
|
+
| `04-validate.md` | Validation results and workflow completion | Always (if save_mode) |
|
|
16
|
+
| `step-complete.md` | Completion marker template | Referenced in steps |
|
|
17
|
+
|
|
18
|
+
## Template Variables
|
|
19
|
+
|
|
20
|
+
Templates use `{{variable}}` syntax for placeholders:
|
|
21
|
+
|
|
22
|
+
| Variable | Description | Example |
|
|
23
|
+
|----------|-------------|---------|
|
|
24
|
+
| `{{task_id}}` | Kebab-case task identifier | `01-add-auth-middleware` |
|
|
25
|
+
| `{{task_description}}` | Plain text task description | `add authentication middleware` |
|
|
26
|
+
| `{{timestamp}}` | ISO 8601 timestamp | `2026-01-12T10:30:00Z` |
|
|
27
|
+
| `{{auto_mode}}` | Auto mode flag | `true` or `false` |
|
|
28
|
+
| `{{save_mode}}` | Save mode flag | `true` or `false` |
|
|
29
|
+
| `{{economy_mode}}` | Economy mode flag | `true` or `false` |
|
|
30
|
+
| `{{branch_mode}}` | Branch mode flag | `true` or `false` |
|
|
31
|
+
| `{{interactive_mode}}` | Interactive mode flag | `true` or `false` |
|
|
32
|
+
| `{{branch_name}}` | Git branch name | `feature/add-auth` |
|
|
33
|
+
| `{{original_input}}` | Raw user input | `/apex -a -s add auth` |
|
|
34
|
+
|
|
35
|
+
## Setup Script
|
|
36
|
+
|
|
37
|
+
### `setup-templates.sh`
|
|
38
|
+
|
|
39
|
+
Initializes all template files in the output directory with variables replaced.
|
|
40
|
+
|
|
41
|
+
**Usage:**
|
|
42
|
+
```bash
|
|
43
|
+
bash scripts/setup-templates.sh \
|
|
44
|
+
"feature_name" \
|
|
45
|
+
"task_description" \
|
|
46
|
+
"auto_mode" \
|
|
47
|
+
"save_mode" \
|
|
48
|
+
"economy_mode" \
|
|
49
|
+
"branch_mode" \
|
|
50
|
+
"interactive_mode" \
|
|
51
|
+
"branch_name" \
|
|
52
|
+
"original_input"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Output:**
|
|
56
|
+
```
|
|
57
|
+
.claude/output/apex/01-add-auth-middleware/
|
|
58
|
+
├── 00-context.md # Always created
|
|
59
|
+
├── 01-analyze.md # Always created
|
|
60
|
+
├── 02-plan.md # Always created
|
|
61
|
+
├── 03-execute.md # Always created
|
|
62
|
+
└── 04-validate.md # Always created
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Progress Update Script
|
|
66
|
+
|
|
67
|
+
### `update-progress.sh`
|
|
68
|
+
|
|
69
|
+
Updates the progress table in `00-context.md` without manual markdown editing.
|
|
70
|
+
|
|
71
|
+
**Usage:**
|
|
72
|
+
```bash
|
|
73
|
+
bash scripts/update-progress.sh <task_id> <step_number> <step_name> <status>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Examples:**
|
|
77
|
+
```bash
|
|
78
|
+
# Mark step 01 as in progress
|
|
79
|
+
bash scripts/update-progress.sh "01-add-auth" "01" "analyze" "in_progress"
|
|
80
|
+
|
|
81
|
+
# Mark step 01 as complete
|
|
82
|
+
bash scripts/update-progress.sh "01-add-auth" "01" "analyze" "complete"
|
|
83
|
+
|
|
84
|
+
# Mark step 02 as in progress
|
|
85
|
+
bash scripts/update-progress.sh "01-add-auth" "02" "plan" "in_progress"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Status Values:**
|
|
89
|
+
- `in_progress` → `⏳ In Progress`
|
|
90
|
+
- `complete` → `✓ Complete`
|
|
91
|
+
|
|
92
|
+
## Token Savings
|
|
93
|
+
|
|
94
|
+
### Before Optimization
|
|
95
|
+
|
|
96
|
+
Each step file contained full template content inline:
|
|
97
|
+
|
|
98
|
+
```markdown
|
|
99
|
+
### 1. Initialize Save Output (if save_mode)
|
|
100
|
+
|
|
101
|
+
**If `{save_mode}` = true:**
|
|
102
|
+
|
|
103
|
+
Create `{output_dir}/01-analyze.md`:
|
|
104
|
+
```markdown
|
|
105
|
+
# Step 01: Analyze
|
|
106
|
+
|
|
107
|
+
**Task:** {task_description}
|
|
108
|
+
**Started:** {ISO timestamp}
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Context Discovery
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Update `00-context.md` progress:
|
|
116
|
+
```markdown
|
|
117
|
+
| 01-analyze | ⏳ In Progress | {timestamp} |
|
|
118
|
+
```
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Token cost per step:** ~200 tokens × 5 steps = ~1,000 tokens
|
|
122
|
+
|
|
123
|
+
### After Optimization
|
|
124
|
+
|
|
125
|
+
Step files now reference templates and scripts:
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
### 1. Initialize Save Output (if save_mode)
|
|
129
|
+
|
|
130
|
+
**If `{save_mode}` = true:**
|
|
131
|
+
|
|
132
|
+
The file `{output_dir}/01-analyze.md` has already been created by the setup script.
|
|
133
|
+
|
|
134
|
+
Update progress:
|
|
135
|
+
```bash
|
|
136
|
+
bash {skill_dir}/scripts/update-progress.sh "{task_id}" "01" "analyze" "in_progress"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Append your findings to `01-analyze.md` as you work.
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Token cost per step:** ~50 tokens × 5 steps = ~250 tokens
|
|
143
|
+
|
|
144
|
+
**Total savings:** ~750 tokens per workflow execution (75% reduction)
|
|
145
|
+
|
|
146
|
+
## How It Works
|
|
147
|
+
|
|
148
|
+
1. **Initialization (step-00-init.md):**
|
|
149
|
+
- Runs `setup-templates.sh` once at workflow start
|
|
150
|
+
- Creates all template files with variables replaced
|
|
151
|
+
- Output directory is ready with pre-initialized files
|
|
152
|
+
|
|
153
|
+
2. **Each Step:**
|
|
154
|
+
- Runs `update-progress.sh` to mark step as "in_progress"
|
|
155
|
+
- Appends findings/logs to the pre-created step file
|
|
156
|
+
- Runs `update-progress.sh` again to mark step as "complete"
|
|
157
|
+
|
|
158
|
+
3. **Benefits:**
|
|
159
|
+
- AI doesn't need to hold template content in context
|
|
160
|
+
- Consistent formatting across all workflows
|
|
161
|
+
- Easy to update templates without editing step files
|
|
162
|
+
- Scripts handle the tedious markdown updates
|
|
163
|
+
|
|
164
|
+
## Updating Templates
|
|
165
|
+
|
|
166
|
+
To modify template content:
|
|
167
|
+
|
|
168
|
+
1. Edit the template file in `templates/`
|
|
169
|
+
2. Changes apply to all future workflows automatically
|
|
170
|
+
3. No need to update step files
|
|
171
|
+
|
|
172
|
+
## Maintenance
|
|
173
|
+
|
|
174
|
+
- Templates are stateless (no workflow-specific logic)
|
|
175
|
+
- Scripts are idempotent (safe to run multiple times)
|
|
176
|
+
- Variables use `{{var}}` syntax to avoid conflicts with markdown
|
package/dist/cli.js
CHANGED
|
@@ -33301,6 +33301,44 @@ function formatDate(date) {
|
|
|
33301
33301
|
const pad = (n) => n.toString().padStart(2, "0");
|
|
33302
33302
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}-${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
|
|
33303
33303
|
}
|
|
33304
|
+
async function listBackups() {
|
|
33305
|
+
const exists = await import_fs_extra5.default.pathExists(BACKUP_BASE_DIR);
|
|
33306
|
+
if (!exists) {
|
|
33307
|
+
return [];
|
|
33308
|
+
}
|
|
33309
|
+
const entries = await import_fs_extra5.default.readdir(BACKUP_BASE_DIR, { withFileTypes: true });
|
|
33310
|
+
const backups = [];
|
|
33311
|
+
for (const entry of entries) {
|
|
33312
|
+
if (!entry.isDirectory())
|
|
33313
|
+
continue;
|
|
33314
|
+
const match = entry.name.match(/^(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})$/);
|
|
33315
|
+
if (!match)
|
|
33316
|
+
continue;
|
|
33317
|
+
const [, year, month, day, hour, minute, second] = match;
|
|
33318
|
+
const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute), parseInt(second));
|
|
33319
|
+
backups.push({
|
|
33320
|
+
name: entry.name,
|
|
33321
|
+
path: path7.join(BACKUP_BASE_DIR, entry.name),
|
|
33322
|
+
date
|
|
33323
|
+
});
|
|
33324
|
+
}
|
|
33325
|
+
return backups.sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
33326
|
+
}
|
|
33327
|
+
async function loadBackup(backupPath, claudeDir) {
|
|
33328
|
+
const exists = await import_fs_extra5.default.pathExists(backupPath);
|
|
33329
|
+
if (!exists) {
|
|
33330
|
+
throw new Error(`Backup not found: ${backupPath}`);
|
|
33331
|
+
}
|
|
33332
|
+
await import_fs_extra5.default.ensureDir(claudeDir);
|
|
33333
|
+
const itemsToCopy = ["commands", "agents", "skills", "scripts", "song", "settings.json"];
|
|
33334
|
+
for (const item of itemsToCopy) {
|
|
33335
|
+
const sourcePath = path7.join(backupPath, item);
|
|
33336
|
+
const destPath = path7.join(claudeDir, item);
|
|
33337
|
+
if (await import_fs_extra5.default.pathExists(sourcePath)) {
|
|
33338
|
+
await import_fs_extra5.default.copy(sourcePath, destPath, { overwrite: true });
|
|
33339
|
+
}
|
|
33340
|
+
}
|
|
33341
|
+
}
|
|
33304
33342
|
async function createBackup(claudeDir) {
|
|
33305
33343
|
const exists = await import_fs_extra5.default.pathExists(claudeDir);
|
|
33306
33344
|
if (!exists) {
|
|
@@ -35732,6 +35770,22 @@ async function proSyncCommand(options = {}) {
|
|
|
35732
35770
|
if (syncMode === "updates") {
|
|
35733
35771
|
selectedItems = [...newItems, ...modifiedItems];
|
|
35734
35772
|
} else if (syncMode === "updates_and_delete") {
|
|
35773
|
+
M2.message("");
|
|
35774
|
+
M2.message(source_default.red.bold("⚠️ WARNING: DESTRUCTIVE ACTION"));
|
|
35775
|
+
M2.message(source_default.red("━".repeat(50)));
|
|
35776
|
+
M2.message(source_default.red("All your custom skills, commands, agents, and configuration files"));
|
|
35777
|
+
M2.message(source_default.red("that are not in the premium version will be PERMANENTLY DELETED"));
|
|
35778
|
+
M2.message(source_default.red("and replaced by the new version."));
|
|
35779
|
+
M2.message(source_default.red("━".repeat(50)));
|
|
35780
|
+
M2.message("");
|
|
35781
|
+
const deleteConfirm = await ye({
|
|
35782
|
+
message: source_default.red.bold("Are you sure you want to delete and replace all files?"),
|
|
35783
|
+
initialValue: false
|
|
35784
|
+
});
|
|
35785
|
+
if (pD(deleteConfirm) || !deleteConfirm) {
|
|
35786
|
+
xe("Sync cancelled");
|
|
35787
|
+
process.exit(0);
|
|
35788
|
+
}
|
|
35735
35789
|
selectedItems = [...newItems, ...modifiedItems, ...deletedItems];
|
|
35736
35790
|
} else {
|
|
35737
35791
|
const fileChoices = choices.filter((c) => c.value.type !== "hook");
|
|
@@ -35879,13 +35933,90 @@ async function proSyncCommand(options = {}) {
|
|
|
35879
35933
|
}
|
|
35880
35934
|
}
|
|
35881
35935
|
|
|
35936
|
+
// src/commands/backup.ts
|
|
35937
|
+
import os15 from "os";
|
|
35938
|
+
import path15 from "path";
|
|
35939
|
+
function formatBackupDate(date) {
|
|
35940
|
+
const now = new Date;
|
|
35941
|
+
const diffMs = now.getTime() - date.getTime();
|
|
35942
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
35943
|
+
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
35944
|
+
const diffMinutes = Math.floor(diffMs / (1000 * 60));
|
|
35945
|
+
let relative;
|
|
35946
|
+
if (diffMinutes < 60) {
|
|
35947
|
+
relative = `${diffMinutes} minute${diffMinutes !== 1 ? "s" : ""} ago`;
|
|
35948
|
+
} else if (diffHours < 24) {
|
|
35949
|
+
relative = `${diffHours} hour${diffHours !== 1 ? "s" : ""} ago`;
|
|
35950
|
+
} else if (diffDays < 7) {
|
|
35951
|
+
relative = `${diffDays} day${diffDays !== 1 ? "s" : ""} ago`;
|
|
35952
|
+
} else {
|
|
35953
|
+
relative = date.toLocaleDateString();
|
|
35954
|
+
}
|
|
35955
|
+
return `${date.toLocaleString()} (${relative})`;
|
|
35956
|
+
}
|
|
35957
|
+
async function backupLoadCommand(options = {}) {
|
|
35958
|
+
const claudeDir = options.folder || path15.join(os15.homedir(), ".claude");
|
|
35959
|
+
Ie(source_default.blue("\uD83D\uDCE6 Load Backup"));
|
|
35960
|
+
const spinner = Y2();
|
|
35961
|
+
spinner.start("Scanning for backups...");
|
|
35962
|
+
const backups = await listBackups();
|
|
35963
|
+
spinner.stop(`Found ${backups.length} backup${backups.length !== 1 ? "s" : ""}`);
|
|
35964
|
+
if (backups.length === 0) {
|
|
35965
|
+
M2.warn("No backups found in ~/.config/aiblueprint/backup/");
|
|
35966
|
+
M2.info("Backups are created automatically when you run setup or sync commands.");
|
|
35967
|
+
Se(source_default.gray("Nothing to restore"));
|
|
35968
|
+
return;
|
|
35969
|
+
}
|
|
35970
|
+
const backupOptions = backups.map((backup) => ({
|
|
35971
|
+
value: backup,
|
|
35972
|
+
label: backup.name,
|
|
35973
|
+
hint: formatBackupDate(backup.date)
|
|
35974
|
+
}));
|
|
35975
|
+
const selected = await ve({
|
|
35976
|
+
message: "Select a backup to restore:",
|
|
35977
|
+
options: backupOptions
|
|
35978
|
+
});
|
|
35979
|
+
if (pD(selected)) {
|
|
35980
|
+
xe("Operation cancelled");
|
|
35981
|
+
process.exit(0);
|
|
35982
|
+
}
|
|
35983
|
+
M2.info(`Selected: ${source_default.cyan(selected.name)}`);
|
|
35984
|
+
M2.info(`Date: ${source_default.gray(formatBackupDate(selected.date))}`);
|
|
35985
|
+
const confirm = await ye({
|
|
35986
|
+
message: `This will overwrite your current configuration in ${source_default.cyan(claudeDir)}. Continue?`,
|
|
35987
|
+
initialValue: false
|
|
35988
|
+
});
|
|
35989
|
+
if (pD(confirm) || !confirm) {
|
|
35990
|
+
xe("Operation cancelled");
|
|
35991
|
+
process.exit(0);
|
|
35992
|
+
}
|
|
35993
|
+
spinner.start("Creating backup of current configuration...");
|
|
35994
|
+
const currentBackup = await createBackup(claudeDir);
|
|
35995
|
+
if (currentBackup) {
|
|
35996
|
+
spinner.stop(`Current config backed up to: ${source_default.gray(currentBackup)}`);
|
|
35997
|
+
} else {
|
|
35998
|
+
spinner.stop("No current config to backup");
|
|
35999
|
+
}
|
|
36000
|
+
spinner.start("Restoring backup...");
|
|
36001
|
+
try {
|
|
36002
|
+
await loadBackup(selected.path, claudeDir);
|
|
36003
|
+
spinner.stop("Backup restored successfully");
|
|
36004
|
+
M2.success(`Restored configuration from ${source_default.cyan(selected.name)}`);
|
|
36005
|
+
Se(source_default.green("✅ Backup loaded successfully"));
|
|
36006
|
+
} catch (error) {
|
|
36007
|
+
spinner.stop("Restore failed");
|
|
36008
|
+
M2.error(`Failed to restore backup: ${error}`);
|
|
36009
|
+
process.exit(1);
|
|
36010
|
+
}
|
|
36011
|
+
}
|
|
36012
|
+
|
|
35882
36013
|
// src/commands/dynamic-scripts.ts
|
|
35883
|
-
import
|
|
36014
|
+
import path18 from "path";
|
|
35884
36015
|
import { homedir } from "os";
|
|
35885
36016
|
|
|
35886
36017
|
// src/lib/script-parser.ts
|
|
35887
36018
|
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
35888
|
-
import
|
|
36019
|
+
import path16 from "path";
|
|
35889
36020
|
var EXCLUDED_SCRIPTS = ["test", "lint", "format", "start"];
|
|
35890
36021
|
var EXCLUDED_SUFFIXES = [":test", ":lint", ":test-fixtures", ":start"];
|
|
35891
36022
|
function shouldIncludeScript(scriptName) {
|
|
@@ -35896,7 +36027,7 @@ function shouldIncludeScript(scriptName) {
|
|
|
35896
36027
|
return true;
|
|
35897
36028
|
}
|
|
35898
36029
|
async function readScriptsPackageJson(claudeDir) {
|
|
35899
|
-
const packageJsonPath =
|
|
36030
|
+
const packageJsonPath = path16.join(claudeDir, "scripts", "package.json");
|
|
35900
36031
|
try {
|
|
35901
36032
|
if (!await import_fs_extra12.default.pathExists(packageJsonPath)) {
|
|
35902
36033
|
return null;
|
|
@@ -35948,11 +36079,11 @@ function groupScriptsByPrefix(commands) {
|
|
|
35948
36079
|
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
35949
36080
|
import { spawn as spawn2 } from "child_process";
|
|
35950
36081
|
import { execSync as execSync4 } from "child_process";
|
|
35951
|
-
import
|
|
35952
|
-
import
|
|
36082
|
+
import path17 from "path";
|
|
36083
|
+
import os16 from "os";
|
|
35953
36084
|
function checkCommand(cmd) {
|
|
35954
36085
|
try {
|
|
35955
|
-
const isWindows =
|
|
36086
|
+
const isWindows = os16.platform() === "win32";
|
|
35956
36087
|
const whichCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
35957
36088
|
execSync4(whichCmd, { stdio: "ignore" });
|
|
35958
36089
|
return true;
|
|
@@ -35978,13 +36109,13 @@ async function executeScript(scriptName, claudeDir) {
|
|
|
35978
36109
|
console.error(source_default.red("Bun is not installed. Install with: npm install -g bun"));
|
|
35979
36110
|
return 1;
|
|
35980
36111
|
}
|
|
35981
|
-
const scriptsDir =
|
|
36112
|
+
const scriptsDir = path17.join(claudeDir, "scripts");
|
|
35982
36113
|
if (!await import_fs_extra13.default.pathExists(scriptsDir)) {
|
|
35983
36114
|
console.error(source_default.red(`Scripts directory not found at ${scriptsDir}`));
|
|
35984
36115
|
console.log(source_default.gray("Run: aiblueprint claude-code setup"));
|
|
35985
36116
|
return 1;
|
|
35986
36117
|
}
|
|
35987
|
-
const packageJsonPath =
|
|
36118
|
+
const packageJsonPath = path17.join(scriptsDir, "package.json");
|
|
35988
36119
|
if (!await import_fs_extra13.default.pathExists(packageJsonPath)) {
|
|
35989
36120
|
console.error(source_default.red(`package.json not found in ${scriptsDir}`));
|
|
35990
36121
|
return 1;
|
|
@@ -36012,7 +36143,7 @@ async function executeScript(scriptName, claudeDir) {
|
|
|
36012
36143
|
|
|
36013
36144
|
// src/commands/dynamic-scripts.ts
|
|
36014
36145
|
function getClaudeDir(parentOptions) {
|
|
36015
|
-
return parentOptions.claudeCodeFolder || parentOptions.folder ?
|
|
36146
|
+
return parentOptions.claudeCodeFolder || parentOptions.folder ? path18.resolve(parentOptions.claudeCodeFolder || parentOptions.folder) : path18.join(homedir(), ".claude");
|
|
36016
36147
|
}
|
|
36017
36148
|
async function registerDynamicScriptCommands(claudeCodeCmd, claudeDir) {
|
|
36018
36149
|
const scripts = await readScriptsPackageJson(claudeDir);
|
|
@@ -36095,6 +36226,12 @@ proCmd.command("sync").description("Sync premium configurations with selective u
|
|
|
36095
36226
|
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
36096
36227
|
proSyncCommand({ folder: claudeCodeFolder });
|
|
36097
36228
|
});
|
|
36229
|
+
var backupCmd = claudeCodeCmd.command("backup").description("Manage Claude Code configuration backups");
|
|
36230
|
+
backupCmd.command("load").description("Load a previous backup interactively").action((options, command) => {
|
|
36231
|
+
const parentOptions = command.parent.parent.opts();
|
|
36232
|
+
const claudeCodeFolder = parentOptions.claudeCodeFolder || parentOptions.folder;
|
|
36233
|
+
backupLoadCommand({ folder: claudeCodeFolder });
|
|
36234
|
+
});
|
|
36098
36235
|
try {
|
|
36099
36236
|
const claudeDir = join2(homedir2(), ".claude");
|
|
36100
36237
|
await registerDynamicScriptCommands(claudeCodeCmd, claudeDir);
|