ccjk 13.6.5 → 13.6.7

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 (49) hide show
  1. package/dist/chunks/api-config-selector.mjs +6 -4
  2. package/dist/chunks/auto-updater.mjs +100 -2
  3. package/dist/chunks/banner.mjs +0 -16
  4. package/dist/chunks/ccjk-mcp.mjs +2 -2
  5. package/dist/chunks/ccr.mjs +5 -3
  6. package/dist/chunks/check-updates.mjs +12 -1
  7. package/dist/chunks/claude-code-config-manager.mjs +3 -1
  8. package/dist/chunks/claude-code-incremental-manager.mjs +46 -20
  9. package/dist/chunks/claude-config.mjs +36 -3
  10. package/dist/chunks/claude-wrapper.mjs +1 -1
  11. package/dist/chunks/cli-hook.mjs +4 -5
  12. package/dist/chunks/codex-config-switch.mjs +3 -2
  13. package/dist/chunks/codex-provider-manager.mjs +1 -0
  14. package/dist/chunks/codex.mjs +3 -359
  15. package/dist/chunks/config-switch.mjs +23 -10
  16. package/dist/chunks/config.mjs +1 -1
  17. package/dist/chunks/config2.mjs +3 -3
  18. package/dist/chunks/constants.mjs +1 -1
  19. package/dist/chunks/doctor.mjs +1 -1
  20. package/dist/chunks/features.mjs +76 -11
  21. package/dist/chunks/index10.mjs +15 -15
  22. package/dist/chunks/init.mjs +14 -30
  23. package/dist/chunks/installer.mjs +3 -3
  24. package/dist/chunks/mcp-cli.mjs +17 -16
  25. package/dist/chunks/mcp.mjs +8 -7
  26. package/dist/chunks/memory-check.mjs +1 -1
  27. package/dist/chunks/package.mjs +1 -1
  28. package/dist/chunks/platform.mjs +1 -1
  29. package/dist/chunks/quick-setup.mjs +12 -10
  30. package/dist/chunks/research.mjs +225 -27
  31. package/dist/chunks/smart-defaults.mjs +2 -2
  32. package/dist/chunks/uninstall.mjs +1 -1
  33. package/dist/chunks/update.mjs +14 -13
  34. package/dist/chunks/version-checker.mjs +11 -1
  35. package/dist/cli.mjs +5 -1
  36. package/dist/i18n/locales/en/cli.json +0 -4
  37. package/dist/i18n/locales/en/menu.json +3 -3
  38. package/dist/i18n/locales/en/notification.json +2 -2
  39. package/dist/i18n/locales/zh-CN/cli.json +0 -4
  40. package/dist/i18n/locales/zh-CN/menu.json +3 -3
  41. package/dist/i18n/locales/zh-CN/notification.json +2 -2
  42. package/dist/shared/{ccjk.DvAP4XfP.mjs → ccjk.B4aXNclK.mjs} +2 -2
  43. package/dist/shared/ccjk.BI-hdI7P.mjs +30 -0
  44. package/dist/shared/{ccjk.C4m4ypdk.mjs → ccjk.DHaUdzX3.mjs} +4 -3
  45. package/dist/shared/ccjk.DKXs7Fbm.mjs +361 -0
  46. package/dist/shared/{ccjk.BP5hsTZQ.mjs → ccjk.Dz0ssUQx.mjs} +1 -1
  47. package/package.json +3 -1
  48. package/templates/common/workflow/essential/en/feat.md +68 -291
  49. package/templates/common/workflow/sixStep/en/workflow.md +56 -330
@@ -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": "配置切换",
@@ -189,7 +189,7 @@
189
189
  "model": "模型配置",
190
190
  "modelDesc": "选择和配置 AI 模型",
191
191
  "memory": "记忆配置",
192
- "memoryDesc": "配置对话记忆设置",
192
+ "memoryDesc": "管理项目记忆同步与 AI 回复偏好",
193
193
  "permission": "权限配置",
194
194
  "permissionDesc": "管理工具和文件权限",
195
195
  "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": "发送测试",
@@ -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.DHaUdzX3.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,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,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 { g as deepMerge, r as readMcpConfig, a as buildMcpServerConfig, w as writeMcpConfig } from '../chunks/claude-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, m as getSystemRoot } from '../chunks/platform.mjs';
10
11
 
11
12
  function readClaudeConfig(configPath = SETTINGS_FILE) {
12
13
  try {
@@ -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 };
@@ -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": "13.6.7",
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",