ccjk 13.5.2 → 13.5.4

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.
Files changed (35) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/boost.mjs +8 -1
  3. package/dist/chunks/ccjk-config.mjs +17 -0
  4. package/dist/chunks/ccr.mjs +2 -2
  5. package/dist/chunks/check-updates.mjs +1 -1
  6. package/dist/chunks/codex-config-switch.mjs +1 -1
  7. package/dist/chunks/codex-provider-manager.mjs +1 -1
  8. package/dist/chunks/codex.mjs +2 -2
  9. package/dist/chunks/completion.mjs +1 -1
  10. package/dist/chunks/config-switch.mjs +1 -1
  11. package/dist/chunks/context.mjs +316 -1
  12. package/dist/chunks/features.mjs +43 -14
  13. package/dist/chunks/index4.mjs +8 -1
  14. package/dist/chunks/init.mjs +2 -2
  15. package/dist/chunks/mcp-cli.mjs +3 -3
  16. package/dist/chunks/mcp.mjs +177 -35
  17. package/dist/{shared/ccjk.Crd_nEfj.mjs → chunks/memory-check.mjs} +18 -424
  18. package/dist/chunks/memory-paths.mjs +259 -0
  19. package/dist/chunks/memory-sync.mjs +209 -0
  20. package/dist/chunks/memory.mjs +140 -17
  21. package/dist/chunks/menu-hierarchical.mjs +2 -2
  22. package/dist/chunks/menu.mjs +1 -1
  23. package/dist/chunks/onboarding-wizard.mjs +8 -1
  24. package/dist/chunks/package.mjs +1 -1
  25. package/dist/chunks/quick-actions.mjs +8 -1
  26. package/dist/chunks/quick-setup.mjs +1 -1
  27. package/dist/chunks/smart-defaults.mjs +1 -20
  28. package/dist/chunks/status.mjs +8 -1
  29. package/dist/chunks/update.mjs +2 -2
  30. package/dist/cli.mjs +16 -4
  31. package/dist/shared/{ccjk.LTONy3IS.mjs → ccjk.BOfPON0N.mjs} +1 -1
  32. package/dist/shared/{ccjk.0aJQmVxS.mjs → ccjk.miT0g_vA.mjs} +3 -160
  33. package/dist/shared/ccjk.xkKNsC02.mjs +421 -0
  34. package/package.json +1 -1
  35. package/dist/chunks/auto-memory-bridge.mjs +0 -221
package/README.md CHANGED
@@ -122,10 +122,10 @@ npx ccjk browser open https://example.com --headed
122
122
  ## 🔥 Features That Matter
123
123
 
124
124
  ### 🧠 Persistent Memory
125
- AI remembers your codebase, conventions, and decisions across sessions.
125
+ Manage Claude Code memory and project notes from the CLI.
126
126
  ```bash
127
- ccjk memory --enable
128
- # Now Claude knows your project structure forever
127
+ ccjk memory
128
+ ccjk memory --edit
129
129
  ```
130
130
 
131
131
  ### 🤖 Agent Teams (NEW)
@@ -249,8 +249,8 @@ ccjk browser status
249
249
  ccjk browser stop
250
250
 
251
251
  # Memory & Context
252
- ccjk memory --enable
253
- ccjk compact # Clean up conversation
252
+ ccjk memory
253
+ ccjk memory --edit
254
254
 
255
255
  # Zero-Config Permission Presets (NEW)
256
256
  ccjk zc --list # List available presets
@@ -3,11 +3,12 @@ import { existsSync, readFileSync } from 'node:fs';
3
3
  import process__default from 'node:process';
4
4
  import { SETTINGS_FILE } from './constants.mjs';
