antikit 1.2.0 → 1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antikit",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "CLI tool to manage AI agent skills from Anti Gravity skills repository",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -8,10 +8,15 @@ import { listLocalSkills } from './commands/local.js';
8
8
  import { installSkill } from './commands/install.js';
9
9
  import { removeSkill } from './commands/remove.js';
10
10
  import { listSources, addNewSource, removeExistingSource, setDefault } from './commands/source.js';
11
+ import { checkForUpdates } from './utils/updateNotifier.js';
11
12
 
12
13
  const require = createRequire(import.meta.url);
13
14
  const pkg = require('../package.json');
14
15
 
16
+ // Check for updates (non-blocking)
17
+ checkForUpdates(pkg.name, pkg.version);
18
+
19
+
15
20
  const program = new Command();
16
21
 
17
22
  program
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Background update checker script
4
+ * Spawned by main CLI to fetch version info without blocking
5
+ */
6
+
7
+ import { existsSync, writeFileSync, mkdirSync } from 'fs';
8
+ import { homedir } from 'os';
9
+ import { join } from 'path';
10
+
11
+ const CONFIG_DIR = join(homedir(), '.antikit');
12
+ const UPDATE_CHECK_FILE = join(CONFIG_DIR, 'update-check.json');
13
+
14
+ const packageName = process.argv[2];
15
+
16
+ if (!packageName) {
17
+ process.exit(1);
18
+ }
19
+
20
+ async function fetchAndCache() {
21
+ try {
22
+ const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
23
+ headers: { 'Accept': 'application/json' },
24
+ signal: AbortSignal.timeout(5000)
25
+ });
26
+
27
+ if (!response.ok) process.exit(1);
28
+
29
+ const data = await response.json();
30
+
31
+ if (!existsSync(CONFIG_DIR)) {
32
+ mkdirSync(CONFIG_DIR, { recursive: true });
33
+ }
34
+
35
+ writeFileSync(UPDATE_CHECK_FILE, JSON.stringify({
36
+ latestVersion: data.version,
37
+ checkedAt: Date.now()
38
+ }, null, 2));
39
+
40
+ } catch {
41
+ process.exit(1);
42
+ }
43
+ }
44
+
45
+ fetchAndCache();
@@ -0,0 +1,113 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { join, dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { spawn } from 'child_process';
6
+ import chalk from 'chalk';
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const CONFIG_DIR = join(homedir(), '.antikit');
10
+ const UPDATE_CHECK_FILE = join(CONFIG_DIR, 'update-check.json');
11
+
12
+ // Check for updates every 6 hours
13
+ const CHECK_INTERVAL = 1000 * 60 * 60 * 6;
14
+
15
+ /**
16
+ * Compare semantic versions
17
+ */
18
+ function compareVersions(v1, v2) {
19
+ const parts1 = v1.split('.').map(Number);
20
+ const parts2 = v2.split('.').map(Number);
21
+
22
+ for (let i = 0; i < 3; i++) {
23
+ if (parts1[i] > parts2[i]) return 1;
24
+ if (parts1[i] < parts2[i]) return -1;
25
+ }
26
+ return 0;
27
+ }
28
+
29
+ /**
30
+ * Load cached update check data
31
+ */
32
+ function loadUpdateCache() {
33
+ try {
34
+ if (!existsSync(UPDATE_CHECK_FILE)) return null;
35
+ return JSON.parse(readFileSync(UPDATE_CHECK_FILE, 'utf-8'));
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Display update notification
43
+ */
44
+ function displayUpdateNotification(packageName, currentVersion, latestVersion) {
45
+ console.error('');
46
+ console.error(chalk.yellow('╭' + '─'.repeat(58) + '╮'));
47
+ console.error(chalk.yellow('│') + ' '.repeat(58) + chalk.yellow('│'));
48
+ console.error(chalk.yellow('│') + ` ${chalk.bold.yellow('Update available!')} ${chalk.dim(currentVersion)} → ${chalk.green.bold(latestVersion)}`.padEnd(76) + chalk.yellow('│'));
49
+ console.error(chalk.yellow('│') + ' '.repeat(58) + chalk.yellow('│'));
50
+ console.error(chalk.yellow('│') + ` Run ${chalk.cyan(`npm i -g ${packageName}`)} to update`.padEnd(65) + chalk.yellow('│'));
51
+ console.error(chalk.yellow('│') + ' '.repeat(58) + chalk.yellow('│'));
52
+ console.error(chalk.yellow('╰' + '─'.repeat(58) + '╯'));
53
+ console.error('');
54
+ }
55
+
56
+ // Store pending notification
57
+ let pendingNotification = null;
58
+ let listenerRegistered = false;
59
+
60
+ /**
61
+ * Check for updates (non-blocking, uses cache)
62
+ */
63
+ export function checkForUpdates(packageName, currentVersion) {
64
+ const cache = loadUpdateCache();
65
+ const now = Date.now();
66
+
67
+ // Display notification from cache if update available
68
+ if (cache && cache.latestVersion && compareVersions(cache.latestVersion, currentVersion) > 0) {
69
+ pendingNotification = { packageName, currentVersion, latestVersion: cache.latestVersion };
70
+ }
71
+
72
+ // Register to show notification after command completes (only once)
73
+ if (!listenerRegistered) {
74
+ listenerRegistered = true;
75
+ process.on('beforeExit', () => {
76
+ if (pendingNotification) {
77
+ displayUpdateNotification(
78
+ pendingNotification.packageName,
79
+ pendingNotification.currentVersion,
80
+ pendingNotification.latestVersion
81
+ );
82
+ pendingNotification = null;
83
+ }
84
+ });
85
+ }
86
+
87
+ // Spawn background process to refresh cache if needed
88
+ if (!cache || !cache.checkedAt || (now - cache.checkedAt) >= CHECK_INTERVAL) {
89
+ try {
90
+ const checkScript = join(__dirname, 'updateCheck.js');
91
+ const child = spawn(process.execPath, [checkScript, packageName], {
92
+ detached: true,
93
+ stdio: 'ignore'
94
+ });
95
+ child.unref();
96
+ } catch {
97
+ // Ignore spawn errors
98
+ }
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Initialize update cache (call this once during install or first run)
104
+ */
105
+ export async function initUpdateCache(packageName) {
106
+ const latestVersion = await fetchLatestVersion(packageName);
107
+ if (latestVersion) {
108
+ saveUpdateCache({ latestVersion, checkedAt: Date.now() });
109
+ }
110
+ return latestVersion;
111
+ }
112
+
113
+