@kaitranntt/ccs 4.1.0 → 4.1.1

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.0
1
+ 4.1.1
package/bin/ccs.js CHANGED
@@ -255,6 +255,12 @@ async function handleDoctorCommand() {
255
255
  }
256
256
 
257
257
  async function handleUpdateCommand() {
258
+ // First, copy .claude/ directory from package to ~/.ccs/.claude/
259
+ const ClaudeDirInstaller = require('./utils/claude-dir-installer');
260
+ const installer = new ClaudeDirInstaller();
261
+ installer.install();
262
+
263
+ // Then, create symlinks from ~/.ccs/.claude/ to ~/.claude/
258
264
  const ClaudeSymlinkManager = require('./utils/claude-symlink-manager');
259
265
  const manager = new ClaudeSymlinkManager();
260
266
 
@@ -88,7 +88,8 @@ class HeadlessExecutor {
88
88
  if (lastSession) {
89
89
  args.push('--resume', lastSession.sessionId);
90
90
  if (process.env.CCS_DEBUG) {
91
- console.error(`[i] Resuming session: ${lastSession.sessionId} (${lastSession.turns} turns, $${lastSession.totalCost.toFixed(4)})`);
91
+ const cost = lastSession.totalCost !== undefined && lastSession.totalCost !== null ? lastSession.totalCost.toFixed(4) : '0.0000';
92
+ console.error(`[i] Resuming session: ${lastSession.sessionId} (${lastSession.turns} turns, $${cost})`);
92
93
  }
93
94
  } else if (sessionId) {
94
95
  args.push('--resume', sessionId);
@@ -437,7 +437,9 @@ class ResultFormatter {
437
437
  // Abbreviate session ID (Git-style first 8 chars)
438
438
  const shortId = sessionId && sessionId.length > 8 ? sessionId.substring(0, 8) : sessionId;
439
439
  output += `[i] Session persisted with ID: ${shortId}\n`;
440
- output += `[i] Cost: $${totalCost.toFixed(4)}\n`;
440
+ if (totalCost !== undefined && totalCost !== null) {
441
+ output += `[i] Cost: $${totalCost.toFixed(4)}\n`;
442
+ }
441
443
 
442
444
  return output;
443
445
  }
@@ -60,7 +60,8 @@ class SessionManager {
60
60
  this._saveSessions(sessions);
61
61
 
62
62
  if (process.env.CCS_DEBUG) {
63
- console.error(`[i] Updated session: ${sessionId}, total: $${sessions[key].totalCost.toFixed(4)}, turns: ${sessions[key].turns}`);
63
+ const cost = sessions[key].totalCost !== undefined && sessions[key].totalCost !== null ? sessions[key].totalCost.toFixed(4) : '0.0000';
64
+ console.error(`[i] Updated session: ${sessionId}, total: $${cost}, turns: ${sessions[key].turns}`);
64
65
  }
65
66
  }
66
67
  }
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const os = require('os');
7
+
8
+ /**
9
+ * ClaudeDirInstaller - Manages copying .claude/ directory from package to ~/.ccs/.claude/
10
+ * v4.1.1: Fix for npm install not copying .claude/ directory
11
+ */
12
+ class ClaudeDirInstaller {
13
+ constructor() {
14
+ this.homeDir = os.homedir();
15
+ this.ccsClaudeDir = path.join(this.homeDir, '.ccs', '.claude');
16
+ }
17
+
18
+ /**
19
+ * Copy .claude/ directory from package to ~/.ccs/.claude/
20
+ * @param {string} packageDir - Package installation directory (default: auto-detect)
21
+ */
22
+ install(packageDir) {
23
+ try {
24
+ // Auto-detect package directory if not provided
25
+ if (!packageDir) {
26
+ // Try to find package root by going up from this file
27
+ packageDir = path.join(__dirname, '..', '..');
28
+ }
29
+
30
+ const packageClaudeDir = path.join(packageDir, '.claude');
31
+
32
+ if (!fs.existsSync(packageClaudeDir)) {
33
+ console.log('[!] Package .claude/ directory not found');
34
+ console.log(` Searched in: ${packageClaudeDir}`);
35
+ console.log(' This may be a development installation');
36
+ return false;
37
+ }
38
+
39
+ console.log('[i] Installing CCS .claude/ items...');
40
+
41
+ // Remove old version before copying new one
42
+ if (fs.existsSync(this.ccsClaudeDir)) {
43
+ fs.rmSync(this.ccsClaudeDir, { recursive: true, force: true });
44
+ }
45
+
46
+ // Use fs.cpSync for recursive copy (Node.js 16.7.0+)
47
+ // Fallback to manual copy for older Node.js versions
48
+ if (fs.cpSync) {
49
+ fs.cpSync(packageClaudeDir, this.ccsClaudeDir, { recursive: true });
50
+ } else {
51
+ // Fallback for Node.js < 16.7.0
52
+ this._copyDirRecursive(packageClaudeDir, this.ccsClaudeDir);
53
+ }
54
+
55
+ console.log('[OK] Copied .claude/ items to ~/.ccs/.claude/');
56
+ return true;
57
+ } catch (err) {
58
+ console.warn('[!] Failed to copy .claude/ directory:', err.message);
59
+ console.warn(' CCS items may not be available');
60
+ return false;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Recursively copy directory (fallback for Node.js < 16.7.0)
66
+ * @param {string} src - Source directory
67
+ * @param {string} dest - Destination directory
68
+ * @private
69
+ */
70
+ _copyDirRecursive(src, dest) {
71
+ // Create destination directory
72
+ if (!fs.existsSync(dest)) {
73
+ fs.mkdirSync(dest, { recursive: true });
74
+ }
75
+
76
+ // Read source directory
77
+ const entries = fs.readdirSync(src, { withFileTypes: true });
78
+
79
+ for (const entry of entries) {
80
+ const srcPath = path.join(src, entry.name);
81
+ const destPath = path.join(dest, entry.name);
82
+
83
+ if (entry.isDirectory()) {
84
+ // Recursively copy subdirectory
85
+ this._copyDirRecursive(srcPath, destPath);
86
+ } else {
87
+ // Copy file
88
+ fs.copyFileSync(srcPath, destPath);
89
+ }
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Check if ~/.ccs/.claude/ exists and is valid
95
+ * @returns {boolean} True if directory exists
96
+ */
97
+ isInstalled() {
98
+ return fs.existsSync(this.ccsClaudeDir);
99
+ }
100
+ }
101
+
102
+ module.exports = ClaudeDirInstaller;
package/lib/ccs CHANGED
@@ -2,7 +2,7 @@
2
2
  set -euo pipefail
3
3
 
4
4
  # Version (updated by scripts/bump-version.sh)
5
- CCS_VERSION="4.1.0"
5
+ CCS_VERSION="4.1.1"
6
6
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
7
  readonly CONFIG_FILE="${CCS_CONFIG:-$HOME/.ccs/config.json}"
8
8
  readonly PROFILES_JSON="$HOME/.ccs/profiles.json"
package/lib/ccs.ps1 CHANGED
@@ -12,7 +12,7 @@ param(
12
12
  $ErrorActionPreference = "Stop"
13
13
 
14
14
  # Version (updated by scripts/bump-version.sh)
15
- $CcsVersion = "4.1.0"
15
+ $CcsVersion = "4.1.1"
16
16
  $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
17
17
  $ConfigFile = if ($env:CCS_CONFIG) { $env:CCS_CONFIG } else { "$env:USERPROFILE\.ccs\config.json" }
18
18
  $ProfilesJson = "$env:USERPROFILE\.ccs\profiles.json"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaitranntt/ccs",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
4
4
  "description": "Claude Code Switch - Instant profile switching between Claude Sonnet 4.5 and GLM 4.6",
5
5
  "keywords": [
6
6
  "cli",
@@ -103,6 +103,17 @@ function createConfigFiles() {
103
103
  }
104
104
  console.log('');
105
105
 
106
+ // Copy .claude/ directory from package to ~/.ccs/.claude/ (v4.1.1)
107
+ try {
108
+ const ClaudeDirInstaller = require('../bin/utils/claude-dir-installer');
109
+ const installer = new ClaudeDirInstaller();
110
+ const packageDir = path.join(__dirname, '..');
111
+ installer.install(packageDir);
112
+ } catch (err) {
113
+ console.warn('[!] Failed to install .claude/ directory:', err.message);
114
+ console.warn(' CCS items may not be available');
115
+ }
116
+
106
117
  // Install CCS items to ~/.claude/ (v4.1.0)
107
118
  try {
108
119
  const ClaudeSymlinkManager = require('../bin/utils/claude-symlink-manager');