ccjk 13.6.5 → 14.0.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.
Files changed (57) hide show
  1. package/dist/chunks/api-cli.mjs +4 -2
  2. package/dist/chunks/api-config-selector.mjs +7 -7
  3. package/dist/chunks/auto-fix.mjs +3 -1
  4. package/dist/chunks/auto-updater.mjs +100 -2
  5. package/dist/chunks/banner.mjs +0 -16
  6. package/dist/chunks/ccjk-all.mjs +5 -2
  7. package/dist/chunks/ccjk-mcp.mjs +6 -3
  8. package/dist/chunks/ccjk-setup.mjs +4 -1
  9. package/dist/chunks/ccr.mjs +5 -5
  10. package/dist/chunks/check-updates.mjs +12 -2
  11. package/dist/chunks/claude-code-incremental-manager.mjs +45 -21
  12. package/dist/chunks/claude-wrapper.mjs +1 -1
  13. package/dist/chunks/cli-hook.mjs +4 -5
  14. package/dist/chunks/codex-config-switch.mjs +3 -3
  15. package/dist/chunks/codex-provider-manager.mjs +1 -1
  16. package/dist/chunks/codex.mjs +4 -360
  17. package/dist/chunks/config-switch.mjs +22 -11
  18. package/dist/chunks/config.mjs +1104 -5
  19. package/dist/chunks/config2.mjs +6 -4
  20. package/dist/chunks/config3.mjs +4 -2
  21. package/dist/chunks/constants.mjs +1 -1
  22. package/dist/chunks/doctor.mjs +2 -2
  23. package/dist/chunks/evolution.mjs +47 -27
  24. package/dist/chunks/features.mjs +76 -12
  25. package/dist/chunks/index10.mjs +78 -24
  26. package/dist/chunks/init.mjs +18 -35
  27. package/dist/chunks/installer.mjs +3 -3
  28. package/dist/chunks/mcp-cli.mjs +16 -16
  29. package/dist/chunks/mcp.mjs +9 -9
  30. package/dist/chunks/memory-check.mjs +1 -1
  31. package/dist/chunks/package.mjs +1 -1
  32. package/dist/chunks/platform.mjs +1 -1
  33. package/dist/chunks/quick-setup.mjs +11 -10
  34. package/dist/chunks/research.mjs +225 -27
  35. package/dist/chunks/slash-commands.mjs +1 -1
  36. package/dist/chunks/smart-defaults.mjs +2 -2
  37. package/dist/chunks/uninstall.mjs +1 -1
  38. package/dist/chunks/update.mjs +16 -16
  39. package/dist/chunks/version-checker.mjs +11 -1
  40. package/dist/cli.mjs +5 -1
  41. package/dist/i18n/locales/en/cli.json +0 -4
  42. package/dist/i18n/locales/en/menu.json +10 -3
  43. package/dist/i18n/locales/en/notification.json +2 -2
  44. package/dist/i18n/locales/zh-CN/cli.json +0 -4
  45. package/dist/i18n/locales/zh-CN/menu.json +10 -3
  46. package/dist/i18n/locales/zh-CN/notification.json +2 -2
  47. package/dist/index.mjs +3 -2
  48. package/dist/shared/{ccjk.C4m4ypdk.mjs → ccjk.B6VCKdyy.mjs} +4 -3
  49. package/dist/shared/ccjk.BI-hdI7P.mjs +30 -0
  50. package/dist/shared/{ccjk.DvAP4XfP.mjs → ccjk.CVjfbEIj.mjs} +2 -2
  51. package/dist/shared/ccjk.DKXs7Fbm.mjs +361 -0
  52. package/dist/shared/{ccjk.BP5hsTZQ.mjs → ccjk.Dh6Be-ef.mjs} +2 -2
  53. package/package.json +3 -1
  54. package/templates/common/workflow/essential/en/feat.md +68 -291
  55. package/templates/common/workflow/sixStep/en/workflow.md +56 -330
  56. package/dist/chunks/claude-code-config-manager.mjs +0 -809
  57. package/dist/chunks/claude-config.mjs +0 -253
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "title": "Notification System",
3
- "description": "Task completion notifications via Feishu, WeChat Work, Email, SMS",
3
+ "description": "Task alerts and completion notifications via cloud and local delivery channels",
4
4
 
