@kaitranntt/ccs 4.1.6 → 4.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/VERSION CHANGED
@@ -1 +1 @@
1
- 4.1.6
1
+ 4.3.0
package/bin/ccs.js CHANGED
@@ -181,6 +181,7 @@ function handleHelpCommand() {
181
181
  console.log(colored('Diagnostics:', 'cyan'));
182
182
  console.log(` ${colored('ccs doctor', 'yellow')} Run health check and diagnostics`);
183
183
  console.log(` ${colored('ccs sync', 'yellow')} Sync delegation commands and skills`);
184
+ console.log(` ${colored('ccs update', 'yellow')} Update CCS to latest version`);
184
185
  console.log('');
185
186
 
186
187
  // Flags
@@ -270,21 +271,189 @@ async function handleDoctorCommand() {
270
271
  }
271
272
 
272
273
  async function handleSyncCommand() {
274
+ const { colored } = require('./utils/helpers');
275
+
276
+ console.log('');
277
+ console.log(colored('Syncing CCS Components...', 'cyan'));
278
+ console.log('');
279
+
273
280
  // First, copy .claude/ directory from package to ~/.ccs/.claude/
274
281
  const ClaudeDirInstaller = require('./utils/claude-dir-installer');
275
282
  const installer = new ClaudeDirInstaller();
276
283
  installer.install();
277
284
 
285
+ console.log('');
286
+
278
287
  // Then, create symlinks from ~/.ccs/.claude/ to ~/.claude/
279
288
  const ClaudeSymlinkManager = require('./utils/claude-symlink-manager');
280
289
  const manager = new ClaudeSymlinkManager();
290
+ manager.install(false);
281
291
 
282
- console.log('[i] Syncing delegation commands and skills to ~/.claude/...');
283
- manager.sync();
292
+ console.log('');
293
+ console.log(colored('[OK] Sync complete!', 'green'));
294
+ console.log('');
284
295
 
285
296
  process.exit(0);
286
297
  }
287
298
 
299
+ async function handleUpdateCommand() {
300
+ const { checkForUpdates } = require('./utils/update-checker');
301
+ const { spawn } = require('child_process');
302
+
303
+ console.log('');
304
+ console.log(colored('Checking for updates...', 'cyan'));
305
+ console.log('');
306
+
307
+ // Detect installation method for proper update source
308
+ const isNpmInstall = process.argv[1].includes('node_modules');
309
+ const installMethod = isNpmInstall ? 'npm' : 'direct';
310
+
311
+ // Check for updates (force check)
312
+ const updateResult = await checkForUpdates(CCS_VERSION, true, installMethod);
313
+
314
+ if (updateResult.status === 'check_failed') {
315
+ console.log(colored(`[X] ${updateResult.message}`, 'red'));
316
+ console.log('');
317
+ console.log(colored('[i] Possible causes:', 'yellow'));
318
+ console.log(' • Network connection issues');
319
+ console.log(' • Firewall blocking requests');
320
+ console.log(' • GitHub/npm API temporarily unavailable');
321
+ console.log('');
322
+ console.log('Try again later or update manually:');
323
+ if (isNpmInstall) {
324
+ console.log(colored(' npm install -g @kaitranntt/ccs@latest', 'yellow'));
325
+ } else {
326
+ const isWindows = process.platform === 'win32';
327
+ if (isWindows) {
328
+ console.log(colored(' irm ccs.kaitran.ca/install | iex', 'yellow'));
329
+ } else {
330
+ console.log(colored(' curl -fsSL ccs.kaitran.ca/install | bash', 'yellow'));
331
+ }
332
+ }
333
+ console.log('');
334
+ process.exit(1);
335
+ }
336
+
337
+ if (updateResult.status === 'no_update') {
338
+ let message = `You are already on the latest version (${CCS_VERSION})`;
339
+
340
+ // Add context for why no update is shown
341
+ switch (updateResult.reason) {
342
+ case 'dismissed':
343
+ message = `Update dismissed. You are on version ${CCS_VERSION}`;
344
+ console.log(colored(`[i] ${message}`, 'yellow'));
345
+ break;
346
+ case 'cached':
347
+ message = `No updates available (cached result). You are on version ${CCS_VERSION}`;
348
+ console.log(colored(`[i] ${message}`, 'cyan'));
349
+ break;
350
+ default:
351
+ console.log(colored(`[OK] ${message}`, 'green'));
352
+ }
353
+ console.log('');
354
+ process.exit(0);
355
+ }
356
+
357
+ // Update available
358
+ console.log(colored(`[i] Update available: ${updateResult.current} → ${updateResult.latest}`, 'yellow'));
359
+ console.log('');
360
+
361
+ if (isNpmInstall) {
362
+ // npm installation - use npm update
363
+ console.log(colored('Updating via npm...', 'cyan'));
364
+ console.log('');
365
+
366
+ const child = spawn('npm', ['install', '-g', '@kaitranntt/ccs@latest'], {
367
+ stdio: 'inherit',
368
+ shell: true
369
+ });
370
+
371
+ child.on('exit', (code) => {
372
+ if (code === 0) {
373
+ console.log('');
374
+ console.log(colored('[OK] Update successful!', 'green'));
375
+ console.log('');
376
+ console.log(`Run ${colored('ccs --version', 'yellow')} to verify`);
377
+ console.log('');
378
+ } else {
379
+ console.log('');
380
+ console.log(colored('[X] Update failed', 'red'));
381
+ console.log('');
382
+ console.log('Try manually:');
383
+ console.log(colored(' npm install -g @kaitranntt/ccs@latest', 'yellow'));
384
+ console.log('');
385
+ }
386
+ process.exit(code || 0);
387
+ });
388
+
389
+ child.on('error', (err) => {
390
+ console.log('');
391
+ console.log(colored('[X] Failed to run npm update', 'red'));
392
+ console.log('');
393
+ console.log('Try manually:');
394
+ console.log(colored(' npm install -g @kaitranntt/ccs@latest', 'yellow'));
395
+ console.log('');
396
+ process.exit(1);
397
+ });
398
+ } else {
399
+ // Direct installation - re-run installer
400
+ console.log(colored('Updating via installer...', 'cyan'));
401
+ console.log('');
402
+
403
+ const isWindows = process.platform === 'win32';
404
+ let command, args;
405
+
406
+ if (isWindows) {
407
+ command = 'powershell.exe';
408
+ args = ['-Command', 'irm ccs.kaitran.ca/install | iex'];
409
+ } else {
410
+ command = 'bash';
411
+ args = ['-c', 'curl -fsSL ccs.kaitran.ca/install | bash'];
412
+ }
413
+
414
+ const child = spawn(command, args, {
415
+ stdio: 'inherit',
416
+ shell: true
417
+ });
418
+
419
+ child.on('exit', (code) => {
420
+ if (code === 0) {
421
+ console.log('');
422
+ console.log(colored('[OK] Update successful!', 'green'));
423
+ console.log('');
424
+ console.log(`Run ${colored('ccs --version', 'yellow')} to verify`);
425
+ console.log('');
426
+ } else {
427
+ console.log('');
428
+ console.log(colored('[X] Update failed', 'red'));
429
+ console.log('');
430
+ console.log('Try manually:');
431
+ if (isWindows) {
432
+ console.log(colored(' irm ccs.kaitran.ca/install | iex', 'yellow'));
433
+ } else {
434
+ console.log(colored(' curl -fsSL ccs.kaitran.ca/install | bash', 'yellow'));
435
+ }
436
+ console.log('');
437
+ }
438
+ process.exit(code || 0);
439
+ });
440
+
441
+ child.on('error', (err) => {
442
+ console.log('');
443
+ console.log(colored('[X] Failed to run installer', 'red'));
444
+ console.log('');
445
+ console.log('Try manually:');
446
+ if (isWindows) {
447
+ console.log(colored(' irm ccs.kaitran.ca/install | iex', 'yellow'));
448
+ } else {
449
+ console.log(colored(' curl -fsSL ccs.kaitran.ca/install | bash', 'yellow'));
450
+ }
451
+ console.log('');
452
+ process.exit(1);
453
+ });
454
+ }
455
+ }
456
+
288
457
  // Smart profile detection
289
458
  function detectProfile(args) {
290
459
  if (args.length === 0 || args[0].startsWith('-')) {
@@ -528,6 +697,12 @@ async function main() {
528
697
  return;
529
698
  }
530
699
 
700
+ // Special case: update command (update CCS to latest version)
701
+ if (firstArg === 'update' || firstArg === '--update') {
702
+ await handleUpdateCommand();
703
+ return;
704
+ }
705
+
531
706
  // Special case: auth command (multi-account management)
532
707
  if (firstArg === 'auth') {
533
708
  const AuthCommands = require('./auth/auth-commands');