5
5
  import { j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
6
- import { r as runHealthCheck } from '../shared/ccjk.Crd_nEfj.mjs';
6
+ import { r as runHealthCheck } from '../shared/ccjk.xkKNsC02.mjs';
7
7
  import '../shared/ccjk.BAGoDD49.mjs';
8
8
  import 'node:os';
9
9
  import './index5.mjs';
10
10
  import 'node:url';
11
+ import './memory-check.mjs';
11
12
  import 'node:path';
12
13
  import 'fs';
13
14
  import 'constants';
@@ -15,6 +16,12 @@ import 'stream';
15
16
  import 'util';
16
17
  import 'assert';
17
18
  import 'path';
19
+ import './memory-paths.mjs';
20
+ import '../shared/ccjk.BBtCGd_g.mjs';
21
+ import './index6.mjs';
22
+ import './fs-operations.mjs';
23
+ import 'node:crypto';
24
+ import 'node:fs/promises';
18
25
 
19
26
  function analyzeProject(root) {
20
27
  const cwd = process__default.cwd();
@@ -66,6 +66,9 @@ function createDefaultTomlConfig(preferredLang = "en", claudeCodeInstallType = "
66
66
  codex: {
67
67
  enabled: false,
68
68
  systemPromptStyle: "senior-architect"
69
+ },
70
+ storage: {
71
+ memory: {}
69
72
  }
70
73
  };
71
74
  }
@@ -93,6 +96,9 @@ function migrateFromJsonConfig(jsonConfig) {
93
96
  codex: {
94
97
  enabled: jsonConfig.codeToolType === "codex",
95
98
  systemPromptStyle: jsonConfig.systemPromptStyle || defaultConfig.codex.systemPromptStyle
99
+ },
100
+ storage: {
101
+ memory: {}
96
102
  }
97
103
  };
98
104
  return tomlConfig;
@@ -113,6 +119,14 @@ function updateTomlConfig(configPath, updates) {
113
119
  codex: {
114
120
  ...existingConfig.codex,
115
121
  ...updates.codex
122
+ },
123
+ storage: {
124
+ ...existingConfig.storage,
125
+ ...updates.storage,
126
+ memory: {
127
+ ...existingConfig.storage?.memory || {},
128
+ ...updates.storage?.memory || {}
129
+ }
116
130
  }
117
131
  };
118
132
  writeTomlConfig(configPath, updatedConfig);
@@ -236,6 +250,9 @@ function writeZcfConfig(config) {
236
250
  tomlConfig.claudeCode.version = existingTomlConfig.claudeCode.version;
237
251
  }
238
252
  }
253
+ if (existingTomlConfig?.storage) {
254
+ tomlConfig.storage = existingTomlConfig.storage;
255
+ }
239
256
  writeTomlConfig(ZCF_CONFIG_FILE, tomlConfig);
240
257
  } catch {
241
258
  }
@@ -24,7 +24,7 @@ import 'node:os';
24
24
  import 'node:crypto';
25
25
  import 'buffer';
26
26
  import 'string_decoder';
27
- import '../shared/ccjk.0aJQmVxS.mjs';
27
+ import '../shared/ccjk.miT0g_vA.mjs';
28
28
  import 'node:child_process';
29
29
  import './constants.mjs';
30
30
  import './ccjk-config.mjs';
@@ -81,7 +81,7 @@ import './uninstall.mjs';
81
81
  import '../shared/ccjk.CvChMYvB.mjs';
82
82
  import 'globby';
83
83
  import './update.mjs';
84
- import '../shared/ccjk.LTONy3IS.mjs';
84
+ import '../shared/ccjk.BOfPON0N.mjs';
85
85
 
