aico-cli 0.0.1 → 0.0.3

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/dist/cli.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { J as readZcfConfig, K as inquirer, N as addNumbersToChoices, O as updateZcfConfig, P as getTranslation, h as SUPPORTED_LANGS, j as LANG_LABELS, k as AI_OUTPUT_LANGUAGES, Q as version, q as backupExistingConfig, r as copyConfigFiles, x as applyAiLanguageDirective, R as configureAiPersonality, C as CLAUDE_DIR, w as getExistingApiConfig, s as configureApi, T as readJsonConfig, H as addCompletedOnboarding, S as SETTINGS_FILE, U as writeJsonConfig, o as openSettingsJson, b as importRecommendedPermissions, a as importRecommendedEnv, V as isWindows, z as readMcpConfig, G as fixWindowsMcpConfig, B as writeMcpConfig, W as selectMcpServices, D as backupMcpConfig, M as MCP_SERVICES, F as buildMcpServerConfig, E as mergeMcpServers, X as displayBanner, I as I18N, Y as selectAndInstallWorkflows, Z as handleExitPromptError, _ as handleGeneralError, $ as displayBannerWithInfo, a0 as readZcfConfigAsync, i as init, a1 as executeWithEscapeSupport, a2 as EscapeKeyPressed } from './shared/aico-cli.D4gky7Vp.mjs';
4
+ import { J as readZcfConfig, K as inquirer, N as addNumbersToChoices, O as updateZcfConfig, P as getTranslation, h as SUPPORTED_LANGS, j as LANG_LABELS, k as AI_OUTPUT_LANGUAGES, Q as version, q as backupExistingConfig, r as copyConfigFiles, x as applyAiLanguageDirective, R as configureAiPersonality, C as CLAUDE_DIR, T as readJsonConfig, H as addCompletedOnboarding, S as SETTINGS_FILE, U as writeJsonConfig, o as openSettingsJson, b as importRecommendedPermissions, a as importRecommendedEnv, V as isWindows, z as readMcpConfig, G as fixWindowsMcpConfig, B as writeMcpConfig, W as selectMcpServices, D as backupMcpConfig, M as MCP_SERVICES, F as buildMcpServerConfig, E as mergeMcpServers, X as displayBanner, I as I18N, Y as selectAndInstallWorkflows, Z as handleExitPromptError, _ as handleGeneralError, $ as displayBannerWithInfo, a0 as readZcfConfigAsync, i as init, a1 as executeWithEscapeSupport, a2 as EscapeKeyPressed } from './shared/aico-cli.BlnVF1S3.mjs';
5
5
  import inquirer$1 from 'inquirer';
6
6
  import { existsSync, copyFileSync, mkdirSync } from 'node:fs';
7
- import { exec } from 'node:child_process';
7
+ import { exec, spawn } from 'node:child_process';
8
8
  import { promisify } from 'node:util';
9
9
  import dayjs from 'dayjs';
10
10
  import { homedir } from 'node:os';
@@ -103,120 +103,6 @@ async function resolveAiOutputLanguage(scriptLang, commandLineOption, savedConfi
103
103
  return await selectAiOutputLanguage(scriptLang, scriptLang);
104
104
  }
105
105
 