5
5
  "status.enabled": "Enabled",
6
6
  "status.disabled": "Disabled",
@@ -126,7 +126,7 @@
126
126
  "errors.cloudError": "Cloud service error: {{error}}",
127
127
  "errors.tokenInvalid": "Device token is invalid. Please regenerate.",
128
128
 
129
- "menu.title": "📱 Notification Settings",
129
+ "menu.title": "📱 Task Alert Settings",
130
130
  "menu.configure": "Configure Notifications",
131
131
  "menu.viewStatus": "View Status",
132
132
  "menu.testNotification": "Send Test",
@@ -137,7 +137,6 @@
137
137
  "commands.ccjkSetup.args.rollbackOnError": "失败时自动回滚",
138
138
  "commands.ccjkSetup.args.lang": "显示语言",
139
139
  "commandDiscovery.title": "🧠 CCJK 命令 (ccjk 命令)",
140
- "commandDiscovery.claudeCodeTitle": "🤖 Claude Code 命令",
141
140
  "commandDiscovery.status": "大脑仪表盘",
142
141
  "commandDiscovery.health": "健康检查",
143
142
  "commandDiscovery.search": "搜索上下文",
@@ -145,8 +144,5 @@
145
144
  "commandDiscovery.tasks": "任务管理",
146
145
  "commandDiscovery.backup": "创建备份",
147
146
  "commandDiscovery.optimize": "优化数据库",
148
- "commandDiscovery.help": "显示所有命令",
149
- "commandDiscovery.clear": "清除对话",
150
- "commandDiscovery.reset": "重置会话",
151
147
  "commandDiscovery.footer": "输入 'ccjk --help' 查看完整命令列表"
152
148
  }
@@ -10,7 +10,7 @@
10
10
  "updateDesc": "更新所有组件到最新版本",
11
11
  "updateComplete": "更新完成!所有组件已是最新版本。",
12
12
  "notify": "通知中心",
13
- "notifyDesc": "查看系统通知和公告",
13
+ "notifyDesc": "配置任务提醒、通知渠道与发送方式",
14
14
  "more": "更多",
15
15
  "running": "正在执行..."
16
16
  },
@@ -91,7 +91,7 @@
91
91
  "model": "模型配置",
92
92
  "modelDesc": "选择和配置 AI 模型",
93
93
  "memory": "记忆配置",
94
- "memoryDesc": "配置对话记忆设置",
94
+ "memoryDesc": "管理项目记忆同步与 AI 回复偏好",
95
95
  "permission": "权限配置",
96
96
  "permissionDesc": "管理工具和文件权限",
97
97
  "configSwitch": "配置切换",
@@ -157,6 +157,13 @@
157
157
  "focus": "核心初始化、配置管理与工具专属操作。",
158
158
  "config": "使用当前激活工具的配置档案。",
159
159
  "menuTitle": "CCJK 控制中心"
160
+ },
161
+ "myclaude": {
162
+ "title": "myclaude 工作台",
163
+ "summary": "面向 Provider 的控制中心,启动时应明确展示当前运行态。",
164
+ "focus": "Provider 档案、路由状态、模型槽位与 Claude 家族兼容配置。",
165
+ "config": "主配置文件:~/.claude.json(运行态) + ~/.ccjk/config.toml(可复用档案)",
166
+ "menuTitle": "myclaude 控制中心"
160
167
  }
161
168
  },
