@vibe-x/agent-better-checkpoint 0.2.0 → 0.3.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.
- package/README.md +22 -0
- package/bin/cli.mjs +105 -24
- package/package.json +1 -1
- package/platform/config.template.yml +16 -0
- package/skill/SKILL.md +4 -4
package/README.md
CHANGED
|
@@ -96,6 +96,28 @@ npx @vibe-x/agent-better-checkpoint --platform cursor
|
|
|
96
96
|
npx @vibe-x/agent-better-checkpoint --platform claude
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
+
### Project-local Install
|
|
100
|
+
|
|
101
|
+
Install scripts into your project for self-contained setup (commit with repo):
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd /path/to/your/project
|
|
105
|
+
npx @vibe-x/agent-better-checkpoint --target .
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Or specify a target directory:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npx @vibe-x/agent-better-checkpoint --target /path/to/your/project
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Uninstall project-local only:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npx @vibe-x/agent-better-checkpoint --uninstall --target .
|
|
118
|
+
npx @vibe-x/agent-better-checkpoint --uninstall --target /path/to/project
|
|
119
|
+
```
|
|
120
|
+
|
|
99
121
|
### Via [skills.sh](https://skills.sh)
|
|
100
122
|
|
|
101
123
|
```bash
|
package/bin/cli.mjs
CHANGED
|
@@ -31,13 +31,14 @@ const SKILL_NAME = 'agent-better-checkpoint';
|
|
|
31
31
|
// In-package source paths
|
|
32
32
|
const PLATFORM_DIR = join(PKG_ROOT, 'platform');
|
|
33
33
|
const SKILL_SRC = join(PKG_ROOT, 'skill', 'SKILL.md');
|
|
34
|
+
const CONFIG_TEMPLATE = join(PLATFORM_DIR, 'config.template.yml');
|
|
34
35
|
|
|
35
36
|
// ============================================================
|
|
36
37
|
// Argument parsing
|
|
37
38
|
// ============================================================
|
|
38
39
|
|
|
39
40
|
function parseArgs(argv) {
|
|
40
|
-
const args = { platform: null, uninstall: false };
|
|
41
|
+
const args = { platform: null, uninstall: false, target: null };
|
|
41
42
|
for (let i = 2; i < argv.length; i++) {
|
|
42
43
|
switch (argv[i]) {
|
|
43
44
|
case '--platform':
|
|
@@ -47,6 +48,13 @@ function parseArgs(argv) {
|
|
|
47
48
|
process.exit(1);
|
|
48
49
|
}
|
|
49
50
|
break;
|
|
51
|
+
case '--target':
|
|
52
|
+
args.target = argv[++i];
|
|
53
|
+
if (!args.target) {
|
|
54
|
+
console.error('Error: --target requires a path argument');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
50
58
|
case '--uninstall':
|
|
51
59
|
args.uninstall = true;
|
|
52
60
|
break;
|
|
@@ -73,6 +81,7 @@ Usage:
|
|
|
73
81
|
|
|
74
82
|
Options:
|
|
75
83
|
--platform <cursor|claude> Target AI platform (auto-detected if omitted)
|
|
84
|
+
--target <path> Install to specified project directory (. for cwd)
|
|
76
85
|
--uninstall Remove installed files and hook registrations
|
|
77
86
|
-h, --help Show this help message
|
|
78
87
|
`);
|
|
@@ -234,6 +243,37 @@ function registerCursorHook(osType) {
|
|
|
234
243
|
console.log(` Config → ${hooksPath}`);
|
|
235
244
|
}
|
|
236
245
|
|
|
246
|
+
function installProjectLocal(targetDir, osType) {
|
|
247
|
+
const projectBase = join(resolve(targetDir), '.vibe-x', 'agent-better-checkpoint');
|
|
248
|
+
ensureDir(projectBase);
|
|
249
|
+
|
|
250
|
+
if (osType === 'unix') {
|
|
251
|
+
copyFileSafe(join(PLATFORM_DIR, 'unix', 'checkpoint.sh'), join(projectBase, 'checkpoint.sh'));
|
|
252
|
+
copyFileSafe(join(PLATFORM_DIR, 'unix', 'check_uncommitted.sh'), join(projectBase, 'check_uncommitted.sh'));
|
|
253
|
+
setExecutable(join(projectBase, 'checkpoint.sh'));
|
|
254
|
+
setExecutable(join(projectBase, 'check_uncommitted.sh'));
|
|
255
|
+
}
|
|
256
|
+
copyFileSafe(join(PLATFORM_DIR, 'win', 'checkpoint.ps1'), join(projectBase, 'checkpoint.ps1'));
|
|
257
|
+
copyFileSafe(join(PLATFORM_DIR, 'win', 'check_uncommitted.ps1'), join(projectBase, 'check_uncommitted.ps1'));
|
|
258
|
+
|
|
259
|
+
const configDest = join(projectBase, 'config.yml');
|
|
260
|
+
if (!existsSync(configDest) && existsSync(CONFIG_TEMPLATE)) {
|
|
261
|
+
copyFileSafe(CONFIG_TEMPLATE, configDest);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
console.log(` Project → ${projectBase}/`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function uninstallProjectLocal(targetDir) {
|
|
268
|
+
const projectBase = join(resolve(targetDir), '.vibe-x', 'agent-better-checkpoint');
|
|
269
|
+
if (existsSync(projectBase)) {
|
|
270
|
+
rmSync(projectBase, { recursive: true, force: true });
|
|
271
|
+
console.log(` Removed project-local: ${projectBase}`);
|
|
272
|
+
} else {
|
|
273
|
+
console.log(` ${projectBase} not found, nothing to remove`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
237
277
|
function registerClaudeHook(osType) {
|
|
238
278
|
const settingsPath = join(homedir(), '.claude', 'settings.json');
|
|
239
279
|
let settings = readJsonFile(settingsPath) || {};
|
|
@@ -268,6 +308,12 @@ function registerClaudeHook(osType) {
|
|
|
268
308
|
// Uninstall logic
|
|
269
309
|
// ============================================================
|
|
270
310
|
|
|
311
|
+
function hasInstallation(platform) {
|
|
312
|
+
const home = homedir();
|
|
313
|
+
const skillDir = join(home, platform === 'cursor' ? '.cursor' : '.claude', 'skills', SKILL_NAME);
|
|
314
|
+
return existsSync(skillDir);
|
|
315
|
+
}
|
|
316
|
+
|
|
271
317
|
function uninstallScripts() {
|
|
272
318
|
if (existsSync(INSTALL_BASE)) {
|
|
273
319
|
rmSync(INSTALL_BASE, { recursive: true, force: true });
|
|
@@ -331,8 +377,9 @@ function main() {
|
|
|
331
377
|
const args = parseArgs(process.argv);
|
|
332
378
|
const osType = getOSType();
|
|
333
379
|
const aiPlatform = args.platform || detectAIPlatform();
|
|
380
|
+
const projectTargetDir = args.target ? resolve(args.target) : null;
|
|
334
381
|
|
|
335
|
-
if (!aiPlatform) {
|
|
382
|
+
if (!aiPlatform && !projectTargetDir && !args.uninstall) {
|
|
336
383
|
console.error(
|
|
337
384
|
'Error: could not detect AI platform.\n' +
|
|
338
385
|
'Please specify: npx @vibe-x/agent-better-checkpoint --platform cursor|claude'
|
|
@@ -341,38 +388,72 @@ function main() {
|
|
|
341
388
|
}
|
|
342
389
|
|
|
343
390
|
if (args.uninstall) {
|
|
344
|
-
|
|
345
|
-
|
|
391
|
+
if (projectTargetDir) {
|
|
392
|
+
console.log('\n[Project-local] Uninstalling...');
|
|
393
|
+
uninstallProjectLocal(projectTargetDir);
|
|
394
|
+
}
|
|
346
395
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
396
|
+
// 指定 --platform 时只清该平台;未指定时清理所有已安装的平台
|
|
397
|
+
const platforms = args.platform
|
|
398
|
+
? [args.platform]
|
|
399
|
+
: ['cursor', 'claude'].filter(p => hasInstallation(p));
|
|
400
|
+
|
|
401
|
+
if (!projectTargetDir || args.platform) {
|
|
402
|
+
for (const p of platforms) {
|
|
403
|
+
console.log(`\n[${p === 'cursor' ? 'Cursor' : 'Claude Code'}] Uninstalling...`);
|
|
404
|
+
if (p === 'cursor') {
|
|
405
|
+
uninstallCursorSkill();
|
|
406
|
+
unregisterCursorHook();
|
|
407
|
+
} else {
|
|
408
|
+
uninstallClaudeSkill();
|
|
409
|
+
unregisterClaudeHook();
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (platforms.length > 0) {
|
|
413
|
+
uninstallScripts();
|
|
414
|
+
}
|
|
353
415
|
}
|
|
354
416
|
|
|
355
|
-
|
|
356
|
-
|
|
417
|
+
if (platforms.length === 0 && !projectTargetDir) {
|
|
418
|
+
console.log('\nNo installation found for any platform.');
|
|
419
|
+
}
|
|
420
|
+
console.log('\n✅ Uninstallation complete!');
|
|
357
421
|
} else {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
422
|
+
if (projectTargetDir) {
|
|
423
|
+
if (!aiPlatform) {
|
|
424
|
+
console.error('Error: --target requires AI platform for global hook. Specify --platform cursor|claude');
|
|
425
|
+
process.exit(1);
|
|
426
|
+
}
|
|
427
|
+
console.log(`\n[${aiPlatform === 'cursor' ? 'Cursor' : 'Claude Code'}] Installing... (OS: ${osType})`);
|
|
428
|
+
installScripts(osType);
|
|
429
|
+
installSkill(aiPlatform);
|
|
430
|
+
if (aiPlatform === 'cursor') {
|
|
431
|
+
registerCursorHook(osType);
|
|
432
|
+
} else {
|
|
433
|
+
registerClaudeHook(osType);
|
|
434
|
+
}
|
|
435
|
+
installProjectLocal(projectTargetDir, osType);
|
|
366
436
|
} else {
|
|
367
|
-
|
|
437
|
+
console.log(`\n[${aiPlatform === 'cursor' ? 'Cursor' : 'Claude Code'}] Installing... (OS: ${osType})`);
|
|
438
|
+
installScripts(osType);
|
|
439
|
+
installSkill(aiPlatform);
|
|
440
|
+
if (aiPlatform === 'cursor') {
|
|
441
|
+
registerCursorHook(osType);
|
|
442
|
+
} else {
|
|
443
|
+
registerClaudeHook(osType);
|
|
444
|
+
}
|
|
368
445
|
}
|
|
369
446
|
|
|
370
|
-
console.log(
|
|
371
|
-
console.log(
|
|
447
|
+
console.log('\n✅ Installation complete!');
|
|
448
|
+
console.log('\nInstalled components:');
|
|
372
449
|
console.log(` 📜 Checkpoint script → ~/.vibe-x/agent-better-checkpoint/scripts/`);
|
|
373
450
|
console.log(` 🔒 Stop hook → ~/.vibe-x/agent-better-checkpoint/hooks/stop/`);
|
|
374
451
|
console.log(` 📖 SKILL.md → ${aiPlatform === 'cursor' ? '~/.cursor/skills/' : '~/.claude/skills/'}${SKILL_NAME}/`);
|
|
375
|
-
|
|
452
|
+
if (projectTargetDir) {
|
|
453
|
+
const projectBase = join(resolve(projectTargetDir), '.vibe-x', 'agent-better-checkpoint');
|
|
454
|
+
console.log(` 📁 Project-local → ${projectBase}/`);
|
|
455
|
+
}
|
|
456
|
+
console.log('\nThe AI agent will now auto-commit with semantic messages. Happy coding! 🎉');
|
|
376
457
|
}
|
|
377
458
|
}
|
|
378
459
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Checkpoint commit trigger conditions
|
|
2
|
+
#
|
|
3
|
+
# Controls when stop hook (check_uncommitted) triggers commit reminder.
|
|
4
|
+
# Affects only stop hook detection, not checkpoint.sh commit behavior.
|
|
5
|
+
|
|
6
|
+
# Trigger reminder if ANY condition met (OR)
|
|
7
|
+
# Empty/commented = condition disabled
|
|
8
|
+
trigger_if_any:
|
|
9
|
+
# min_changed_files: 3 # At least N active files changed
|
|
10
|
+
min_changed_lines: 5 # At least N lines changed
|
|
11
|
+
|
|
12
|
+
# Passive file patterns — matched files do not trigger reminder alone
|
|
13
|
+
passive_patterns:
|
|
14
|
+
- ".discuss/**"
|
|
15
|
+
- ".vibe-x/**"
|
|
16
|
+
- ".DS_Store"
|
package/skill/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: agent-better-checkpoint
|
|
|
3
3
|
description: "Automatically creates semantic Git checkpoint commits during AI coding sessions. Replaces opaque platform checkpoints with transparent, queryable Git commits using Conventional Commits format with Git Trailers. You MUST follow this skill whenever you make code changes — commit after each meaningful edit."
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.3.0"
|
|
7
7
|
author: "alienzhou"
|
|
8
8
|
category: "version-control"
|
|
9
9
|
---
|
|
@@ -26,10 +26,10 @@ Before your first commit, verify the checkpoint scripts are available:
|
|
|
26
26
|
If neither exists, run:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
npx @vibe-x/agent-better-checkpoint@0.
|
|
29
|
+
npx @vibe-x/agent-better-checkpoint@0.3.0
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
This installs the global scripts and stop hook.
|
|
32
|
+
This installs the global scripts and stop hook. For self-contained setup (commit with project), add `--target .` or `--target <path>`.
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
@@ -177,4 +177,4 @@ This should feel natural — commit as you go, like any good developer.
|
|
|
177
177
|
|
|
178
178
|
---
|
|
179
179
|
|
|
180
|
-
**Version**: 0.
|
|
180
|
+
**Version**: 0.3.0
|