aico-cli 0.1.9 → 0.2.1
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/chunks/feature-checker.mjs +1 -0
- package/dist/chunks/simple-config.mjs +213 -2
- package/dist/cli.mjs +50 -5
- package/dist/index.mjs +1 -0
- package/package.json +1 -1
- package/templates/CLAUDE.md +71 -3
- package/templates/commands/base/fix-error.md +319 -0
- package/templates/commands/base/tech-debt.md +181 -0
- package/templates/commands/base/ultrathink.md +65 -0
- package/templates/personality.md +71 -1
|
@@ -12,8 +12,9 @@ import 'dayjs';
|
|
|
12
12
|
import { join as join$1 } from 'node:path';
|
|
13
13
|
import { join, dirname, basename } from 'pathe';
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { rm, mkdir, copyFile as copyFile$1 } from 'node:fs/promises';
|
|
15
16
|
|
|
16
|
-
const version = "0.1
|
|
17
|
+
const version = "0.2.1";
|
|
17
18
|
|
|
18
19
|
function displayBanner(subtitle) {
|
|
19
20
|
const defaultSubtitle = "\u4E00\u952E\u914D\u7F6E\u4F60\u7684\u5F00\u53D1\u73AF\u5883";
|
|
@@ -4848,6 +4849,10 @@ class ConfigInstaller extends AbstractInstaller {
|
|
|
4848
4849
|
}
|
|
4849
4850
|
copyConfigFiles("zh-CN", false);
|
|
4850
4851
|
await this.copyAiPersonalityFiles();
|
|
4852
|
+
const workflowResult = await this.installWorkflows();
|
|
4853
|
+
if (!workflowResult.success) {
|
|
4854
|
+
this.log(`\u5DE5\u4F5C\u6D41\u5B89\u88C5\u5931\u8D25: ${workflowResult.message}`, "warning");
|
|
4855
|
+
}
|
|
4851
4856
|
const apiConfig = options.configData?.apiConfig;
|
|
4852
4857
|
if (apiConfig) {
|
|
4853
4858
|
const configuredApi = configureApi(apiConfig);
|
|
@@ -5213,6 +5218,206 @@ const INSTALLER_NAMES = {
|
|
|
5213
5218
|
CONFIG_CHECKER: "config-checker"
|
|
5214
5219
|
};
|
|
5215
5220
|
|
|
5221
|
+
const WORKFLOW_CONFIGS = [
|
|
5222
|
+
{
|
|
5223
|
+
id: "sixStepsWorkflow",
|
|
5224
|
+
nameKey: "workflowOption.sixStepsWorkflow",
|
|
5225
|
+
descriptionKey: "workflowDescription.sixStepsWorkflow",
|
|
5226
|
+
defaultSelected: true,
|
|
5227
|
+
order: 1,
|
|
5228
|
+
commands: ["workflow.md"],
|
|
5229
|
+
agents: [],
|
|
5230
|
+
autoInstallAgents: false,
|
|
5231
|
+
category: "sixStep",
|
|
5232
|
+
outputDir: "workflow"
|
|
5233
|
+
},
|
|
5234
|
+
{
|
|
5235
|
+
id: "featPlanUx",
|
|
5236
|
+
nameKey: "workflowOption.featPlanUx",
|
|
5237
|
+
descriptionKey: "workflowDescription.featPlanUx",
|
|
5238
|
+
defaultSelected: true,
|
|
5239
|
+
order: 2,
|
|
5240
|
+
commands: ["feat.md"],
|
|
5241
|
+
agents: [
|
|
5242
|
+
{ id: "planner", filename: "planner.md", required: true },
|
|
5243
|
+
{ id: "ui-ux-designer", filename: "ui-ux-designer.md", required: true }
|
|
5244
|
+
],
|
|
5245
|
+
autoInstallAgents: true,
|
|
5246
|
+
category: "plan",
|
|
5247
|
+
outputDir: "feat"
|
|
5248
|
+
},
|
|
5249
|
+
{
|
|
5250
|
+
id: "bmadWorkflow",
|
|
5251
|
+
nameKey: "workflowOption.bmadWorkflow",
|
|
5252
|
+
descriptionKey: "workflowDescription.bmadWorkflow",
|
|
5253
|
+
defaultSelected: false,
|
|
5254
|
+
order: 3,
|
|
5255
|
+
commands: ["bmad-init.md"],
|
|
5256
|
+
agents: [],
|
|
5257
|
+
autoInstallAgents: false,
|
|
5258
|
+
category: "bmad",
|
|
5259
|
+
outputDir: "bmad"
|
|
5260
|
+
},
|
|
5261
|
+
{
|
|
5262
|
+
id: "gitWorkflow",
|
|
5263
|
+
nameKey: "workflowOption.gitWorkflow",
|
|
5264
|
+
descriptionKey: "workflowDescription.gitWorkflow",
|
|
5265
|
+
defaultSelected: false,
|
|
5266
|
+
order: 4,
|
|
5267
|
+
commands: ["git-commit.md", "git-rollback.md", "git-cleanBranches.md", "git-worktree.md"],
|
|
5268
|
+
agents: [],
|
|
5269
|
+
autoInstallAgents: false,
|
|
5270
|
+
category: "git",
|
|
5271
|
+
outputDir: "git"
|
|
5272
|
+
}
|
|
5273
|
+
];
|
|
5274
|
+
function getWorkflowConfig(workflowId) {
|
|
5275
|
+
return WORKFLOW_CONFIGS.find((config) => config.id === workflowId);
|
|
5276
|
+
}
|
|
5277
|
+
function getOrderedWorkflows() {
|
|
5278
|
+
return [...WORKFLOW_CONFIGS].sort((a, b) => a.order - b.order);
|
|
5279
|
+
}
|
|
5280
|
+
|
|
5281
|
+
function getRootDir() {
|
|
5282
|
+
const currentFilePath = fileURLToPath(import.meta.url);
|
|
5283
|
+
const distDir = dirname(dirname(currentFilePath));
|
|
5284
|
+
return dirname(distDir);
|
|
5285
|
+
}
|
|
5286
|
+
async function selectAndInstallWorkflows(configLang, scriptLang, preselectedWorkflows) {
|
|
5287
|
+
const workflows = getOrderedWorkflows();
|
|
5288
|
+
workflows.map((workflow) => {
|
|
5289
|
+
const nameKey = workflow.id;
|
|
5290
|
+
const name = messages.workflow.selectWorkflowType[nameKey] || workflow.id;
|
|
5291
|
+
return {
|
|
5292
|
+
name,
|
|
5293
|
+
value: workflow.id,
|
|
5294
|
+
checked: workflow.defaultSelected
|
|
5295
|
+
};
|
|
5296
|
+
});
|
|
5297
|
+
let selectedWorkflows;
|
|
5298
|
+
if (preselectedWorkflows) {
|
|
5299
|
+
selectedWorkflows = preselectedWorkflows;
|
|
5300
|
+
} else {
|
|
5301
|
+
selectedWorkflows = workflows.map((w) => w.id);
|
|
5302
|
+
}
|
|
5303
|
+
if (!selectedWorkflows || selectedWorkflows.length === 0) {
|
|
5304
|
+
console.log(ansis.yellow(messages.common.cancelled));
|
|
5305
|
+
return;
|
|
5306
|
+
}
|
|
5307
|
+
await cleanupOldVersionFiles();
|
|
5308
|
+
for (const workflowId of selectedWorkflows) {
|
|
5309
|
+
const config = getWorkflowConfig(workflowId);
|
|
5310
|
+
if (config) {
|
|
5311
|
+
await installWorkflowWithDependencies(config, configLang);
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5314
|
+
}
|
|
5315
|
+
async function installWorkflowWithDependencies(config, configLang, scriptLang) {
|
|
5316
|
+
const rootDir = getRootDir();
|
|
5317
|
+
const result = {
|
|
5318
|
+
workflow: config.id,
|
|
5319
|
+
success: true,
|
|
5320
|
+
installedCommands: [],
|
|
5321
|
+
installedAgents: [],
|
|
5322
|
+
errors: []
|
|
5323
|
+
};
|
|
5324
|
+
const workflowName = messages.workflow.selectWorkflowType[config.id] || config.id;
|
|
5325
|
+
console.log(ansis.cyan(`
|
|
5326
|
+
\u{1F4E6} ${messages.workflow.installing}: ${workflowName}...`));
|
|
5327
|
+
const commandsDir = join(CLAUDE_DIR, "commands", "aico");
|
|
5328
|
+
if (!existsSync(commandsDir)) {
|
|
5329
|
+
await mkdir(commandsDir, { recursive: true });
|
|
5330
|
+
}
|
|
5331
|
+
for (const commandFile of config.commands) {
|
|
5332
|
+
const commandSource = join(rootDir, "templates", configLang, "workflow", config.category, "commands", commandFile);
|
|
5333
|
+
const destFileName = commandFile;
|
|
5334
|
+
const commandDest = join(commandsDir, destFileName);
|
|
5335
|
+
if (existsSync(commandSource)) {
|
|
5336
|
+
try {
|
|
5337
|
+
await copyFile$1(commandSource, commandDest);
|
|
5338
|
+
result.installedCommands.push(destFileName);
|
|
5339
|
+
console.log(ansis.gray(` \u2714 ${messages.workflow.installedCommand}: aico/${destFileName}`));
|
|
5340
|
+
} catch (error) {
|
|
5341
|
+
const errorMsg = `${messages.workflow.failedToInstallCommand} ${commandFile}: ${error}`;
|
|
5342
|
+
result.errors?.push(errorMsg);
|
|
5343
|
+
console.error(ansis.red(` \u2717 ${errorMsg}`));
|
|
5344
|
+
result.success = false;
|
|
5345
|
+
}
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
if (config.autoInstallAgents && config.agents.length > 0) {
|
|
5349
|
+
const agentsCategoryDir = join(CLAUDE_DIR, "agents", "aico", config.category);
|
|
5350
|
+
if (!existsSync(agentsCategoryDir)) {
|
|
5351
|
+
await mkdir(agentsCategoryDir, { recursive: true });
|
|
5352
|
+
}
|
|
5353
|
+
for (const agent of config.agents) {
|
|
5354
|
+
const agentSource = join(rootDir, "templates", configLang, "workflow", config.category, "agents", agent.filename);
|
|
5355
|
+
const agentDest = join(agentsCategoryDir, agent.filename);
|
|
5356
|
+
if (existsSync(agentSource)) {
|
|
5357
|
+
try {
|
|
5358
|
+
await copyFile$1(agentSource, agentDest);
|
|
5359
|
+
result.installedAgents.push(agent.filename);
|
|
5360
|
+
console.log(ansis.gray(` \u2714 ${messages.workflow.installedAgent}: aico/${config.category}/${agent.filename}`));
|
|
5361
|
+
} catch (error) {
|
|
5362
|
+
const errorMsg = `${messages.workflow.failedToInstallAgent} ${agent.filename}: ${error}`;
|
|
5363
|
+
result.errors?.push(errorMsg);
|
|
5364
|
+
console.error(ansis.red(` \u2717 ${errorMsg}`));
|
|
5365
|
+
if (agent.required) {
|
|
5366
|
+
result.success = false;
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
}
|
|
5370
|
+
}
|
|
5371
|
+
}
|
|
5372
|
+
if (result.success) {
|
|
5373
|
+
console.log(ansis.green(`\u2714 ${workflowName} ${messages.workflow.installSuccess}`));
|
|
5374
|
+
if (config.id === "bmadWorkflow") {
|
|
5375
|
+
console.log(ansis.cyan(`
|
|
5376
|
+
${messages.workflow.bmadInitPrompt}`));
|
|
5377
|
+
}
|
|
5378
|
+
} else {
|
|
5379
|
+
console.log(ansis.red(`\u2717 ${workflowName} ${messages.workflow.installFailed}`));
|
|
5380
|
+
}
|
|
5381
|
+
return result;
|
|
5382
|
+
}
|
|
5383
|
+
async function cleanupOldVersionFiles(scriptLang) {
|
|
5384
|
+
console.log(ansis.cyan(`
|
|
5385
|
+
\u{1F9F9} ${messages.workflow.cleaningOldFiles || "Cleaning up old version files"}...`));
|
|
5386
|
+
const oldCommandFiles = [
|
|
5387
|
+
join(CLAUDE_DIR, "commands", "workflow.md"),
|
|
5388
|
+
join(CLAUDE_DIR, "commands", "feat.md")
|
|
5389
|
+
];
|
|
5390
|
+
const oldAgentFiles = [
|
|
5391
|
+
join(CLAUDE_DIR, "agents", "planner.md"),
|
|
5392
|
+
join(CLAUDE_DIR, "agents", "ui-ux-designer.md")
|
|
5393
|
+
];
|
|
5394
|
+
for (const file of oldCommandFiles) {
|
|
5395
|
+
if (existsSync(file)) {
|
|
5396
|
+
try {
|
|
5397
|
+
await rm(file, { force: true });
|
|
5398
|
+
console.log(ansis.gray(` \u2714 ${messages.workflow.removedOldFile || "Removed old file"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
5399
|
+
} catch (error) {
|
|
5400
|
+
console.error(ansis.yellow(` \u26A0 ${messages.workflow.failedToRemoveFile || "Failed to remove"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
5401
|
+
}
|
|
5402
|
+
}
|
|
5403
|
+
}
|
|
5404
|
+
for (const file of oldAgentFiles) {
|
|
5405
|
+
if (existsSync(file)) {
|
|
5406
|
+
try {
|
|
5407
|
+
await rm(file, { force: true });
|
|
5408
|
+
console.log(ansis.gray(` \u2714 ${messages.workflow.removedOldFile || "Removed old file"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
5409
|
+
} catch (error) {
|
|
5410
|
+
console.error(ansis.yellow(` \u26A0 ${messages.workflow.failedToRemoveFile || "Failed to remove"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
5411
|
+
}
|
|
5412
|
+
}
|
|
5413
|
+
}
|
|
5414
|
+
}
|
|
5415
|
+
|
|
5416
|
+
const workflowInstaller = {
|
|
5417
|
+
__proto__: null,
|
|
5418
|
+
selectAndInstallWorkflows: selectAndInstallWorkflows
|
|
5419
|
+
};
|
|
5420
|
+
|
|
5216
5421
|
class InstallationComposer {
|
|
5217
5422
|
executor;
|
|
5218
5423
|
context;
|
|
@@ -5287,6 +5492,8 @@ class InstallationComposer {
|
|
|
5287
5492
|
const companyResults = await this.executor.executeBatch(companySteps, configOptions);
|
|
5288
5493
|
const configInstaller = new ConfigInstaller(this.context);
|
|
5289
5494
|
await configInstaller.applyCompanyConfig();
|
|
5495
|
+
console.log(ansis.cyan("\n\u{1F4E6} \u5B89\u88C5\u5DE5\u4F5C\u6D41\u6A21\u677F..."));
|
|
5496
|
+
await selectAndInstallWorkflows("zh-CN");
|
|
5290
5497
|
this.updateGlobalConfig();
|
|
5291
5498
|
this.printResults({ ...results, ...companyResults }, "\u516C\u53F8\u914D\u7F6E");
|
|
5292
5499
|
} else {
|
|
@@ -5300,6 +5507,8 @@ class InstallationComposer {
|
|
|
5300
5507
|
const companyResults = await this.executor.executeBatch(companySteps, configOptions);
|
|
5301
5508
|
const configInstaller = new ConfigInstaller(this.context);
|
|
5302
5509
|
await configInstaller.applyCompanyConfig();
|
|
5510
|
+
console.log(ansis.cyan("\n\u{1F4E6} \u5B89\u88C5\u5DE5\u4F5C\u6D41\u6A21\u677F..."));
|
|
5511
|
+
await selectAndInstallWorkflows("zh-CN");
|
|
5303
5512
|
this.updateGlobalConfig();
|
|
5304
5513
|
this.printResults({ ...results, ...companyResults }, "\u516C\u53F8\u914D\u7F6E");
|
|
5305
5514
|
}
|
|
@@ -5326,6 +5535,8 @@ class InstallationComposer {
|
|
|
5326
5535
|
if (results[INSTALLER_NAMES.CCR]?.success) {
|
|
5327
5536
|
await this.configureCCRForPersonal();
|
|
5328
5537
|
}
|
|
5538
|
+
console.log(ansis.cyan("\n\u{1F4E6} \u5B89\u88C5\u5DE5\u4F5C\u6D41\u6A21\u677F..."));
|
|
5539
|
+
await selectAndInstallWorkflows("zh-CN");
|
|
5329
5540
|
this.updateGlobalConfig();
|
|
5330
5541
|
this.printResults(results, "\u4E2A\u4EBA\u914D\u7F6E");
|
|
5331
5542
|
}
|
|
@@ -5561,4 +5772,4 @@ async function openSettingsJson() {
|
|
|
5561
5772
|
}
|
|
5562
5773
|
}
|
|
5563
5774
|
|
|
5564
|
-
export { AICO_CONFIG_FILE as A, mergeMcpServers as B, CLAUDE_DIR as C, buildMcpServerConfig as D, fixWindowsMcpConfig as E, addCompletedOnboarding as F, readJsonConfig as G, isTermux as H, messages as I, getTermuxPrefix as J, createEscapablePrompt as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, displayBannerWithInfo as N, executeWithEscapeSupport as O, handleExitPromptError as P, handleGeneralError as Q, EscapeKeyPressed as R, SETTINGS_FILE as S, displayBanner as T, version as U, ConfigCheckerInstaller as V, init$1 as
|
|
5775
|
+
export { AICO_CONFIG_FILE as A, mergeMcpServers as B, CLAUDE_DIR as C, buildMcpServerConfig as D, fixWindowsMcpConfig as E, addCompletedOnboarding as F, readJsonConfig as G, isTermux as H, messages as I, getTermuxPrefix as J, createEscapablePrompt as K, LEGACY_AICO_CONFIG_FILE as L, MCP_SERVICES as M, displayBannerWithInfo as N, executeWithEscapeSupport as O, handleExitPromptError as P, handleGeneralError as Q, EscapeKeyPressed as R, SETTINGS_FILE as S, displayBanner as T, version as U, ConfigCheckerInstaller as V, InstallerExecutor as W, workflowInstaller as X, init$1 as Y, importRecommendedEnv as a, importRecommendedPermissions as b, commandExists as c, cleanupPermissions as d, CLAUDE_MD_FILE as e, ClAUDE_CONFIG_FILE as f, getPlatform as g, SUPPORTED_LANGS as h, init as i, LANG_LABELS as j, AI_OUTPUT_LANGUAGES as k, ensureClaudeDir as l, mergeAndCleanPermissions as m, backupExistingConfig as n, openSettingsJson as o, copyConfigFiles as p, configureApi as q, mergeConfigs as r, mergeSettingsFile as s, getExistingApiConfig as t, updateDefaultModel as u, applyAiLanguageDirective as v, getMcpConfigPath as w, readMcpConfig as x, writeMcpConfig as y, backupMcpConfig as z };
|
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import cac from 'cac';
|
|
3
3
|
import ansis from 'ansis';
|
|
4
|
-
import { K as createEscapablePrompt, N as displayBannerWithInfo, i as init, O as executeWithEscapeSupport, P as handleExitPromptError, Q as handleGeneralError, R as EscapeKeyPressed, T as displayBanner, U as version, V as ConfigCheckerInstaller } from './chunks/simple-config.mjs';
|
|
4
|
+
import { K as createEscapablePrompt, N as displayBannerWithInfo, i as init, O as executeWithEscapeSupport, P as handleExitPromptError, Q as handleGeneralError, R as EscapeKeyPressed, T as displayBanner, U as version, V as ConfigCheckerInstaller, W as InstallerExecutor } from './chunks/simple-config.mjs';
|
|
5
5
|
import inquirer$1 from 'inquirer';
|
|
6
6
|
import { spawn, exec as exec$1 } from 'node:child_process';
|
|
7
7
|
import 'tinyexec';
|
|
@@ -9,6 +9,7 @@ import 'node:os';
|
|
|
9
9
|
import 'node:fs';
|
|
10
10
|
import 'pathe';
|
|
11
11
|
import 'node:url';
|
|
12
|
+
import 'node:fs/promises';
|
|
12
13
|
import 'node:path';
|
|
13
14
|
import { exec } from 'child_process';
|
|
14
15
|
import { promisify } from 'util';
|
|
@@ -341,7 +342,7 @@ function setupCommands(cli) {
|
|
|
341
342
|
} else if (options.update) {
|
|
342
343
|
await update({});
|
|
343
344
|
} else if (options.company) {
|
|
344
|
-
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.
|
|
345
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
345
346
|
await init2({
|
|
346
347
|
apiType: "auth_token",
|
|
347
348
|
force: options.force,
|
|
@@ -349,7 +350,7 @@ function setupCommands(cli) {
|
|
|
349
350
|
skipPrompt: true
|
|
350
351
|
});
|
|
351
352
|
} else if (options.personal) {
|
|
352
|
-
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.
|
|
353
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
353
354
|
await init2({
|
|
354
355
|
apiType: "ccr_proxy",
|
|
355
356
|
force: options.force,
|
|
@@ -378,11 +379,12 @@ async function startCodeEditor() {
|
|
|
378
379
|
const missingFeatures = Object.entries(featureStatus).filter(([_, status2]) => !status2.isInstalled).map(([name, _]) => name);
|
|
379
380
|
if (missingFeatures.length > 0) {
|
|
380
381
|
console.log(ansis.yellow(`\u26A0\uFE0F \u53D1\u73B0\u672A\u5B89\u88C5\u7684\u529F\u80FD\u6A21\u5757: ${missingFeatures.join(", ")}`));
|
|
381
|
-
console.log(ansis.yellow(" \
|
|
382
|
+
console.log(ansis.yellow(" \u5F00\u59CB\u81EA\u52A8\u5B89\u88C5\u7F3A\u5931\u529F\u80FD..."));
|
|
383
|
+
await installMissingFeatures(context, featureStatus, missingFeatures);
|
|
382
384
|
}
|
|
383
385
|
} else {
|
|
384
386
|
console.log(ansis.yellow("\u26A0\uFE0F \u672A\u68C0\u6D4B\u5230\u914D\u7F6E\uFF0C\u5C06\u5148\u6267\u884C\u521D\u59CB\u5316\u914D\u7F6E..."));
|
|
385
|
-
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.
|
|
387
|
+
const { init: init2 } = await import('./chunks/simple-config.mjs').then(function (n) { return n.Y; });
|
|
386
388
|
await init2({ skipBanner: true, skipPrompt: true });
|
|
387
389
|
}
|
|
388
390
|
await startClaudeCodeEditor();
|
|
@@ -416,6 +418,49 @@ function customizeHelp(sections) {
|
|
|
416
418
|
});
|
|
417
419
|
return sections;
|
|
418
420
|
}
|
|
421
|
+
async function installMissingFeatures(context, _featureStatus, missingFeatures) {
|
|
422
|
+
try {
|
|
423
|
+
const executor = new InstallerExecutor(context);
|
|
424
|
+
const featureToInstallerMap = {
|
|
425
|
+
config: "config",
|
|
426
|
+
claudeCode: "claude-code",
|
|
427
|
+
statusBar: "ccometix-line"
|
|
428
|
+
// workflow 和 aiPersonality 需要特殊处理,不能映射到 config-checker
|
|
429
|
+
};
|
|
430
|
+
for (const featureName of missingFeatures) {
|
|
431
|
+
if (featureName === "workflow" || featureName === "aiPersonality") {
|
|
432
|
+
console.log(ansis.blue(`\u{1F4E6} \u5B89\u88C5\u529F\u80FD: ${featureName}...`));
|
|
433
|
+
try {
|
|
434
|
+
const { selectAndInstallWorkflows } = await import('./chunks/simple-config.mjs').then(function (n) { return n.X; });
|
|
435
|
+
await selectAndInstallWorkflows("zh-CN", "zh-CN");
|
|
436
|
+
console.log(ansis.green(`\u2705 ${featureName} \u5B89\u88C5\u6210\u529F`));
|
|
437
|
+
} catch (error) {
|
|
438
|
+
console.log(ansis.yellow(`\u26A0\uFE0F ${featureName} \u5B89\u88C5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`));
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
441
|
+
const installerName = featureToInstallerMap[featureName];
|
|
442
|
+
if (installerName) {
|
|
443
|
+
console.log(ansis.blue(`\u{1F4E6} \u5B89\u88C5\u529F\u80FD: ${featureName}...`));
|
|
444
|
+
const result = await executor.execute(installerName, {
|
|
445
|
+
skipPrompt: true,
|
|
446
|
+
silent: true
|
|
447
|
+
});
|
|
448
|
+
if (result.success) {
|
|
449
|
+
console.log(ansis.green(`\u2705 ${featureName} \u5B89\u88C5\u6210\u529F`));
|
|
450
|
+
} else {
|
|
451
|
+
console.log(ansis.yellow(`\u26A0\uFE0F ${featureName} \u5B89\u88C5\u5931\u8D25: ${result.message}`));
|
|
452
|
+
}
|
|
453
|
+
} else {
|
|
454
|
+
console.log(ansis.yellow(`\u26A0\uFE0F \u672A\u77E5\u529F\u80FD: ${featureName}\uFF0C\u8DF3\u8FC7\u5B89\u88C5`));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
console.log(ansis.green("\u{1F389} \u7F3A\u5931\u529F\u80FD\u5B89\u88C5\u5B8C\u6210\uFF01"));
|
|
459
|
+
} catch (error) {
|
|
460
|
+
console.error(ansis.red(`\u2716 \u81EA\u52A8\u5B89\u88C5\u529F\u80FD\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`));
|
|
461
|
+
console.log(ansis.yellow("\u{1F4A1} \u8BF7\u624B\u52A8\u8FD0\u884C `aico --init` \u6765\u5B89\u88C5\u7F3A\u5931\u529F\u80FD"));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
419
464
|
|
|
420
465
|
if (!Array.prototype.findLastIndex) {
|
|
421
466
|
Array.prototype.findLastIndex = function(predicate, thisArg) {
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
package/templates/CLAUDE.md
CHANGED
|
@@ -1,3 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
[根目录](../CLAUDE.md) > **templates**
|
|
2
|
+
|
|
3
|
+
## 模块职责
|
|
4
|
+
- AI工作流模板与配置文件模板库
|
|
5
|
+
- 提供标准化的配置模板和工作流定义
|
|
6
|
+
- 支持多种AI场景的配置模板
|
|
7
|
+
|
|
8
|
+
## 模板分类
|
|
9
|
+
|
|
10
|
+
### AI智能体模板 (agents/)
|
|
11
|
+
- **规划智能体**: `agents/aico/plan/`
|
|
12
|
+
- `init-architect.md` - 架构师初始化模板
|
|
13
|
+
- `planner.md` - 规划器模板
|
|
14
|
+
- `ui-ux-designer.md` - UI/UX设计师模板
|
|
15
|
+
- `get-current-datetime.md` - 时间获取模板
|
|
16
|
+
- **需求智能体**: `agents/aico/requirement/`
|
|
17
|
+
- `requirement-identifier.md` - 需求识别器
|
|
18
|
+
- `requirement-aligner.md` - 需求对齐器
|
|
19
|
+
- `task-executor.md` - 任务执行器
|
|
20
|
+
- `task-executor-validator.md` - 任务执行验证器
|
|
21
|
+
- `task-splitter-validator.md` - 任务拆分验证器
|
|
22
|
+
|
|
23
|
+
### 命令模板 (commands/)
|
|
24
|
+
- **AICO命令**: `commands/aico/`
|
|
25
|
+
- `init-project.md` - 项目初始化模板
|
|
26
|
+
- `workflow.md` - 工作流模板
|
|
27
|
+
- `requirement.md` - 需求处理模板
|
|
28
|
+
|
|
29
|
+
### 基础配置模板
|
|
30
|
+
- `base.md` - 基础配置模板
|
|
31
|
+
- `language.md` - 语言配置模板
|
|
32
|
+
- `personality.md` - AI个性配置模板
|
|
33
|
+
- `settings.json` - 设置文件模板
|
|
34
|
+
|
|
35
|
+
## 模板使用
|
|
36
|
+
- **安装时使用**: 通过安装器将模板复制到用户目录
|
|
37
|
+
- **配置生成**: 根据模板生成具体的配置文件
|
|
38
|
+
- **动态替换**: 支持变量替换和个性化配置
|
|
39
|
+
|
|
40
|
+
## 模板规范
|
|
41
|
+
- **Markdown格式**: 大部分模板使用Markdown格式
|
|
42
|
+
- **JSON配置**: 配置文件使用JSON格式
|
|
43
|
+
- **变量占位符**: 使用特定的占位符语法进行变量替换
|
|
44
|
+
- **注释说明**: 包含详细的配置说明和使用指南
|
|
45
|
+
|
|
46
|
+
## 测试与质量
|
|
47
|
+
- **模板验证**: 确保模板语法正确性和完整性
|
|
48
|
+
- **变量检查**: 验证所有占位符都有对应的替换逻辑
|
|
49
|
+
- **格式校验**: 使用工具验证JSON和Markdown格式
|
|
50
|
+
|
|
51
|
+
## 常见问题 (FAQ)
|
|
52
|
+
- Q: 如何添加新的模板?
|
|
53
|
+
A: 在合适的分类目录下创建模板文件,确保有相应的安装器支持
|
|
54
|
+
- Q: 模板中的变量如何替换?
|
|
55
|
+
A: 通过安装器中的模板处理逻辑进行变量替换
|
|
56
|
+
- Q: 模板更新后如何生效?
|
|
57
|
+
A: 用户需要重新运行安装命令或更新命令
|
|
58
|
+
|
|
59
|
+
## 相关文件清单(主要)
|
|
60
|
+
- `agents/aico/plan/init-architect.md` - 架构师模板
|
|
61
|
+
- `agents/aico/plan/planner.md` - 规划器模板
|
|
62
|
+
- `agents/aico/requirement/requirement-identifier.md` - 需求识别模板
|
|
63
|
+
- `commands/aico/init-project.md` - 项目初始化模板
|
|
64
|
+
- `base.md` - 基础配置模板
|
|
65
|
+
- `language.md` - 语言配置模板
|
|
66
|
+
- `personality.md` - 个性配置模板
|
|
67
|
+
- `settings.json` - 设置文件模板
|
|
68
|
+
|
|
69
|
+
## 变更记录 (Changelog)
|
|
70
|
+
- 2025-09-14: 初始模板模块文档
|
|
71
|
+
- 2025-09-19: 完善模板分类和文档结构
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
## 错误修复
|
|
2
|
+
|
|
3
|
+
从错误信息中识别根本原因,预测解决时间,提出经过验证的解决方案。学习类似错误的模式,立即提供合适的处理方法。
|
|
4
|
+
|
|
5
|
+
### 使用方法
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
/fix-error [选项]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### 选项
|
|
12
|
+
|
|
13
|
+
- 无 : 标准错误分析
|
|
14
|
+
- `--deep` : 深度分析模式(包括依赖关系·环境因素)
|
|
15
|
+
- `--preventive` : 重视预防措施的分析
|
|
16
|
+
- `--quick` : 仅提供立即可用的修复方案
|
|
17
|
+
|
|
18
|
+
### 基本示例
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# 标准错误分析
|
|
22
|
+
npm run build 2>&1
|
|
23
|
+
/fix-error
|
|
24
|
+
"分析构建错误并提出修复方法"
|
|
25
|
+
|
|
26
|
+
# 深度分析模式
|
|
27
|
+
python app.py 2>&1
|
|
28
|
+
/fix-error --deep
|
|
29
|
+
"包括环境因素在内分析错误的根本原因"
|
|
30
|
+
|
|
31
|
+
# 即时修复重视
|
|
32
|
+
cargo test 2>&1
|
|
33
|
+
/fix-error --quick
|
|
34
|
+
"提供可立即应用的修复方法"
|
|
35
|
+
|
|
36
|
+
# 预防措施重视
|
|
37
|
+
./app 2>&1 | tail -50
|
|
38
|
+
/fix-error --preventive
|
|
39
|
+
"提出错误修复和未来的预防措施"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 与 Claude 的协作
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# 错误日志分析
|
|
46
|
+
cat error.log
|
|
47
|
+
/fix-error
|
|
48
|
+
"识别错误的根本原因,提出修复方法"
|
|
49
|
+
|
|
50
|
+
# 测试失败的解决
|
|
51
|
+
npm test 2>&1
|
|
52
|
+
/fix-error --quick
|
|
53
|
+
"分析失败的测试,提出可立即应用的修复方案"
|
|
54
|
+
|
|
55
|
+
# 堆栈跟踪的解析
|
|
56
|
+
python script.py 2>&1
|
|
57
|
+
/fix-error --deep
|
|
58
|
+
"从这个堆栈跟踪中定位问题,包括环境因素一起分析"
|
|
59
|
+
|
|
60
|
+
# 批量解决多个错误
|
|
61
|
+
grep -E "ERROR|WARN" app.log | tail -20
|
|
62
|
+
/fix-error
|
|
63
|
+
"按优先级分类这些错误和警告,分别提出解决方法"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 错误解决时间预测
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
🚀 即时修复(5 分钟内)
|
|
70
|
+
├─ 拼写错误、import 遗忘
|
|
71
|
+
├─ 环境变量未设置
|
|
72
|
+
├─ 未定义变量引用
|
|
73
|
+
└─ 预测时间: 2-5 分钟
|
|
74
|
+
|
|
75
|
+
⚡ 快速修复(30 分钟内)
|
|
76
|
+
├─ 依赖关系不一致
|
|
77
|
+
├─ 配置文件错误
|
|
78
|
+
├─ 类型不匹配
|
|
79
|
+
└─ 预测时间: 10-30 分钟
|
|
80
|
+
|
|
81
|
+
🔧 需要调查(2 小时内)
|
|
82
|
+
├─ 复杂逻辑错误
|
|
83
|
+
├─ 异步处理竞争
|
|
84
|
+
├─ API 集成问题
|
|
85
|
+
└─ 预测时间: 30 分钟-2 小时
|
|
86
|
+
|
|
87
|
+
🔌 深层分析(半天以上)
|
|
88
|
+
├─ 架构原因
|
|
89
|
+
├─ 多系统集成
|
|
90
|
+
├─ 性能降级
|
|
91
|
+
└─ 预测时间: 4 小时-数日
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 类似错误模式数据库
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
高频错误及即时解决方案
|
|
98
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
99
|
+
|
|
100
|
+
📊 "Cannot read property 'X' of undefined/null" (频出度: 极高)
|
|
101
|
+
├─ 主要原因: 对象的 null 检查不足
|
|
102
|
+
├─ 解决时间: 5-10 分钟
|
|
103
|
+
└─ 处理方法: 可选链式调用 (?.) 或添加 null 检查
|
|
104
|
+
|
|
105
|
+
📊 "ECONNREFUSED" / "ENOTFOUND" (频出度: 高)
|
|
106
|
+
├─ 主要原因: 服务未启动或 URL 配置错误
|
|
107
|
+
├─ 解决时间: 5-15 分钟
|
|
108
|
+
└─ 处理方法: 确认服务启动、检查环境变量
|
|
109
|
+
|
|
110
|
+
📊 "Module not found" / "Cannot resolve" (频出度: 高)
|
|
111
|
+
├─ 主要原因: 包未安装、路径指定错误
|
|
112
|
+
├─ 解决时间: 2-5 分钟
|
|
113
|
+
└─ 处理方法: 执行 npm install、确认相对路径
|
|
114
|
+
|
|
115
|
+
📊 "Unexpected token" / "SyntaxError" (频出度: 中)
|
|
116
|
+
├─ 主要原因: 括号、引号不匹配、使用保留字
|
|
117
|
+
├─ 解决时间: 2-10 分钟
|
|
118
|
+
└─ 处理方法: 确认语法高亮、执行 Linter
|
|
119
|
+
|
|
120
|
+
📊 "CORS policy" / "Access-Control-Allow-Origin" (频出度: 中)
|
|
121
|
+
├─ 主要原因: 服务端 CORS 配置不足
|
|
122
|
+
├─ 解决时间: 15-30 分钟
|
|
123
|
+
└─ 处理方法: 服务端 CORS 配置、代理设置
|
|
124
|
+
|
|
125
|
+
📊 "Maximum call stack size exceeded" (频出度: 低)
|
|
126
|
+
├─ 主要原因: 无限循环、递归、循环引用
|
|
127
|
+
├─ 解决时间: 30 分钟-2 小时
|
|
128
|
+
└─ 处理方法: 确认递归的终止条件、解决循环引用
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 错误分析优先级矩阵
|
|
132
|
+
|
|
133
|
+
| 优先级 | 图标 | 影响范围 | 解决难度 | 处理期限 | 说明 |
|
|
134
|
+
|--------|---------|---------|-----------|---------|------|
|
|
135
|
+
| **Critical** | 🔴 紧急处理 | 广 | 低 | 15 分钟内着手 | 系统全体停止、数据丢失风险 |
|
|
136
|
+
| **High Priority** | 🟠 早期处理 | 广 | 高 | 1 小时内着手 | 主要功能停止、多数用户影响 |
|
|
137
|
+
| **Medium** | 🟡 计划处理 | 狭 | 高 | 当日内处理 | 部分功能限制、有规避方案 |
|
|
138
|
+
| **Low** | 🟢 经过观察 | 狭 | 低 | 下次修改时 | 轻微不具、UX 影响小 |
|
|
139
|
+
|
|
140
|
+
### 分析流程
|
|
141
|
+
|
|
142
|
+
#### 阶段 1: 错误信息收集
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
🔴 必须执行:
|
|
146
|
+
- 完整获取错误信息
|
|
147
|
+
- 确认堆栈跟踪
|
|
148
|
+
- 确定发生条件(可重现性)
|
|
149
|
+
|
|
150
|
+
🟡 尽早执行:
|
|
151
|
+
- 收集环境信息(OS、版本、依赖)
|
|
152
|
+
- 最近的更改历史(git log、最近提交)
|
|
153
|
+
- 确认相关日志
|
|
154
|
+
|
|
155
|
+
🟢 附加执行:
|
|
156
|
+
- 系统资源状况
|
|
157
|
+
- 网络状态
|
|
158
|
+
- 外部服务状态
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### 阶段 2: 根本原因分析
|
|
162
|
+
|
|
163
|
+
1. **整理表面症状**
|
|
164
|
+
- 错误信息的准确内容
|
|
165
|
+
- 发生时机和模式
|
|
166
|
+
- 确定影响范围
|
|
167
|
+
|
|
168
|
+
2. **识别深层原因**
|
|
169
|
+
- 应用 5 Whys 分析
|
|
170
|
+
- 追踪依赖关系
|
|
171
|
+
- 确认环境差异
|
|
172
|
+
|
|
173
|
+
3. **验证假设**
|
|
174
|
+
- 创建最小重现代码
|
|
175
|
+
- 执行隔离测试
|
|
176
|
+
- 缩小原因范围
|
|
177
|
+
|
|
178
|
+
#### 阶段 3: 实施解决方案
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
🔴 立即处理(热修复):
|
|
182
|
+
- 抑制症状的最小修复
|
|
183
|
+
- 应用临时解决方案
|
|
184
|
+
- 准备紧急部署
|
|
185
|
+
|
|
186
|
+
🟡 根本解决:
|
|
187
|
+
- 针对原因的本质修复
|
|
188
|
+
- 添加测试用例
|
|
189
|
+
- 更新文档
|
|
190
|
+
|
|
191
|
+
🟢 实施预防措施:
|
|
192
|
+
- 加强错误处理
|
|
193
|
+
- 设置监控·告警
|
|
194
|
+
- 改进 CI/CD 管道
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 输出示例
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
🚨 错误分析报告
|
|
201
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
202
|
+
|
|
203
|
+
📍 错误概要
|
|
204
|
+
├─ 类型: [编译/运行时/逻辑/环境]
|
|
205
|
+
├─ 紧急度: 🔴 高 / 🟡 中 / 🟢 低
|
|
206
|
+
├─ 影响范围: [功能名/组件]
|
|
207
|
+
├─ 重现性: [100% / 间歇性 / 特定条件]
|
|
208
|
+
└─ 预测解决时间: [2-5 分钟 / 30 分钟-2 小时 / 4 小时+]
|
|
209
|
+
|
|
210
|
+
🔍 根本原因
|
|
211
|
+
├─ 直接原因: [具体原因]
|
|
212
|
+
├─ 背景因素: [环境/设置/依赖关系]
|
|
213
|
+
├─ 触发器: [发生条件]
|
|
214
|
+
└─ 类似模式: [已知错误类型 / 首次发生]
|
|
215
|
+
|
|
216
|
+
💡 解决方案
|
|
217
|
+
🔴 即时处理 (预计: X 分钟):
|
|
218
|
+
1. [具体修复命令/代码]
|
|
219
|
+
2. [临时解决方案]
|
|
220
|
+
|
|
221
|
+
🟡 根本解决 (预计: Y 小时):
|
|
222
|
+
1. [本质修复方法]
|
|
223
|
+
2. [必要的重构]
|
|
224
|
+
|
|
225
|
+
🟢 预防措施:
|
|
226
|
+
1. [错误处理改进]
|
|
227
|
+
2. [测试添加]
|
|
228
|
+
3. [监控设置]
|
|
229
|
+
|
|
230
|
+
📋 风险评估
|
|
231
|
+
├─ 修复失败风险: [低/中/高]
|
|
232
|
+
├─ 副作用影响: [无/有限/广泛]
|
|
233
|
+
└─ 回滚计划: [简单/复杂/不可能]
|
|
234
|
+
|
|
235
|
+
📝 验证步骤
|
|
236
|
+
1. [修复后的确认方法]
|
|
237
|
+
2. [测试执行命令]
|
|
238
|
+
3. [功能确认项目]
|
|
239
|
+
4. [性能影响检查]
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### 错误类型别分析方法
|
|
243
|
+
|
|
244
|
+
#### 编译/构建错误
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# TypeScript 类型错误
|
|
248
|
+
必须确认(高):
|
|
249
|
+
- tsconfig.json 设置
|
|
250
|
+
- 类型定义文件(.d.ts)存在
|
|
251
|
+
- import 语句的准确性
|
|
252
|
+
|
|
253
|
+
# Rust 生命周期错误
|
|
254
|
+
必须确认(高):
|
|
255
|
+
- 所有权转移
|
|
256
|
+
- 引用的有效期
|
|
257
|
+
- 可变性冲突
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### 运行时错误
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Null/Undefined 引用
|
|
264
|
+
必须确认(高):
|
|
265
|
+
- 可选链不足
|
|
266
|
+
- 初始化时机
|
|
267
|
+
- 异步处理的完成等待
|
|
268
|
+
|
|
269
|
+
# 内存相关错误
|
|
270
|
+
必须确认(高):
|
|
271
|
+
- 获取堆转储
|
|
272
|
+
- 分析 GC 日志
|
|
273
|
+
- 检测循环引用
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
#### 依赖关系错误
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# 版本冲突
|
|
280
|
+
必须确认(高):
|
|
281
|
+
- lock 文件的一致性
|
|
282
|
+
- peer dependencies 的要求
|
|
283
|
+
- 传递依赖关系
|
|
284
|
+
|
|
285
|
+
# 模块解析错误
|
|
286
|
+
必须确认(高):
|
|
287
|
+
- NODE_PATH 设置
|
|
288
|
+
- 路径别名设置
|
|
289
|
+
- 符号链接
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### 注意事项
|
|
293
|
+
|
|
294
|
+
- **绝对禁止**: 仅凭部分错误信息判断、未经验证就应用 Stack Overflow 的解决方案
|
|
295
|
+
- **例外条件**: 临时解决方案仅在以下 3 个条件下允许
|
|
296
|
+
1. 生产环境紧急响应(24 小时内必须根本解决)
|
|
297
|
+
2. 外部服务故障(等待恢复期间的替代手段)
|
|
298
|
+
3. 已知框架 bug(等待修复版本发布)
|
|
299
|
+
- **建议事项**: 优先识别根本原因,避免表面修复
|
|
300
|
+
|
|
301
|
+
### 最佳实践
|
|
302
|
+
|
|
303
|
+
1. **完整信息收集**: 确认错误信息从头到尾
|
|
304
|
+
2. **确认重现性**: 优先创建最小重现代码
|
|
305
|
+
3. **渐进式方法**: 从小修复开始验证
|
|
306
|
+
4. **文档化**: 记录解决过程以便知识共享
|
|
307
|
+
|
|
308
|
+
#### 常见陷阱
|
|
309
|
+
|
|
310
|
+
- **处理症状**: 表面修复忽略根本原因
|
|
311
|
+
- **过度泛化**: 将特定案例的解决方案广泛应用
|
|
312
|
+
- **省略验证**: 不确认修复后的副作用
|
|
313
|
+
- **知识孤岛**: 不记录解决方法
|
|
314
|
+
|
|
315
|
+
### 相关命令
|
|
316
|
+
|
|
317
|
+
- `/design-patterns` : 分析代码结构问题并提出模式建议
|
|
318
|
+
- `/tech-debt` : 从技术债务角度分析错误的根本原因
|
|
319
|
+
- `/analyzer` : 需要更深入的根本原因分析时使用
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
## 技术债务
|
|
2
|
+
|
|
3
|
+
分析项目的技术债务,创建按优先级排序的改进计划。
|
|
4
|
+
|
|
5
|
+
### 使用方法
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 确认项目结构并分析技术债务
|
|
9
|
+
ls -la
|
|
10
|
+
「分析这个项目的技术债务并创建改进计划」
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### 基本示例
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# 分析 TODO/FIXME 注释
|
|
17
|
+
grep -r "TODO\|FIXME\|HACK\|XXX\|WORKAROUND" . --exclude-dir=node_modules --exclude-dir=.git
|
|
18
|
+
「按优先级整理这些 TODO 注释并制定改进计划」
|
|
19
|
+
|
|
20
|
+
# 确认项目依赖关系
|
|
21
|
+
ls -la | grep -E "package.json|Cargo.toml|pubspec.yaml|go.mod|requirements.txt"
|
|
22
|
+
「分析项目的依赖关系,识别过时的依赖和风险」
|
|
23
|
+
|
|
24
|
+
# 检测大文件和复杂函数
|
|
25
|
+
find . -type f -not -path "*/\.*" -not -path "*/node_modules/*" -exec wc -l {} + | sort -rn | head -10
|
|
26
|
+
「识别过大的文件和复杂的结构,提出改进方案」
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 与 Claude 配合
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 全面的技术债务分析
|
|
33
|
+
ls -la && find . -name "*.md" -maxdepth 2 -exec head -20 {} \;
|
|
34
|
+
「从以下角度分析这个项目的技术债务:
|
|
35
|
+
1. 代码质量(复杂度、重复、可维护性)
|
|
36
|
+
2. 依赖关系健康度
|
|
37
|
+
3. 安全风险
|
|
38
|
+
4. 性能问题
|
|
39
|
+
5. 测试覆盖不足」
|
|
40
|
+
|
|
41
|
+
# 架构债务分析
|
|
42
|
+
find . -type d -name "src" -o -name "lib" -o -name "app" | head -10 | xargs ls -la
|
|
43
|
+
「识别架构层面的技术债务,提出重构计划」
|
|
44
|
+
|
|
45
|
+
# 按优先级排序的改进计划
|
|
46
|
+
「按以下标准评估技术债务并以表格形式展示:
|
|
47
|
+
- 影响度(高/中/低)
|
|
48
|
+
- 修复成本(时间)
|
|
49
|
+
- 业务风险
|
|
50
|
+
- 改进效果
|
|
51
|
+
- 推荐实施时期」
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 详细示例
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# 自动检测项目类型并分析
|
|
58
|
+
find . -maxdepth 2 -type f \( -name "package.json" -o -name "Cargo.toml" -o -name "pubspec.yaml" -o -name "go.mod" -o -name "pom.xml" \)
|
|
59
|
+
「基于检测到的项目类型,分析以下内容:
|
|
60
|
+
1. 语言和框架特定的技术债务
|
|
61
|
+
2. 偏离最佳实践的情况
|
|
62
|
+
3. 现代化机会
|
|
63
|
+
4. 分阶段改进策略」
|
|
64
|
+
|
|
65
|
+
# 代码质量指标分析
|
|
66
|
+
find . -type f -name "*" | grep -E "\.(js|ts|py|rs|go|dart|kotlin|swift|java)$" | wc -l
|
|
67
|
+
「分析项目的代码质量,展示以下指标:
|
|
68
|
+
- 循环复杂度高的函数
|
|
69
|
+
- 重复代码检测
|
|
70
|
+
- 过长的文件/函数
|
|
71
|
+
- 缺乏适当的错误处理」
|
|
72
|
+
|
|
73
|
+
# 安全债务检测
|
|
74
|
+
grep -r "password\|secret\|key\|token" . --exclude-dir=.git --exclude-dir=node_modules | grep -v ".env.example"
|
|
75
|
+
「检测安全相关的技术债务,提出修复优先级和对策」
|
|
76
|
+
|
|
77
|
+
# 测试不足分析
|
|
78
|
+
find . -type f \( -name "*test*" -o -name "*spec*" \) | wc -l && find . -type f -name "*.md" | xargs grep -l "test"
|
|
79
|
+
「分析测试覆盖的技术债务,提出测试策略」
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 项目健康度仪表盘
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
项目健康度评分:72/100
|
|
86
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
87
|
+
|
|
88
|
+
📊 分类评分
|
|
89
|
+
├─ 依赖关系新鲜度:████████░░ 82%(最新:45/55)
|
|
90
|
+
├─ 文档完整度:███░░░░░░░ 35%(缺少 README、API 文档)
|
|
91
|
+
├─ 测试覆盖率:██████░░░░ 65%(目标:80%)
|
|
92
|
+
├─ 安全性:███████░░░ 78%(漏洞:2 个中等风险)
|
|
93
|
+
├─ 架构:██████░░░░ 60%(循环依赖:3 处)
|
|
94
|
+
└─ 代码质量:███████░░░ 70%(高复杂度:12 个文件)
|
|
95
|
+
|
|
96
|
+
📈 趋势(过去 30 天)
|
|
97
|
+
├─ 总体评分:68 → 72 (+4) ↗️
|
|
98
|
+
├─ 改进项目:12 项 ✅
|
|
99
|
+
├─ 新增债务:3 项 ⚠️
|
|
100
|
+
├─ 已解决债务:8 项 🎉
|
|
101
|
+
└─ 改进速度:+0.13/天
|
|
102
|
+
|
|
103
|
+
⏱️ 债务的时间影响
|
|
104
|
+
├─ 开发速度降低:-20%(新功能开发需要正常 1.25 倍时间)
|
|
105
|
+
├─ Bug 修复时间增加:+15%(平均修复时间 2h → 2.3h)
|
|
106
|
+
├─ 代码审查开销:+30%(复杂度导致理解时间增加)
|
|
107
|
+
├─ 入职延迟:+50%(新成员理解所需时间)
|
|
108
|
+
└─ 累积延迟时间:相当于每周 40 小时
|
|
109
|
+
|
|
110
|
+
🎯 改进预期效果(基于时间)
|
|
111
|
+
├─ 即时效果:开发速度 +10%(1 周后)
|
|
112
|
+
├─ 短期效果:Bug 率 -25%(1 个月后)
|
|
113
|
+
├─ 中期效果:开发速度 +30%(3 个月后)
|
|
114
|
+
├─ 长期效果:维护时间 -50%(6 个月后)
|
|
115
|
+
└─ ROI:投资 40 小时 → 回收 120 小时(3 个月)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 优先级矩阵
|
|
119
|
+
|
|
120
|
+
| 优先级 | 开发影响 | 修复成本 | 时间节省效果 | 投资效率 | 响应期限 |
|
|
121
|
+
|--------|---------|---------|-------------|---------|---------|
|
|
122
|
+
| **[P0] 立即修复** | 高 | 低 | > 5 倍 | 投资 1h → 节省 5h+ | 立即 |
|
|
123
|
+
| **[P1] 本周内** | 高 | 中 | 2-5 倍 | 投资 1h → 节省 2-5h | 1 周内 |
|
|
124
|
+
| **[P2] 本月内** | 低 | 高 | 1-2 倍 | 投资 1h → 节省 1-2h | 1 个月内 |
|
|
125
|
+
| **[P3] 本季度内** | 低 | 低 | < 1 倍 | 投资=节省时间 | 3 个月内 |
|
|
126
|
+
|
|
127
|
+
### 债务类型评估标准
|
|
128
|
+
|
|
129
|
+
| 债务类型 | 检测方法 | 开发影响 | 修复时间 |
|
|
130
|
+
|---------|---------|---------|---------|
|
|
131
|
+
| **架构债务** | 循环依赖、紧耦合 | 变更影响范围大、测试困难 | 40-80h |
|
|
132
|
+
| **安全债务** | CVE 扫描、OWASP | 漏洞风险、合规问题 | 8-40h |
|
|
133
|
+
| **性能债务** | N+1 查询、内存泄漏 | 响应时间增加、资源消耗 | 16-40h |
|
|
134
|
+
| **测试债务** | 覆盖率 < 60% | Bug 检测延迟、质量不稳定 | 20-60h |
|
|
135
|
+
| **文档债务** | 缺少 README、API 文档 | 入职时间增加 | 8-24h |
|
|
136
|
+
| **依赖债务** | 2 年以上未更新 | 安全风险、兼容性问题 | 4-16h |
|
|
137
|
+
| **代码质量债务** | 复杂度 > 10 | 理解/修改时间增加 | 2-8h |
|
|
138
|
+
|
|
139
|
+
### 技术债务影响度计算
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
影响度 = Σ(各要素权重 × 测量值)
|
|
143
|
+
|
|
144
|
+
📊 可测量的影响指标:
|
|
145
|
+
├─ 开发速度影响
|
|
146
|
+
│ ├─ 代码理解时间:+X%(与复杂度成正比)
|
|
147
|
+
│ ├─ 变更时影响范围:Y 个文件(通过耦合度测量)
|
|
148
|
+
│ └─ 测试执行时间:Z 分钟(CI/CD 流水线)
|
|
149
|
+
│
|
|
150
|
+
├─ 质量影响
|
|
151
|
+
│ ├─ Bug 发生率:复杂度每 10 分增加 +25%
|
|
152
|
+
│ ├─ 代码审查时间:代码行数 × 复杂度系数
|
|
153
|
+
│ └─ 测试不足风险:覆盖率 < 60% 时高风险
|
|
154
|
+
│
|
|
155
|
+
└─ 团队效率影响
|
|
156
|
+
├─ 入职时间:缺少文档时增加 +100%
|
|
157
|
+
├─ 知识孤岛:单一贡献者比例 >80% 时需要注意
|
|
158
|
+
└─ 代码重复修复位置:重复率 × 变更频率
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 基于时间的 ROI 计算
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
ROI = (节省时间 - 投资时间) ÷ 投资时间 × 100
|
|
165
|
+
|
|
166
|
+
示例:解决循环依赖
|
|
167
|
+
├─ 投资时间:16 小时(重构)
|
|
168
|
+
├─ 每月节省:
|
|
169
|
+
│ ├─ 编译时间:-10 分钟/天 × 20 天 = 200 分钟
|
|
170
|
+
│ ├─ 调试时间:-2 小时/周 × 4 周 = 8 小时
|
|
171
|
+
│ └─ 新功能开发:-30% 时间缩短 = 12 小时
|
|
172
|
+
├─ 每月节省时间:23.3 小时
|
|
173
|
+
└─ 3 个月 ROI:(70 - 16) ÷ 16 × 100 = 337%
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 注意事项
|
|
177
|
+
|
|
178
|
+
- 自动检测项目的语言和框架,进行相应的分析
|
|
179
|
+
- 健康度评分采用 0-100 分制:70 分以上健康,50 分以下需要改进
|
|
180
|
+
- 计算具体的时间成本和改进效果,支持基于数据的决策制定
|
|
181
|
+
- 如需货币换算,请单独指定团队平均时薪或项目特定系数
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
## Ultrathink
|
|
2
|
+
|
|
3
|
+
对复杂课题或重要决策执行分阶段的结构化思考过程。
|
|
4
|
+
|
|
5
|
+
### 使用方法
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 请求 Claude 进行深度思考
|
|
9
|
+
「用 ultrathink 探讨[课题]」
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### 基本示例
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# 架构设计探讨
|
|
16
|
+
「用 ultrathink 探讨应该选择微服务还是单体架构」
|
|
17
|
+
|
|
18
|
+
# 技术选型分析
|
|
19
|
+
「用 ultrathink 分析这个项目适合 Rust 还是 TypeScript」
|
|
20
|
+
|
|
21
|
+
# 问题解决深入探讨
|
|
22
|
+
「用 ultrathink 探讨应用性能差的原因和改进方法」
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 与 Claude 配合
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# 业务判断
|
|
29
|
+
「用 ultrathink 探讨新功能的优先级排序。从用户价值、开发成本、技术风险的角度」
|
|
30
|
+
|
|
31
|
+
# 系统设计
|
|
32
|
+
「用 ultrathink 探讨认证系统的设计。考虑安全性、可扩展性、可维护性」
|
|
33
|
+
|
|
34
|
+
# 权衡分析
|
|
35
|
+
「用 ultrathink 分析 GraphQL vs REST API 的选择。基于项目需求」
|
|
36
|
+
|
|
37
|
+
# 重构策略
|
|
38
|
+
cat src/legacy_code.js
|
|
39
|
+
「用 ultrathink 制定这个遗留代码的重构策略」
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 思考过程
|
|
43
|
+
|
|
44
|
+
1. **问题分解** - 将课题分解为组成要素
|
|
45
|
+
2. **MECE 分析** - 无遗漏无重复地整理
|
|
46
|
+
3. **多角度探讨** - 从技术、业务、用户角度分析
|
|
47
|
+
4. **交互式确认** - 在重要判断点向用户确认
|
|
48
|
+
5. **有依据的建议** - 基于数据和逻辑的结论
|
|
49
|
+
|
|
50
|
+
### 详细示例
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# 复杂技术债务的解决
|
|
54
|
+
「用 ultrathink 探讨将 10 年的遗留系统现代化的策略。包括分阶段迁移、风险、ROI」
|
|
55
|
+
|
|
56
|
+
# 组织性课题
|
|
57
|
+
「用 ultrathink 探讨开发团队的扩展策略。假设从目前 5 人扩展到 20 人」
|
|
58
|
+
|
|
59
|
+
# 数据库迁移
|
|
60
|
+
「用 ultrathink 分析从 PostgreSQL 迁移到 DynamoDB。考虑成本、性能、运维」
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 注意事项
|
|
64
|
+
|
|
65
|
+
ultrathink 最适合需要花时间深入思考的课题。对于简单问题或需要即时回答的情况,请使用常规提问形式。
|
package/templates/personality.md
CHANGED
|
@@ -158,7 +158,71 @@ description: 架构师级软件工程师,以工程卓越为信仰,为追求
|
|
|
158
158
|
|
|
159
159
|
**实战智慧**: 在大规模系统中,技术治理的缺失会在6个月后开始显现,12个月后变成噩梦
|
|
160
160
|
|
|
161
|
-
### 4.
|
|
161
|
+
### 4. 需求分析与智能复述
|
|
162
|
+
|
|
163
|
+
**核心理念:**
|
|
164
|
+
> 准确理解需求是工程成功的第一步,模糊的需求只会产生错误的实现
|
|
165
|
+
|
|
166
|
+
**智能需求分析流程:**
|
|
167
|
+
|
|
168
|
+
**阶段一:需求解构分析**
|
|
169
|
+
- **功能需求识别**: 提取用户表达中的核心功能点和业务逻辑
|
|
170
|
+
- **非功能需求挖掘**: 识别性能、安全性、可用性等隐含要求
|
|
171
|
+
- **技术约束评估**: 分析现有技术栈、环境限制和依赖关系
|
|
172
|
+
- **边界条件确定**: 明确功能范围、异常场景和边界处理
|
|
173
|
+
|
|
174
|
+
**阶段二:结构化需求复述**
|
|
175
|
+
当接收到用户需求后,必须使用以下标准格式进行智能复述:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
📋 需求理解确认
|
|
179
|
+
|
|
180
|
+
🎯 核心目标
|
|
181
|
+
[用一句话概括用户的主要诉求]
|
|
182
|
+
|
|
183
|
+
🔧 功能需求
|
|
184
|
+
• [功能点1]: [具体描述和预期行为]
|
|
185
|
+
• [功能点2]: [具体描述和预期行为]
|
|
186
|
+
• [功能点N]: [具体描述和预期行为]
|
|
187
|
+
|
|
188
|
+
⚡ 非功能需求
|
|
189
|
+
• 性能要求: [响应时间、并发量等]
|
|
190
|
+
• 兼容性: [平台、浏览器、版本等]
|
|
191
|
+
• 安全性: [数据保护、访问控制等]
|
|
192
|
+
• 可维护性: [代码规范、文档要求等]
|
|
193
|
+
|
|
194
|
+
🎯 技术约束
|
|
195
|
+
• 技术栈: [现有框架、语言、工具限制]
|
|
196
|
+
• 环境限制: [部署环境、资源限制]
|
|
197
|
+
• 依赖关系: [第三方库、API、服务依赖]
|
|
198
|
+
|
|
199
|
+
📐 实现边界
|
|
200
|
+
• 包含功能: [明确要实现的功能范围]
|
|
201
|
+
• 排除功能: [明确不在本次范围内的功能]
|
|
202
|
+
• 边界场景: [异常情况、错误处理策略]
|
|
203
|
+
|
|
204
|
+
❓ 需要确认的点
|
|
205
|
+
• [不确定的技术细节或业务逻辑]
|
|
206
|
+
• [可能存在多种实现方案的选择点]
|
|
207
|
+
• [需要用户进一步澄清的需求点]
|
|
208
|
+
|
|
209
|
+
请确认以上理解是否准确,或指出需要调整的部分。
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**阶段三:交互式需求澄清**
|
|
213
|
+
- **主动询问**: 对模糊或不完整的需求主动提出专业性问题
|
|
214
|
+
- **方案权衡**: 当存在多种技术方案时,列举优缺点供用户选择
|
|
215
|
+
- **风险预警**: 提前识别潜在的技术风险和实现难点
|
|
216
|
+
- **迭代优化**: 基于用户反馈持续完善需求理解
|
|
217
|
+
|
|
218
|
+
**质量标准:**
|
|
219
|
+
- ✅ 需求复述必须覆盖用户提及的所有要点
|
|
220
|
+
- ✅ 使用用户能理解的业务语言,避免过度技术化
|
|
221
|
+
- ✅ 识别并主动询问缺失的关键信息
|
|
222
|
+
- ✅ 对有歧义的表述提供多种理解供确认
|
|
223
|
+
- ✅ 预见性地提出可能影响实现的技术考量
|
|
224
|
+
|
|
225
|
+
### 5. 持续问题解决
|
|
162
226
|
|
|
163
227
|
**行为准则:**
|
|
164
228
|
- 持续工作直到问题完全解决
|
|
@@ -221,6 +285,12 @@ description: 架构师级软件工程师,以工程卓越为信仰,为追求
|
|
|
221
285
|
- "懂你的意思,你遇到的是典型的[技术场景]..."
|
|
222
286
|
- "懂你的意思,让我从架构角度来分析..."
|
|
223
287
|
|
|
288
|
+
**需求理解确认:**
|
|
289
|
+
- "让我确认一下理解:你的需求是..."
|
|
290
|
+
- "懂你的意思,为了确保准确实现,我重新梳理一下需求..."
|
|
291
|
+
- "基于你的描述,我理解的核心需求包括..."
|
|
292
|
+
- "为避免理解偏差,请确认以下需求分析是否准确..."
|
|
293
|
+
|
|
224
294
|
**开场方式:**
|
|
225
295
|
- "从架构角度看,这个问题的关键是..."
|
|
226
296
|
- "基于我的经验,最有效的解决方案是..."
|