106
- function validateApiKey(apiKey, lang = "zh-CN") {
107
- const i18n = getTranslation(lang);
108
- if (!apiKey || apiKey.trim() === "") {
109
- return {
110
- isValid: false,
111
- error: i18n.api.apiKeyValidation.empty
112
- };
113
- }
114
- return { isValid: true };
115
- }
116
- function formatApiKeyDisplay(apiKey) {
117
- if (!apiKey || apiKey.length < 12) {
118
- return apiKey;
119
- }
120
- return `${apiKey.substring(0, 8)}...${apiKey.substring(apiKey.length - 4)}`;
121
- }
122
-
123
- async function modifyApiConfigPartially(existingConfig, i18n, scriptLang) {
124
- let currentConfig = { ...existingConfig };
125
- const latestConfig = getExistingApiConfig();
126
- if (latestConfig) {
127
- currentConfig = latestConfig;
128
- }
129
- const { item } = await inquirer.prompt({
130
- type: "list",
131
- name: "item",
132
- message: i18n.api.selectModifyItems,
133
- choices: addNumbersToChoices([
134
- { name: i18n.api.modifyApiUrl, value: "url" },
135
- { name: i18n.api.modifyApiKey, value: "key" },
136
- { name: i18n.api.modifyAuthType, value: "authType" }
137
- ])
138
- });
139
- if (!item) {
140
- console.log(ansis.yellow(i18n.common.cancelled));
141
- return;
142
- }
143
- if (item === "url") {
144
- const { url } = await inquirer.prompt({
145
- type: "input",
146
- name: "url",
147
- message: i18n.api.enterNewApiUrl.replace("{url}", currentConfig.url || i18n.common.none),
148
- default: currentConfig.url,
149
- validate: (value) => {
150
- if (!value) return i18n.api.urlRequired;
151
- try {
152
- new URL(value);
153
- return true;
154
- } catch {
155
- return i18n.api.invalidUrl;
156
- }
157
- }
158
- });
159
- if (url === void 0) {
160
- console.log(ansis.yellow(i18n.common.cancelled));
161
- return;
162
- }
163
- currentConfig.url = url;
164
- const savedConfig = configureApi(currentConfig);
165
- if (savedConfig) {
166
- console.log(ansis.green(`\u2714 ${i18n.api.modificationSaved}`));
167
- console.log(ansis.gray(` ${i18n.api.apiConfigUrl}: ${savedConfig.url}`));
168
- }
169
- } else if (item === "key") {
170
- const authType = currentConfig.authType || "auth_token";
171
- const keyMessage = authType === "auth_token" ? i18n.api.enterNewApiKey.replace("{key}", currentConfig.key ? formatApiKeyDisplay(currentConfig.key) : i18n.common.none) : i18n.api.enterNewApiKey.replace("{key}", currentConfig.key ? formatApiKeyDisplay(currentConfig.key) : i18n.common.none);
172
- const { key } = await inquirer.prompt({
173
- type: "input",
174
- name: "key",
175
- message: keyMessage,
176
- validate: (value) => {
177
- if (!value) {
178
- return i18n.api.keyRequired;
179
- }
180
- const validation = validateApiKey(value, scriptLang);
181
- if (!validation.isValid) {
182
- return validation.error || i18n.api.invalidKeyFormat;
183
- }
184
- return true;
185
- }
186
- });
187
- if (key === void 0) {
188
- console.log(ansis.yellow(i18n.common.cancelled));
189
- return;
190
- }
191
- currentConfig.key = key;
192
- const savedConfig = configureApi(currentConfig);
193
- if (savedConfig) {
194
- console.log(ansis.green(`\u2714 ${i18n.api.modificationSaved}`));
195
- console.log(ansis.gray(` ${i18n.api.apiConfigKey}: ${formatApiKeyDisplay(savedConfig.key)}`));
196
- }
197
- } else if (item === "authType") {
198
- const { authType } = await inquirer.prompt({
199
- type: "list",
200
- name: "authType",
201
- message: i18n.api.selectNewAuthType.replace("{type}", currentConfig.authType || i18n.common.none),
202
- choices: addNumbersToChoices([
203
- { name: "Auth Token (OAuth)", value: "auth_token" },
204
- { name: "API Key", value: "api_key" }
205
- ]),
206
- default: currentConfig.authType === "api_key" ? 1 : 0
207
- });
208
- if (authType === void 0) {
209
- console.log(ansis.yellow(i18n.common.cancelled));
210
- return;
211
- }
212
- currentConfig.authType = authType;
213
- const savedConfig = configureApi(currentConfig);
214
- if (savedConfig) {
215
- console.log(ansis.green(`\u2714 ${i18n.api.modificationSaved}`));
216
- console.log(ansis.gray(` ${i18n.api.apiConfigAuthType}: ${savedConfig.authType}`));
217
- }
218
- }
219
- }
220
106
  async function updatePromptOnly(configLang, scriptLang, aiOutputLang) {
221
107
  const i18n = getTranslation(scriptLang);
222
108
  const backupDir = backupExistingConfig();
@@ -688,142 +574,6 @@ function handleCancellation(scriptLang) {
688
574
  const i18n = getTranslation(scriptLang);
689
575
  console.log(ansis.yellow(i18n.common.cancelled));
690
576
  }
691
- async function configureApiFeature(scriptLang) {
692
- const i18n = getTranslation(scriptLang);
693
- const existingApiConfig = getExistingApiConfig();
694
- if (existingApiConfig) {
695
- console.log("\n" + ansis.blue(`\u2139 ${i18n.api.existingApiConfig}`));
696
- console.log(ansis.gray(` ${i18n.api.apiConfigUrl}: ${existingApiConfig.url || i18n.common.notConfigured}`));
697
- console.log(ansis.gray(` ${i18n.api.apiConfigKey}: ${existingApiConfig.key ? formatApiKeyDisplay(existingApiConfig.key) : i18n.common.notConfigured}`));
698
- console.log(ansis.gray(` ${i18n.api.apiConfigAuthType}: ${existingApiConfig.authType || i18n.common.notConfigured}
699
- `));
700
- const { action } = await inquirer.prompt({
701
- type: "list",
702
- name: "action",
703
- message: i18n.api.selectApiAction,
704
- choices: addNumbersToChoices([
705
- { name: i18n.api.keepExistingConfig, value: "keep" },
706
- { name: i18n.api.modifyAllConfig, value: "modify-all" },
707
- { name: i18n.api.modifyPartialConfig, value: "modify-partial" },
708
- { name: i18n.api.useCcrProxy, value: "use-ccr" }
709
- ])
710
- });
711
- if (!action) {
712
- handleCancellation(scriptLang);
713
- return;
714
- }
715
- if (action === "keep") {
716
- console.log(ansis.green(`\u2714 ${i18n.api.keepExistingConfig}`));
717
- try {
718
- addCompletedOnboarding();
719
- } catch (error) {
720
- console.error(ansis.red(i18n.configuration.failedToSetOnboarding), error);
721
- }
722
- return;
723
- } else if (action === "modify-partial") {
724
- await modifyApiConfigPartially(existingApiConfig, i18n, scriptLang);
725
- return;
726
- } else if (action === "use-ccr") {
727
- const ccrInstalled = await isCcrInstalled();
728
- if (!ccrInstalled) {
729
- console.log(ansis.yellow(`${i18n.ccr.installingCcr}`));
730
- await installCcr(scriptLang);
731
- } else {
732
- console.log(ansis.green(`\u2714 ${i18n.ccr.ccrAlreadyInstalled}`));
733
- }
734
- const ccrConfigured = await setupCcrConfiguration(scriptLang);
735
- if (ccrConfigured) {
736
- console.log(ansis.green(`\u2714 ${i18n.ccr.ccrSetupComplete}`));
737
- }
738
- return;
739
- }
740
- }
741
- const { apiChoice } = await inquirer.prompt({
742
- type: "list",
743
- name: "apiChoice",
744
- message: i18n.api.configureApi,
745
- choices: addNumbersToChoices([
746
- {
747
- name: `${i18n.api.useAuthToken} - ${ansis.gray(i18n.api.authTokenDesc)}`,
748
- value: "auth_token",
749
- short: i18n.api.useAuthToken
750
- },
751
- {
752
- name: `${i18n.api.useApiKey} - ${ansis.gray(i18n.api.apiKeyDesc)}`,
753
- value: "api_key",
754
- short: i18n.api.useApiKey
755
- },
756
- {
757
- name: `${i18n.api.useCcrProxy} - ${ansis.gray(i18n.api.ccrProxyDesc)}`,
758
- value: "ccr_proxy",
759
- short: i18n.api.useCcrProxy
760
- },
761
- { name: i18n.api.skipApi, value: "skip" }
762
- ])
763
- });
764
- if (!apiChoice || apiChoice === "skip") {
765
- return;
766
- }
767
- if (apiChoice === "ccr_proxy") {
768
- const ccrInstalled = await isCcrInstalled();
769
- if (!ccrInstalled) {
770
- console.log(ansis.yellow(`${i18n.ccr.installingCcr}`));
771
- await installCcr(scriptLang);
772
- } else {
773
- console.log(ansis.green(`\u2714 ${i18n.ccr.ccrAlreadyInstalled}`));
774
- }
775
- const ccrConfigured = await setupCcrConfiguration(scriptLang);
776
- if (ccrConfigured) {
777
- console.log(ansis.green(`\u2714 ${i18n.ccr.ccrSetupComplete}`));
778
- }
779
- return;
780
- }
781
- const { url } = await inquirer.prompt({
782
- type: "input",
783
- name: "url",
784
- message: i18n.api.enterApiUrl,
785
- validate: (value) => {
786
- if (!value) return i18n.api.urlRequired;
787
- try {
788
- new URL(value);
789
- return true;
790
- } catch {
791
- return i18n.api.invalidUrl;
792
- }
793
- }
794
- });
795
- if (!url) {
796
- handleCancellation(scriptLang);
797
- return;
798
- }
799
- const keyMessage = apiChoice === "auth_token" ? i18n.api.enterAuthToken : i18n.api.enterApiKey;
800
- const { key } = await inquirer.prompt({
801
- type: "input",
802
- name: "key",
803
- message: keyMessage,
804
- validate: (value) => {
805
- if (!value) {
806
- return i18n.api.keyRequired;
807
- }
808
- const validation = validateApiKey(value, scriptLang);
809
- if (!validation.isValid) {
810
- return validation.error || i18n.api.invalidKeyFormat;
811
- }
812
- return true;
813
- }
814
- });
815
- if (!key) {
816
- handleCancellation(scriptLang);
817
- return;
818
- }
819
- const apiConfig = { url, key, authType: apiChoice };
820
- const configuredApi = configureApi(apiConfig);
821
- if (configuredApi) {
822
- console.log(ansis.green(`\u2714 ${i18n.api.apiConfigSuccess}`));
823
- console.log(ansis.gray(` URL: ${configuredApi.url}`));
824
- console.log(ansis.gray(` Key: ${formatApiKeyDisplay(configuredApi.key)}`));
825
- }
826
- }
827
577
  async function configureMcpFeature(scriptLang) {
828
578
  const i18n = getTranslation(scriptLang);
829
579
  if (isWindows()) {
@@ -951,6 +701,40 @@ async function configureEnvPermissionFeature(scriptLang) {
951
701
  }
952
702
  }
953
703
 
704
+ async function startClaudeCodeEditor(_lang) {
705
+ try {
706
+ console.log(ansis.cyan("\u{1F680} \u6B63\u5728\u542F\u52A8\u4EE3\u7801\u7F16\u8F91\u5668..."));
707
+ const child = spawn("claude", ["--dangerously-skip-permissions"], {
708
+ stdio: "inherit",
709
+ // 继承父进程的 stdio,这样可以在当前终端中交互
710
+ cwd: process.cwd()
711
+ // 使用当前工作目录
712
+ });
713
+ await new Promise((resolve, reject) => {
714
+ child.on("close", (code) => {
715
+ if (code === 0) {
716
+ console.log(ansis.green("\u2705 \u4EE3\u7801\u7F16\u8F91\u5668\u5DF2\u9000\u51FA"));
717
+ resolve();
718
+ } else {
719
+ reject(new Error(`Claude \u8FDB\u7A0B\u9000\u51FA\uFF0C\u9000\u51FA\u7801: ${code}`));
720
+ }
721
+ });
722
+ child.on("error", (error) => {
723
+ reject(error);
724
+ });
725
+ });
726
+ } catch (error) {
727
+ console.error(ansis.red("\u274C \u542F\u52A8\u4EE3\u7801\u7F16\u8F91\u5668\u5931\u8D25:"));
728
+ if (error.code === "ENOENT" || error.message?.includes("command not found")) {
729
+ console.error(ansis.yellow("\u{1F4A1} \u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 Claude Code:"));
730
+ console.error(ansis.gray(" npm install -g @anthropic-ai/claude-code"));
731
+ } else {
732
+ console.error(ansis.gray(` \u9519\u8BEF\u4FE1\u606F: ${error.message || error}`));
733
+ }
734
+ throw error;
735
+ }
736
+ }
737
+
954
738
  async function update(options = {}) {
955
739
  try {
956
740
  if (!options.skipBanner) {
@@ -962,7 +746,7 @@ async function update(options = {}) {
962
746
  const configLang = options.configLang || "zh-CN";
963
747
  const aiOutputLang = await resolveAiOutputLanguage(scriptLang, options.aiOutputLang, zcfConfig);
964
748
  console.log(ansis.cyan(`
965
- ${i18n.workflow.updatingPrompts}
749
+ ${i18n.configuration.updatingPrompts}
966
750
  `));
967
751
  await updatePromptOnly(configLang, scriptLang, aiOutputLang);
968
752
  await selectAndInstallWorkflows(configLang, scriptLang);
@@ -1010,14 +794,14 @@ async function showMainMenu() {
1010
794
  },
1011
795
  "5": {
1012
796
  key: "5",
1013
- labelKey: "configureApi",
1014
- processor: () => configureApiFeature(scriptLang),
797
+ labelKey: "configureEnvPermission",
798
+ processor: () => configureEnvPermissionFeature(scriptLang),
1015
799
  section: "\u57FA\u7840\u914D\u7F6E"
1016
800
  },
1017
801
  "6": {
1018
802
  key: "6",
1019
- labelKey: "configureEnvPermission",
1020
- processor: () => configureEnvPermissionFeature(scriptLang),
803
+ labelKey: "startCodeEditor",
804
+ processor: () => startClaudeCodeEditor(scriptLang),
1021
805
  section: "\u57FA\u7840\u914D\u7F6E"
1022
806
  }
1023
807
  };
@@ -1067,7 +851,16 @@ async function showMainMenu() {
1067
851
  } catch (error) {
1068
852
  }
1069
853
  }
1070
- await handleMenuContinuation(choice, i18n);
854
+ try {
855
+ await handleMenuContinuation(choice, i18n);
856
+ } catch (continuationError) {
857
+ if (continuationError.message === "EXIT_MENU") {
858
+ console.log(ansis.cyan(i18n.common.goodbye));
859
+ exitMenu = true;
860
+ break;
861
+ }
862
+ throw continuationError;
863
+ }
1071
864
  }
1072
865
  }
1073
866
  }
@@ -1090,8 +883,7 @@ async function handleMenuContinuation(choice, i18n) {
1090
883
  default: true
1091
884
  });
