zcf 2.1.1 → 2.2.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.
- package/dist/cli.mjs +3 -27
- package/dist/index.mjs +1 -1
- package/dist/shared/{zcf.ccfEwLWL.mjs → zcf.BES32wHt.mjs} +46 -43
- package/package.json +1 -1
- package/templates/CLAUDE.md +1 -0
- package/templates/en/technical-guides.md +74 -0
- package/templates/zh-CN/commands/workflow.md +1 -1
- package/templates/zh-CN/technical-guides.md +74 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import ansis from 'ansis';
|
|
3
3
|
import cac from 'cac';
|
|
4
|
-
import { d as SUPPORTED_LANGS, I as I18N, L as LANG_LABELS, z as updateZcfConfig, Z as ZCF_CONFIG_FILE, B as readZcfConfig, D as resolveAiOutputLanguage, p as applyAiLanguageDirective, E as configureAiPersonality, u as updateDefaultModel, F as isWindows, r as readMcpConfig, x as fixWindowsMcpConfig, w as writeMcpConfig,
|
|
4
|
+
import { d as SUPPORTED_LANGS, I as I18N, L as LANG_LABELS, z as updateZcfConfig, Z as ZCF_CONFIG_FILE, B as readZcfConfig, D as resolveAiOutputLanguage, p as applyAiLanguageDirective, E as configureAiPersonality, u as updateDefaultModel, F as isWindows, r as readMcpConfig, x as fixWindowsMcpConfig, w as writeMcpConfig, G as selectMcpServices, s as backupMcpConfig, M as MCP_SERVICES, v as buildMcpServerConfig, t as mergeMcpServers, o as getExistingApiConfig, H as formatApiKeyDisplay, J as modifyApiConfigPartially, K as validateApiKey, l as configureApi, N as displayBanner, O as selectScriptLanguage, S as SETTINGS_FILE, P as updatePromptOnly, Q as version, R as handleExitPromptError, T as handleGeneralError, U as displayBannerWithInfo, i as init } from './shared/zcf.BES32wHt.mjs';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
6
|
import { existsSync, unlinkSync } from 'node:fs';
|
|
7
7
|
import 'node:os';
|
|
@@ -127,31 +127,10 @@ async function configureMcpFeature(scriptLang) {
|
|
|
127
127
|
console.log(ansis.green(`\u2714 ${i18n.windowsMcpFixed || "Windows MCP configuration fixed"}`));
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
title: ansis.bold(i18n.allServices),
|
|
133
|
-
value: "ALL",
|
|
134
|
-
selected: false
|
|
135
|
-
},
|
|
136
|
-
...MCP_SERVICES.map((service) => ({
|
|
137
|
-
title: `${service.name[scriptLang]} - ${ansis.gray(service.description[scriptLang])}`,
|
|
138
|
-
value: service.id,
|
|
139
|
-
selected: false
|
|
140
|
-
}))
|
|
141
|
-
];
|
|
142
|
-
const { services } = await inquirer.prompt({
|
|
143
|
-
type: "checkbox",
|
|
144
|
-
name: "services",
|
|
145
|
-
message: i18n.selectMcpServices + " " + ansis.gray(i18n.spaceToSelectReturn),
|
|
146
|
-
choices
|
|
147
|
-
});
|
|
148
|
-
if (!services) {
|
|
130
|
+
const selectedServices = await selectMcpServices(scriptLang);
|
|
131
|
+
if (!selectedServices) {
|
|
149
132
|
return;
|
|
150
133
|
}
|
|
151
|
-
let selectedServices = services || [];
|
|
152
|
-
if (selectedServices.includes("ALL")) {
|
|
153
|
-
selectedServices = MCP_SERVICES.map((s) => s.id);
|
|
154
|
-
}
|
|
155
134
|
if (selectedServices.length > 0) {
|
|
156
135
|
const mcpBackupPath = backupMcpConfig();
|
|
157
136
|
if (mcpBackupPath) {
|
|
@@ -285,9 +264,6 @@ async function update(options = {}) {
|
|
|
285
264
|
}
|
|
286
265
|
let configLang = options.configLang;
|
|
287
266
|
if (!configLang) {
|
|
288
|
-
console.log(ansis.dim(` ${i18n.configLangHint["zh-CN"]}`));
|
|
289
|
-
console.log(ansis.dim(` ${i18n.configLangHint["en"]}
|
|
290
|
-
`));
|
|
291
267
|
const { lang } = await inquirer.prompt({
|
|
292
268
|
type: "list",
|
|
293
269
|
name: "lang",
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, a as CLAUDE_MD_FILE, b as ClAUDE_CONFIG_FILE, I as I18N, L as LANG_LABELS, M as MCP_SERVICES, S as SETTINGS_FILE, d as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, y as addCompletedOnboarding, p as applyAiLanguageDirective, j as backupExistingConfig, s as backupMcpConfig, v as buildMcpServerConfig, c as commandExists, l as configureApi, k as copyConfigFiles, h as ensureClaudeDir, x as fixWindowsMcpConfig, o as getExistingApiConfig, q as getMcpConfigPath, g as getPlatform, i as init, f as installClaudeCode, e as isClaudeCodeInstalled, m as mergeConfigs, t as mergeMcpServers, n as mergeSettingsFile, r as readMcpConfig, u as updateDefaultModel, w as writeMcpConfig } from './shared/zcf.
|
|
1
|
+
export { A as AI_OUTPUT_LANGUAGES, C as CLAUDE_DIR, a as CLAUDE_MD_FILE, b as ClAUDE_CONFIG_FILE, I as I18N, L as LANG_LABELS, M as MCP_SERVICES, S as SETTINGS_FILE, d as SUPPORTED_LANGS, Z as ZCF_CONFIG_FILE, y as addCompletedOnboarding, p as applyAiLanguageDirective, j as backupExistingConfig, s as backupMcpConfig, v as buildMcpServerConfig, c as commandExists, l as configureApi, k as copyConfigFiles, h as ensureClaudeDir, x as fixWindowsMcpConfig, o as getExistingApiConfig, q as getMcpConfigPath, g as getPlatform, i as init, f as installClaudeCode, e as isClaudeCodeInstalled, m as mergeConfigs, t as mergeMcpServers, n as mergeSettingsFile, r as readMcpConfig, u as updateDefaultModel, w as writeMcpConfig } from './shared/zcf.BES32wHt.mjs';
|
|
2
2
|
import 'inquirer';
|
|
3
3
|
import 'ansis';
|
|
4
4
|
import 'node:fs';
|
|
@@ -7,7 +7,7 @@ import dayjs from 'dayjs';
|
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
import { exec } from 'tinyexec';
|
|
9
9
|
|
|
10
|
-
const version = "2.
|
|
10
|
+
const version = "2.2.0";
|
|
11
11
|
const homepage = "https://github.com/UfoMiao/zcf";
|
|
12
12
|
|
|
13
13
|
const CLAUDE_DIR = join(homedir(), ".claude");
|
|
@@ -33,8 +33,8 @@ const I18N = {
|
|
|
33
33
|
aiOutputLangHint: "AI \u5C06\u4F7F\u7528\u6B64\u8BED\u8A00\u56DE\u590D\u4F60\u7684\u95EE\u9898",
|
|
34
34
|
enterCustomLanguage: "\u8BF7\u8F93\u5165\u81EA\u5B9A\u4E49\u8BED\u8A00\uFF08\u4F8B\u5982\uFF1AJapanese, French \u7B49\uFF09",
|
|
35
35
|
configLangHint: {
|
|
36
|
-
"zh-CN": "\
|
|
37
|
-
en: "\
|
|
36
|
+
"zh-CN": "\u4FBF\u4E8E\u4E2D\u6587\u7528\u6237\u81EA\u5B9A\u4E49",
|
|
37
|
+
en: "\u63A8\u8350\uFF0Ctoken \u6D88\u8017\u66F4\u4F4E"
|
|
38
38
|
},
|
|
39
39
|
installPrompt: "\u68C0\u6D4B\u5230 Claude Code \u672A\u5B89\u88C5\uFF0C\u662F\u5426\u81EA\u52A8\u5B89\u88C5\uFF1F",
|
|
40
40
|
installing: "\u6B63\u5728\u5B89\u88C5 Claude Code...",
|
|
@@ -82,7 +82,7 @@ const I18N = {
|
|
|
82
82
|
configSuccess: "\u914D\u7F6E\u6587\u4EF6\u5DF2\u590D\u5236\u5230",
|
|
83
83
|
apiConfigSuccess: "API \u914D\u7F6E\u5B8C\u6210",
|
|
84
84
|
mcpConfigSuccess: "MCP \u670D\u52A1\u5DF2\u914D\u7F6E",
|
|
85
|
-
selectMcpServices: "\u9009\u62E9\u8981\u5B89\u88C5\u7684 MCP \u670D\u52A1\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09",
|
|
85
|
+
selectMcpServices: "\u9009\u62E9\u8981\u5B89\u88C5\u7684 MCP \u670D\u52A1\uFF08\u7A7A\u683C\u9009\u62E9\uFF0Ca\u5168\u9009\uFF0Ci\u53CD\u9009\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09",
|
|
86
86
|
allServices: "\u5168\u90E8\u5B89\u88C5",
|
|
87
87
|
mcpServiceInstalled: "\u5DF2\u9009\u62E9\u7684 MCP \u670D\u52A1",
|
|
88
88
|
enterExaApiKey: "\u8BF7\u8F93\u5165 Exa API Key\uFF08\u53EF\u4ECE https://dashboard.exa.ai/api-keys \u83B7\u53D6\uFF09",
|
|
@@ -208,8 +208,8 @@ const I18N = {
|
|
|
208
208
|
aiOutputLangHint: "AI will respond to you in this language",
|
|
209
209
|
enterCustomLanguage: "Enter custom language (e.g., Japanese, French, etc.)",
|
|
210
210
|
configLangHint: {
|
|
211
|
-
"zh-CN": "
|
|
212
|
-
en: "
|
|
211
|
+
"zh-CN": "easier for Chinese users to customize",
|
|
212
|
+
en: "recommended, lower token consumption"
|
|
213
213
|
},
|
|
214
214
|
installPrompt: "Claude Code not found. Install automatically?",
|
|
215
215
|
installing: "Installing Claude Code...",
|
|
@@ -257,7 +257,7 @@ const I18N = {
|
|
|
257
257
|
configSuccess: "Config files copied to",
|
|
258
258
|
apiConfigSuccess: "API configured",
|
|
259
259
|
mcpConfigSuccess: "MCP services configured",
|
|
260
|
-
selectMcpServices: "Select MCP services to install (space to select, enter to confirm)",
|
|
260
|
+
selectMcpServices: "Select MCP services to install (space to select, a to select all, i to deselect, enter to confirm)",
|
|
261
261
|
allServices: "Install all",
|
|
262
262
|
mcpServiceInstalled: "Selected MCP services",
|
|
263
263
|
enterExaApiKey: "Enter Exa API Key (get from https://dashboard.exa.ai/api-keys)",
|
|
@@ -1452,6 +1452,26 @@ async function resolveAiOutputLanguage(scriptLang, commandLineOption, savedConfi
|
|
|
1452
1452
|
return await selectAiOutputLanguage(scriptLang, scriptLang);
|
|
1453
1453
|
}
|
|
1454
1454
|
|
|
1455
|
+
async function selectMcpServices(scriptLang) {
|
|
1456
|
+
const i18n = I18N[scriptLang];
|
|
1457
|
+
const choices = MCP_SERVICES.map((service) => ({
|
|
1458
|
+
name: `${service.name[scriptLang]} - ${ansis.gray(service.description[scriptLang])}`,
|
|
1459
|
+
value: service.id,
|
|
1460
|
+
selected: false
|
|
1461
|
+
}));
|
|
1462
|
+
const { services } = await inquirer.prompt({
|
|
1463
|
+
type: "checkbox",
|
|
1464
|
+
name: "services",
|
|
1465
|
+
message: i18n.selectMcpServices,
|
|
1466
|
+
choices
|
|
1467
|
+
});
|
|
1468
|
+
if (services === void 0) {
|
|
1469
|
+
console.log(ansis.yellow(i18n.cancelled));
|
|
1470
|
+
return void 0;
|
|
1471
|
+
}
|
|
1472
|
+
return services;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1455
1475
|
async function init(options = {}) {
|
|
1456
1476
|
try {
|
|
1457
1477
|
if (!options.skipBanner) {
|
|
@@ -1504,10 +1524,9 @@ async function init(options = {}) {
|
|
|
1504
1524
|
console.log(ansis.green(`\u2714 ${i18n.installSuccess}`));
|
|
1505
1525
|
}
|
|
1506
1526
|
ensureClaudeDir();
|
|
1507
|
-
let onlyUpdateDocs = false;
|
|
1508
1527
|
let action = "new";
|
|
1509
1528
|
if (existsSync(SETTINGS_FILE) && !options.force) {
|
|
1510
|
-
const { action:
|
|
1529
|
+
const { action: userAction } = await inquirer.prompt({
|
|
1511
1530
|
type: "list",
|
|
1512
1531
|
name: "action",
|
|
1513
1532
|
message: i18n.existingConfig,
|
|
@@ -1518,21 +1537,19 @@ async function init(options = {}) {
|
|
|
1518
1537
|
{ name: i18n.skip, value: "skip" }
|
|
1519
1538
|
]
|
|
1520
1539
|
});
|
|
1521
|
-
if (!
|
|
1540
|
+
if (!userAction) {
|
|
1522
1541
|
console.log(ansis.yellow(i18n.cancelled));
|
|
1523
1542
|
process.exit(0);
|
|
1524
1543
|
}
|
|
1525
|
-
|
|
1544
|
+
action = userAction;
|
|
1545
|
+
if (action === "skip") {
|
|
1526
1546
|
console.log(ansis.yellow(i18n.skip));
|
|
1527
1547
|
return;
|
|
1528
1548
|
}
|
|
1529
|
-
if (action2 === "docs-only") {
|
|
1530
|
-
onlyUpdateDocs = true;
|
|
1531
|
-
}
|
|
1532
1549
|
}
|
|
1533
1550
|
let apiConfig = null;
|
|
1534
1551
|
const isNewInstall = !existsSync(SETTINGS_FILE);
|
|
1535
|
-
if (
|
|
1552
|
+
if (action !== "docs-only" && (isNewInstall || ["backup", "merge"].includes(action))) {
|
|
1536
1553
|
const existingApiConfig = getExistingApiConfig();
|
|
1537
1554
|
if (existingApiConfig) {
|
|
1538
1555
|
console.log("\n" + ansis.blue(`\u2139 ${i18n.existingApiConfig}`));
|
|
@@ -1598,12 +1615,20 @@ async function init(options = {}) {
|
|
|
1598
1615
|
}
|
|
1599
1616
|
}
|
|
1600
1617
|
}
|
|
1601
|
-
if (
|
|
1618
|
+
if (["backup", "docs-only", "merge"].includes(action)) {
|
|
1619
|
+
const backupDir = backupExistingConfig();
|
|
1620
|
+
if (backupDir) {
|
|
1621
|
+
console.log(ansis.gray(`\u2714 ${i18n.backupSuccess}: ${backupDir}`));
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
if (action === "docs-only") {
|
|
1625
|
+
copyConfigFiles(configLang, true);
|
|
1626
|
+
} else if (["backup", "merge", "new"].includes(action)) {
|
|
1602
1627
|
copyConfigFiles(configLang, false);
|
|
1603
1628
|
}
|
|
1604
1629
|
applyAiLanguageDirective(aiOutputLang);
|
|
1605
1630
|
await configureAiPersonality(scriptLang);
|
|
1606
|
-
if (apiConfig &&
|
|
1631
|
+
if (apiConfig && action !== "docs-only") {
|
|
1607
1632
|
const configuredApi = configureApi(apiConfig);
|
|
1608
1633
|
if (configuredApi) {
|
|
1609
1634
|
console.log(ansis.green(`\u2714 ${i18n.apiConfigSuccess}`));
|
|
@@ -1616,7 +1641,7 @@ async function init(options = {}) {
|
|
|
1616
1641
|
}
|
|
1617
1642
|
}
|
|
1618
1643
|
}
|
|
1619
|
-
if (
|
|
1644
|
+
if (action !== "docs-only") {
|
|
1620
1645
|
const { shouldConfigureMcp } = await inquirer.prompt({
|
|
1621
1646
|
type: "confirm",
|
|
1622
1647
|
name: "shouldConfigureMcp",
|
|
@@ -1635,32 +1660,10 @@ async function init(options = {}) {
|
|
|
1635
1660
|
)
|
|
1636
1661
|
);
|
|
1637
1662
|
}
|
|
1638
|
-
const
|
|
1639
|
-
|
|
1640
|
-
title: ansis.bold(i18n.allServices),
|
|
1641
|
-
value: "ALL",
|
|
1642
|
-
selected: false
|
|
1643
|
-
},
|
|
1644
|
-
...MCP_SERVICES.map((service) => ({
|
|
1645
|
-
title: `${service.name[scriptLang]} - ${ansis.gray(service.description[scriptLang])}`,
|
|
1646
|
-
value: service.id,
|
|
1647
|
-
selected: false
|
|
1648
|
-
}))
|
|
1649
|
-
];
|
|
1650
|
-
const { services } = await inquirer.prompt({
|
|
1651
|
-
type: "checkbox",
|
|
1652
|
-
name: "services",
|
|
1653
|
-
message: i18n.selectMcpServices + " " + ansis.gray(i18n.spaceToSelectReturn),
|
|
1654
|
-
choices
|
|
1655
|
-
});
|
|
1656
|
-
if (services === void 0) {
|
|
1657
|
-
console.log(ansis.yellow(i18n.cancelled));
|
|
1663
|
+
const selectedServices = await selectMcpServices(scriptLang);
|
|
1664
|
+
if (selectedServices === void 0) {
|
|
1658
1665
|
process.exit(0);
|
|
1659
1666
|
}
|
|
1660
|
-
let selectedServices = services || [];
|
|
1661
|
-
if (selectedServices.includes("ALL")) {
|
|
1662
|
-
selectedServices = MCP_SERVICES.map((s) => s.id);
|
|
1663
|
-
}
|
|
1664
1667
|
if (selectedServices.length > 0) {
|
|
1665
1668
|
const mcpBackupPath = backupMcpConfig();
|
|
1666
1669
|
if (mcpBackupPath) {
|
|
@@ -1716,4 +1719,4 @@ async function init(options = {}) {
|
|
|
1716
1719
|
}
|
|
1717
1720
|
}
|
|
1718
1721
|
|
|
1719
|
-
export { AI_OUTPUT_LANGUAGES as A, readZcfConfig as B, CLAUDE_DIR as C, resolveAiOutputLanguage as D, configureAiPersonality as E, isWindows as F,
|
|
1722
|
+
export { AI_OUTPUT_LANGUAGES as A, readZcfConfig as B, CLAUDE_DIR as C, resolveAiOutputLanguage as D, configureAiPersonality as E, isWindows as F, selectMcpServices as G, formatApiKeyDisplay as H, I18N as I, modifyApiConfigPartially as J, validateApiKey as K, LANG_LABELS as L, MCP_SERVICES as M, displayBanner as N, selectScriptLanguage as O, updatePromptOnly as P, version as Q, handleExitPromptError as R, SETTINGS_FILE as S, handleGeneralError as T, displayBannerWithInfo as U, ZCF_CONFIG_FILE as Z, CLAUDE_MD_FILE as a, ClAUDE_CONFIG_FILE as b, commandExists as c, SUPPORTED_LANGS as d, isClaudeCodeInstalled as e, installClaudeCode as f, getPlatform as g, ensureClaudeDir as h, init as i, backupExistingConfig as j, copyConfigFiles as k, configureApi as l, mergeConfigs as m, mergeSettingsFile as n, getExistingApiConfig as o, applyAiLanguageDirective as p, getMcpConfigPath as q, readMcpConfig as r, backupMcpConfig as s, mergeMcpServers as t, updateDefaultModel as u, buildMcpServerConfig as v, writeMcpConfig as w, fixWindowsMcpConfig as x, addCompletedOnboarding as y, updateZcfConfig as z };
|
package/package.json
CHANGED
package/templates/CLAUDE.md
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Technical Execution Guidelines
|
|
2
|
+
|
|
3
|
+
This document provides best practices that Claude Code should follow when executing specific technical tasks.
|
|
4
|
+
|
|
5
|
+
## Command Execution Best Practices
|
|
6
|
+
|
|
7
|
+
### Path Handling Standards
|
|
8
|
+
|
|
9
|
+
**Important**: Always use double quotes to wrap file paths when executing commands on all operating systems, especially on Windows.
|
|
10
|
+
|
|
11
|
+
#### Correct Examples
|
|
12
|
+
```bash
|
|
13
|
+
# ✅ Correct: Paths wrapped in double quotes
|
|
14
|
+
cd "C:\Users\name\My Documents"
|
|
15
|
+
python "C:\Program Files\MyApp\script.py"
|
|
16
|
+
node "/path/with spaces/app.js"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
#### Incorrect Examples
|
|
20
|
+
```bash
|
|
21
|
+
# ❌ Incorrect: No quotes, backslashes will be swallowed on Windows
|
|
22
|
+
cd C:\Users\name\My Documents
|
|
23
|
+
python C:\Program Files\MyApp\script.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Cross-Platform Compatibility
|
|
27
|
+
|
|
28
|
+
- Prefer forward slashes `/` as path separators (supported by most tools)
|
|
29
|
+
- When backslashes must be used, ensure paths are wrapped in double quotes
|
|
30
|
+
- Be mindful of spaces and special characters even with relative paths
|
|
31
|
+
|
|
32
|
+
## Search Tool Usage Guidelines
|
|
33
|
+
|
|
34
|
+
### Content Search Priority
|
|
35
|
+
|
|
36
|
+
**Always prioritize `rg` (ripgrep) for file content searches** over `grep`.
|
|
37
|
+
|
|
38
|
+
> **Note**: ripgrep requires user installation. Most developers already have this tool installed. If `rg` command is not found, remind users to install:
|
|
39
|
+
> - macOS: `brew install ripgrep`
|
|
40
|
+
> - Windows: `scoop install ripgrep` or `choco install ripgrep`
|
|
41
|
+
> - Linux: `sudo apt-get install ripgrep` or see [official installation guide](https://github.com/BurntSushi/ripgrep#installation)
|
|
42
|
+
|
|
43
|
+
#### Reasons
|
|
44
|
+
1. **Superior Performance**: rg won't timeout in large codebases (e.g., Chromium, Emacs)
|
|
45
|
+
2. **Faster Execution**: rg is significantly faster than grep
|
|
46
|
+
3. **Smarter Defaults**: Automatically respects .gitignore files
|
|
47
|
+
|
|
48
|
+
#### Usage Examples
|
|
49
|
+
```bash
|
|
50
|
+
# ✅ Prefer rg
|
|
51
|
+
rg "search pattern" .
|
|
52
|
+
rg -i "case insensitive" src/
|
|
53
|
+
rg -t js "console.log" .
|
|
54
|
+
|
|
55
|
+
# ⚠️ Only use grep when rg is unavailable
|
|
56
|
+
grep -r "pattern" .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### File Finding
|
|
60
|
+
- Use Glob tool for filename pattern matching
|
|
61
|
+
- Use LS tool for directory listings
|
|
62
|
+
- Avoid using `find` command (specialized tools are more efficient)
|
|
63
|
+
|
|
64
|
+
## Tool Usage Principles
|
|
65
|
+
|
|
66
|
+
1. **Prefer Specialized Tools**: Use Read, Write, Edit tools instead of cat, echo commands
|
|
67
|
+
2. **Batch Operations**: Call multiple tools simultaneously for efficiency
|
|
68
|
+
3. **Error Handling**: Check for path quoting issues first when commands fail
|
|
69
|
+
|
|
70
|
+
## Performance Optimization Tips
|
|
71
|
+
|
|
72
|
+
- Use Task tool for complex searches in large projects
|
|
73
|
+
- Understand project structure before searching to narrow scope
|
|
74
|
+
- Use search parameters wisely (e.g., file type filters) for efficiency
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# 技术执行指南
|
|
2
|
+
|
|
3
|
+
本文档提供 Claude Code 在执行具体技术任务时应遵循的最佳实践。
|
|
4
|
+
|
|
5
|
+
## 命令执行最佳实践
|
|
6
|
+
|
|
7
|
+
### 路径处理规范
|
|
8
|
+
|
|
9
|
+
**重要**:在所有操作系统上执行命令时,**始终使用双引号包裹文件路径**,特别是在 Windows 系统上。
|
|
10
|
+
|
|
11
|
+
#### 正确示例
|
|
12
|
+
```bash
|
|
13
|
+
# ✅ 正确:路径使用双引号
|
|
14
|
+
cd "C:\Users\name\My Documents"
|
|
15
|
+
python "C:\Program Files\MyApp\script.py"
|
|
16
|
+
node "/path/with spaces/app.js"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
#### 错误示例
|
|
20
|
+
```bash
|
|
21
|
+
# ❌ 错误:未使用引号,Windows 下反斜杠会被吞掉
|
|
22
|
+
cd C:\Users\name\My Documents
|
|
23
|
+
python C:\Program Files\MyApp\script.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 跨平台兼容性
|
|
27
|
+
|
|
28
|
+
- 优先使用正斜杠 `/` 作为路径分隔符(大多数工具都支持)
|
|
29
|
+
- 当必须使用反斜杠时,确保路径被双引号包裹
|
|
30
|
+
- 使用相对路径时也要注意空格和特殊字符
|
|
31
|
+
|
|
32
|
+
## 搜索工具使用指南
|
|
33
|
+
|
|
34
|
+
### 内容搜索优先级
|
|
35
|
+
|
|
36
|
+
**始终优先使用 `rg` (ripgrep) 进行文件内容搜索**,而不是 `grep`。
|
|
37
|
+
|
|
38
|
+
> **注意**:ripgrep 需要用户自行安装。大多数开发者已经安装了此工具,如果遇到 `rg` 命令不存在,请提醒用户安装:
|
|
39
|
+
> - macOS: `brew install ripgrep`
|
|
40
|
+
> - Windows: `scoop install ripgrep` 或 `choco install ripgrep`
|
|
41
|
+
> - Linux: `sudo apt-get install ripgrep` 或查看 [官方安装指南](https://github.com/BurntSushi/ripgrep#installation)
|
|
42
|
+
|
|
43
|
+
#### 原因
|
|
44
|
+
1. **性能优越**:在大型代码库(如 Chromium、Emacs)中,rg 不会超时
|
|
45
|
+
2. **速度更快**:rg 的执行速度显著快于 grep
|
|
46
|
+
3. **默认配置更智能**:自动忽略 .gitignore 中的文件
|
|
47
|
+
|
|
48
|
+
#### 使用示例
|
|
49
|
+
```bash
|
|
50
|
+
# ✅ 优先使用 rg
|
|
51
|
+
rg "search pattern" .
|
|
52
|
+
rg -i "case insensitive" src/
|
|
53
|
+
rg -t js "console.log" .
|
|
54
|
+
|
|
55
|
+
# ⚠️ 仅在 rg 不可用时才使用 grep
|
|
56
|
+
grep -r "pattern" .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 文件查找
|
|
60
|
+
- 使用 Glob 工具查找文件名模式
|
|
61
|
+
- 使用 LS 工具列出目录内容
|
|
62
|
+
- 避免使用 `find` 命令(使用专门的工具更高效)
|
|
63
|
+
|
|
64
|
+
## 工具使用原则
|
|
65
|
+
|
|
66
|
+
1. **优先使用专门的工具**:使用 Read、Write、Edit 等专门工具,而不是 cat、echo 等命令
|
|
67
|
+
2. **批量操作**:可以同时调用多个工具以提高效率
|
|
68
|
+
3. **错误处理**:命令失败后,先检查路径引号问题再重试
|
|
69
|
+
|
|
70
|
+
## 性能优化建议
|
|
71
|
+
|
|
72
|
+
- 对于大型项目,使用 Task 工具进行复杂搜索
|
|
73
|
+
- 搜索前先了解项目结构,缩小搜索范围
|
|
74
|
+
- 合理使用搜索参数(如文件类型过滤)以提高效率
|