ccli-core 0.0.1 → 0.0.2
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/commands/ccli.js +183 -0
- package/dist/commands/ccli.js.map +1 -0
- package/package.json +2 -4
- package/dist/commands/cpu-list.js +0 -44
- package/dist/commands/cpu-list.js.map +0 -1
- package/dist/commands/cpu-log.d.ts +0 -2
- package/dist/commands/cpu-log.js +0 -85
- package/dist/commands/cpu-log.js.map +0 -1
- package/dist/commands/cpu-update.d.ts +0 -2
- package/dist/commands/cpu-update.js +0 -47
- package/dist/commands/cpu-update.js.map +0 -1
- /package/dist/commands/{cpu-list.d.ts → ccli.d.ts} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @cmdName ccli
|
|
4
|
+
* ccli 父命令:list / log / update 三个子命令。
|
|
5
|
+
* 必须在 workspace 根目录下运行(list / update 子命令依赖 process.cwd() 为 workspace 根)。
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import { homedir } from "os";
|
|
11
|
+
import { execSync } from "child_process";
|
|
12
|
+
import chalk from "chalk";
|
|
13
|
+
import Table from "cli-table3";
|
|
14
|
+
import { syncCommands, npmLink } from "../index.js";
|
|
15
|
+
const program = new Command();
|
|
16
|
+
program.name("ccli").description("ccli 工具链管理命令(list / log / update)");
|
|
17
|
+
// ═══════════════════════════════════════════════
|
|
18
|
+
// ccli list 子命令
|
|
19
|
+
// ═══════════════════════════════════════════════
|
|
20
|
+
// 👁️ ccli list:读取 workspace package.json → 打印已注册命令表格
|
|
21
|
+
const listCmd = new Command("list")
|
|
22
|
+
.description("列出 workspace 当前已注册的所有命令(在 workspace 根目录下运行)")
|
|
23
|
+
.action(() => {
|
|
24
|
+
const workspaceRoot = process.cwd();
|
|
25
|
+
const packageJsonPath = path.join(workspaceRoot, "package.json");
|
|
26
|
+
try {
|
|
27
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
28
|
+
const bin = packageJson.bin || {};
|
|
29
|
+
const commandNames = Object.keys(bin);
|
|
30
|
+
if (commandNames.length === 0) {
|
|
31
|
+
console.log(chalk.yellow("目前没有注册任何命令。"));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
console.log(chalk.cyan(`\n🚀 当前已注册命令 (${commandNames.length}):\n`));
|
|
35
|
+
const table = new Table({
|
|
36
|
+
head: [chalk.green("领域"), chalk.green("命令名称"), chalk.green("源文件路径")],
|
|
37
|
+
colWidths: [15, 25, 60],
|
|
38
|
+
});
|
|
39
|
+
for (const [name, filePath] of Object.entries(bin)) {
|
|
40
|
+
const parts = filePath.split("/");
|
|
41
|
+
let domain = "unknown";
|
|
42
|
+
const commandsIdx = parts.indexOf("commands");
|
|
43
|
+
if (commandsIdx !== -1 && parts.length > commandsIdx + 1) {
|
|
44
|
+
domain = parts[commandsIdx + 1];
|
|
45
|
+
if (domain.endsWith(".js"))
|
|
46
|
+
domain = "root";
|
|
47
|
+
}
|
|
48
|
+
table.push([chalk.blue(domain), chalk.yellow(name), filePath]);
|
|
49
|
+
}
|
|
50
|
+
console.log(table.toString());
|
|
51
|
+
console.log("");
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error(chalk.red("读取 package.json 失败:"), error.message);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// ═══════════════════════════════════════════════
|
|
59
|
+
// ccli log 子命令(辅助函数)
|
|
60
|
+
// ═══════════════════════════════════════════════
|
|
61
|
+
function formatDuration(ms) {
|
|
62
|
+
return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;
|
|
63
|
+
}
|
|
64
|
+
function shortenPath(p) {
|
|
65
|
+
return p.replace(homedir(), "~");
|
|
66
|
+
}
|
|
67
|
+
function truncateCmd(cmd, args, maxLen = 38) {
|
|
68
|
+
const full = args.length ? `${cmd} ${args.join(" ")}` : cmd;
|
|
69
|
+
return full.length > maxLen ? full.slice(0, maxLen - 3) + "..." : full;
|
|
70
|
+
}
|
|
71
|
+
function readIndex() {
|
|
72
|
+
const indexFile = path.join(homedir(), "ccli", "logs", "index.jsonl");
|
|
73
|
+
if (!fs.existsSync(indexFile))
|
|
74
|
+
return [];
|
|
75
|
+
const lines = fs.readFileSync(indexFile, "utf8").trim().split("\n");
|
|
76
|
+
const entries = [];
|
|
77
|
+
for (const line of lines) {
|
|
78
|
+
if (!line.trim())
|
|
79
|
+
continue;
|
|
80
|
+
try {
|
|
81
|
+
entries.push(JSON.parse(line));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// 跳过损坏行
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return entries;
|
|
88
|
+
}
|
|
89
|
+
// 👁️ ccli log:查看历史运行记录(含 -n、-c、--failed 选项)
|
|
90
|
+
const logCmd = new Command("log")
|
|
91
|
+
.description("查看命令历史运行记录(存储于 ~/ccli/logs/)")
|
|
92
|
+
.option("-n, --tail <n>", "显示最近 n 条", "30")
|
|
93
|
+
.option("-c, --cmd <name>", "按命令名过滤")
|
|
94
|
+
.option("--failed", "只显示失败记录")
|
|
95
|
+
.action((opts) => {
|
|
96
|
+
let entries = readIndex();
|
|
97
|
+
if (opts.cmd) {
|
|
98
|
+
entries = entries.filter((e) => e.cmd === opts.cmd);
|
|
99
|
+
}
|
|
100
|
+
if (opts.failed) {
|
|
101
|
+
entries = entries.filter((e) => e.exitCode !== 0);
|
|
102
|
+
}
|
|
103
|
+
// 按时间倒序(最新在上)
|
|
104
|
+
entries.sort((a, b) => b.ts.localeCompare(a.ts));
|
|
105
|
+
const tail = Math.max(1, parseInt(opts.tail, 10) || 30);
|
|
106
|
+
entries = entries.slice(0, tail);
|
|
107
|
+
if (entries.length === 0) {
|
|
108
|
+
console.log(chalk.yellow("暂无运行记录。运行任意带 initCmdLogger 的命令后再试。"));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const table = new Table({
|
|
112
|
+
head: [
|
|
113
|
+
chalk.cyan("命令"),
|
|
114
|
+
chalk.cyan("结果"),
|
|
115
|
+
chalk.cyan("耗时"),
|
|
116
|
+
chalk.cyan("日志位置"),
|
|
117
|
+
],
|
|
118
|
+
colWidths: [40, 14, 8, 48],
|
|
119
|
+
style: { compact: false },
|
|
120
|
+
});
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
const cmdDisplay = truncateCmd(entry.cmd, entry.args);
|
|
123
|
+
const resultDisplay = entry.exitCode === 0
|
|
124
|
+
? chalk.green("✅ 成功")
|
|
125
|
+
: chalk.red(`❌ 失败(${entry.exitCode})`);
|
|
126
|
+
const durationDisplay = formatDuration(entry.duration);
|
|
127
|
+
const pathDisplay = shortenPath(entry.logFile);
|
|
128
|
+
table.push([cmdDisplay, resultDisplay, durationDisplay, pathDisplay]);
|
|
129
|
+
}
|
|
130
|
+
console.log(chalk.bold(`\n最近 ${entries.length} 条运行记录:\n`));
|
|
131
|
+
console.log(table.toString());
|
|
132
|
+
console.log();
|
|
133
|
+
});
|
|
134
|
+
// ═══════════════════════════════════════════════
|
|
135
|
+
// ccli update 子命令
|
|
136
|
+
// ═══════════════════════════════════════════════
|
|
137
|
+
// 👁️ ccli update:tsc → syncCommands → npmLink(逻辑封装在 action 中,避免模块顶层副作用)
|
|
138
|
+
const updateCmd = new Command("update")
|
|
139
|
+
.description("编译 workspace (tsc),扫描 dist/commands,同步 package.json bin,执行 npm link(在 workspace 根目录下运行)")
|
|
140
|
+
.action(() => {
|
|
141
|
+
const workspaceRoot = process.cwd();
|
|
142
|
+
console.log("\n[1/5] 正在编译 workspace (tsc)...");
|
|
143
|
+
execSync("npx tsc", { stdio: "inherit", cwd: workspaceRoot });
|
|
144
|
+
console.log(" - 编译完成。");
|
|
145
|
+
console.log("\n[2/5] 正在清理旧命令并扫描命令文件...");
|
|
146
|
+
const { previous, added } = syncCommands({ projectRoot: workspaceRoot });
|
|
147
|
+
if (previous.length > 0) {
|
|
148
|
+
console.log(` - 已清理旧命令 (${previous.length} 个): ${previous.join(", ")}`);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
console.log(" - 无需清理旧命令。");
|
|
152
|
+
}
|
|
153
|
+
console.log("\n[3/5] 扫描命令文件完成。");
|
|
154
|
+
if (added.length > 0) {
|
|
155
|
+
console.log(` - 发现 ${added.length} 个命令: ${added.join(", ")}`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
console.log(" - 未发现任何命令。");
|
|
159
|
+
}
|
|
160
|
+
console.log("\n[4/5] 正在注册命令到全局 (npm link)...");
|
|
161
|
+
try {
|
|
162
|
+
npmLink(workspaceRoot);
|
|
163
|
+
console.log(" - 注册成功。");
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
console.error(" - 注册失败:", error.message);
|
|
167
|
+
}
|
|
168
|
+
console.log("\n[5/5] 更新完成!");
|
|
169
|
+
console.log("---------------------------------------");
|
|
170
|
+
if (added.length > 0) {
|
|
171
|
+
console.log("你可以直接运行以下命令:");
|
|
172
|
+
added.forEach((cmd) => console.log(` $ ${cmd}`));
|
|
173
|
+
}
|
|
174
|
+
console.log("---------------------------------------\n");
|
|
175
|
+
});
|
|
176
|
+
// ═══════════════════════════════════════════════
|
|
177
|
+
// 注册子命令并解析
|
|
178
|
+
// ═══════════════════════════════════════════════
|
|
179
|
+
program.addCommand(listCmd);
|
|
180
|
+
program.addCommand(logCmd);
|
|
181
|
+
program.addCommand(updateCmd);
|
|
182
|
+
program.parse(process.argv);
|
|
183
|
+
//# sourceMappingURL=ccli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ccli.js","sourceRoot":"","sources":["../../src/commands/ccli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * @cmdName ccli\n * ccli 父命令:list / log / update 三个子命令。\n * 必须在 workspace 根目录下运行(list / update 子命令依赖 process.cwd() 为 workspace 根)。\n */\nimport { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { homedir } from \"os\";\nimport { execSync } from \"child_process\";\nimport chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport type { LogEntry } from \"../utils/cmdLogger.js\";\nimport { syncCommands, npmLink } from \"../index.js\";\n\nconst program = new Command();\nprogram.name(\"ccli\").description(\"ccli 工具链管理命令(list / log / update)\");\n\n// ═══════════════════════════════════════════════\n// ccli list 子命令\n// ═══════════════════════════════════════════════\n\n// 👁️ ccli list:读取 workspace package.json → 打印已注册命令表格\nconst listCmd = new Command(\"list\")\n .description(\"列出 workspace 当前已注册的所有命令(在 workspace 根目录下运行)\")\n .action(() => {\n const workspaceRoot = process.cwd();\n const packageJsonPath = path.join(workspaceRoot, \"package.json\");\n\n try {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf8\"));\n const bin: Record<string, string> = packageJson.bin || {};\n const commandNames = Object.keys(bin);\n\n if (commandNames.length === 0) {\n console.log(chalk.yellow(\"目前没有注册任何命令。\"));\n return;\n }\n\n console.log(chalk.cyan(`\\n🚀 当前已注册命令 (${commandNames.length}):\\n`));\n\n const table = new Table({\n head: [chalk.green(\"领域\"), chalk.green(\"命令名称\"), chalk.green(\"源文件路径\")],\n colWidths: [15, 25, 60],\n });\n\n for (const [name, filePath] of Object.entries(bin)) {\n const parts = filePath.split(\"/\");\n let domain = \"unknown\";\n const commandsIdx = parts.indexOf(\"commands\");\n if (commandsIdx !== -1 && parts.length > commandsIdx + 1) {\n domain = parts[commandsIdx + 1];\n if (domain.endsWith(\".js\")) domain = \"root\";\n }\n table.push([chalk.blue(domain), chalk.yellow(name), filePath]);\n }\n\n console.log(table.toString());\n console.log(\"\");\n } catch (error: any) {\n console.error(chalk.red(\"读取 package.json 失败:\"), error.message);\n process.exit(1);\n }\n });\n\n// ═══════════════════════════════════════════════\n// ccli log 子命令(辅助函数)\n// ═══════════════════════════════════════════════\n\nfunction formatDuration(ms: number): string {\n return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction shortenPath(p: string): string {\n return p.replace(homedir(), \"~\");\n}\n\nfunction truncateCmd(cmd: string, args: string[], maxLen = 38): string {\n const full = args.length ? `${cmd} ${args.join(\" \")}` : cmd;\n return full.length > maxLen ? full.slice(0, maxLen - 3) + \"...\" : full;\n}\n\nfunction readIndex(): LogEntry[] {\n const indexFile = path.join(homedir(), \"ccli\", \"logs\", \"index.jsonl\");\n if (!fs.existsSync(indexFile)) return [];\n\n const lines = fs.readFileSync(indexFile, \"utf8\").trim().split(\"\\n\");\n const entries: LogEntry[] = [];\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n entries.push(JSON.parse(line) as LogEntry);\n } catch {\n // 跳过损坏行\n }\n }\n return entries;\n}\n\n// 👁️ ccli log:查看历史运行记录(含 -n、-c、--failed 选项)\nconst logCmd = new Command(\"log\")\n .description(\"查看命令历史运行记录(存储于 ~/ccli/logs/)\")\n .option(\"-n, --tail <n>\", \"显示最近 n 条\", \"30\")\n .option(\"-c, --cmd <name>\", \"按命令名过滤\")\n .option(\"--failed\", \"只显示失败记录\")\n .action((opts: { tail: string; cmd?: string; failed?: boolean }) => {\n let entries = readIndex();\n\n if (opts.cmd) {\n entries = entries.filter((e) => e.cmd === opts.cmd);\n }\n if (opts.failed) {\n entries = entries.filter((e) => e.exitCode !== 0);\n }\n\n // 按时间倒序(最新在上)\n entries.sort((a, b) => b.ts.localeCompare(a.ts));\n\n const tail = Math.max(1, parseInt(opts.tail, 10) || 30);\n entries = entries.slice(0, tail);\n\n if (entries.length === 0) {\n console.log(chalk.yellow(\"暂无运行记录。运行任意带 initCmdLogger 的命令后再试。\"));\n return;\n }\n\n const table = new Table({\n head: [\n chalk.cyan(\"命令\"),\n chalk.cyan(\"结果\"),\n chalk.cyan(\"耗时\"),\n chalk.cyan(\"日志位置\"),\n ],\n colWidths: [40, 14, 8, 48],\n style: { compact: false },\n });\n\n for (const entry of entries) {\n const cmdDisplay = truncateCmd(entry.cmd, entry.args);\n const resultDisplay =\n entry.exitCode === 0\n ? chalk.green(\"✅ 成功\")\n : chalk.red(`❌ 失败(${entry.exitCode})`);\n const durationDisplay = formatDuration(entry.duration);\n const pathDisplay = shortenPath(entry.logFile);\n\n table.push([cmdDisplay, resultDisplay, durationDisplay, pathDisplay]);\n }\n\n console.log(chalk.bold(`\\n最近 ${entries.length} 条运行记录:\\n`));\n console.log(table.toString());\n console.log();\n });\n\n// ═══════════════════════════════════════════════\n// ccli update 子命令\n// ═══════════════════════════════════════════════\n\n// 👁️ ccli update:tsc → syncCommands → npmLink(逻辑封装在 action 中,避免模块顶层副作用)\nconst updateCmd = new Command(\"update\")\n .description(\"编译 workspace (tsc),扫描 dist/commands,同步 package.json bin,执行 npm link(在 workspace 根目录下运行)\")\n .action(() => {\n const workspaceRoot = process.cwd();\n\n console.log(\"\\n[1/5] 正在编译 workspace (tsc)...\");\n execSync(\"npx tsc\", { stdio: \"inherit\", cwd: workspaceRoot });\n console.log(\" - 编译完成。\");\n\n console.log(\"\\n[2/5] 正在清理旧命令并扫描命令文件...\");\n\n const { previous, added } = syncCommands({ projectRoot: workspaceRoot });\n\n if (previous.length > 0) {\n console.log(` - 已清理旧命令 (${previous.length} 个): ${previous.join(\", \")}`);\n } else {\n console.log(\" - 无需清理旧命令。\");\n }\n\n console.log(\"\\n[3/5] 扫描命令文件完成。\");\n if (added.length > 0) {\n console.log(` - 发现 ${added.length} 个命令: ${added.join(\", \")}`);\n } else {\n console.log(\" - 未发现任何命令。\");\n }\n\n console.log(\"\\n[4/5] 正在注册命令到全局 (npm link)...\");\n try {\n npmLink(workspaceRoot);\n console.log(\" - 注册成功。\");\n } catch (error: any) {\n console.error(\" - 注册失败:\", error.message);\n }\n\n console.log(\"\\n[5/5] 更新完成!\");\n console.log(\"---------------------------------------\");\n if (added.length > 0) {\n console.log(\"你可以直接运行以下命令:\");\n added.forEach((cmd) => console.log(` $ ${cmd}`));\n }\n console.log(\"---------------------------------------\\n\");\n });\n\n// ═══════════════════════════════════════════════\n// 注册子命令并解析\n// ═══════════════════════════════════════════════\n\nprogram.addCommand(listCmd);\nprogram.addCommand(logCmd);\nprogram.addCommand(updateCmd);\n\nprogram.parse(process.argv);\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccli-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -15,9 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"bin": {
|
|
17
17
|
"adc": "./dist/commands/adc.js",
|
|
18
|
-
"
|
|
19
|
-
"cpu-list": "./dist/commands/cpu-list.js",
|
|
20
|
-
"cpu-log": "./dist/commands/cpu-log.js"
|
|
18
|
+
"ccli": "./dist/commands/ccli.js"
|
|
21
19
|
},
|
|
22
20
|
"files": [
|
|
23
21
|
"dist/**/*"
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* @cmdName cpu-list
|
|
4
|
-
* 列出 workspace 当前已注册的所有命令。
|
|
5
|
-
* 必须在 workspace 根目录下运行。
|
|
6
|
-
*/
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import chalk from "chalk";
|
|
10
|
-
import Table from "cli-table3";
|
|
11
|
-
const workspaceRoot = process.cwd();
|
|
12
|
-
const packageJsonPath = path.join(workspaceRoot, "package.json");
|
|
13
|
-
try {
|
|
14
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
15
|
-
const bin = packageJson.bin || {};
|
|
16
|
-
const commandNames = Object.keys(bin);
|
|
17
|
-
if (commandNames.length === 0) {
|
|
18
|
-
console.log(chalk.yellow("目前没有注册任何命令。"));
|
|
19
|
-
process.exit(0);
|
|
20
|
-
}
|
|
21
|
-
console.log(chalk.cyan(`\n🚀 当前已注册命令 (${commandNames.length}):\n`));
|
|
22
|
-
const table = new Table({
|
|
23
|
-
head: [chalk.green("领域"), chalk.green("命令名称"), chalk.green("源文件路径")],
|
|
24
|
-
colWidths: [15, 25, 60],
|
|
25
|
-
});
|
|
26
|
-
for (const [name, filePath] of Object.entries(bin)) {
|
|
27
|
-
const parts = filePath.split("/");
|
|
28
|
-
let domain = "unknown";
|
|
29
|
-
const commandsIdx = parts.indexOf("commands");
|
|
30
|
-
if (commandsIdx !== -1 && parts.length > commandsIdx + 1) {
|
|
31
|
-
domain = parts[commandsIdx + 1];
|
|
32
|
-
if (domain.endsWith(".js"))
|
|
33
|
-
domain = "root";
|
|
34
|
-
}
|
|
35
|
-
table.push([chalk.blue(domain), chalk.yellow(name), filePath]);
|
|
36
|
-
}
|
|
37
|
-
console.log(table.toString());
|
|
38
|
-
console.log("");
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
console.error(chalk.red("读取 package.json 失败:"), error.message);
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=cpu-list.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cpu-list.js","sourceRoot":"","sources":["../../src/commands/cpu-list.ts"],"names":[],"mappings":";AACA;;;;GAIG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AACpC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AAEjE,IAAI,CAAC;IACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,GAAG,GAA2B,WAAW,CAAC,GAAG,IAAI,EAAE,CAAC;IAC1D,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,YAAY,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC;IAEpE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;KACxB,CAAC,CAAC;IAEH,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,MAAM,GAAG,SAAS,CAAC;QACvB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,WAAW,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,GAAG,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;YAChC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,MAAM,GAAG,MAAM,CAAC;QAC9C,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAAC,OAAO,KAAU,EAAE,CAAC;IACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC","sourcesContent":["#!/usr/bin/env node\n/**\n * @cmdName cpu-list\n * 列出 workspace 当前已注册的所有命令。\n * 必须在 workspace 根目录下运行。\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport Table from \"cli-table3\";\n\nconst workspaceRoot = process.cwd();\nconst packageJsonPath = path.join(workspaceRoot, \"package.json\");\n\ntry {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf8\"));\n const bin: Record<string, string> = packageJson.bin || {};\n const commandNames = Object.keys(bin);\n\n if (commandNames.length === 0) {\n console.log(chalk.yellow(\"目前没有注册任何命令。\"));\n process.exit(0);\n }\n\n console.log(chalk.cyan(`\\n🚀 当前已注册命令 (${commandNames.length}):\\n`));\n\n const table = new Table({\n head: [chalk.green(\"领域\"), chalk.green(\"命令名称\"), chalk.green(\"源文件路径\")],\n colWidths: [15, 25, 60],\n });\n\n for (const [name, filePath] of Object.entries(bin)) {\n const parts = filePath.split(\"/\");\n let domain = \"unknown\";\n const commandsIdx = parts.indexOf(\"commands\");\n if (commandsIdx !== -1 && parts.length > commandsIdx + 1) {\n domain = parts[commandsIdx + 1];\n if (domain.endsWith(\".js\")) domain = \"root\";\n }\n table.push([chalk.blue(domain), chalk.yellow(name), filePath]);\n }\n\n console.log(table.toString());\n console.log(\"\");\n} catch (error: any) {\n console.error(chalk.red(\"读取 package.json 失败:\"), error.message);\n process.exit(1);\n}\n"]}
|
package/dist/commands/cpu-log.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* @cmdName cpu-log
|
|
4
|
-
* 查看所有命令的历史运行记录。
|
|
5
|
-
*/
|
|
6
|
-
import { homedir } from "os";
|
|
7
|
-
import { join } from "path";
|
|
8
|
-
import { existsSync, readFileSync } from "fs";
|
|
9
|
-
import { program } from "commander";
|
|
10
|
-
import chalk from "chalk";
|
|
11
|
-
import Table from "cli-table3";
|
|
12
|
-
function formatDuration(ms) {
|
|
13
|
-
return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;
|
|
14
|
-
}
|
|
15
|
-
function shortenPath(p) {
|
|
16
|
-
return p.replace(homedir(), "~");
|
|
17
|
-
}
|
|
18
|
-
function truncateCmd(cmd, args, maxLen = 38) {
|
|
19
|
-
const full = args.length ? `${cmd} ${args.join(" ")}` : cmd;
|
|
20
|
-
return full.length > maxLen ? full.slice(0, maxLen - 3) + "..." : full;
|
|
21
|
-
}
|
|
22
|
-
function readIndex() {
|
|
23
|
-
const indexFile = join(homedir(), "ccli", "logs", "index.jsonl");
|
|
24
|
-
if (!existsSync(indexFile))
|
|
25
|
-
return [];
|
|
26
|
-
const lines = readFileSync(indexFile, "utf8").trim().split("\n");
|
|
27
|
-
const entries = [];
|
|
28
|
-
for (const line of lines) {
|
|
29
|
-
if (!line.trim())
|
|
30
|
-
continue;
|
|
31
|
-
try {
|
|
32
|
-
entries.push(JSON.parse(line));
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// 跳过损坏行
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return entries;
|
|
39
|
-
}
|
|
40
|
-
program
|
|
41
|
-
.description("查看命令历史运行记录(存储于 ~/ccli/logs/)")
|
|
42
|
-
.option("-n, --tail <n>", "显示最近 n 条", "30")
|
|
43
|
-
.option("-c, --cmd <name>", "按命令名过滤")
|
|
44
|
-
.option("--failed", "只显示失败记录")
|
|
45
|
-
.action((opts) => {
|
|
46
|
-
let entries = readIndex();
|
|
47
|
-
if (opts.cmd) {
|
|
48
|
-
entries = entries.filter((e) => e.cmd === opts.cmd);
|
|
49
|
-
}
|
|
50
|
-
if (opts.failed) {
|
|
51
|
-
entries = entries.filter((e) => e.exitCode !== 0);
|
|
52
|
-
}
|
|
53
|
-
// 按时间倒序(最新在上)
|
|
54
|
-
entries.sort((a, b) => b.ts.localeCompare(a.ts));
|
|
55
|
-
const tail = Math.max(1, parseInt(opts.tail, 10) || 30);
|
|
56
|
-
entries = entries.slice(0, tail);
|
|
57
|
-
if (entries.length === 0) {
|
|
58
|
-
console.log(chalk.yellow("暂无运行记录。运行任意带 initCmdLogger 的命令后再试。"));
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const table = new Table({
|
|
62
|
-
head: [
|
|
63
|
-
chalk.cyan("命令"),
|
|
64
|
-
chalk.cyan("结果"),
|
|
65
|
-
chalk.cyan("耗时"),
|
|
66
|
-
chalk.cyan("日志位置"),
|
|
67
|
-
],
|
|
68
|
-
colWidths: [40, 14, 8, 48],
|
|
69
|
-
style: { compact: false },
|
|
70
|
-
});
|
|
71
|
-
for (const entry of entries) {
|
|
72
|
-
const cmdDisplay = truncateCmd(entry.cmd, entry.args);
|
|
73
|
-
const resultDisplay = entry.exitCode === 0
|
|
74
|
-
? chalk.green("✅ 成功")
|
|
75
|
-
: chalk.red(`❌ 失败(${entry.exitCode})`);
|
|
76
|
-
const durationDisplay = formatDuration(entry.duration);
|
|
77
|
-
const pathDisplay = shortenPath(entry.logFile);
|
|
78
|
-
table.push([cmdDisplay, resultDisplay, durationDisplay, pathDisplay]);
|
|
79
|
-
}
|
|
80
|
-
console.log(chalk.bold(`\n最近 ${entries.length} 条运行记录:\n`));
|
|
81
|
-
console.log(table.toString());
|
|
82
|
-
console.log();
|
|
83
|
-
})
|
|
84
|
-
.parse(process.argv);
|
|
85
|
-
//# sourceMappingURL=cpu-log.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cpu-log.js","sourceRoot":"","sources":["../../src/commands/cpu-log.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * @cmdName cpu-log\n * 查看所有命令的历史运行记录。\n */\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { program } from \"commander\";\nimport chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport type { LogEntry } from \"../utils/cmdLogger.js\";\n\nfunction formatDuration(ms: number): string {\n return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction shortenPath(p: string): string {\n return p.replace(homedir(), \"~\");\n}\n\nfunction truncateCmd(cmd: string, args: string[], maxLen = 38): string {\n const full = args.length ? `${cmd} ${args.join(\" \")}` : cmd;\n return full.length > maxLen ? full.slice(0, maxLen - 3) + \"...\" : full;\n}\n\nfunction readIndex(): LogEntry[] {\n const indexFile = join(homedir(), \"ccli\", \"logs\", \"index.jsonl\");\n if (!existsSync(indexFile)) return [];\n\n const lines = readFileSync(indexFile, \"utf8\").trim().split(\"\\n\");\n const entries: LogEntry[] = [];\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n entries.push(JSON.parse(line) as LogEntry);\n } catch {\n // 跳过损坏行\n }\n }\n return entries;\n}\n\nprogram\n .description(\"查看命令历史运行记录(存储于 ~/ccli/logs/)\")\n .option(\"-n, --tail <n>\", \"显示最近 n 条\", \"30\")\n .option(\"-c, --cmd <name>\", \"按命令名过滤\")\n .option(\"--failed\", \"只显示失败记录\")\n .action((opts: { tail: string; cmd?: string; failed?: boolean }) => {\n let entries = readIndex();\n\n if (opts.cmd) {\n entries = entries.filter((e) => e.cmd === opts.cmd);\n }\n if (opts.failed) {\n entries = entries.filter((e) => e.exitCode !== 0);\n }\n\n // 按时间倒序(最新在上)\n entries.sort((a, b) => b.ts.localeCompare(a.ts));\n\n const tail = Math.max(1, parseInt(opts.tail, 10) || 30);\n entries = entries.slice(0, tail);\n\n if (entries.length === 0) {\n console.log(chalk.yellow(\"暂无运行记录。运行任意带 initCmdLogger 的命令后再试。\"));\n return;\n }\n\n const table = new Table({\n head: [\n chalk.cyan(\"命令\"),\n chalk.cyan(\"结果\"),\n chalk.cyan(\"耗时\"),\n chalk.cyan(\"日志位置\"),\n ],\n colWidths: [40, 14, 8, 48],\n style: { compact: false },\n });\n\n for (const entry of entries) {\n const cmdDisplay = truncateCmd(entry.cmd, entry.args);\n const resultDisplay =\n entry.exitCode === 0\n ? chalk.green(\"✅ 成功\")\n : chalk.red(`❌ 失败(${entry.exitCode})`);\n const durationDisplay = formatDuration(entry.duration);\n const pathDisplay = shortenPath(entry.logFile);\n\n table.push([cmdDisplay, resultDisplay, durationDisplay, pathDisplay]);\n }\n\n console.log(chalk.bold(`\\n最近 ${entries.length} 条运行记录:\\n`));\n console.log(table.toString());\n console.log();\n })\n .parse(process.argv);\n"]}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* @cmdName cpu-update
|
|
4
|
-
* 先在 workspace 执行一次 tsc(根项目 + cli-core),再扫描 dist/commands、同步 package.json bin 并 npm link。
|
|
5
|
-
* 必须在 workspace 根目录下运行。
|
|
6
|
-
*/
|
|
7
|
-
import { execSync } from "child_process";
|
|
8
|
-
import { syncCommands, npmLink } from "../index.js";
|
|
9
|
-
const workspaceRoot = process.cwd();
|
|
10
|
-
console.log("\n[1/5] 正在编译 workspace (tsc)...");
|
|
11
|
-
execSync("npx tsc", { stdio: "inherit", cwd: workspaceRoot });
|
|
12
|
-
execSync("npx tsc -p packages/cli-core/tsconfig.json", {
|
|
13
|
-
stdio: "inherit",
|
|
14
|
-
cwd: workspaceRoot,
|
|
15
|
-
});
|
|
16
|
-
console.log(" - 编译完成。");
|
|
17
|
-
console.log("\n[2/5] 正在清理旧命令并扫描命令文件...");
|
|
18
|
-
const { previous, added } = syncCommands({ projectRoot: workspaceRoot });
|
|
19
|
-
if (previous.length > 0) {
|
|
20
|
-
console.log(` - 已清理旧命令 (${previous.length} 个): ${previous.join(", ")}`);
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
console.log(" - 无需清理旧命令。");
|
|
24
|
-
}
|
|
25
|
-
console.log("\n[3/5] 扫描命令文件完成。");
|
|
26
|
-
if (added.length > 0) {
|
|
27
|
-
console.log(` - 发现 ${added.length} 个命令: ${added.join(", ")}`);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
console.log(" - 未发现任何命令。");
|
|
31
|
-
}
|
|
32
|
-
console.log("\n[4/5] 正在注册命令到全局 (npm link)...");
|
|
33
|
-
try {
|
|
34
|
-
npmLink(workspaceRoot);
|
|
35
|
-
console.log(" - 注册成功。");
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
console.error(" - 注册失败:", error.message);
|
|
39
|
-
}
|
|
40
|
-
console.log("\n[5/5] 更新完成!");
|
|
41
|
-
console.log("---------------------------------------");
|
|
42
|
-
if (added.length > 0) {
|
|
43
|
-
console.log("你可以直接运行以下命令:");
|
|
44
|
-
added.forEach((cmd) => console.log(` $ ${cmd}`));
|
|
45
|
-
}
|
|
46
|
-
console.log("---------------------------------------\n");
|
|
47
|
-
//# sourceMappingURL=cpu-update.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cpu-update.js","sourceRoot":"","sources":["../../src/commands/cpu-update.ts"],"names":[],"mappings":";AACA;;;;GAIG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAEpC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AAC/C,QAAQ,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;AAC9D,QAAQ,CAAC,4CAA4C,EAAE;IACrD,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,aAAa;CACnB,CAAC,CAAC;AACH,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAEzB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAEzC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC;AAEzE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACxB,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,MAAM,QAAQ,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC9B,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC9B,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AAC/C,IAAI,CAAC;IACH,OAAO,CAAC,aAAa,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC3B,CAAC;AAAC,OAAO,KAAU,EAAE,CAAC;IACpB,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AAC7B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;AACvD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;AACpD,CAAC;AACD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\n/**\n * @cmdName cpu-update\n * 先在 workspace 执行一次 tsc(根项目 + cli-core),再扫描 dist/commands、同步 package.json bin 并 npm link。\n * 必须在 workspace 根目录下运行。\n */\nimport { execSync } from \"child_process\";\nimport { syncCommands, npmLink } from \"../index.js\";\n\nconst workspaceRoot = process.cwd();\n\nconsole.log(\"\\n[1/5] 正在编译 workspace (tsc)...\");\nexecSync(\"npx tsc\", { stdio: \"inherit\", cwd: workspaceRoot });\nexecSync(\"npx tsc -p packages/cli-core/tsconfig.json\", {\n stdio: \"inherit\",\n cwd: workspaceRoot,\n});\nconsole.log(\" - 编译完成。\");\n\nconsole.log(\"\\n[2/5] 正在清理旧命令并扫描命令文件...\");\n\nconst { previous, added } = syncCommands({ projectRoot: workspaceRoot });\n\nif (previous.length > 0) {\n console.log(` - 已清理旧命令 (${previous.length} 个): ${previous.join(\", \")}`);\n} else {\n console.log(\" - 无需清理旧命令。\");\n}\n\nconsole.log(\"\\n[3/5] 扫描命令文件完成。\");\nif (added.length > 0) {\n console.log(` - 发现 ${added.length} 个命令: ${added.join(\", \")}`);\n} else {\n console.log(\" - 未发现任何命令。\");\n}\n\nconsole.log(\"\\n[4/5] 正在注册命令到全局 (npm link)...\");\ntry {\n npmLink(workspaceRoot);\n console.log(\" - 注册成功。\");\n} catch (error: any) {\n console.error(\" - 注册失败:\", error.message);\n}\n\nconsole.log(\"\\n[5/5] 更新完成!\");\nconsole.log(\"---------------------------------------\");\nif (added.length > 0) {\n console.log(\"你可以直接运行以下命令:\");\n added.forEach((cmd) => console.log(` $ ${cmd}`));\n}\nconsole.log(\"---------------------------------------\\n\");\n"]}
|
|
File without changes
|