ccjk 2.1.0 → 2.2.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/README.md CHANGED
@@ -123,7 +123,7 @@ In the realm of AI-assisted development, **Context Engineering** and **Cognitive
123
123
 
124
124
  ```
125
125
  ┌─────────────────────────────────────────────────────────────────┐
126
- │ CCJK Cognitive Enhancement Engine v2.0
126
+ │ CCJK Cognitive Enhancement Engine v2.2
127
127
  ├─────────────────────────────────────────────────────────────────┤
128
128
  │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
129
129
  │ │ 🧠 Skill │ │ 🤖 Agent │ │ 🔌 Integr. │ │
@@ -618,7 +618,7 @@ Want to contribute? [View Guidelines](CONTRIBUTING.md)
618
618
 
619
619
  ## 📜 License
620
620
 
621
- **MIT License** © 2025 [CCJK Contributors](https://github.com/miounet11/ccjk/graphs/contributors)
621
+ **MIT License** © 2025-2026 [CCJK Contributors](https://github.com/miounet11/ccjk/graphs/contributors)
622
622
 
623
623
  <br/>
624
624
 
@@ -29,12 +29,12 @@ import './platform.mjs';
29
29
  import '../shared/ccjk.DhBeLRzf.mjs';
30
30
  import 'inquirer-toggle';
31
31
  import './prompts.mjs';
32
- import '../shared/ccjk.HAxAfl1Z.mjs';
32
+ import '../shared/ccjk.DwDtZ5cK.mjs';
33
+ import 'node:child_process';
33
34
  import '../shared/ccjk.CUdzQluX.mjs';
34
35
  import './features2.mjs';
35
36
  import './init.mjs';
36
- import '../shared/ccjk.TVnFUDQc.mjs';
37
- import 'node:child_process';
37
+ import '../shared/ccjk.qYAnUMuy.mjs';
38
38
  import 'node:util';
39
39
  import './auto-updater.mjs';
40
40
  import '../shared/ccjk.Cy-RH2qV.mjs';
@@ -32,7 +32,7 @@ import 'inquirer';
32
32
  import './claude-config.mjs';
33
33
  import './prompts.mjs';
34
34
  import './package.mjs';
35
- import '../shared/ccjk.HAxAfl1Z.mjs';
35
+ import '../shared/ccjk.DwDtZ5cK.mjs';
36
36
 
37
37
  class ToolUpdateScheduler {
38
38
  /**
@@ -26,7 +26,8 @@ import '../shared/ccjk.DhBeLRzf.mjs';
26
26
  import 'inquirer-toggle';
27
27
  import './prompts.mjs';
28
28
  import './package.mjs';
29
- import '../shared/ccjk.HAxAfl1Z.mjs';
29
+ import '../shared/ccjk.DwDtZ5cK.mjs';
30
+ import 'node:child_process';
30
31
 
31
32
  class ClaudeCodeConfigManager {
32
33
  static CONFIG_FILE = ZCF_CONFIG_FILE;
@@ -3,7 +3,7 @@ import inquirer from 'inquirer';
3
3
  import { ensureI18nInitialized, i18n } from './index2.mjs';
4
4
  import { ClaudeCodeConfigManager } from './claude-code-config-manager.mjs';
5
5
  import { a as addNumbersToChoices, p as promptBoolean } from '../shared/ccjk.DhBeLRzf.mjs';
6
- import { v as validateApiKey } from '../shared/ccjk.TVnFUDQc.mjs';
6
+ import { v as validateApiKey } from '../shared/ccjk.qYAnUMuy.mjs';
7
7
  import 'node:fs';
8
8
  import 'node:process';
9
9
  import 'node:url';
@@ -27,7 +27,8 @@ import './claude-config.mjs';
27
27
  import './platform.mjs';
28
28
  import './prompts.mjs';
29
29
  import './package.mjs';
30
- import '../shared/ccjk.HAxAfl1Z.mjs';
30
+ import '../shared/ccjk.DwDtZ5cK.mjs';
31
+ import 'node:child_process';
31
32
  import 'inquirer-toggle';
32
33
 
33
34
  function getAuthTypeLabel(authType) {
@@ -17,7 +17,7 @@ import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
17
17
  import { isWindows, getMcpCommand, getSystemRoot, wrapCommandWithSudo, normalizeTomlPath } from './platform.mjs';
18
18
  import { p as promptBoolean, a as addNumbersToChoices } from '../shared/ccjk.DhBeLRzf.mjs';
19
19
  import { resolveAiOutputLanguage } from './prompts.mjs';
20
- import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
20
+ import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
21
21
 
22
22
  const MODEL_ENV_KEYS = [
23
23
  "ANTHROPIC_MODEL",
@@ -28,7 +28,8 @@ import './platform.mjs';
28
28
  import 'inquirer-toggle';
29
29
  import './prompts.mjs';
30
30
  import './package.mjs';
31
- import '../shared/ccjk.HAxAfl1Z.mjs';
31
+ import '../shared/ccjk.DwDtZ5cK.mjs';
32
+ import 'node:child_process';
32
33
 
33
34
  async function configSwitchCommand(options) {
34
35
  try {
@@ -1,20 +1,21 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { g as getMcpServices } from '../shared/ccjk.HAxAfl1Z.mjs';
3
+ import { g as getMcpServices } from '../shared/ccjk.DwDtZ5cK.mjs';
4
4
  import { SUPPORTED_LANGS, LANG_LABELS } from './constants.mjs';
5
5
  import { ensureI18nInitialized, i18n, changeLanguage } from './index2.mjs';
6
6
  import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
7
7
  import { q as isCcrInstalled, t as installCcr, E as setupCcrConfiguration } from './init.mjs';
8
8
  import { r as readMcpConfig, f as fixWindowsMcpConfig, w as writeMcpConfig, b as backupMcpConfig, a as buildMcpServerConfig, m as mergeMcpServers } from './claude-config.mjs';
9
9
  import { Y as applyAiLanguageDirective, W as getExistingModelConfig, T as updateCustomModel, U as updateDefaultModel, $ as selectMcpServices, X as getExistingApiConfig, _ as promptApiConfigurationAction, R as configureApi, Z as switchToOfficialLogin } from './codex.mjs';
10
- import { a as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.TVnFUDQc.mjs';
10
+ import { a as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.qYAnUMuy.mjs';
11
11
  import { isWindows } from './platform.mjs';
12
12
  import { a as addNumbersToChoices, p as promptBoolean } from '../shared/ccjk.DhBeLRzf.mjs';
13
13
  import { o as openSettingsJson, a as importRecommendedPermissions, i as importRecommendedEnv } from '../shared/ccjk.DJM5aVQJ.mjs';
14
+ import 'node:child_process';
14
15
  import 'node:os';
16
+ import 'node:process';
15
17
  import 'pathe';
16
18
  import 'node:fs';
17
- import 'node:process';
18
19
  import 'node:url';
19
20
  import 'i18next';
20
21
  import 'i18next-fs-backend';
@@ -26,7 +27,6 @@ import './json-config.mjs';
26
27
  import 'dayjs';
27
28
  import './package.mjs';
28
29
  import '../shared/ccjk.BhKlRJ0h.mjs';
29
- import 'node:child_process';
30
30
  import 'node:util';
31
31
  import './auto-updater.mjs';
32
32
  import 'ora';
@@ -4,8 +4,8 @@ import process from 'node:process';
4
4
  import ansis from 'ansis';
5
5
  import inquirer from 'inquirer';
6
6
  import { version } from './package.mjs';
7
- import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
8
- import { m as modifyApiConfigPartially, c as configureApiCompletely, s as selectAndInstallWorkflows, a as configureOutputStyle, f as formatApiKeyDisplay, W as WORKFLOW_CONFIG_BASE } from '../shared/ccjk.TVnFUDQc.mjs';
7
+ import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
8
+ import { m as modifyApiConfigPartially, c as configureApiCompletely, s as selectAndInstallWorkflows, a as configureOutputStyle, f as formatApiKeyDisplay, W as WORKFLOW_CONFIG_BASE } from '../shared/ccjk.qYAnUMuy.mjs';
9
9
  import { SETTINGS_FILE, DEFAULT_CODE_TOOL_TYPE, CODE_TOOL_BANNERS, API_DEFAULT_URL } from './constants.mjs';
10
10
  import { ensureI18nInitialized, i18n } from './index2.mjs';
11
11
  import { a as displayBannerWithInfo, p as padToDisplayWidth } from '../shared/ccjk.BhKlRJ0h.mjs';
@@ -1,16 +1,17 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { a as getMcpService, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
3
+ import { a as getMcpService, M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
4
4
  import { ensureI18nInitialized, i18n } from './index2.mjs';
5
5
  import { ClAUDE_CONFIG_FILE, CODEX_CONFIG_FILE } from './constants.mjs';
6
6
  import { r as readMcpConfig, w as writeMcpConfig, a as buildMcpServerConfig } from './claude-config.mjs';
7
7
  import { r as readCodexConfig, w as writeCodexConfig, N as applyCodexPlatformCommand } from './codex.mjs';
8
8
  import { exists } from './fs-operations.mjs';
9
9
  import { isWindows, getSystemRoot } from './platform.mjs';
10
+ import 'node:child_process';
10
11
  import 'node:os';
12
+ import 'node:process';
11
13
  import 'pathe';
12
14
  import 'node:fs';
13
- import 'node:process';
14
15
  import 'node:url';
15
16
  import 'i18next';
16
17
  import 'i18next-fs-backend';
@@ -1,12 +1,13 @@
1
1
  import ansis from 'ansis';
2
- import { M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.HAxAfl1Z.mjs';
2
+ import { M as MCP_SERVICE_CONFIGS } from '../shared/ccjk.DwDtZ5cK.mjs';
3
3
  import { i18n } from './index2.mjs';
4
4
  import { b as backupMcpConfig, r as readMcpConfig, w as writeMcpConfig } from './claude-config.mjs';
5
5
  import { checkMcpPerformance, formatPerformanceWarning } from './mcp-performance.mjs';
6
+ import 'node:child_process';
6
7
  import 'node:os';
8
+ import 'node:process';
7
9
  import 'pathe';
8
10
  import 'node:fs';
9
- import 'node:process';
10
11
  import 'node:url';
11
12
  import 'i18next';
12
13
  import 'i18next-fs-backend';
@@ -1,4 +1,4 @@
1
- const version = "2.1.0";
1
+ const version = "2.2.1";
2
2
  const homepage = "https://github.com/miounet11/ccjk";
3
3
 
4
4
  export { homepage, version };
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from 'node:fs';
2
- import { mkdir, writeFile, readdir, readFile } from 'node:fs/promises';
2
+ import { mkdir, writeFile, readdir, readFile, rm, stat } from 'node:fs/promises';
3
3
  import { homedir } from 'node:os';
4
4
  import { join } from 'node:path';
5
5
  import process from 'node:process';
@@ -7,6 +7,8 @@ import ansis from 'ansis';
7
7
  import inquirer from 'inquirer';
8
8
 
9
9
  const SESSIONS_DIR = join(homedir(), ".ccjk", "sessions");
10
+ const CCJK_DIR = join(homedir(), ".ccjk");
11
+ const CLAUDE_DIR = join(homedir(), ".claude");
10
12
  async function saveSession() {
11
13
  try {
12
14
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
@@ -164,5 +166,190 @@ Session data would be exported here.
164
166
  console.error(ansis.red("Failed to export session:"), error);
165
167
  }
166
168
  }
169
+ function formatBytes(bytes) {
170
+ if (bytes === 0)
171
+ return "0 B";
172
+ const k = 1024;
173
+ const sizes = ["B", "KB", "MB", "GB"];
174
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
175
+ return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
176
+ }
177
+ async function getDirSize(dirPath) {
178
+ if (!existsSync(dirPath))
179
+ return 0;
180
+ let totalSize = 0;
181
+ try {
182
+ const entries = await readdir(dirPath, { withFileTypes: true });
183
+ for (const entry of entries) {
184
+ const fullPath = join(dirPath, entry.name);
185
+ if (entry.isDirectory()) {
186
+ totalSize += await getDirSize(fullPath);
187
+ } else {
188
+ const fileStat = await stat(fullPath);
189
+ totalSize += fileStat.size;
190
+ }
191
+ }
192
+ } catch {
193
+ }
194
+ return totalSize;
195
+ }
196
+ async function countFiles(dirPath) {
197
+ if (!existsSync(dirPath))
198
+ return 0;
199
+ let count = 0;
200
+ try {
201
+ const entries = await readdir(dirPath, { withFileTypes: true });
202
+ for (const entry of entries) {
203
+ const fullPath = join(dirPath, entry.name);
204
+ if (entry.isDirectory()) {
205
+ count += await countFiles(fullPath);
206
+ } else {
207
+ count++;
208
+ }
209
+ }
210
+ } catch {
211
+ }
212
+ return count;
213
+ }
214
+ async function analyzeCleanupTargets() {
215
+ const targets = [];
216
+ const ccjkCacheDirs = [
217
+ { name: "ccjk/cache", path: join(CCJK_DIR, "cache"), desc: "General cache files", safe: true },
218
+ { name: "ccjk/sessions", path: join(CCJK_DIR, "sessions"), desc: "Saved session data", safe: true },
219
+ { name: "ccjk/logs", path: join(CCJK_DIR, "logs"), desc: "Log files", safe: true },
220
+ { name: "ccjk/temp", path: join(CCJK_DIR, "temp"), desc: "Temporary files", safe: true }
221
+ ];
222
+ const claudeDirs = [
223
+ { name: "claude/projects", path: join(CLAUDE_DIR, "projects"), desc: "Claude project caches", safe: true },
224
+ { name: "claude/debug", path: join(CLAUDE_DIR, "debug"), desc: "Debug logs and traces", safe: true },
225
+ { name: "claude/file-history", path: join(CLAUDE_DIR, "file-history"), desc: "File edit history", safe: true },
226
+ { name: "claude/shell-snapshots", path: join(CLAUDE_DIR, "shell-snapshots"), desc: "Shell state snapshots", safe: true },
227
+ { name: "claude/paste-cache", path: join(CLAUDE_DIR, "paste-cache"), desc: "Clipboard paste cache", safe: true },
228
+ { name: "claude/todos", path: join(CLAUDE_DIR, "todos"), desc: "Todo list files", safe: false },
229
+ { name: "claude/plans", path: join(CLAUDE_DIR, "plans"), desc: "Plan files", safe: true },
230
+ { name: "claude/session-env", path: join(CLAUDE_DIR, "session-env"), desc: "Session environment data", safe: true },
231
+ { name: "claude/ide", path: join(CLAUDE_DIR, "ide"), desc: "IDE integration cache", safe: true }
232
+ ];
233
+ for (const dir of [...ccjkCacheDirs, ...claudeDirs]) {
234
+ if (existsSync(dir.path)) {
235
+ const size = await getDirSize(dir.path);
236
+ const fileCount = await countFiles(dir.path);
237
+ if (size > 0) {
238
+ targets.push({
239
+ name: dir.name,
240
+ path: dir.path,
241
+ description: dir.desc,
242
+ size,
243
+ fileCount,
244
+ safe: dir.safe
245
+ });
246
+ }
247
+ }
248
+ }
249
+ return targets.sort((a, b) => b.size - a.size);
250
+ }
251
+ async function cleanupSession(options = {}) {
252
+ try {
253
+ console.log(ansis.cyan.bold("\n\u{1F9F9} Session & Cache Cleanup\n"));
254
+ console.log(ansis.gray("Analyzing cleanup targets..."));
255
+ const targets = await analyzeCleanupTargets();
256
+ if (targets.length === 0) {
257
+ console.log(ansis.green("\u2714 No cleanup needed - everything is clean!"));
258
+ return;
259
+ }
260
+ console.log(ansis.white.bold("\nCleanup Targets:\n"));
261
+ let totalSize = 0;
262
+ let totalFiles = 0;
263
+ for (const target of targets) {
264
+ totalSize += target.size;
265
+ totalFiles += target.fileCount;
266
+ const sizeStr = formatBytes(target.size).padStart(10);
267
+ const filesStr = `${target.fileCount} files`.padStart(12);
268
+ console.log(` ${ansis.yellow(sizeStr)} ${ansis.gray(filesStr)} ${ansis.white(target.name)}`);
269
+ console.log(` ${ansis.gray(` ${target.description}`)}`);
270
+ console.log(` ${ansis.gray(` ${target.path}`)}`);
271
+ console.log("");
272
+ }
273
+ console.log(ansis.white.bold("\u2500".repeat(50)));
274
+ console.log(` ${ansis.cyan(formatBytes(totalSize).padStart(10))} ${ansis.gray(`${totalFiles} files`.padStart(12))} ${ansis.white.bold("Total")}`);
275
+ console.log("");
276
+ if (!options.force) {
277
+ const { confirm } = await inquirer.prompt({
278
+ type: "confirm",
279
+ name: "confirm",
280
+ message: options.all ? `Delete ALL ${targets.length} targets (${formatBytes(totalSize)})?` : "Select targets to clean?",
281
+ default: false
282
+ });
283
+ if (!confirm) {
284
+ console.log(ansis.yellow("Cleanup cancelled"));
285
+ return;
286
+ }
287
+ }
288
+ let selectedTargets = targets;
289
+ if (!options.all && !options.force) {
290
+ const { selected } = await inquirer.prompt({
291
+ type: "checkbox",
292
+ name: "selected",
293
+ message: "Select targets to clean:",
294
+ choices: targets.map((t) => ({
295
+ name: `${t.name} (${formatBytes(t.size)}, ${t.fileCount} files)`,
296
+ value: t.path,
297
+ checked: t.safe
298
+ }))
299
+ });
300
+ selectedTargets = targets.filter((t) => selected.includes(t.path));
301
+ }
302
+ if (selectedTargets.length === 0) {
303
+ console.log(ansis.yellow("No targets selected"));
304
+ return;
305
+ }
306
+ console.log(ansis.gray("\nCleaning up..."));
307
+ let cleanedSize = 0;
308
+ let cleanedFiles = 0;
309
+ for (const target of selectedTargets) {
310
+ try {
311
+ await rm(target.path, { recursive: true, force: true });
312
+ cleanedSize += target.size;
313
+ cleanedFiles += target.fileCount;
314
+ console.log(ansis.green(` \u2714 ${target.name}`));
315
+ } catch (error) {
316
+ console.log(ansis.red(` \u2716 ${target.name}: ${error}`));
317
+ }
318
+ }
319
+ console.log("");
320
+ console.log(ansis.green.bold(`\u2714 Cleanup complete!`));
321
+ console.log(ansis.gray(` Freed ${formatBytes(cleanedSize)} (${cleanedFiles} files)`));
322
+ } catch (error) {
323
+ console.error(ansis.red("Failed to cleanup:"), error);
324
+ }
325
+ }
326
+ async function sessionStatus() {
327
+ try {
328
+ console.log(ansis.cyan.bold("\n\u{1F4CA} Session & Cache Status\n"));
329
+ const targets = await analyzeCleanupTargets();
330
+ if (targets.length === 0) {
331
+ console.log(ansis.green("\u2714 All clean - no cached data found"));
332
+ return;
333
+ }
334
+ let totalSize = 0;
335
+ let totalFiles = 0;
336
+ console.log(ansis.white.bold("Directory Size Files"));
337
+ console.log(ansis.gray("\u2500".repeat(50)));
338
+ for (const target of targets) {
339
+ totalSize += target.size;
340
+ totalFiles += target.fileCount;
341
+ const name = target.name.padEnd(24);
342
+ const size = formatBytes(target.size).padStart(10);
343
+ const files = String(target.fileCount).padStart(8);
344
+ console.log(`${ansis.white(name)} ${ansis.yellow(size)} ${ansis.gray(files)}`);
345
+ }
346
+ console.log(ansis.gray("\u2500".repeat(50)));
347
+ console.log(`${ansis.white.bold("Total".padEnd(24))} ${ansis.cyan.bold(formatBytes(totalSize).padStart(10))} ${ansis.gray(String(totalFiles).padStart(8))}`);
348
+ console.log("");
349
+ console.log(ansis.gray(`Run ${ansis.cyan("ccjk session cleanup")} to free up space`));
350
+ } catch (error) {
351
+ console.error(ansis.red("Failed to get status:"), error);
352
+ }
353
+ }
167
354
 
168
- export { exportSession, listSessions, restoreSession, saveSession };
355
+ export { cleanupSession, exportSession, listSessions, restoreSession, saveSession, sessionStatus };
@@ -5,7 +5,7 @@ import { i18n } from './index2.mjs';
5
5
  import { d as displayBanner } from '../shared/ccjk.BhKlRJ0h.mjs';
6
6
  import { readZcfConfig, updateZcfConfig } from './ccjk-config.mjs';
7
7
  import { E as runCodexUpdate } from './codex.mjs';
8
- import { u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.TVnFUDQc.mjs';
8
+ import { u as updatePromptOnly, s as selectAndInstallWorkflows } from '../shared/ccjk.qYAnUMuy.mjs';
9
9
  import { h as handleExitPromptError, a as handleGeneralError } from '../shared/ccjk.B7169qud.mjs';
10
10
  import { resolveAiOutputLanguage } from './prompts.mjs';
11
11
  import { c as checkClaudeCodeVersionAndPrompt } from '../shared/ccjk.Cy-RH2qV.mjs';
@@ -30,7 +30,7 @@ import './claude-config.mjs';
30
30
  import './platform.mjs';
31
31
  import '../shared/ccjk.DhBeLRzf.mjs';
32
32
  import 'inquirer-toggle';
33
- import '../shared/ccjk.HAxAfl1Z.mjs';
33
+ import '../shared/ccjk.DwDtZ5cK.mjs';
34
34
  import 'node:child_process';
35
35
  import 'node:path';
36
36
  import 'node:util';
package/dist/cli.mjs CHANGED
@@ -246,11 +246,15 @@ const COMMANDS = [
246
246
  },
247
247
  {
248
248
  name: "session <action> [id]",
249
- description: "Manage sessions",
249
+ description: "Manage sessions (save, list, restore, export, cleanup, status)",
250
250
  tier: "extended",
251
+ options: [
252
+ { flags: "--all, -a", description: "Clean all targets without selection" },
253
+ { flags: "--force, -f", description: "Force cleanup without confirmation" }
254
+ ],
251
255
  loader: async () => {
252
- const { saveSession, listSessions, restoreSession, exportSession } = await import('./chunks/session.mjs');
253
- return async (_options, action, id) => {
256
+ const { saveSession, listSessions, restoreSession, exportSession, cleanupSession, sessionStatus } = await import('./chunks/session.mjs');
257
+ return async (options, action, id) => {
254
258
  const actionStr = action;
255
259
  if (actionStr === "save")
256
260
  await saveSession();
@@ -260,6 +264,12 @@ const COMMANDS = [
260
264
  await restoreSession(id);
261
265
  else if (actionStr === "export")
262
266
  await exportSession(id);
267
+ else if (actionStr === "cleanup" || actionStr === "clean")
268
+ await cleanupSession({ all: options.all, force: options.force });
269
+ else if (actionStr === "status")
270
+ await sessionStatus();
271
+ else
272
+ console.error(`Unknown action: ${actionStr}. Use: save, list, restore, export, cleanup, or status`);
263
273
  };
264
274
  }
265
275
  },
package/dist/index.mjs CHANGED
@@ -17,14 +17,15 @@ import 'node:process';
17
17
  import 'ansis';
18
18
  import 'inquirer';
19
19
  import './chunks/package.mjs';
20
- import './shared/ccjk.HAxAfl1Z.mjs';
20
+ import './shared/ccjk.DwDtZ5cK.mjs';
21
+ import 'node:child_process';
21
22
  import 'node:os';
22
23
  import 'pathe';
23
24
  import './chunks/index2.mjs';
24
25
  import 'node:url';
25
26
  import 'i18next';
26
27
  import 'i18next-fs-backend';
27
- import './shared/ccjk.TVnFUDQc.mjs';
28
+ import './shared/ccjk.qYAnUMuy.mjs';
28
29
  import './chunks/ccjk-config.mjs';
29
30
  import 'smol-toml';
30
31
  import './chunks/fs-operations.mjs';
@@ -34,7 +35,6 @@ import './chunks/json-config.mjs';
34
35
  import 'dayjs';
35
36
  import './shared/ccjk.DhBeLRzf.mjs';
36
37
  import 'inquirer-toggle';
37
- import 'node:child_process';
38
38
  import 'node:util';
39
39
  import './chunks/auto-updater.mjs';
40
40
  import 'ora';
@@ -1,4 +1,6 @@
1
+ import 'node:child_process';
1
2
  import { homedir } from 'node:os';
3
+ import 'node:process';
2
4
  import { join } from 'pathe';
3
5
  import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
4
6
 
@@ -25,7 +27,7 @@ function createPlaywrightMcpConfig(options = {}) {
25
27
  };
26
28
  }
27
29
  const MCP_SERVICE_CONFIGS = [
28
- // Documentation and Search Services
30
+ // Documentation and Search Services - Universal (no GUI required)
29
31
  {
30
32
  id: "context7",
31
33
  requiresApiKey: false,
@@ -35,6 +37,7 @@ const MCP_SERVICE_CONFIGS = [
35
37
  args: ["-y", "@upstash/context7-mcp@latest"],
36
38
  env: {}
37
39
  }
40
+ // Works on all platforms - no special requirements
38
41
  },
39
42
  {
40
43
  id: "open-websearch",
@@ -49,6 +52,7 @@ const MCP_SERVICE_CONFIGS = [
49
52
  ALLOWED_SEARCH_ENGINES: "duckduckgo,bing,brave"
50
53
  }
51
54
  }
55
+ // Works on all platforms - no special requirements
52
56
  },
53
57
  {
54
58
  id: "mcp-deepwiki",
@@ -59,6 +63,7 @@ const MCP_SERVICE_CONFIGS = [
59
63
  args: ["-y", "mcp-deepwiki@latest"],
60
64
  env: {}
61
65
  }
66
+ // Works on all platforms - no special requirements
62
67
  },
63
68
  // Development Workflow Services
64
69
  {
@@ -70,6 +75,7 @@ const MCP_SERVICE_CONFIGS = [
70
75
  args: ["-y", "@pimzino/spec-workflow-mcp@latest"],
71
76
  env: {}
72
77
  }
78
+ // Works on all platforms - no special requirements
73
79
  },
74
80
  {
75
81
  id: "serena",
@@ -79,14 +85,23 @@ const MCP_SERVICE_CONFIGS = [
79
85
  command: "uvx",
80
86
  args: ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--enable-web-dashboard", "false"],
81
87
  env: {}
88
+ },
89
+ platformRequirements: {
90
+ requiredCommands: ["uvx"]
91
+ // Requires uv/uvx to be installed
82
92
  }
83
93
  },
84
- // Browser and Automation Services
94
+ // Browser and Automation Services - Require GUI environment
85
95
  {
86
96
  id: "Playwright",
87
97
  requiresApiKey: false,
88
- config: createPlaywrightMcpConfig()
98
+ config: createPlaywrightMcpConfig(),
89
99
  // Uses default profile with chromium browser
100
+ platformRequirements: {
101
+ platforms: ["macos", "windows"],
102
+ // GUI required - exclude headless Linux/WSL/Termux
103
+ requiresGui: true
104
+ }
90
105
  },
91
106
  {
92
107
  id: "puppeteer",
@@ -96,9 +111,14 @@ const MCP_SERVICE_CONFIGS = [
96
111
  command: "npx",
97
112
  args: ["-y", "@anthropic-ai/mcp-server-puppeteer@latest"],
98
113
  env: {}
114
+ },
115
+ platformRequirements: {
116
+ platforms: ["macos", "windows"],
117
+ // GUI required - exclude headless Linux/WSL/Termux
118
+ requiresGui: true
99
119
  }
100
120
  },
101
- // Anthropic Official MCP Services
121
+ // Anthropic Official MCP Services - Universal
102
122
  {
103
123
  id: "filesystem",
104
124
  requiresApiKey: false,
@@ -108,6 +128,7 @@ const MCP_SERVICE_CONFIGS = [
108
128
  args: ["-y", "@anthropic-ai/mcp-server-filesystem@latest", "."],
109
129
  env: {}
110
130
  }
131
+ // Works on all platforms - no special requirements
111
132
  },
112
133
  {
113
134
  id: "memory",
@@ -118,6 +139,7 @@ const MCP_SERVICE_CONFIGS = [
118
139
  args: ["-y", "@anthropic-ai/mcp-server-memory@latest"],
119
140
  env: {}
120
141
  }
142
+ // Works on all platforms - no special requirements
121
143
  },
122
144
  {
123
145
  id: "sequential-thinking",
@@ -128,6 +150,7 @@ const MCP_SERVICE_CONFIGS = [
128
150
  args: ["-y", "@anthropic-ai/mcp-server-sequential-thinking@latest"],
129
151
  env: {}
130
152
  }
153
+ // Works on all platforms - no special requirements
131
154
  },
132
155
  {
133
156
  id: "fetch",
@@ -138,6 +161,7 @@ const MCP_SERVICE_CONFIGS = [
138
161
  args: ["-y", "@anthropic-ai/mcp-server-fetch@latest"],
139
162
  env: {}
140
163
  }
164
+ // Works on all platforms - no special requirements
141
165
  },
142
166
  {
143
167
  id: "sqlite",
@@ -148,6 +172,7 @@ const MCP_SERVICE_CONFIGS = [
148
172
  args: ["-y", "@anthropic-ai/mcp-server-sqlite@latest"],
149
173
  env: {}
150
174
  }
175
+ // Works on all platforms - no special requirements
151
176
  }
152
177
  ];
153
178
  async function getMcpServices() {
@@ -280,8 +280,8 @@ async function configureOutputStyle(preselectedStyles, preselectedDefault) {
280
280
  return {
281
281
  name: `${styleInfo?.name || style.id} - ${ansis.gray(styleInfo?.description || "")}`,
282
282
  value: style.id,
283
- checked: true
284
- // Default select all custom styles
283
+ checked: false
284
+ // Let user choose, not pre-selected
285
285
  };
286
286
  })),
287
287
  validate: async (input) => input.length > 0 || i18n.t("configuration:selectAtLeastOne")
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ccjk",
3
3
  "type": "module",
4
- "version": "2.1.0",
4
+ "version": "2.2.1",
5
5
  "packageManager": "pnpm@10.17.1",
6
6
  "description": "Claude Code JinKu - Advanced AI-powered development assistant with skills, agents, and LLM-driven audit",
7
7
  "author": {