@ax-llm/ax 16.0.11 → 16.0.13
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/cli/index.mjs +264 -0
- package/index.cjs +39 -39
- package/index.cjs.map +1 -1
- package/index.d.cts +953 -28
- package/index.d.ts +953 -28
- package/index.global.js +54 -54
- package/index.global.js.map +1 -1
- package/index.js +39 -39
- package/index.js.map +1 -1
- package/package.json +7 -1
- package/scripts/postinstall.mjs +211 -0
- package/skills/ax-llm.md +1582 -0
package/cli/index.mjs
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLI for @ax-llm/ax
|
|
5
|
+
*
|
|
6
|
+
* Commands:
|
|
7
|
+
* setup-claude [--force] Install/upgrade Claude Code skill to .claude/skills/ax/ (project-local)
|
|
8
|
+
* remove-claude Remove the Claude Code skill
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* npx @ax-llm/ax setup-claude # Install or upgrade if newer version
|
|
12
|
+
* npx @ax-llm/ax setup-claude --force # Force overwrite regardless of version
|
|
13
|
+
* npx @ax-llm/ax remove-claude # Remove the skill
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
existsSync,
|
|
18
|
+
mkdirSync,
|
|
19
|
+
readFileSync,
|
|
20
|
+
rmSync,
|
|
21
|
+
writeFileSync,
|
|
22
|
+
} from 'node:fs';
|
|
23
|
+
import { dirname, join } from 'node:path';
|
|
24
|
+
import { fileURLToPath } from 'node:url';
|
|
25
|
+
|
|
26
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
27
|
+
const __dirname = dirname(__filename);
|
|
28
|
+
|
|
29
|
+
// Skill file location in the package
|
|
30
|
+
const SKILL_SOURCE = join(__dirname, '..', 'skills', 'ax-llm.md');
|
|
31
|
+
|
|
32
|
+
// Target location in current working directory (project-local)
|
|
33
|
+
const SKILL_TARGET_DIR = join(process.cwd(), '.claude', 'skills', 'ax');
|
|
34
|
+
const SKILL_TARGET = join(SKILL_TARGET_DIR, 'ax-llm.md');
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Compare semver versions
|
|
38
|
+
* Returns: 1 if a > b, -1 if a < b, 0 if equal
|
|
39
|
+
*/
|
|
40
|
+
function compareSemver(a, b) {
|
|
41
|
+
const parseVersion = (v) => {
|
|
42
|
+
const match = v.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
43
|
+
if (!match) return [0, 0, 0];
|
|
44
|
+
return [
|
|
45
|
+
Number.parseInt(match[1], 10),
|
|
46
|
+
Number.parseInt(match[2], 10),
|
|
47
|
+
Number.parseInt(match[3], 10),
|
|
48
|
+
];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const [aMajor, aMinor, aPatch] = parseVersion(a);
|
|
52
|
+
const [bMajor, bMinor, bPatch] = parseVersion(b);
|
|
53
|
+
|
|
54
|
+
if (aMajor !== bMajor) return aMajor > bMajor ? 1 : -1;
|
|
55
|
+
if (aMinor !== bMinor) return aMinor > bMinor ? 1 : -1;
|
|
56
|
+
if (aPatch !== bPatch) return aPatch > bPatch ? 1 : -1;
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get the installed skill version from the file
|
|
62
|
+
*/
|
|
63
|
+
function getInstalledVersion() {
|
|
64
|
+
if (!existsSync(SKILL_TARGET)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const content = readFileSync(SKILL_TARGET, 'utf8');
|
|
70
|
+
const match = content.match(/^version:\s*["']?([^"'\n\r]+)/m);
|
|
71
|
+
return match ? match[1].trim() : null;
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get the package version from the skill source file
|
|
79
|
+
*/
|
|
80
|
+
function getPackageVersion() {
|
|
81
|
+
if (!existsSync(SKILL_SOURCE)) {
|
|
82
|
+
// Fallback: try to read from package.json
|
|
83
|
+
const packageJsonPath = join(__dirname, '..', 'package.json');
|
|
84
|
+
if (existsSync(packageJsonPath)) {
|
|
85
|
+
try {
|
|
86
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
87
|
+
return pkg.version || null;
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const content = readFileSync(SKILL_SOURCE, 'utf8');
|
|
97
|
+
const match = content.match(/^version:\s*["']?([^"'\n\r]+)/m);
|
|
98
|
+
return match ? match[1].trim() : null;
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Install or upgrade the Claude Code skill
|
|
106
|
+
*/
|
|
107
|
+
function setupClaude(force = false) {
|
|
108
|
+
// Check if skill source exists
|
|
109
|
+
if (!existsSync(SKILL_SOURCE)) {
|
|
110
|
+
console.error('Error: Skill file not found. The package may be corrupted.');
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const packageVersion = getPackageVersion();
|
|
115
|
+
const installedVersion = getInstalledVersion();
|
|
116
|
+
|
|
117
|
+
// Determine if we should install
|
|
118
|
+
let shouldInstall = false;
|
|
119
|
+
let action = 'Installed';
|
|
120
|
+
|
|
121
|
+
if (!existsSync(SKILL_TARGET)) {
|
|
122
|
+
// Fresh install
|
|
123
|
+
shouldInstall = true;
|
|
124
|
+
} else if (force) {
|
|
125
|
+
// Force overwrite
|
|
126
|
+
shouldInstall = true;
|
|
127
|
+
action = installedVersion ? 'Reinstalled' : 'Installed';
|
|
128
|
+
} else if (installedVersion && packageVersion) {
|
|
129
|
+
// Compare versions
|
|
130
|
+
const comparison = compareSemver(packageVersion, installedVersion);
|
|
131
|
+
if (comparison > 0) {
|
|
132
|
+
shouldInstall = true;
|
|
133
|
+
action = `Upgraded`;
|
|
134
|
+
} else if (comparison === 0) {
|
|
135
|
+
console.log(`Ax Claude Code skill is up to date (v${installedVersion})`);
|
|
136
|
+
return;
|
|
137
|
+
} else {
|
|
138
|
+
// Installed version is newer (shouldn't happen normally)
|
|
139
|
+
console.log(
|
|
140
|
+
`Ax Claude Code skill is already at v${installedVersion} (package has v${packageVersion})`
|
|
141
|
+
);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
} else if (!installedVersion && existsSync(SKILL_TARGET)) {
|
|
145
|
+
// File exists but no version - upgrade
|
|
146
|
+
shouldInstall = true;
|
|
147
|
+
action = 'Upgraded';
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!shouldInstall) {
|
|
151
|
+
console.log(
|
|
152
|
+
`Ax Claude Code skill is up to date (v${installedVersion || 'unknown'})`
|
|
153
|
+
);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Create target directory if it doesn't exist
|
|
158
|
+
if (!existsSync(SKILL_TARGET_DIR)) {
|
|
159
|
+
mkdirSync(SKILL_TARGET_DIR, { recursive: true });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Copy the skill file
|
|
163
|
+
try {
|
|
164
|
+
const content = readFileSync(SKILL_SOURCE, 'utf8');
|
|
165
|
+
writeFileSync(SKILL_TARGET, content, 'utf8');
|
|
166
|
+
|
|
167
|
+
if (action === 'Upgraded' && installedVersion && packageVersion) {
|
|
168
|
+
console.log(
|
|
169
|
+
`\u2713 ${action} Ax Claude Code skill (v${installedVersion} \u2192 v${packageVersion})`
|
|
170
|
+
);
|
|
171
|
+
} else {
|
|
172
|
+
console.log(
|
|
173
|
+
`\u2713 ${action} Ax Claude Code skill (v${packageVersion || 'unknown'})`
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
} catch (err) {
|
|
177
|
+
console.error(`Error installing skill: ${err.message}`);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Remove the Claude Code skill
|
|
184
|
+
*/
|
|
185
|
+
function removeClaude() {
|
|
186
|
+
if (!existsSync(SKILL_TARGET)) {
|
|
187
|
+
console.log('Ax Claude Code skill is not installed.');
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
rmSync(SKILL_TARGET, { force: true });
|
|
193
|
+
|
|
194
|
+
// Try to remove the directory if empty
|
|
195
|
+
try {
|
|
196
|
+
const dir = dirname(SKILL_TARGET);
|
|
197
|
+
const files = readdirSync(dir);
|
|
198
|
+
if (files.length === 0) {
|
|
199
|
+
rmSync(dir, { recursive: true, force: true });
|
|
200
|
+
}
|
|
201
|
+
} catch {
|
|
202
|
+
// Ignore errors when trying to clean up directory
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
console.log('\u2713 Removed Ax Claude Code skill');
|
|
206
|
+
} catch (err) {
|
|
207
|
+
console.error(`Error removing skill: ${err.message}`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Import readdirSync for cleanup
|
|
213
|
+
import { readdirSync } from 'node:fs';
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Show help
|
|
217
|
+
*/
|
|
218
|
+
function showHelp() {
|
|
219
|
+
console.log(`
|
|
220
|
+
@ax-llm/ax CLI
|
|
221
|
+
|
|
222
|
+
Usage:
|
|
223
|
+
npx @ax-llm/ax <command> [options]
|
|
224
|
+
|
|
225
|
+
Commands:
|
|
226
|
+
setup-claude [--force] Install/upgrade Claude Code skill
|
|
227
|
+
remove-claude Remove the Claude Code skill
|
|
228
|
+
help Show this help message
|
|
229
|
+
|
|
230
|
+
Options:
|
|
231
|
+
--force Force reinstall regardless of version
|
|
232
|
+
|
|
233
|
+
Examples:
|
|
234
|
+
npx @ax-llm/ax setup-claude # Install or upgrade
|
|
235
|
+
npx @ax-llm/ax setup-claude --force # Force reinstall
|
|
236
|
+
npx @ax-llm/ax remove-claude # Remove skill
|
|
237
|
+
`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Parse command line arguments
|
|
241
|
+
const args = process.argv.slice(2);
|
|
242
|
+
const command = args[0];
|
|
243
|
+
const flags = args.slice(1);
|
|
244
|
+
|
|
245
|
+
switch (command) {
|
|
246
|
+
case 'setup-claude':
|
|
247
|
+
setupClaude(flags.includes('--force'));
|
|
248
|
+
break;
|
|
249
|
+
case 'remove-claude':
|
|
250
|
+
removeClaude();
|
|
251
|
+
break;
|
|
252
|
+
case 'help':
|
|
253
|
+
case '--help':
|
|
254
|
+
case '-h':
|
|
255
|
+
showHelp();
|
|
256
|
+
break;
|
|
257
|
+
case undefined:
|
|
258
|
+
showHelp();
|
|
259
|
+
break;
|
|
260
|
+
default:
|
|
261
|
+
console.error(`Unknown command: ${command}`);
|
|
262
|
+
console.error('Run "npx @ax-llm/ax help" for usage information.');
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|