clawt 2.7.4 → 2.8.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/.claude/agent-memory/docs-sync-updater/MEMORY.md +11 -0
- package/README.md +18 -1
- package/dist/index.js +57 -19
- package/docs/spec.md +45 -3
- package/package.json +8 -8
- package/scripts/postinstall.ts +1 -1
- package/scripts/release.sh +9 -9
- package/src/constants/index.ts +1 -0
- package/src/constants/logger.ts +5 -0
- package/src/index.ts +10 -2
- package/src/logger/index.ts +50 -1
|
@@ -16,8 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
### README.md
|
|
18
18
|
- 面向用户的使用文档
|
|
19
|
+
- 全局选项在 `## 全局选项` 章节(位于 `## 使用前提` 和 `## 命令` 之间)
|
|
19
20
|
- 每个命令一个 `###` 小节,含命令格式、参数表格、简要说明、示例
|
|
20
21
|
- 配置文件说明在 `## 配置文件` 章节
|
|
22
|
+
- 日志说明在 `## 日志` 章节(文档末尾)
|
|
21
23
|
- 更新模式:更新命令说明段落,配置项表格
|
|
22
24
|
|
|
23
25
|
## 关键约定
|
|
@@ -90,3 +92,12 @@ Notes:
|
|
|
90
92
|
- `removeSnapshot()` 同时清理 `.tree` 和 `.head` 文件
|
|
91
93
|
- merge 成功后自动清理对应快照;merge 时主 worktree 脏 + 存在快照会输出警告提示
|
|
92
94
|
- docs/spec.md 中 validate 章节(5.4)按 `--clean 模式`、`首次 validate`、`增量 validate` 三段描述
|
|
95
|
+
|
|
96
|
+
## 全局选项
|
|
97
|
+
|
|
98
|
+
- `--debug` 全局选项在 `src/index.ts` 通过 Commander.js `.option()` + `preAction` 钩子实现
|
|
99
|
+
- `enableConsoleTransport()` 在 `src/logger/index.ts`,幂等地向 winston 添加 Console transport
|
|
100
|
+
- 调试相关常量在 `src/constants/logger.ts`:`DEBUG_LOG_PREFIX`、`DEBUG_TIMESTAMP_FORMAT`
|
|
101
|
+
- docs/spec.md 中 `--debug` 说明位于 `5.9 日志系统` 章节下的 `#### --debug 控制台调试输出` 子章节
|
|
102
|
+
- docs/spec.md 中 `4. 命令总览` 的命令表格后有 `**全局选项:**` 表格
|
|
103
|
+
- README.md 中 `## 全局选项` 章节(在 `## 使用前提` 和 `## 命令` 之间)
|
package/README.md
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
+
# 推荐
|
|
9
|
+
pnpm add -g clawt
|
|
10
|
+
|
|
11
|
+
# 或使用 npm
|
|
8
12
|
npm i -g clawt
|
|
9
13
|
```
|
|
10
14
|
|
|
@@ -18,6 +22,19 @@ npm i -g clawt
|
|
|
18
22
|
|
|
19
23
|
所有命令**必须在主 worktree 的仓库根目录**下执行(即包含 `.git` 目录的原始仓库)。在子 worktree 或子目录中执行会被拒绝。
|
|
20
24
|
|
|
25
|
+
## 全局选项
|
|
26
|
+
|
|
27
|
+
| 选项 | 说明 |
|
|
28
|
+
| ---- | ---- |
|
|
29
|
+
| `--debug` | 输出详细调试信息到终端,实时显示带颜色和时间戳的日志 |
|
|
30
|
+
|
|
31
|
+
`--debug` 可与任意子命令组合使用:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
clawt run -b feature-login --debug
|
|
35
|
+
clawt validate -b scheme --debug
|
|
36
|
+
```
|
|
37
|
+
|
|
21
38
|
## 命令
|
|
22
39
|
|
|
23
40
|
### `clawt create` — 批量创建 worktree
|
|
@@ -313,4 +330,4 @@ feature/a.b → feature-a-b
|
|
|
313
330
|
|
|
314
331
|
## 日志
|
|
315
332
|
|
|
316
|
-
日志保存在 `~/.clawt/logs/` 目录,按日期滚动,保留 30
|
|
333
|
+
日志保存在 `~/.clawt/logs/` 目录,按日期滚动,保留 30 天。使用 `--debug` 全局选项可在终端实时查看调试日志。
|
package/dist/index.js
CHANGED
|
@@ -221,6 +221,9 @@ var CONFIG_DESCRIPTIONS = deriveConfigDescriptions(CONFIG_DEFINITIONS);
|
|
|
221
221
|
// src/constants/git.ts
|
|
222
222
|
var AUTO_SAVE_COMMIT_MESSAGE = "chore: auto-save before sync";
|
|
223
223
|
|
|
224
|
+
// src/constants/logger.ts
|
|
225
|
+
var DEBUG_TIMESTAMP_FORMAT = "HH:mm:ss.SSS";
|
|
226
|
+
|
|
224
227
|
// src/errors/index.ts
|
|
225
228
|
var ClawtError = class extends Error {
|
|
226
229
|
/** 退出码 */
|
|
@@ -239,6 +242,7 @@ var ClawtError = class extends Error {
|
|
|
239
242
|
// src/logger/index.ts
|
|
240
243
|
import winston from "winston";
|
|
241
244
|
import DailyRotateFile from "winston-daily-rotate-file";
|
|
245
|
+
import chalk from "chalk";
|
|
242
246
|
import { existsSync, mkdirSync } from "fs";
|
|
243
247
|
if (!existsSync(LOGS_DIR)) {
|
|
244
248
|
mkdirSync(LOGS_DIR, { recursive: true });
|
|
@@ -262,6 +266,35 @@ var logger = winston.createLogger({
|
|
|
262
266
|
),
|
|
263
267
|
transports: [dailyRotateTransport]
|
|
264
268
|
});
|
|
269
|
+
var LEVEL_COLORS = {
|
|
270
|
+
error: chalk.red,
|
|
271
|
+
warn: chalk.yellow,
|
|
272
|
+
info: chalk.cyan,
|
|
273
|
+
debug: chalk.gray
|
|
274
|
+
};
|
|
275
|
+
function colorizeLevel(level) {
|
|
276
|
+
const colorFn = LEVEL_COLORS[level] || chalk.white;
|
|
277
|
+
return colorFn(level.toUpperCase().padEnd(5));
|
|
278
|
+
}
|
|
279
|
+
function enableConsoleTransport() {
|
|
280
|
+
const hasConsole = logger.transports.some(
|
|
281
|
+
(t) => t instanceof winston.transports.Console
|
|
282
|
+
);
|
|
283
|
+
if (hasConsole) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const consoleFormat = winston.format.printf(({ level, message, timestamp }) => {
|
|
287
|
+
return `${chalk.gray(timestamp)} ${colorizeLevel(level)} ${message}`;
|
|
288
|
+
});
|
|
289
|
+
const consoleTransport = new winston.transports.Console({
|
|
290
|
+
level: "debug",
|
|
291
|
+
format: winston.format.combine(
|
|
292
|
+
winston.format.timestamp({ format: DEBUG_TIMESTAMP_FORMAT }),
|
|
293
|
+
consoleFormat
|
|
294
|
+
)
|
|
295
|
+
});
|
|
296
|
+
logger.add(consoleTransport);
|
|
297
|
+
}
|
|
265
298
|
|
|
266
299
|
// src/utils/shell.ts
|
|
267
300
|
import { execSync, execFileSync, spawn } from "child_process";
|
|
@@ -467,16 +500,16 @@ function gitApplyCachedCheck(patchContent, cwd) {
|
|
|
467
500
|
}
|
|
468
501
|
|
|
469
502
|
// src/utils/formatter.ts
|
|
470
|
-
import
|
|
503
|
+
import chalk2 from "chalk";
|
|
471
504
|
import { createInterface } from "readline";
|
|
472
505
|
function printSuccess(message) {
|
|
473
|
-
console.log(
|
|
506
|
+
console.log(chalk2.green(message));
|
|
474
507
|
}
|
|
475
508
|
function printError(message) {
|
|
476
|
-
console.error(
|
|
509
|
+
console.error(chalk2.red(`\u2717 ${message}`));
|
|
477
510
|
}
|
|
478
511
|
function printWarning(message) {
|
|
479
|
-
console.log(
|
|
512
|
+
console.log(chalk2.yellow(`\u26A0 ${message}`));
|
|
480
513
|
}
|
|
481
514
|
function printInfo(message) {
|
|
482
515
|
console.log(message);
|
|
@@ -500,7 +533,7 @@ function confirmAction(question) {
|
|
|
500
533
|
});
|
|
501
534
|
}
|
|
502
535
|
function confirmDestructiveAction(dangerousCommand, description) {
|
|
503
|
-
printWarning(`\u5373\u5C06\u6267\u884C ${
|
|
536
|
+
printWarning(`\u5373\u5C06\u6267\u884C ${chalk2.red.bold(dangerousCommand)}\uFF0C${description}`);
|
|
504
537
|
return confirmAction("\u662F\u5426\u7EE7\u7EED\uFF1F");
|
|
505
538
|
}
|
|
506
539
|
function isWorktreeIdle(status) {
|
|
@@ -508,17 +541,17 @@ function isWorktreeIdle(status) {
|
|
|
508
541
|
}
|
|
509
542
|
function formatWorktreeStatus(status) {
|
|
510
543
|
const parts = [];
|
|
511
|
-
parts.push(
|
|
544
|
+
parts.push(chalk2.yellow(`${status.commitCount} \u4E2A\u63D0\u4EA4`));
|
|
512
545
|
if (status.insertions === 0 && status.deletions === 0) {
|
|
513
546
|
parts.push("\u65E0\u53D8\u66F4");
|
|
514
547
|
} else {
|
|
515
548
|
const diffParts = [];
|
|
516
|
-
diffParts.push(
|
|
517
|
-
diffParts.push(
|
|
549
|
+
diffParts.push(chalk2.green(`+${status.insertions}`));
|
|
550
|
+
diffParts.push(chalk2.red(`-${status.deletions}`));
|
|
518
551
|
parts.push(diffParts.join(" "));
|
|
519
552
|
}
|
|
520
553
|
if (status.hasDirtyFiles) {
|
|
521
|
-
parts.push(
|
|
554
|
+
parts.push(chalk2.gray("(\u672A\u63D0\u4EA4\u4FEE\u6539)"));
|
|
522
555
|
}
|
|
523
556
|
return parts.join(" ");
|
|
524
557
|
}
|
|
@@ -826,7 +859,7 @@ async function resolveTargetWorktree(worktrees, messages, branchName) {
|
|
|
826
859
|
}
|
|
827
860
|
|
|
828
861
|
// src/commands/list.ts
|
|
829
|
-
import
|
|
862
|
+
import chalk3 from "chalk";
|
|
830
863
|
function registerListCommand(program2) {
|
|
831
864
|
program2.command("list").description("\u5217\u51FA\u5F53\u524D\u9879\u76EE\u6240\u6709 worktree").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action((options) => {
|
|
832
865
|
handleList(options);
|
|
@@ -863,12 +896,12 @@ function printListAsText(projectName, worktrees) {
|
|
|
863
896
|
for (const wt of worktrees) {
|
|
864
897
|
const status = getWorktreeStatus(wt);
|
|
865
898
|
const isIdle = status ? isWorktreeIdle(status) : false;
|
|
866
|
-
const pathDisplay = isIdle ?
|
|
899
|
+
const pathDisplay = isIdle ? chalk3.hex("#FF8C00")(wt.path) : wt.path;
|
|
867
900
|
printInfo(` ${pathDisplay} [${wt.branch}]`);
|
|
868
901
|
if (status) {
|
|
869
902
|
printInfo(` ${formatWorktreeStatus(status)}`);
|
|
870
903
|
} else {
|
|
871
|
-
printInfo(` ${
|
|
904
|
+
printInfo(` ${chalk3.yellow(MESSAGES.WORKTREE_STATUS_UNAVAILABLE)}`);
|
|
872
905
|
}
|
|
873
906
|
printInfo("");
|
|
874
907
|
}
|
|
@@ -1467,7 +1500,7 @@ async function handleMerge(options) {
|
|
|
1467
1500
|
}
|
|
1468
1501
|
|
|
1469
1502
|
// src/commands/config.ts
|
|
1470
|
-
import
|
|
1503
|
+
import chalk4 from "chalk";
|
|
1471
1504
|
function registerConfigCommand(program2) {
|
|
1472
1505
|
const configCmd = program2.command("config").description("\u67E5\u770B\u548C\u7BA1\u7406\u5168\u5C40\u914D\u7F6E").action(() => {
|
|
1473
1506
|
handleConfig();
|
|
@@ -1480,7 +1513,7 @@ function handleConfig() {
|
|
|
1480
1513
|
const config = loadConfig();
|
|
1481
1514
|
logger.info("config \u547D\u4EE4\u6267\u884C\uFF0C\u5C55\u793A\u5168\u5C40\u914D\u7F6E");
|
|
1482
1515
|
printInfo(`
|
|
1483
|
-
${
|
|
1516
|
+
${chalk4.dim("\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84:")} ${CONFIG_PATH}
|
|
1484
1517
|
`);
|
|
1485
1518
|
printSeparator();
|
|
1486
1519
|
const keys = Object.keys(DEFAULT_CONFIG);
|
|
@@ -1490,8 +1523,8 @@ ${chalk3.dim("\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84:")} ${CONFIG_PATH}
|
|
|
1490
1523
|
const description = CONFIG_DESCRIPTIONS[key];
|
|
1491
1524
|
const formattedValue = formatConfigValue(value);
|
|
1492
1525
|
if (i === 0) printInfo("");
|
|
1493
|
-
printInfo(` ${
|
|
1494
|
-
printInfo(` ${
|
|
1526
|
+
printInfo(` ${chalk4.bold(key)}: ${formattedValue}`);
|
|
1527
|
+
printInfo(` ${chalk4.dim(description)}`);
|
|
1495
1528
|
printInfo("");
|
|
1496
1529
|
}
|
|
1497
1530
|
printSeparator();
|
|
@@ -1511,9 +1544,9 @@ async function handleConfigReset() {
|
|
|
1511
1544
|
}
|
|
1512
1545
|
function formatConfigValue(value) {
|
|
1513
1546
|
if (typeof value === "boolean") {
|
|
1514
|
-
return value ?
|
|
1547
|
+
return value ? chalk4.green("true") : chalk4.yellow("false");
|
|
1515
1548
|
}
|
|
1516
|
-
return
|
|
1549
|
+
return chalk4.cyan(String(value));
|
|
1517
1550
|
}
|
|
1518
1551
|
|
|
1519
1552
|
// src/commands/sync.ts
|
|
@@ -1604,7 +1637,12 @@ var require2 = createRequire(import.meta.url);
|
|
|
1604
1637
|
var { version } = require2("../package.json");
|
|
1605
1638
|
ensureClawtDirs();
|
|
1606
1639
|
var program = new Command();
|
|
1607
|
-
program.name("clawt").description("\u672C\u5730\u5E76\u884C\u6267\u884C\u591A\u4E2AClaude Code Agent\u4EFB\u52A1\uFF0C\u878D\u5408 Git Worktree \u4E0E Claude Code CLI \u7684\u547D\u4EE4\u884C\u5DE5\u5177").version(version);
|
|
1640
|
+
program.name("clawt").description("\u672C\u5730\u5E76\u884C\u6267\u884C\u591A\u4E2AClaude Code Agent\u4EFB\u52A1\uFF0C\u878D\u5408 Git Worktree \u4E0E Claude Code CLI \u7684\u547D\u4EE4\u884C\u5DE5\u5177").version(version).option("--debug", "\u8F93\u51FA\u8BE6\u7EC6\u8C03\u8BD5\u4FE1\u606F\u5230\u7EC8\u7AEF");
|
|
1641
|
+
program.hook("preAction", (thisCommand) => {
|
|
1642
|
+
if (thisCommand.opts().debug) {
|
|
1643
|
+
enableConsoleTransport();
|
|
1644
|
+
}
|
|
1645
|
+
});
|
|
1608
1646
|
registerListCommand(program);
|
|
1609
1647
|
registerCreateCommand(program);
|
|
1610
1648
|
registerRemoveCommand(program);
|
package/docs/spec.md
CHANGED
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
| -------- | ----------------------------- |
|
|
37
37
|
| 运行时 | Node.js >= 18 |
|
|
38
38
|
| 语言 | TypeScript |
|
|
39
|
-
| 包管理 |
|
|
39
|
+
| 包管理 | pnpm |
|
|
40
40
|
| CLI 框架 | Commander.js |
|
|
41
41
|
| 日志库 | winston (按日期滚动文件) |
|
|
42
42
|
| 交互式 | enquirer (选项选择/确认对话) |
|
|
43
43
|
| 构建 | tsup / tsc |
|
|
44
|
-
| 分发 |
|
|
44
|
+
| 分发 | pnpm 全局安装 (`pnpm add -g clawt`) |
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
@@ -173,6 +173,12 @@ git show-ref --verify refs/heads/<branchName> 2>/dev/null
|
|
|
173
173
|
| `clawt sync` | 将主分支最新代码同步到目标 worktree | 5.12 |
|
|
174
174
|
| `clawt reset` | 重置主 worktree 工作区和暂存区 | 5.13 |
|
|
175
175
|
|
|
176
|
+
**全局选项:**
|
|
177
|
+
|
|
178
|
+
| 选项 | 说明 |
|
|
179
|
+
| --------- | ---------------------------------------- |
|
|
180
|
+
| `--debug` | 输出详细调试信息到终端(启用 Console transport) |
|
|
181
|
+
|
|
176
182
|
所有命令执行前,都必须先执行**主 worktree 校验**(见 [2.1](#21-主-worktree-的定义与定位规则))。
|
|
177
183
|
|
|
178
184
|
---
|
|
@@ -748,7 +754,7 @@ clawt merge [-m <commitMessage>]
|
|
|
748
754
|
|
|
749
755
|
**路径:** `~/.clawt/config.json`
|
|
750
756
|
|
|
751
|
-
**生成时机:**
|
|
757
|
+
**生成时机:** 全局安装后自动生成(通过 `postinstall` 脚本)。
|
|
752
758
|
|
|
753
759
|
**升级策略:** 配置文件已存在时,执行增量合并而非简单跳过:
|
|
754
760
|
|
|
@@ -879,6 +885,42 @@ clawt list [--json]
|
|
|
879
885
|
- 日志文件保留 30 天
|
|
880
886
|
- 单个日志文件最大 10MB
|
|
881
887
|
|
|
888
|
+
#### `--debug` 控制台调试输出
|
|
889
|
+
|
|
890
|
+
通过全局选项 `--debug` 可将调试日志实时输出到终端,方便排查问题。
|
|
891
|
+
|
|
892
|
+
**实现机制:**
|
|
893
|
+
|
|
894
|
+
- 在 Commander.js 的 `preAction` 钩子中检测 `--debug` 选项,按需调用 `enableConsoleTransport()` 函数
|
|
895
|
+
- `enableConsoleTransport()` 动态向 winston 实例添加 `Console` transport(level 为 `debug`),该函数幂等,多次调用不会重复添加 transport
|
|
896
|
+
- 相关常量定义在 `src/constants/logger.ts`:
|
|
897
|
+
- `DEBUG_LOG_PREFIX`:控制台调试输出的日志前缀标识
|
|
898
|
+
- `DEBUG_TIMESTAMP_FORMAT`:时间戳格式(`HH:mm:ss.SSS`,精简,不含日期)
|
|
899
|
+
|
|
900
|
+
**控制台日志格式:**
|
|
901
|
+
|
|
902
|
+
```
|
|
903
|
+
HH:mm:ss.SSS LEVEL 消息内容
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
**日志级别颜色映射:**
|
|
907
|
+
|
|
908
|
+
| 级别 | 颜色 |
|
|
909
|
+
| ------- | ------ |
|
|
910
|
+
| `error` | 红色 |
|
|
911
|
+
| `warn` | 黄色 |
|
|
912
|
+
| `info` | 青色 |
|
|
913
|
+
| `debug` | 灰色 |
|
|
914
|
+
|
|
915
|
+
**使用示例:**
|
|
916
|
+
|
|
917
|
+
```bash
|
|
918
|
+
clawt run -b feature-login --debug
|
|
919
|
+
clawt validate -b feature-scheme --debug
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
> **注意:** `--debug` 选项不影响文件日志(file transport),文件日志始终按原有策略写入。控制台输出仅在传入 `--debug` 时启用。
|
|
923
|
+
|
|
882
924
|
---
|
|
883
925
|
|
|
884
926
|
### 5.10 查看和管理全局配置
|
package/package.json
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawt",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.1",
|
|
4
4
|
"description": "本地并行执行多个Claude Code Agent任务,融合 Git Worktree 与 Claude Code CLI 的命令行工具",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"clawt": "dist/index.js"
|
|
9
9
|
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsup",
|
|
12
|
-
"dev": "tsup --watch",
|
|
13
|
-
"postinstall": "node dist/postinstall.js",
|
|
14
|
-
"release": "bash scripts/release.sh"
|
|
15
|
-
},
|
|
16
10
|
"keywords": [
|
|
17
11
|
"claude",
|
|
18
12
|
"worktree",
|
|
@@ -35,5 +29,11 @@
|
|
|
35
29
|
},
|
|
36
30
|
"engines": {
|
|
37
31
|
"node": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup",
|
|
35
|
+
"dev": "tsup --watch",
|
|
36
|
+
"postinstall": "node dist/postinstall.js",
|
|
37
|
+
"release": "bash scripts/release.sh"
|
|
38
38
|
}
|
|
39
|
-
}
|
|
39
|
+
}
|
package/scripts/postinstall.ts
CHANGED
package/scripts/release.sh
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ============================================================
|
|
3
3
|
# release.sh - Clawt 自动发布脚本
|
|
4
|
-
# 功能: 构建 → 交互式选择版本级别 → 更新 package.json → 提交 → 打 tag → push →
|
|
4
|
+
# 功能: 构建 → 交互式选择版本级别 → 更新 package.json → 提交 → 打 tag → push → pnpm publish
|
|
5
5
|
# 用法: bash scripts/release.sh
|
|
6
6
|
# ============================================================
|
|
7
7
|
|
|
@@ -138,7 +138,7 @@ echo ""
|
|
|
138
138
|
|
|
139
139
|
TAG="v${NEW_VERSION}"
|
|
140
140
|
|
|
141
|
-
# 回滚函数:
|
|
141
|
+
# 回滚函数:pnpm publish 失败时撤销 commit、tag、push
|
|
142
142
|
# 参数 $1: 是否已推送到远程("pushed" 表示已推送)
|
|
143
143
|
rollback() {
|
|
144
144
|
local pushed="${1:-}"
|
|
@@ -166,7 +166,7 @@ rollback() {
|
|
|
166
166
|
# ────────────────────────────────────────
|
|
167
167
|
|
|
168
168
|
print_step "构建项目..."
|
|
169
|
-
|
|
169
|
+
pnpm build
|
|
170
170
|
print_success "构建完成"
|
|
171
171
|
|
|
172
172
|
# ────────────────────────────────────────
|
|
@@ -174,8 +174,8 @@ print_success "构建完成"
|
|
|
174
174
|
# ────────────────────────────────────────
|
|
175
175
|
|
|
176
176
|
print_step "更新版本号: ${CURRENT_VERSION} → ${NEW_VERSION}"
|
|
177
|
-
# 使用
|
|
178
|
-
|
|
177
|
+
# 使用 pnpm version 更新版本号,--no-git-tag-version 避免自动打 tag
|
|
178
|
+
pnpm version "$NEW_VERSION" --no-git-tag-version > /dev/null
|
|
179
179
|
print_success "版本号已更新"
|
|
180
180
|
|
|
181
181
|
# ────────────────────────────────────────
|
|
@@ -183,7 +183,7 @@ print_success "版本号已更新"
|
|
|
183
183
|
# ────────────────────────────────────────
|
|
184
184
|
|
|
185
185
|
print_step "提交版本变更..."
|
|
186
|
-
git add package.json
|
|
186
|
+
git add package.json pnpm-lock.yaml 2>/dev/null || git add package.json
|
|
187
187
|
git commit -m "build: bump version to ${NEW_VERSION}"
|
|
188
188
|
print_success "版本变更已提交"
|
|
189
189
|
|
|
@@ -197,14 +197,14 @@ print_success "tag 已创建: ${TAG}"
|
|
|
197
197
|
|
|
198
198
|
# ────────────────────────────────────────
|
|
199
199
|
# 步骤 5: 发布到 npm(先发布,成功后再推送 git)
|
|
200
|
-
# 调整顺序:
|
|
200
|
+
# 调整顺序:pnpm publish 放在 git push 之前
|
|
201
201
|
# 如果 publish 失败,只需回滚本地 commit 和 tag,无需处理远程
|
|
202
202
|
# ────────────────────────────────────────
|
|
203
203
|
|
|
204
204
|
print_step "发布到 npm..."
|
|
205
|
-
# 临时关闭 set -e,手动捕获
|
|
205
|
+
# 临时关闭 set -e,手动捕获 pnpm publish 的退出码
|
|
206
206
|
set +e
|
|
207
|
-
NPM_OUTPUT=$(
|
|
207
|
+
NPM_OUTPUT=$(pnpm publish --access public --registry https://registry.npmjs.org/ --no-git-checks 2>&1)
|
|
208
208
|
NPM_EXIT_CODE=$?
|
|
209
209
|
set -e
|
|
210
210
|
|
package/src/constants/index.ts
CHANGED
|
@@ -5,3 +5,4 @@ export { EXIT_CODES } from './exitCodes.js';
|
|
|
5
5
|
export { ENABLE_BRACKETED_PASTE, DISABLE_BRACKETED_PASTE, PASTE_THRESHOLD_MS } from './terminal.js';
|
|
6
6
|
export { DEFAULT_CONFIG, CONFIG_DESCRIPTIONS, APPEND_SYSTEM_PROMPT } from './config.js';
|
|
7
7
|
export { AUTO_SAVE_COMMIT_MESSAGE } from './git.js';
|
|
8
|
+
export { DEBUG_LOG_PREFIX, DEBUG_TIMESTAMP_FORMAT } from './logger.js';
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { ClawtError } from './errors/index.js';
|
|
4
|
-
import { logger } from './logger/index.js';
|
|
4
|
+
import { logger, enableConsoleTransport } from './logger/index.js';
|
|
5
5
|
import { EXIT_CODES } from './constants/index.js';
|
|
6
6
|
import { printError, ensureClawtDirs } from './utils/index.js';
|
|
7
7
|
import { registerListCommand } from './commands/list.js';
|
|
@@ -27,7 +27,15 @@ const program = new Command();
|
|
|
27
27
|
program
|
|
28
28
|
.name('clawt')
|
|
29
29
|
.description('本地并行执行多个Claude Code Agent任务,融合 Git Worktree 与 Claude Code CLI 的命令行工具')
|
|
30
|
-
.version(version)
|
|
30
|
+
.version(version)
|
|
31
|
+
.option('--debug', '输出详细调试信息到终端');
|
|
32
|
+
|
|
33
|
+
// 在子命令 action 执行前检查 --debug 选项,按需启用控制台日志
|
|
34
|
+
program.hook('preAction', (thisCommand) => {
|
|
35
|
+
if (thisCommand.opts().debug) {
|
|
36
|
+
enableConsoleTransport();
|
|
37
|
+
}
|
|
38
|
+
});
|
|
31
39
|
|
|
32
40
|
// 注册所有命令
|
|
33
41
|
registerListCommand(program);
|
package/src/logger/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import winston from 'winston';
|
|
2
2
|
import DailyRotateFile from 'winston-daily-rotate-file';
|
|
3
|
-
import
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { LOGS_DIR, DEBUG_TIMESTAMP_FORMAT } from '../constants/index.js';
|
|
4
5
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
5
6
|
|
|
6
7
|
// 确保日志目录存在
|
|
@@ -32,3 +33,51 @@ export const logger = winston.createLogger({
|
|
|
32
33
|
),
|
|
33
34
|
transports: [dailyRotateTransport],
|
|
34
35
|
});
|
|
36
|
+
|
|
37
|
+
/** 日志级别颜色映射 */
|
|
38
|
+
const LEVEL_COLORS: Record<string, (text: string) => string> = {
|
|
39
|
+
error: chalk.red,
|
|
40
|
+
warn: chalk.yellow,
|
|
41
|
+
info: chalk.cyan,
|
|
42
|
+
debug: chalk.gray,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 为日志级别添加对应颜色
|
|
47
|
+
* @param {string} level - 日志级别
|
|
48
|
+
* @returns {string} 带颜色的日志级别字符串
|
|
49
|
+
*/
|
|
50
|
+
function colorizeLevel(level: string): string {
|
|
51
|
+
const colorFn = LEVEL_COLORS[level] || chalk.white;
|
|
52
|
+
return colorFn(level.toUpperCase().padEnd(5));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 启用控制台日志输出(--debug 模式)
|
|
57
|
+
* 动态向 winston 实例添加 Console transport,输出带颜色和时间戳的调试信息
|
|
58
|
+
* 该函数幂等,多次调用不会重复添加 transport
|
|
59
|
+
*/
|
|
60
|
+
export function enableConsoleTransport(): void {
|
|
61
|
+
// 幂等保护:检查是否已添加过 Console transport
|
|
62
|
+
const hasConsole = logger.transports.some(
|
|
63
|
+
(t) => t instanceof winston.transports.Console,
|
|
64
|
+
);
|
|
65
|
+
if (hasConsole) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** --debug 模式的控制台日志格式:精简时间戳 + 带颜色级别 + 消息 */
|
|
70
|
+
const consoleFormat = winston.format.printf(({ level, message, timestamp }) => {
|
|
71
|
+
return `${chalk.gray(timestamp)} ${colorizeLevel(level)} ${message}`;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const consoleTransport = new winston.transports.Console({
|
|
75
|
+
level: 'debug',
|
|
76
|
+
format: winston.format.combine(
|
|
77
|
+
winston.format.timestamp({ format: DEBUG_TIMESTAMP_FORMAT }),
|
|
78
|
+
consoleFormat,
|
|
79
|
+
),
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
logger.add(consoleTransport);
|
|
83
|
+
}
|