86
86
  async function ccr(options = {}) {
87
87
  try {
@@ -49,7 +49,7 @@ import '../shared/ccjk.DScm_NnL.mjs';
49
49
  import '../shared/ccjk.BFQ7yr5S.mjs';
50
50
  import './prompts.mjs';
51
51
  import '../shared/ccjk.gDEDGD_t.mjs';
52
- import '../shared/ccjk.0aJQmVxS.mjs';
52
+ import '../shared/ccjk.miT0g_vA.mjs';
53
53
 
54
54
  class ToolUpdateScheduler {
55
55
  /**
@@ -45,7 +45,7 @@ import './platform.mjs';
45
45
  import '../shared/ccjk.DScm_NnL.mjs';
46
46
  import './prompts.mjs';
47
47
  import '../shared/ccjk.gDEDGD_t.mjs';
48
- import '../shared/ccjk.0aJQmVxS.mjs';
48
+ import '../shared/ccjk.miT0g_vA.mjs';
49
49
 
50
50
  async function configureIncrementalManagement() {
51
51
  ensureI18nInitialized();
@@ -44,7 +44,7 @@ import '../shared/ccjk.BFQ7yr5S.mjs';
44
44
  import './prompts.mjs';
45
45
  import '../shared/ccjk.gDEDGD_t.mjs';
46
46
  import '../shared/ccjk.BWFpnOr3.mjs';
47
- import '../shared/ccjk.0aJQmVxS.mjs';
47
+ import '../shared/ccjk.miT0g_vA.mjs';
48
48
 
49
49
  async function addProviderToExisting(provider, apiKey, allowOverwrite = false) {
50
50
  ensureI18nInitialized();
@@ -7,7 +7,7 @@ import ora from './index7.mjs';
7
7
  import { a as semver } from '../shared/ccjk.CxpGa6MC.mjs';
8
8
  import { p as parse } from '../shared/ccjk.BBtCGd_g.mjs';
9
9
  import { x as K } from './main.mjs';
10
- import { CODEX_AUTH_FILE, SUPPORTED_LANGS, CODEX_CONFIG_FILE, CODEX_DIR, CODEX_AGENTS_FILE, CODEX_PROMPTS_DIR, AI_OUTPUT_LANGUAGES, ZCF_CONFIG_FILE } from './constants.mjs';
10
+ import { CODEX_CONFIG_FILE, CODEX_AUTH_FILE, CODEX_DIR, SUPPORTED_LANGS, CODEX_AGENTS_FILE, CODEX_PROMPTS_DIR, ZCF_CONFIG_FILE, AI_OUTPUT_LANGUAGES } from './constants.mjs';
11
11
  import { ensureI18nInitialized, i18n, format } from './index5.mjs';
12
12
  import { updateZcfConfig, readZcfConfig, readDefaultTomlConfig, updateTomlConfig } from './ccjk-config.mjs';
13
13
  import { e as applyAiLanguageDirective } from './config2.mjs';
@@ -17,7 +17,7 @@ import { i as isWindows, m as getMcpCommand, l as getSystemRoot, w as wrapComman
17
17
  import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
18
18
  import { resolveAiOutputLanguage } from './prompts.mjs';
19
19
  import { p as promptBoolean } from '../shared/ccjk.BWFpnOr3.mjs';
20
- import { M as MCP_SERVICE_CONFIGS, s as selectMcpServices, g as getMcpServices } from '../shared/ccjk.0aJQmVxS.mjs';
20
+ import { M as MCP_SERVICE_CONFIGS, s as selectMcpServices, g as getMcpServices } from '../shared/ccjk.miT0g_vA.mjs';
21
21
  import { j as join, d as dirname } from '../shared/ccjk.bQ7Dh1g4.mjs';
22
22
 
23
23
  function detectConfigManagementMode() {
@@ -56,7 +56,7 @@ const COMPLETION_COMMANDS = [
56
56
  subcommands: [
57
57
  { name: "status", description: "Quick MCP status overview" },
58
58
  { name: "doctor", description: "Health check and diagnostics" },
59
- { name: "profile", description: "Switch profile (minimal/dev/full)" },
59
+ { name: "profile", description: "Switch profile (minimal/development/full)" },
60
60
  { name: "release", description: "Release idle services" },
61
61
  { name: "market", description: "MCP service marketplace" },
62
62
  { name: "list", description: "List installed services" },
@@ -46,7 +46,7 @@ import '../shared/ccjk.CxpGa6MC.mjs';
46
46
  import './prompts.mjs';
47
47
  import '../shared/ccjk.gDEDGD_t.mjs';
48
48
  import '../shared/ccjk.BWFpnOr3.mjs';
49
- import '../shared/ccjk.0aJQmVxS.mjs';
49
+ import '../shared/ccjk.miT0g_vA.mjs';
50
50
 
51
51
  async function configSwitchCommand(options) {
52
52
  try {
@@ -1,6 +1,20 @@
1
1
  import { mkdir, writeFile, access, readFile, readdir, stat } from 'node:fs/promises';
2
2
  import { d as dirname, j as join, r as relative } from '../shared/ccjk.bQ7Dh1g4.mjs';
3
- import { constants } from 'node:fs';
3
+ import { constants, existsSync, lstatSync, readFileSync, readdirSync } from 'node:fs';
4
+ import a from './index2.mjs';
5
+ import { getTranslation } from './index5.mjs';
6
+ import { inspectMemoryFiles } from './memory-sync.mjs';
7
+ import '../shared/ccjk.BAGoDD49.mjs';
8
+ import 'node:process';
9
+ import 'node:url';
10
+ import 'node:path';
11
+ import './memory-paths.mjs';
12
+ import './constants.mjs';
13
+ import 'node:os';
14
+ import '../shared/ccjk.BBtCGd_g.mjs';
15
+ import './index6.mjs';
16
+ import './fs-operations.mjs';
17
+ import 'node:crypto';
4
18
 
5
19
  function buildContextPack(intelligence, options = {}) {
6
20
  const {
@@ -590,6 +604,303 @@ async function analyzeProject(projectRoot = ".") {
590
604
  };
591
605
  }
592
606
 
607
+ async function analyzeContext() {
608
+ const t = getTranslation();
609
+ console.log(a.green.bold(`
610
+ \u{1F50D} ${t("context.analyzing")}
611
+ `));
612
+ const analysis = analyzeDirectory(process.cwd());
613
+ console.log(a.white(`${t("context.filesInContext")}: ${a.bold(analysis.files.length.toString())}`));
614
+ console.log(a.white(`${t("context.estimatedTokens")}: ${a.bold(analysis.totalTokens.toLocaleString())}`));
615
+ console.log(a.white(`${t("context.totalSize")}: ${a.bold(formatBytes(analysis.totalSize))}
616
+ `));
617
+ if (analysis.largestFiles.length > 0) {
618
+ console.log(a.yellow(`${t("context.largestFiles")}:
619
+ `));
620
+ for (const file of analysis.largestFiles.slice(0, 5)) {
621
+ const sizeStr = formatBytes(file.size);
622
+ const tokensStr = file.tokens.toLocaleString();
623
+ console.log(` ${a.white(file.path)}`);
624
+ console.log(` ${a.dim(`${t("context.size")}: ${sizeStr} | ${t("context.tokens")}: ${tokensStr}`)}`);
625
+ }
626
+ console.log();
627
+ }
628
+ }
629
+ async function showContextStatus() {
630
+ const t = getTranslation();
631
+ const memoryStatus = inspectMemoryFiles({ projectPath: process.cwd() });
632
+ console.log(a.green.bold(`
633
+ \u{1F4CA} ${t("context.status")}
634
+ `));
635
+ console.log(a.white(`Project: ${a.bold(process.cwd())}`));
636
+ const claudeMdPath = join(process.cwd(), "CLAUDE.md");
637
+ const hasClaudeMd = existsSync(claudeMdPath);
638
+ console.log(`${hasClaudeMd ? a.green("\u2713") : a.red("\u2717")} CLAUDE.md`);
639
+ if (hasClaudeMd) {
640
+ const stats = lstatSync(claudeMdPath);
641
+ const content = readFileSync(claudeMdPath, "utf-8");
642
+ const tokens = estimateTokens(content);
643
+ console.log(` ${a.dim(`${t("context.size")}: ${formatBytes(stats.size)} | ${t("context.tokens")}: ${tokens.toLocaleString()}`)}`);
644
+ }
645
+ console.log();
646
+ const claudeIgnorePath = join(process.cwd(), ".claudeignore");
647
+ const hasIgnore = existsSync(claudeIgnorePath);
648
+ console.log(`${hasIgnore ? a.green("\u2713") : a.yellow("\u25CB")} .claudeignore`);
649
+ const contextFiles = findContextFiles(process.cwd());
650
+ console.log(`
651
+ ${a.white(`${t("context.additionalFiles")}: ${contextFiles.length}`)}
652
+ `);
653
+ for (const file of contextFiles.slice(0, 10)) {
654
+ const tokens = estimateTokens(readFileSync(file, "utf-8"));
655
+ lstatSync(file).size;
656
+ console.log(` ${a.white(file)} ${a.dim(`(${tokens.toLocaleString()} ${t("context.tokens")})`)}`);
657
+ }
658
+ if (contextFiles.length > 10) {
659
+ console.log(` ${a.dim(`... and ${contextFiles.length - 10} more`)}`);
660
+ }
661
+ console.log(a.yellow("\nMemory\n"));
662
+ console.log(` ${a.white(`State: ${describeMemorySyncState(memoryStatus.syncState)}`)}`);
663
+ console.log(` ${a.dim(`Claude: ${memoryStatus.paths.claude}`)}`);
664
+ console.log(` ${a.dim(`CCJK: ${memoryStatus.paths.ccjk}`)}`);
665
+ if (memoryStatus.parseMode === "structured") {
666
+ console.log(` ${a.dim(`Entries: ${memoryStatus.entryCount} | Facts: ${memoryStatus.factCount} | Patterns: ${memoryStatus.patternCount} | Decisions: ${memoryStatus.decisionCount}`)}`);
667
+ } else if (memoryStatus.parseMode === "freeform") {
668
+ console.log(` ${a.dim("Structured parsing: freeform notes detected")}`);
669
+ } else {
670
+ console.log(` ${a.dim("Structured parsing: no memory content found")}`);
671
+ }
672
+ console.log(a.yellow("\nNext Commands\n"));
673
+ console.log(` ${a.white("ccjk context status")} ${a.dim("Review project context readiness")}`);
674
+ console.log(` ${a.white("ccjk memory --status")} ${a.dim("Inspect Claude and CCJK memory files")}`);
675
+ console.log(` ${a.white("ccjk memory --doctor")} ${a.dim("Run memory diagnostics and recommendations")}`);
676
+ console.log(` ${a.white("ccjk context --show")} ${a.dim("Preview loaded context layers")}`);
677
+ console.log();
678
+ }
679
+ function describeMemorySyncState(syncState) {
680
+ switch (syncState) {
681
+ case "in-sync":
682
+ return "Claude and CCJK memory are in sync";
683
+ case "claude-only":
684
+ return "Only Claude memory has content";
685
+ case "ccjk-only":
686
+ return "Only CCJK memory has content";
687
+ case "claude-newer":
688
+ return "Claude memory is newer than the CCJK mirror";
689
+ case "ccjk-newer":
690
+ return "CCJK mirror is newer than Claude memory";
691
+ case "empty":
692
+ return "No project memory found";
693
+ }
694
+ }
695
+ async function compressContext() {
696
+ const t = getTranslation();
697
+ console.log(a.green.bold(`
698
+ \u{1F5DC}\uFE0F ${t("context.compressing")}
699
+ `));
700
+ const analysis = analyzeDirectory(process.cwd());
701
+ const duplicates = findDuplicates(analysis.files);
702
+ const largeFiles = analysis.files.filter((f) => f.tokens > 1e3);
703
+ const binaryFiles = analysis.files.filter((f) => f.type === "binary");
704
+ let totalSavings = 0;
705
+ if (duplicates.length > 0) {
706
+ console.log(a.yellow(`${t("context.duplicatesFound")}: ${duplicates.length}
707
+ `));
708
+ totalSavings += duplicates.length * 500;
709
+ }
710
+ if (largeFiles.length > 0) {
711
+ console.log(a.yellow(`${t("context.largeFiles")}: ${largeFiles.length}
712
+ `));
713
+ for (const file of largeFiles.slice(0, 5)) {
714
+ console.log(` ${a.white(file.path)} (${file.tokens.toLocaleString()} ${t("context.tokens")})`);
715
+ }
716
+ if (largeFiles.length > 5) {
717
+ console.log(` ${a.dim(`... and ${largeFiles.length - 5} more`)}`);
718
+ }
719
+ console.log();
720
+ totalSavings += largeFiles.reduce((sum, f) => sum + Math.floor(f.tokens * 0.3), 0);
721
+ }
722
+ if (binaryFiles.length > 0) {
723
+ console.log(a.yellow(`${t("context.binaryFiles")}: ${binaryFiles.length}
724
+ `));
725
+ console.log(a.dim(`${t("context.binaryNote")}
726
+ `));
727
+ totalSavings += binaryFiles.length * 200;
728
+ }
729
+ if (totalSavings > 0) {
730
+ console.log(a.green(`${t("context.estimatedSavings")}: ${a.bold(totalSavings.toLocaleString())} ${t("context.tokens")}
731
+ `));
732
+ } else {
733
+ console.log(a.dim(`${t("context.noCompressionNeeded")}
734
+ `));
735
+ }
736
+ }
737
+ async function optimizeContext() {
738
+ const t = getTranslation();
739
+ console.log(a.green.bold(`
740
+ \u26A1 ${t("context.optimizing")}
741
+ `));
742
+ const analysis = analyzeDirectory(process.cwd());
743
+ const suggestions = [];
744
+ const largeFiles = analysis.files.filter((f) => f.tokens > 1e3);
745
+ if (largeFiles.length > 0) {
746
+ suggestions.push(`${t("context.suggestionLargeFiles")}: ${largeFiles.map((f) => f.path).join(", ")}`);
747
+ }
748
+ if (analysis.files.length > 20) {
749
+ suggestions.push(`${t("context.suggestionManyFiles")}: ${analysis.files.length}`);
750
+ }
751
+ if (!existsSync(join(process.cwd(), ".claudeignore"))) {
752
+ suggestions.push(t("context.suggestionClaudeignore"));
753
+ }
754
+ if (suggestions.length === 0) {
755
+ console.log(a.green(`${t("context.optimized")}
756
+ `));
757
+ } else {
758
+ console.log(a.yellow(`${t("context.suggestions")}:
759
+ `));
760
+ for (const suggestion of suggestions) {
761
+ console.log(` \u2022 ${suggestion}`);
762
+ }
763
+ console.log();
764
+ }
765
+ }
766
+ function analyzeDirectory(dir) {
767
+ const files = [];
768
+ let totalTokens = 0;
769
+ let totalSize = 0;
770
+ try {
771
+ const entries = readdirSync(dir, { withFileTypes: true });
772
+ for (const entry of entries) {
773
+ if (entry.isDirectory()) {
774
+ if (["node_modules", ".git", "dist", "build", ".next", "target"].includes(entry.name)) {
775
+ continue;
776
+ }
777
+ continue;
778
+ }
779
+ const filePath = join(dir, entry.name);
780
+ const fileType = getFileType(entry.name);
781
+ if (fileType === "binary") {
782
+ continue;
783
+ }
784
+ try {
785
+ const stats = lstatSync(filePath);
786
+ const content = readFileSync(filePath, "utf-8");
787
+ const tokens = estimateTokens(content);
788
+ files.push({
789
+ path: filePath,
790
+ size: stats.size,
791
+ tokens,
792
+ type: fileType
793
+ });
794
+ totalTokens += tokens;
795
+ totalSize += stats.size;
796
+ } catch {
797
+ }
798
+ }
799
+ } catch {
800
+ }
801
+ const largestFiles = [...files].sort((a, b) => b.tokens - a.tokens);
802
+ return {
803
+ files,
804
+ totalTokens,
805
+ totalSize,
806
+ largestFiles
807
+ };
808
+ }
809
+ function findContextFiles(dir) {
810
+ const contextFiles = [];
811
+ const contextPatterns = [
812
+ "CLAUDE.md",
813
+ "README.md",
814
+ "package.json",
815
+ "tsconfig.json",
816
+ ".gitignore",
817
+ ".claudeignore"
818
+ ];
819
+ try {
820
+ const entries = readdirSync(dir);
821
+ for (const entry of entries) {
822
+ if (contextPatterns.includes(entry)) {
823
+ contextFiles.push(join(dir, entry));
824
+ }
825
+ }
826
+ } catch {
827
+ }
828
+ return contextFiles;
829
+ }
830
+ function findDuplicates(files) {
831
+ const seen = /* @__PURE__ */ new Map();
832
+ const duplicates = [];
833
+ for (const file of files) {
834
+ const name = file.path.split("/").pop() || file.path;
835
+ if (!seen.has(name)) {
836
+ seen.set(name, []);
837
+ }
838
+ seen.get(name).push(file);
839
+ }
840
+ for (const [, group] of seen) {
841
+ if (group.length > 1) {
842
+ duplicates.push(...group.slice(1));
843
+ }
844
+ }
845
+ return duplicates;
846
+ }
847
+ function getFileType(filename) {
848
+ const ext = filename.split(".").pop()?.toLowerCase();
849
+ if (["ts", "tsx", "js", "jsx", "py", "rs", "go", "java", "c", "cpp", "h", "hpp"].includes(ext || "")) {
850
+ return "code";
851
+ }
852
+ if (["md", "markdown", "txt"].includes(ext || "")) {
853
+ return "markdown";
854
+ }
855
+ if (["json", "yaml", "yml", "toml", "xml"].includes(ext || "")) {
856
+ return "text";
857
+ }
858
+ if (["png", "jpg", "jpeg", "gif", "ico", "pdf", "zip", "tar", "gz"].includes(ext || "")) {
859
+ return "binary";
860
+ }
861
+ return "text";
862
+ }
863
+ function estimateTokens(text) {
864
+ const chineseChars = (text.match(/[\u4E00-\u9FA5]/g) || []).length;
865
+ const nonChineseChars = text.length - chineseChars;
866
+ return Math.ceil(chineseChars / 2 + nonChineseChars / 4);
867
+ }
868
+ function formatBytes(bytes) {
869
+ if (bytes === 0)
870
+ return "0 B";
871
+ const k = 1024;
872
+ const sizes = ["B", "KB", "MB", "GB"];
873
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
874
+ return `${Number.parseFloat((bytes / k ** i).toFixed(1))} ${sizes[i]}`;
875
+ }
876
+ async function handleContextCommand(args) {
877
+ const [action, ..._rest] = args;
878
+ switch (action) {
879
+ case "analyze":
880
+ await analyzeContext();
881
+ break;
882
+ case "status":
883
+ await showContextStatus();
884
+ break;
885
+ case "compress":
886
+ await compressContext();
887
+ break;
888
+ case "optimize":
889
+ await optimizeContext();
890
+ break;
891
+ default:
892
+ showContextHelp();
893
+ }
894
+ }
895
+ function showContextHelp() {
896
+ console.log(a.green.bold("\n\u{1F4DD} Context Commands\n"));
897
+ console.log(a.white(" ccjk context analyze ") + a.dim("Analyze context usage"));
898
+ console.log(a.white(" ccjk context status ") + a.dim("Show context status"));
899
+ console.log(a.white(" ccjk context compress ") + a.dim("Compress context"));
900
+ console.log(a.white(" ccjk context optimize ") + a.dim("Optimize context"));
901
+ console.log();
902
+ }
903
+
593
904
  async function contextBuild(options = {}) {
594
905
  const {
595
906
  target: _target = "claude-code",
@@ -645,6 +956,10 @@ async function contextDoctor() {
645
956
  console.log("\n\u2705 Context health check complete");
646
957
  }
647
958
  async function contextCommand(options = {}) {
959
+ if (options.action && ["analyze", "compress", "optimize", "status"].includes(options.action)) {
960
+ await handleContextCommand([options.action]);
961
+ return;
962
+ }
648
963
  if (options.action === "refresh") {
649
964
  await contextRefresh();
650
965
  return;
@@ -3,7 +3,7 @@ import { homedir } from 'node:os';
3
3
  import process__default from 'node:process';
4
4
  import a from './index2.mjs';
5
5
  import { i as inquirer } from './index3.mjs';
6
- import { s as selectMcpServices, g as getMcpServices } from '../shared/ccjk.0aJQmVxS.mjs';
6
+ import { s as selectMcpServices, g as getMcpServices } from '../shared/ccjk.miT0g_vA.mjs';
7
7
  import { SUPPORTED_LANGS, LANG_LABELS } from './constants.mjs';
8
8
  import { ensureI18nInitialized, i18n, changeLanguage } from './index5.mjs';
9
9
  import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
@@ -600,7 +600,7 @@ async function mcpManagerFeature() {
600
600
  value: "list"
601
601
  },
602
602
  {
603
- name: isZh ? `\u{1F504} \u5207\u6362\u914D\u7F6E\u9884\u8BBE ${a.gray("- minimal\uFF08\u8F7B\u91CF\uFF09/ dev\uFF08\u5F00\u53D1\uFF09/ full\uFF08\u5B8C\u6574\uFF09")}` : `\u{1F504} Switch profile ${a.gray("- minimal / dev / full preset")}`,
603
+ name: isZh ? `\u{1F504} \u5207\u6362\u914D\u7F6E\u9884\u8BBE ${a.gray("- minimal\uFF08\u8F7B\u91CF\uFF09/ development\uFF08\u5F00\u53D1\uFF09/ full\uFF08\u5B8C\u6574\uFF09")}` : `\u{1F504} Switch profile ${a.gray("- minimal / development / full preset")}`,
604
604
  value: "profile"
605
605
  },
606
606
  {
@@ -636,18 +636,19 @@ async function mcpManagerFeature() {
636
636
  }
637
637
  case "profile": {
638
638
  const { listProfiles, useProfile } = await import('./mcp.mjs');
639
- await listProfiles();
639
+ const targetTool = readZcfConfig()?.codeToolType === "codex" ? "codex" : "claude-code";
640
+ await listProfiles({ tool: targetTool });
640
641
  const { profileId } = await inquirer.prompt({
641
642
  type: "list",
642
643
  name: "profileId",
643
644
  message: isZh ? "\u9009\u62E9\u8981\u5207\u6362\u7684\u9884\u8BBE:" : "Select profile to switch:",
644
645
  choices: [
645
646
  { name: isZh ? "minimal \u2014 \u4EC5\u6838\u5FC3\u670D\u52A1\uFF08\u6700\u4F4E\u8D44\u6E90\u5360\u7528\uFF09" : "minimal \u2014 Core services only (least resources)", value: "minimal" },
646
- { name: isZh ? "dev \u2014 \u5F00\u53D1\u5E38\u7528\u670D\u52A1\u5957\u88C5" : "dev \u2014 Dev-oriented service bundle", value: "dev" },
647
+ { name: isZh ? "development \u2014 \u5F00\u53D1\u5E38\u7528\u670D\u52A1\u5957\u88C5" : "development \u2014 Dev-oriented service bundle", value: "development" },
647
648
  { name: isZh ? "full \u2014 \u5B8C\u6574\u670D\u52A1\uFF08\u9AD8\u6027\u80FD\u673A\u5668\u63A8\u8350\uFF09" : "full \u2014 Full services (high-end machines)", value: "full" }
648
649
  ]
649
650
  });
650
- await useProfile(profileId);
651
+ await useProfile(profileId, { tool: targetTool });
651
652
  break;
652
653
  }
653
654
  case "release": {
@@ -719,18 +720,18 @@ async function configureMergedPermissionsFeature() {
719
720
  }
720
721
  }
721
722
  async function configureMemoryFeature() {
722
- const { AutoMemoryBridge } = await import('./auto-memory-bridge.mjs');
723
723
  const inquirer2 = (await import('./index3.mjs').then(function (n) { return n.c; })).default;
724
724
  const ansis2 = (await import('./index2.mjs')).default;
725
725
  const { execSync } = await import('node:child_process');
726
726
  const fs = await import('node:fs/promises');
727
- const path = await import('node:path');
728
- const os = await import('node:os');
727
+ const { getCcjkMemoryPath, getClaudeMemoryPath } = await import('./memory-paths.mjs');
728
+ const { inspectMemoryFiles, syncMemoryFiles } = await import('./memory-sync.mjs');
729
+ const { memoryCheck } = await import('./memory-check.mjs');
729
730
  console.log(ansis2.cyan(`
730
731
  ${i18n.t("memory:title")}`));
731
- const bridge = new AutoMemoryBridge();
732
- const claudeMemoryPath = path.join(os.homedir(), ".claude", "projects", "-Users-lu-ccjk-public", "memory", "MEMORY.md");
733
- const ccjkMemoryPath = path.join(os.homedir(), ".ccjk", "memory", "MEMORY.md");
732
+ const projectPath = process__default.cwd();
733
+ const claudeMemoryPath = getClaudeMemoryPath(projectPath);
734
+ const ccjkMemoryPath = getCcjkMemoryPath(projectPath);
734
735
  let claudeMemoryExists = false;
735
736
  let ccjkMemoryExists = false;
736
737
  try {
@@ -755,6 +756,8 @@ ${ansis2.bold(i18n.t("memory:currentStatus"))}`);
755
756
  name: "action",
756
757
  message: i18n.t("memory:selectAction"),
757
758
  choices: [
759
+ { name: "Status", value: "status" },
760
+ { name: "Doctor", value: "doctor" },
758
761
  { name: i18n.t("memory:viewMemory"), value: "view" },
759
762
  { name: i18n.t("memory:editMemory"), value: "edit" },
760
763
  { name: i18n.t("memory:syncNow"), value: "sync" },
@@ -764,8 +767,34 @@ ${ansis2.bold(i18n.t("memory:currentStatus"))}`);
764
767
  }
765
768
  ]);
766
769
  switch (action) {
770
+ case "status": {
771
+ const inspection = inspectMemoryFiles({ projectPath });
772
+ console.log(ansis2.bold("\nMemory Status"));
773
+ console.log(ansis2.gray("\u2500".repeat(50)));
774
+ console.log(`State: ${inspection.syncState}`);
775
+ console.log(`Source: ${inspection.source}`);
776
+ console.log(`Claude: ${inspection.paths.claude}`);
777
+ console.log(`CCJK: ${inspection.paths.ccjk}`);
778
+ console.log(`Entries: ${inspection.entryCount}`);
779
+ console.log(ansis2.gray("\u2500".repeat(50)));
780
+ break;
781
+ }
782
+ case "doctor": {
783
+ const health = await memoryCheck.check();
784
+ console.log(ansis2.bold("\nMemory Doctor"));
785
+ console.log(ansis2.gray("\u2500".repeat(50)));
786
+ console.log(`${health.message} (${health.score}/100)`);
787
+ for (const detail of health.details || []) {
788
+ console.log(detail);
789
+ }
790
+ if (health.fix) {
791
+ console.log(ansis2.yellow(`Fix: ${health.fix}`));
792
+ }
793
+ console.log(ansis2.gray("\u2500".repeat(50)));
794
+ break;
795
+ }
767
796
  case "view": {
768
- const memoryPath = path.join(os.homedir(), ".claude", "projects", "-Users-lu-ccjk-public", "memory", "MEMORY.md");
797
+ const memoryPath = getClaudeMemoryPath(projectPath);
769
798
  try {
770
799
  const content = await fs.readFile(memoryPath, "utf-8");
771
800
  console.log(`
@@ -779,7 +808,7 @@ ${ansis2.bold(i18n.t("memory:memoryContent"))}`);
779
808
  break;
780
809
  }
781
810
  case "edit": {
782
- const memoryPath = path.join(os.homedir(), ".claude", "projects", "-Users-lu-ccjk-public", "memory", "MEMORY.md");
811
+ const memoryPath = getClaudeMemoryPath(projectPath);
783
812
  const editor = process__default.env.EDITOR || "nano";
784
813
  try {
785
814
  execSync(`${editor} "${memoryPath}"`, { stdio: "inherit" });
@@ -792,7 +821,7 @@ ${ansis2.bold(i18n.t("memory:memoryContent"))}`);
792
821
  case "sync": {
793
822
  console.log(ansis2.cyan(i18n.t("memory:syncing")));
794
823
  try {
795
- await bridge.syncToClaude();
824
+ syncMemoryFiles({ projectPath });
796
825
  console.log(ansis2.green(i18n.t("memory:syncComplete")));
797
826
  } catch (error) {
798
827
  console.log(ansis2.red(i18n.t("memory:syncError")));
@@ -1,4 +1,4 @@
1
- export { r as runHealthCheck } from '../shared/ccjk.Crd_nEfj.mjs';
1
+ export { r as runHealthCheck } from '../shared/ccjk.xkKNsC02.mjs';
2
2
  import 'node:fs';
3
3
  import './constants.mjs';
4
4
  import 'node:os';
@@ -6,6 +6,7 @@ import './index5.mjs';
6
6
  import 'node:process';
7
7
  import 'node:url';
8
8
  import '../shared/ccjk.bQ7Dh1g4.mjs';
9
+ import './memory-check.mjs';
9
10
  import 'node:path';
10
11
  import '../shared/ccjk.BAGoDD49.mjs';
11
12
  import 'fs';
@@ -14,3 +15,9 @@ import 'stream';
14
15
  import 'util';
15
16
  import 'assert';
16
17
  import 'path';
18
+ import './memory-paths.mjs';
19
+ import '../shared/ccjk.BBtCGd_g.mjs';
20
+ import './index6.mjs';
21
+ import './fs-operations.mjs';
22
+ import 'node:crypto';
23
+ import 'node:fs/promises';