162
169
  "menu": {
@@ -189,7 +196,7 @@
189
196
  "model": "模型配置",
190
197
  "modelDesc": "选择和配置 AI 模型",
191
198
  "memory": "记忆配置",
192
- "memoryDesc": "配置对话记忆设置",
199
+ "memoryDesc": "管理项目记忆同步与 AI 回复偏好",
193
200
  "permission": "权限配置",
194
201
  "permissionDesc": "管理工具和文件权限",
195
202
  "configSwitch": "配置切换",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "title": "通知系统",
3
- "description": "通过飞书、企业微信、邮件、短信接收任务完成通知",
3
+ "description": "通过云端与本地渠道接收任务提醒和完成通知",
4
4
 
5
5
  "status.enabled": "已启用",
6
6
  "status.disabled": "已禁用",
@@ -126,7 +126,7 @@
126
126
  "errors.cloudError": "云服务错误: {{error}}",
127
127
  "errors.tokenInvalid": "设备令牌无效,请重新生成。",
128
128
 
129
- "menu.title": "📱 通知设置",
129
+ "menu.title": "📱 任务提醒设置",
130
130
  "menu.configure": "配置通知",
131
131
  "menu.viewStatus": "查看状态",
132
132
  "menu.testNotification": "发送测试",
package/dist/index.mjs CHANGED
@@ -15,7 +15,7 @@ import a from './chunks/index5.mjs';
15
15
  import { g as getRuntimeVersion } from './shared/ccjk.gDEDGD_t.mjs';
16
16
  import { j as join$1 } from './shared/ccjk.bQ7Dh1g4.mjs';
17
17
  import { b as buildCommand, c as commandExists, a as escapeArgument, e as executeCommand, d as executeCommandParallel, f as executeCommandSequence, g as executeCommandStream, h as getCommandPath, i as getCommandVersion, p as parseVersion } from './shared/ccjk.BnsY5WxD.mjs';
18
- export { j as config } from './chunks/config.mjs';
18
+ export { B as config } from './chunks/config.mjs';
19
19
  export { a as loggerUtils } from './shared/ccjk.8oaxX4iR.mjs';
20
20
  export { p as platform } from './chunks/platform.mjs';
21
21
  import { Transform } from 'node:stream';
@@ -40,11 +40,12 @@ import 'fs';
40
40
  import 'child_process';
41
41
  import 'buffer';
42
42
  import 'string_decoder';
43
- import './chunks/claude-config.mjs';
44
43
  import './chunks/json-config.mjs';
45
44
  import './chunks/fs-operations.mjs';
46
45
  import 'node:fs/promises';
47
46
  import './shared/ccjk.DScm_NnL.mjs';
47
+ import './chunks/ccjk-config.mjs';
48
+ import './chunks/index3.mjs';
48
49
  import './chunks/main.mjs';
49
50
  import 'module';
50
51
 
@@ -1,12 +1,13 @@
1
1
  import a from '../chunks/index5.mjs';
2
2
  import { i as inquirer } from '../chunks/index6.mjs';
3
- import { h as getMcpService, i as dynamicMcpRegistry, r as readCodexConfig, j as applyCodexPlatformCommand, w as writeCodexConfig, M as MCP_SERVICE_CONFIGS } from '../chunks/codex.mjs';
3
+ import { a as getMcpService, d as dynamicMcpRegistry, M as MCP_SERVICE_CONFIGS } from './ccjk.DKXs7Fbm.mjs';
4
4
  import { SETTINGS_FILE, CLAUDE_DIR, ClAUDE_CONFIG_FILE, CODEX_CONFIG_FILE } from '../chunks/constants.mjs';
5
5
  import { exists, ensureDir } from '../chunks/fs-operations.mjs';
6
6
  import { readJsonConfig, writeJsonConfig } from '../chunks/json-config.mjs';
7
- import { d as deepMerge, r as readMcpConfig, b as buildMcpServerConfig, w as writeMcpConfig } from '../chunks/claude-config.mjs';
7
+ import { o as deepMerge, r as readMcpConfig, e as buildMcpServerConfig, w as writeMcpConfig } from '../chunks/config.mjs';
8
8
  import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
9
- import { k as isWindows, m as getSystemRoot } from '../chunks/platform.mjs';
9
+ import { r as readCodexConfig, g as applyCodexPlatformCommand, w as writeCodexConfig } from '../chunks/codex.mjs';
10
+ import { i as isWindows, l as getSystemRoot } from '../chunks/platform.mjs';
10
11
 
11
12
  function readClaudeConfig(configPath = SETTINGS_FILE) {
12
13
  try {
@@ -0,0 +1,30 @@
1
+ import a from '../chunks/index5.mjs';
2
+ import { i as inquirer } from '../chunks/index6.mjs';
3
+ import { g as getMcpServices, M as MCP_SERVICE_CONFIGS } from './ccjk.DKXs7Fbm.mjs';
4
+ import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
5
+
6
+ async function selectMcpServices() {
7
+ ensureI18nInitialized();
8
+ const mcpServices = await getMcpServices();
9
+ const defaultSelectedIds = new Set(
10
+ MCP_SERVICE_CONFIGS.filter((c) => c.defaultSelected).map((c) => c.id)
11
+ );
12
+ const choices = mcpServices.map((service) => ({
13
+ name: `${service.name} - ${a.gray(service.description)}`,
14
+ value: service.id,
15
+ checked: defaultSelectedIds.has(service.id)
16
+ }));
17
+ const { services } = await inquirer.prompt({
18
+ type: "checkbox",
19
+ name: "services",
20
+ message: `${i18n.t("mcp:selectMcpServices")}${i18n.t("common:multiSelectHint")}`,
21
+ choices
22
+ });
23
+ if (services === void 0) {
24
+ console.log(a.yellow(i18n.t("common:cancelled")));
25
+ return void 0;
26
+ }
27
+ return services;
28
+ }
29
+
30
+ export { selectMcpServices as s };
@@ -1,8 +1,8 @@
1
1
  import a from '../chunks/index5.mjs';
2
2
  import { i as inquirer } from '../chunks/index6.mjs';
3
- import { M as MCP_SERVICE_CONFIGS } from '../chunks/codex.mjs';
3
+ import { M as MCP_SERVICE_CONFIGS } from './ccjk.DKXs7Fbm.mjs';
4
4
  import { i18n } from '../chunks/index2.mjs';
5
- import { d as displayInstalledMcpServices, b as isMcpServiceInstalled, i as installMcpService, u as uninstallMcpService } from './ccjk.C4m4ypdk.mjs';
5
+ import { d as displayInstalledMcpServices, b as isMcpServiceInstalled, i as installMcpService, u as uninstallMcpService } from './ccjk.B6VCKdyy.mjs';
6
6
  import { existsSync, unlinkSync, statSync, mkdirSync, readFileSync } from 'node:fs';
7
7
  import { homedir } from 'node:os';
8
8
  import { writeFileAtomic } from '../chunks/fs-operations.mjs';
@@ -0,0 +1,361 @@
1
+ import { execSync } from 'node:child_process';
2
+ import process__default from 'node:process';
3
+ import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
4
+
5
+ const MCP_SERVICE_CONFIGS = [
6
+ // Documentation and research services
7
+ {
8
+ id: "context7",
9
+ requiresApiKey: false,
10
+ defaultSelected: true,
11
+ config: {
12
+ type: "stdio",
13
+ command: "npx",
14
+ args: ["-y", "@upstash/context7-mcp@latest"],
15
+ env: {}
16
+ }
17
+ },
18
+ {
19
+ id: "open-websearch",
20
+ requiresApiKey: false,
21
+ config: {
22
+ type: "stdio",
23
+ command: "npx",
24
+ args: ["-y", "open-websearch@latest"],
25
+ env: {
26
+ MODE: "stdio",
27
+ DEFAULT_SEARCH_ENGINE: "duckduckgo",
28
+ ALLOWED_SEARCH_ENGINES: "duckduckgo,bing,brave"
29
+ }
30
+ }
31
+ },
32
+ {
33
+ id: "mcp-deepwiki",
34
+ requiresApiKey: false,
35
+ config: {
36
+ type: "stdio",
37
+ command: "npx",
38
+ args: ["-y", "mcp-deepwiki@latest"],
39
+ env: {}
40
+ }
41
+ },
42
+ {
43
+ id: "spec-workflow",
44
+ requiresApiKey: false,
45
+ config: {
46
+ type: "stdio",
47
+ command: "npx",
48
+ args: ["-y", "@pimzino/spec-workflow-mcp@latest"],
49
+ env: {}
50
+ }
51
+ },
52
+ {
53
+ id: "serena",
54
+ requiresApiKey: false,
55
+ config: {
56
+ type: "stdio",
57
+ command: "uvx",
58
+ args: ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--enable-web-dashboard", "false"],
59
+ env: {}
60
+ },
61
+ platformRequirements: {
62
+ requiredCommands: ["uvx"]
63
+ }
64
+ },
65
+ {
66
+ id: "Playwright",
67
+ requiresApiKey: false,
68
+ config: {
69
+ type: "stdio",
70
+ command: "npx",
71
+ args: ["-y", "@playwright/mcp@latest", "--browser", "chromium"],
72
+ env: {}
73
+ },
74
+ platformRequirements: {
75
+ platforms: ["macos", "windows"],
76
+ requiresGui: true
77
+ }
78
+ },
79
+ {
80
+ id: "intent-engine",
81
+ requiresApiKey: false,
82
+ config: {
83
+ type: "stdio",
84
+ command: "npx",
85
+ args: ["-y", "@origintask/intent-engine@latest", "mcp"],
86
+ env: {}
87
+ }
88
+ },
89
+ {
90
+ id: "sqlite",
91
+ requiresApiKey: false,
92
+ config: {
93
+ type: "stdio",
94
+ command: "npx",
95
+ args: ["-y", "@anthropic-ai/mcp-server-sqlite@latest"],
96
+ env: {}
97
+ }
98
+ }
99
+ ];
100
+ async function getMcpServices() {
101
+ ensureI18nInitialized();
102
+ const mcpServiceList = [
103
+ {
104
+ id: "context7",
105
+ name: i18n.t("mcp:services.context7.name"),
106
+ description: i18n.t("mcp:services.context7.description")
107
+ },
108
+ {
109
+ id: "open-websearch",
110
+ name: i18n.t("mcp:services.open-websearch.name"),
111
+ description: i18n.t("mcp:services.open-websearch.description")
112
+ },
113
+ {
114
+ id: "mcp-deepwiki",
115
+ name: i18n.t("mcp:services.mcp-deepwiki.name"),
116
+ description: i18n.t("mcp:services.mcp-deepwiki.description")
117
+ },
118
+ {
119
+ id: "spec-workflow",
120
+ name: i18n.t("mcp:services.spec-workflow.name"),
121
+ description: i18n.t("mcp:services.spec-workflow.description")
122
+ },
123
+ {
124
+ id: "serena",
125
+ name: i18n.t("mcp:services.serena.name"),
126
+ description: i18n.t("mcp:services.serena.description")
127
+ },
128
+ {
129
+ id: "Playwright",
130
+ name: i18n.t("mcp:services.Playwright.name"),
131
+ description: i18n.t("mcp:services.Playwright.description")
132
+ },
133
+ {
134
+ id: "intent-engine",
135
+ name: i18n.t("mcp:services.intent-engine.name"),
136
+ description: i18n.t("mcp:services.intent-engine.description")
137
+ },
138
+ {
139
+ id: "sqlite",
140
+ name: i18n.t("mcp:services.sqlite.name"),
141
+ description: i18n.t("mcp:services.sqlite.description")
142
+ }
143
+ ];
144
+ return MCP_SERVICE_CONFIGS.map((config) => {
145
+ const serviceInfo = mcpServiceList.find((s) => s.id === config.id);
146
+ const service = {
147
+ id: config.id,
148
+ name: serviceInfo?.name || config.id,
149
+ description: serviceInfo?.description || "",
150
+ requiresApiKey: config.requiresApiKey,
151
+ config: config.config
152
+ };
153
+ if (config.apiKeyEnvVar) {
154
+ service.apiKeyEnvVar = config.apiKeyEnvVar;
155
+ }
156
+ return service;
157
+ });
158
+ }
159
+ async function getMcpService(id) {
160
+ const services = await getMcpServices();
161
+ return services.find((service) => service.id === id);
162
+ }
163
+ function detectPlatform() {
164
+ const platform = process__default.platform;
165
+ const env = process__default.env;
166
+ const isWsl = !!(env.WSL_DISTRO_NAME || env.WSLENV || env.PATH && env.PATH.includes("/mnt/c/"));
167
+ const isTermux = !!(env.TERMUX_VERSION || env.PREFIX?.includes("com.termux"));
168
+ const isHeadless = !!(env.SSH_CLIENT || env.SSH_TTY || env.SSH_CONNECTION || !env.DISPLAY && platform === "linux");
169
+ const hasGui = (() => {
170
+ if (platform === "darwin")
171
+ return true;
172
+ if (platform === "win32")
173
+ return !isHeadless;
174
+ if (isWsl || isTermux)
175
+ return false;
176
+ if (platform === "linux")
177
+ return !!env.DISPLAY || !!env.WAYLAND_DISPLAY;
178
+ return false;
179
+ })();
180
+ let detectedPlatform;
181
+ if (platform === "darwin") {
182
+ detectedPlatform = "macos";
183
+ } else if (platform === "win32") {
184
+ detectedPlatform = "windows";
185
+ } else if (isWsl) {
186
+ detectedPlatform = "wsl";
187
+ } else if (isTermux) {
188
+ detectedPlatform = "termux";
189
+ } else if (platform === "linux") {
190
+ detectedPlatform = "linux";
191
+ } else {
192
+ detectedPlatform = "unknown";
193
+ }
194
+ return {
195
+ platform: detectedPlatform,
196
+ hasGui,
197
+ isHeadless
198
+ };
199
+ }
200
+ function isCommandAvailable(command) {
201
+ try {
202
+ execSync(`which ${command}`, { stdio: "ignore" });
203
+ return true;
204
+ } catch {
205
+ return false;
206
+ }
207
+ }
208
+ function isMcpServiceCompatible(serviceId) {
209
+ const config = MCP_SERVICE_CONFIGS.find((c) => c.id === serviceId);
210
+ if (!config) {
211
+ return { compatible: false, reason: "Service not found" };
212
+ }
213
+ const requirements = config.platformRequirements;
214
+ if (!requirements) {
215
+ return { compatible: true };
216
+ }
217
+ const { platform, hasGui } = detectPlatform();
218
+ if (requirements.platforms && requirements.platforms.length > 0) {
219
+ if (platform !== "unknown" && !requirements.platforms.includes(platform)) {
220
+ return {
221
+ compatible: false,
222
+ reason: `Not supported on ${platform}. Requires: ${requirements.platforms.join(", ")}`
223
+ };
224
+ }
225
+ }
226
+ if (requirements.requiresGui && !hasGui) {
227
+ return {
228
+ compatible: false,
229
+ reason: "Requires GUI environment (X11/Wayland/Desktop)"
230
+ };
231
+ }
232
+ if (requirements.requiredCommands) {
233
+ for (const cmd of requirements.requiredCommands) {
234
+ if (!isCommandAvailable(cmd)) {
235
+ return {
236
+ compatible: false,
237
+ reason: `Required command not found: ${cmd}`
238
+ };
239
+ }
240
+ }
241
+ }
242
+ return { compatible: true };
243
+ }
244
+ async function getMcpServicesWithCompatibility() {
245
+ const allServices = await getMcpServices();
246
+ return allServices.map((service) => {
247
+ const { compatible, reason } = isMcpServiceCompatible(service.id);
248
+ return {
249
+ ...service,
250
+ compatible,
251
+ incompatibleReason: reason
252
+ };
253
+ });
254
+ }
255
+ const DEFAULT_MCP_TOOL_SEARCH_CONFIG = {
256
+ mcpAutoEnableThreshold: 10,
257
+ excludedServices: ["mcp-search", "context7"]
258
+ };
259
+ function getMcpToolSearchConfig() {
260
+ const env = process__default.env;
261
+ return {
262
+ mcpAutoEnableThreshold: env.MCP_AUTO_THRESHOLD || DEFAULT_MCP_TOOL_SEARCH_CONFIG.mcpAutoEnableThreshold,
263
+ dynamicServiceDiscovery: env.MCP_DYNAMIC_DISCOVERY !== "false",
264
+ listChangedNotifications: env.MCP_LIST_CHANGED !== "false",
265
+ excludedServices: env.MCP_EXCLUDED_SERVICES?.split(",").map((s) => s.trim()).filter(Boolean) || DEFAULT_MCP_TOOL_SEARCH_CONFIG.excludedServices
266
+ };
267
+ }
268
+ class DynamicMcpServiceRegistry {
269
+ _services = /* @__PURE__ */ new Map();
270
+ _listeners = /* @__PURE__ */ new Set();
271
+ _enabled = false;
272
+ /**
273
+ * Enable dynamic service discovery
274
+ */
275
+ enable() {
276
+ this._enabled = true;
277
+ }
278
+ /**
279
+ * Disable dynamic service discovery
280
+ */
281
+ disable() {
282
+ this._enabled = false;
283
+ }
284
+ /**
285
+ * Check if dynamic discovery is enabled
286
+ */
287
+ isEnabled() {
288
+ return this._enabled;
289
+ }
290
+ /**
291
+ * Add a service dynamically
292
+ */
293
+ addService(serviceId, config) {
294
+ if (!this._enabled) {
295
+ return false;
296
+ }
297
+ const isUpdate = this._services.has(serviceId);
298
+ this._services.set(serviceId, config);
299
+ this._notify({
300
+ type: isUpdate ? "updated" : "added",
301
+ serviceId,
302
+ timestamp: Date.now(),
303
+ config
304
+ });
305
+ return true;
306
+ }
307
+ /**
308
+ * Remove a service dynamically
309
+ */
310
+ removeService(serviceId) {
311
+ if (!this._enabled || !this._services.has(serviceId)) {
312
+ return false;
313
+ }
314
+ const config = this._services.get(serviceId);
315
+ this._services.delete(serviceId);
316
+ this._notify({
317
+ type: "removed",
318
+ serviceId,
319
+ timestamp: Date.now(),
320
+ config
321
+ });
322
+ return true;
323
+ }
324
+ /**
325
+ * Get a service configuration
326
+ */
327
+ getService(serviceId) {
328
+ return this._services.get(serviceId);
329
+ }
330
+ /**
331
+ * List all dynamically registered services
332
+ */
333
+ listServices() {
334
+ return new Map(this._services);
335
+ }
336
+ /**
337
+ * Subscribe to list change notifications
338
+ */
339
+ subscribe(listener) {
340
+ this._listeners.add(listener);
341
+ return () => this._listeners.delete(listener);
342
+ }
343
+ /**
344
+ * Notify all listeners of a change
345
+ */
346
+ _notify(notification) {
347
+ const toolSearchConfig = getMcpToolSearchConfig();
348
+ if (toolSearchConfig.listChangedNotifications) {
349
+ for (const listener of Array.from(this._listeners)) {
350
+ try {
351
+ listener(notification);
352
+ } catch (error) {
353
+ console.error("Error notifying MCP list change listener:", error);
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+ const dynamicMcpRegistry = new DynamicMcpServiceRegistry();
360
+
361
+ export { MCP_SERVICE_CONFIGS as M, getMcpService as a, getMcpServicesWithCompatibility as b, dynamicMcpRegistry as d, getMcpServices as g, isMcpServiceCompatible as i };
@@ -2,7 +2,7 @@ import a from '../chunks/index5.mjs';
2
2
  import { i as inquirer } from '../chunks/index6.mjs';
3
3
  import { CLAUDE_DIR, SETTINGS_FILE } from '../chunks/constants.mjs';
4
4
  import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
5
- import { d as getExistingApiConfig, e as configureApi, s as switchToOfficialLogin, b as backupExistingConfig, h as applyAiLanguageDirective } from '../chunks/config.mjs';
5
+ import { h as getExistingApiConfig, i as configureApi, q as switchToOfficialLogin, b as backupExistingConfig, t as applyAiLanguageDirective } from '../chunks/config.mjs';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { updateZcfConfig } from '../chunks/ccjk-config.mjs';
8
8
  import { exists, removeFile, ensureDir, copyFile } from '../chunks/fs-operations.mjs';
@@ -490,4 +490,4 @@ async function updatePromptOnly(aiOutputLang) {
490
490
  ${a.green(i18n.t("common:complete"))}`);
491
491
  }
492
492
 
493
- export { configureOutputStyle as a, configureApiCompletely as c, formatApiKeyDisplay as f, modifyApiConfigPartially as m, updatePromptOnly as u, validateApiKey as v };
493
+ export { configureApiCompletely as a, configureOutputStyle as c, formatApiKeyDisplay as f, modifyApiConfigPartially as m, updatePromptOnly as u, validateApiKey as v };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ccjk",
3
3
  "type": "module",
4
- "version": "13.6.5",
4
+ "version": "14.0.0",
5
5
  "packageManager": "pnpm@10.17.1",
6
6
  "description": "Production-ready AI dev environment for Claude Code, Codex, and modern coding workflows with 30-second onboarding, persistent memory, Agent Teams, remote control, and capability discovery.",
7
7
  "author": {
@@ -84,6 +84,7 @@
84
84
  "scripts": {
85
85
  "dev": "tsx ./src/cli.ts",
86
86
  "build": "unbuild",
87
+ "build:release:deps": "pnpm --filter @ccjk/wire build && pnpm --filter @ccjk/evolution build",
87
88
  "start": "node bin/ccjk.mjs",
88
89
  "typecheck": "tsc --noEmit",
89
90
  "release:verify": "node scripts/release-verify.mjs",
@@ -95,6 +96,7 @@
95
96
  "test:ui": "vitest --ui",
96
97
  "test:coverage": "vitest run --coverage",
97
98
  "test:run": "vitest run",
99
+ "test:release": "vitest run src/commands/menu/index.test.ts src/commands/menu/main-menu.test.ts src/utils/tool-update-scheduler.test.ts tests/commands/api-config-selector.test.ts tests/commands/init.silent.test.ts tests/commands/onboarding-wizard.test.ts tests/commands/research.test.ts tests/utils/banner.test.ts tests/utils/code-type-resolver.test.ts tests/utils/memory-feature.test.ts",
98
100
  "test:watch": "vitest watch",
99
101
  "test:e2e": "NODE_ENV=test vitest --config vitest.e2e.config.ts",
100
102
  "test:e2e:run": "NODE_ENV=test vitest run --config vitest.e2e.config.ts",