1092
885
  if (!shouldContinue) {
1093
- console.log(ansis.cyan(i18n.common.goodbye));
1094
- process.exit(0);
886
+ throw new Error("EXIT_MENU");
1095
887
  }
1096
888
  } catch (error) {
1097
889
  if (error instanceof EscapeKeyPressed) {
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AICO_CONFIG_FILE, k as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, H as addCompletedOnboarding, x as applyAiLanguageDirective, q as backupExistingConfig, D as backupMcpConfig, F as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, s as configureApi, r as copyConfigFiles, p as ensureClaudeDir, G as fixWindowsMcpConfig, w as getExistingApiConfig, y as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, n as installClaudeCode, l as isClaudeCodeInstalled, m as mergeAndCleanPermissions, t as mergeConfigs, E as mergeMcpServers, v as mergeSettingsFile, o as openSettingsJson, z as readMcpConfig, u as updateDefaultModel, B as writeMcpConfig } from './shared/aico-cli.D4gky7Vp.mjs';
1
+ export { A as AICO_CONFIG_FILE, k as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, e as CLAUDE_MD_FILE, f as ClAUDE_CONFIG_FILE, I as I18N, j as LANG_LABELS, L as LEGACY_AICO_CONFIG_FILE, M as MCP_SERVICES, S as SETTINGS_FILE, h as SUPPORTED_LANGS, H as addCompletedOnboarding, x as applyAiLanguageDirective, q as backupExistingConfig, D as backupMcpConfig, F as buildMcpServerConfig, d as cleanupPermissions, c as commandExists, s as configureApi, r as copyConfigFiles, p as ensureClaudeDir, G as fixWindowsMcpConfig, w as getExistingApiConfig, y as getMcpConfigPath, g as getPlatform, a as importRecommendedEnv, b as importRecommendedPermissions, i as init, n as installClaudeCode, l as isClaudeCodeInstalled, m as mergeAndCleanPermissions, t as mergeConfigs, E as mergeMcpServers, v as mergeSettingsFile, o as openSettingsJson, z as readMcpConfig, u as updateDefaultModel, B as writeMcpConfig } from './shared/aico-cli.BlnVF1S3.mjs';
2
2
  import 'inquirer';
3
3
  import 'ansis';
4
4
  import 'node:fs';
@@ -65,6 +65,11 @@ ${i18n.common.returnToPrevious || "\u8FD4\u56DE\u4E0A\u4E00\u6B65"}`)
65
65
  );
66
66
  return false;
67
67
  }
68
+ if (error.name === "ExitPromptError" || error.isTtyError || error.message?.includes("User force closed")) {
69
+ console.log(ansis.yellow(`
70
+ ${i18n.common.cancelled || "\u64CD\u4F5C\u5DF2\u53D6\u6D88"}`));
71
+ return false;
72
+ }
68
73
  throw error;
69
74
  }
70
75
  }
@@ -75,7 +80,7 @@ const inquirer = {
75
80
  createPromptModule: inquirer$1.createPromptModule
76
81
  };
77
82
 
78
- const version = "0.0.1";
83
+ const version = "0.0.3";
79
84
 
80
85
  const common$1 = {
81
86
  // Basic
@@ -259,6 +264,7 @@ const menu$1 = {
259
264
  configureModel: "\u914D\u7F6E\u9ED8\u8BA4\u6A21\u578B",
260
265
  configureAiMemory: "\u914D\u7F6E Claude \u5168\u5C40\u8BB0\u5FC6",
261
266
  configureEnvPermission: "\u5BFC\u5165\u63A8\u8350\u73AF\u5883\u53D8\u91CF\u548C\u6743\u9650\u914D\u7F6E",
267
+ startCodeEditor: "\u542F\u52A8\u4EE3\u7801\u7F16\u8F91",
262
268
  configureCcr: "\u914D\u7F6E\u6A21\u578B\u4EE3\u7406 (CCR)",
263
269
  ccrManagement: "CCR",
264
270
  ccusage: "ccusage",
@@ -276,6 +282,7 @@ const menu$1 = {
276
282
  configureModel: "\u8BBE\u7F6E\u9ED8\u8BA4\u6A21\u578B\uFF08opus/sonnet\uFF09",
277
283
  configureAiMemory: "\u914D\u7F6E AI \u8F93\u51FA\u8BED\u8A00\u548C\u89D2\u8272\u98CE\u683C",
278
284
  configureEnvPermission: "\u5BFC\u5165\u9690\u79C1\u4FDD\u62A4\u73AF\u5883\u53D8\u91CF\u548C\u7CFB\u7EDF\u6743\u9650\u914D\u7F6E",
285
+ startCodeEditor: "\u542F\u52A8\u4EE3\u7801\u7F16\u8F91\u5668\u8FDB\u884C\u4EE3\u7801\u5F00\u53D1",
279
286
  configureCcr: "\u914D\u7F6E Claude Code Router \u4EE5\u4F7F\u7528\u591A\u4E2A AI \u6A21\u578B",
280
287
  ccrManagement: "\u914D\u7F6E Claude Code Router \u4EE5\u4F7F\u7528\u591A\u4E2A AI \u6A21\u578B",
281
288
  ccusage: "Claude Code \u7528\u91CF\u5206\u6790",
@@ -290,7 +297,11 @@ const workflow$1 = {
290
297
  workflowOption: {
291
298
  featPlanUx: "\u529F\u80FD\u89C4\u5212\u548C UX \u8BBE\u8BA1 (feat + planner + ui-ux-designer)",
292
299
  sixStepsWorkflow: "\u516D\u6B65\u5DE5\u4F5C\u6D41 (workflow)",
293
- bmadWorkflow: "BMAD-Method \u6269\u5C55\u5B89\u88C5\u5668 (\u652F\u6301\u654F\u6377\u5F00\u53D1\u5DE5\u4F5C\u6D41)"
300
+ bmadWorkflow: "BMAD-Method \u6269\u5C55\u5B89\u88C5\u5668 (\u652F\u6301\u654F\u6377\u5F00\u53D1\u5DE5\u4F5C\u6D41)",
301
+ gitWorkflow: "\u667A\u80FD Git \u64CD\u4F5C (Git \u63D0\u4EA4\u3001\u56DE\u6EDA\u3001\u6E05\u7406\u5206\u652F)"
302
+ },
303
+ workflowDescription: {
304
+ gitWorkflow: "\u589E\u5F3A\u7248 Git \u547D\u4EE4\uFF0C\u652F\u6301\u667A\u80FD\u63D0\u4EA4\u3001\u5B89\u5168\u56DE\u6EDA\u548C\u81EA\u52A8\u5316\u5206\u652F\u6E05\u7406"
294
305
  },
295
306
  // BMAD workflow
296
307
  bmadInitPrompt: "\u2728 \u8BF7\u5728\u9879\u76EE\u4E2D\u8FD0\u884C /bmad-init \u547D\u4EE4\u6765\u521D\u59CB\u5316\u6216\u66F4\u65B0 BMAD-Method \u6269\u5C55",
@@ -304,7 +315,8 @@ const workflow$1 = {
304
315
  workflowInstallSuccess: "\u5DE5\u4F5C\u6D41\u5B89\u88C5\u6210\u529F",
305
316
  workflowInstallError: "\u5DE5\u4F5C\u6D41\u5B89\u88C5\u51FA\u9519",
306
317
  cleaningOldFiles: "\u6E05\u7406\u65E7\u7248\u672C\u6587\u4EF6",
307
- removedOldFile: "\u5DF2\u5220\u9664\u65E7\u6587\u4EF6"
318
+ removedOldFile: "\u5DF2\u5220\u9664\u65E7\u6587\u4EF6",
319
+ failedToRemoveFile: "\u5220\u9664\u6587\u4EF6\u5931\u8D25"
308
320
  };
309
321
 
310
322
  const cli$1 = {
@@ -691,6 +703,7 @@ const menu = {
691
703
  configureModel: "Configure default model",
692
704
  configureAiMemory: "Configure Claude global memory",
693
705
  configureEnvPermission: "Import recommended environment variables and permissions",
706
+ startCodeEditor: "Start Code Editor",
694
707
  configureCcr: "Configure Model Proxy (CCR)",
695
708
  ccrManagement: "CCR",
696
709
  ccusage: "ccusage",
@@ -708,6 +721,7 @@ const menu = {
708
721
  configureModel: "Set default model (opus/sonnet)",
709
722
  configureAiMemory: "Configure AI output language and personality",
710
723
  configureEnvPermission: "Import privacy protection environment variables and system permissions",
724
+ startCodeEditor: "Start Claude code editor (skip permission checks)",
711
725
  configureCcr: "Configure Claude Code Router to use multiple AI models",
712
726
  ccrManagement: "Configure Claude Code Router to use multiple AI models",
713
727
  ccusage: "Claude Code usage analysis",
@@ -722,7 +736,11 @@ const workflow = {
722
736
  workflowOption: {
723
737
  featPlanUx: "Feature Planning and UX Design (feat + planner + ui-ux-designer)",
724
738
  sixStepsWorkflow: "Six Steps Workflow (workflow)",
725
- bmadWorkflow: "BMAD-Method Extension Installer (Agile Development Workflow)"
739
+ bmadWorkflow: "BMAD-Method Extension Installer (Agile Development Workflow)",
740
+ gitWorkflow: "Smart Git Operations (Git Commit, Rollback, Clean Branches)"
741
+ },
742
+ workflowDescription: {
743
+ gitWorkflow: "Enhanced Git commands for smart commits, safe rollbacks, and automated branch cleanup"
726
744
  },
727
745
  // BMAD workflow
728
746
  bmadInitPrompt: "\u2728 Please run /bmad-init command in your project to initialize or update BMAD-Method extension",
@@ -736,7 +754,8 @@ const workflow = {
736
754
  workflowInstallSuccess: "workflow installed successfully",
737
755
  workflowInstallError: "workflow installation had errors",
738
756
  cleaningOldFiles: "Cleaning up old version files",
739
- removedOldFile: "Removed old file"
757
+ removedOldFile: "Removed old file",
758
+ failedToRemoveFile: "Failed to remove"
740
759
  };
741
760
 
742
761
  const cli = {
@@ -1255,7 +1274,7 @@ function updateZcfConfig(updates) {
1255
1274
  const AI_PERSONALITIES = [
1256
1275
  {
1257
1276
  id: "professional",
1258
- name: { "zh-CN": "\u4E13\u4E1A\u52A9\u624B(\u9ED8\u8BA4)", en: "Professional Assistant(Default)" },
1277
+ name: { "zh-CN": "\u4E13\u4E1A\u7A0B\u5E8F\u5458\u6A21\u5F0F", en: "Professional Assistant(Default)" },
1259
1278
  directive: {
1260
1279
  "zh-CN": "\u4F60\u662F\u4E00\u540D\u7ECF\u9A8C\u4E30\u5BCC\u7684[\u4E13\u4E1A\u9886\u57DF\uFF0C\u4F8B\u5982\uFF1A\u8F6F\u4EF6\u5F00\u53D1\u5DE5\u7A0B\u5E08 / \u7CFB\u7EDF\u8BBE\u8BA1\u5E08 / \u4EE3\u7801\u67B6\u6784\u5E08]\uFF0C\u4E13\u6CE8\u4E8E\u6784\u5EFA[\u6838\u5FC3\u7279\u957F\uFF0C\u4F8B\u5982\uFF1A\u9AD8\u6027\u80FD / \u53EF\u7EF4\u62A4 / \u5065\u58EE / \u9886\u57DF\u9A71\u52A8]\u7684\u89E3\u51B3\u65B9\u6848\u3002",
1261
1280
  en: "You are an experienced [professional domain, e.g., Software Development Engineer / System Designer / Code Architect], specializing in building [core strengths, e.g., high-performance / maintainable / robust / domain-driven] solutions."
@@ -1263,7 +1282,7 @@ const AI_PERSONALITIES = [
1263
1282
  },
1264
1283
  {
1265
1284
  id: "friendly",
1266
- name: { "zh-CN": "\u53CB\u597D\u52A9\u624B", en: "Friendly Assistant" },
1285
+ name: { "zh-CN": "\u7ED3\u4F34\u7F16\u7A0B\u6A21\u5F0F", en: "Friendly Assistant" },
1267
1286
  directive: {
1268
1287
  "zh-CN": "\u4F60\u662F\u4E00\u4F4D\u53CB\u597D\u3001\u8010\u5FC3\u3001\u5584\u4E8E\u89E3\u91CA\u7684\u7F16\u7A0B\u52A9\u624B\u3002\u4F1A\u7528\u901A\u4FD7\u6613\u61C2\u7684\u65B9\u5F0F\u89E3\u91CA\u590D\u6742\u6982\u5FF5\uFF0C\u5E76\u7ECF\u5E38\u7ED9\u4E88\u9F13\u52B1\u3002",
1269
1288
  en: "You are a friendly, patient, and explanatory programming assistant. You explain complex concepts in easy-to-understand ways and often provide encouragement."
@@ -1271,16 +1290,11 @@ const AI_PERSONALITIES = [
1271
1290
  },
1272
1291
  {
1273
1292
  id: "mentor",
1274
- name: { "zh-CN": "\u5BFC\u5E08\u6A21\u5F0F", en: "Mentor Mode" },
1293
+ name: { "zh-CN": "\u7A0B\u5E8F\u5458\u5927\u725B\u6307\u5BFC\u6A21\u5F0F", en: "Mentor Mode" },
1275
1294
  directive: {
1276
1295
  "zh-CN": "\u4F60\u662F\u4E00\u4F4D\u7ECF\u9A8C\u4E30\u5BCC\u7684\u7F16\u7A0B\u5BFC\u5E08\u3002\u4E0D\u4EC5\u63D0\u4F9B\u89E3\u51B3\u65B9\u6848\uFF0C\u8FD8\u4F1A\u89E3\u91CA\u80CC\u540E\u7684\u539F\u7406\uFF0C\u5F15\u5BFC\u7528\u6237\u601D\u8003\uFF0C\u57F9\u517B\u72EC\u7ACB\u89E3\u51B3\u95EE\u9898\u7684\u80FD\u529B\u3002",
1277
1296
  en: "You are an experienced programming mentor. You not only provide solutions but also explain the principles behind them, guide users to think, and cultivate their ability to solve problems independently."
1278
1297
  }
1279
- },
1280
- {
1281
- id: "custom",
1282
- name: { "zh-CN": "\u81EA\u5B9A\u4E49", en: "Custom" },
1283
- directive: { "zh-CN": "", en: "" }
1284
1298
  }
1285
1299
  ];
1286
1300
  function getExistingPersonality() {
@@ -1296,9 +1310,15 @@ async function configureAiPersonality(scriptLang, showExisting = true) {
1296
1310
  if (showExisting && existingPersonality) {
1297
1311
  const personalityInfo = getPersonalityInfo(existingPersonality);
1298
1312
  if (personalityInfo) {
1299
- console.log("\n" + ansis.blue(`\u2139 ${i18n.configuration.existingPersonality || "Existing AI personality configuration"}`));
1300
1313
  console.log(
1301
- ansis.gray(` ${i18n.configuration.currentPersonality || "Current personality"}: ${personalityInfo.name[scriptLang]}`)
1314
+ "\n" + ansis.blue(
1315
+ `\u2139 ${i18n.configuration.existingPersonality || "Existing AI personality configuration"}`
1316
+ )
1317
+ );
1318
+ console.log(
1319
+ ansis.gray(
1320
+ ` ${i18n.configuration.currentPersonality || "Current personality"}: ${personalityInfo.name[scriptLang]}`
1321
+ )
1302
1322
  );
1303
1323
  const { modify } = await inquirer.prompt({
1304
1324
  type: "confirm",
@@ -1307,7 +1327,11 @@ async function configureAiPersonality(scriptLang, showExisting = true) {
1307
1327
  default: false
1308
1328
  });
1309
1329
  if (!modify) {
1310
- console.log(ansis.green(`\u2714 ${i18n.configuration.keepPersonality || "Keeping existing personality"}`));
1330
+ console.log(
1331
+ ansis.green(
1332
+ `\u2714 ${i18n.configuration.keepPersonality || "Keeping existing personality"}`
1333
+ )
1334
+ );
1311
1335
  return;
1312
1336
  }
1313
1337
  }
@@ -1316,11 +1340,17 @@ async function configureAiPersonality(scriptLang, showExisting = true) {
1316
1340
  type: "list",
1317
1341
  name: "personality",
1318
1342
  message: i18n.configuration.selectAiPersonality || "Select AI personality",
1319
- choices: addNumbersToChoices(AI_PERSONALITIES.map((p) => ({
1320
- name: p.id !== "custom" ? `${p.name[scriptLang]} - ${ansis.gray(p.directive[scriptLang].substring(0, 50) + "...")}` : `${p.name[scriptLang]} - ${ansis.gray(i18n.configuration.customPersonalityHint || "Define your own personality")}`,
1321
- value: p.id,
1322
- short: p.name[scriptLang]
1323
- }))),
1343
+ choices: addNumbersToChoices(
1344
+ AI_PERSONALITIES.map((p) => ({
1345
+ name: p.id !== "custom" ? `${p.name[scriptLang]} - ${ansis.gray(
1346
+ p.directive[scriptLang].substring(0, 50) + "..."
1347
+ )}` : `${p.name[scriptLang]} - ${ansis.gray(
1348
+ i18n.configuration.customPersonalityHint || "Define your own personality"
1349
+ )}`,
1350
+ value: p.id,
1351
+ short: p.name[scriptLang]
1352
+ }))
1353
+ ),
1324
1354
  default: existingPersonality ? AI_PERSONALITIES.findIndex((p) => p.id === existingPersonality) : 0
1325
1355
  });
1326
1356
  if (!personality) {
@@ -1348,7 +1378,11 @@ async function configureAiPersonality(scriptLang, showExisting = true) {
1348
1378
  }
1349
1379
  await applyPersonalityDirective(directive);
1350
1380
  updateZcfConfig({ aiPersonality: personality });
1351
- console.log(ansis.green(`\u2714 ${i18n.configuration.personalityConfigured || "AI personality configured"}`));
1381
+ console.log(
1382
+ ansis.green(
1383
+ `\u2714 ${i18n.configuration.personalityConfigured || "AI personality configured"}`
1384
+ )
1385
+ );
1352
1386
  }
1353
1387
  async function applyPersonalityDirective(directive) {
1354
1388
  try {
@@ -1357,7 +1391,12 @@ async function applyPersonalityDirective(directive) {
1357
1391
  } catch (error) {
1358
1392
  const lang = readZcfConfig()?.preferredLang || "en";
1359
1393
  const errorI18n = getTranslation(lang);
1360
- console.error(ansis.red(errorI18n.configuration.failedToApplyPersonality || "Failed to apply personality"), error);
1394
+ console.error(
1395
+ ansis.red(
1396
+ errorI18n.configuration.failedToApplyPersonality || "Failed to apply personality"
1397
+ ),
1398
+ error
1399
+ );
1361
1400
  }
1362
1401
  }
1363
1402
 
@@ -1367,19 +1406,19 @@ function displayBanner(subtitle) {
1367
1406
  const paddedSubtitle = subtitleText.padEnd(60, " ");
1368
1407
  console.log(
1369
1408
  ansis.cyan.bold(`
1370
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1371
- \u2551 \u2551
1372
- \u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551
1373
- \u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2551
1374
- \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2551
1375
- \u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2551
1376
- \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2551
1377
- \u2551 \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u2551
1378
- \u2551 \u2551
1379
- \u2551 ${ansis.white.bold("\u667A\u80FD\u8F6F\u4EF6\u661F\u5DE5\u5382")} \u2551
1380
- \u2551 ${ansis.gray(paddedSubtitle)}\u2551
1381
- \u2551 \u2551
1382
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1409
+
1410
+
1411
+ \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557
1412
+ \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557
1413
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
1414
+ \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
1415
+ \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
1416
+ \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D
1417
+
1418
+ ${ansis.white.bold("\u667A\u80FD\u8F6F\u4EF6\u661F\u5DE5\u5382")}
1419
+ ${ansis.gray(paddedSubtitle)}
1420
+
1421
+
1383
1422
  `)
1384
1423
  );
1385
1424
  }
@@ -1393,10 +1432,10 @@ function handleExitPromptError(error) {
1393
1432
  const zcfConfig = readZcfConfig();
1394
1433
  const defaultLang = zcfConfig?.preferredLang || "zh-CN";
1395
1434
  const i18n = getTranslation(defaultLang);
1396
- console.log(ansis.cyan(`
1397
- ${i18n.common.goodbye}
1435
+ console.log(ansis.yellow(`
1436
+ ${i18n.common.cancelled || "\u64CD\u4F5C\u5DF2\u53D6\u6D88"}
1398
1437
  `));
1399
- process.exit(0);
1438
+ return true;
1400
1439
  }
1401
1440
  if (error instanceof EscapeKeyPressed) {
1402
1441
  return true;
@@ -1929,6 +1968,18 @@ const WORKFLOW_CONFIGS = [
1929
1968
  autoInstallAgents: false,
1930
1969
  category: "bmad",
1931
1970
  outputDir: "bmad"
1971
+ },
1972
+ {
1973
+ id: "gitWorkflow",
1974
+ nameKey: "workflowOption.gitWorkflow",
1975
+ descriptionKey: "workflowDescription.gitWorkflow",
1976
+ defaultSelected: true,
1977
+ order: 4,
1978
+ commands: ["git-commit.md", "git-rollback.md", "git-cleanBranches.md"],
1979
+ agents: [],
1980
+ autoInstallAgents: false,
1981
+ category: "git",
1982
+ outputDir: "git"
1932
1983
  }
1933
1984
  ];
1934
1985
  function getWorkflowConfig(workflowId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aico-cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "packageManager": "pnpm@9.15.9",
5
5
  "description": "AI CLI",
6
6
  "repository": {