@kevlns/v-cli 0.2.8 → 0.2.10
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/AGENTS.md +2 -2
- package/README.md +1 -1
- package/dist/cli.mjs +20 -22
- package/package.json +1 -1
- package/skills/v-cli/SKILL.md +3 -4
package/AGENTS.md
CHANGED
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
## 核心约定(v-cli 本体)
|
|
9
9
|
|
|
10
|
-
- 环境要求 Node.js >= 20;v-cli 版本 @kevlns/v-cli@0.2.
|
|
10
|
+
- 环境要求 Node.js >= 20;v-cli 版本 @kevlns/v-cli@0.2.10
|
|
11
11
|
- 命令分三类:builtin(内置)、local(~/.v-cli/commands/ 下的本地插件)、official(官方插件白名单);
|
|
12
12
|
**最新、live 的命令集合以实际发现为准**:先运行 `v-cli agent index --json` 获取全部命令与 agent 元数据
|
|
13
13
|
- 单个命令的完整元数据用 `v-cli agent describe <命令名> --json` 查看
|
|
14
14
|
- AI Agent 引导文档:`v-cli agent docs` 输出本文件原文(`--json` 含 sha256/content);
|
|
15
15
|
`v-cli agent init .` 把它写入工作区(已存在默认拒绝,`--force` 覆盖,`--dry-run` 预览;符号链接目标 fail-closed);
|
|
16
16
|
同时把随包发布的 v-cli skill(skills/v-cli)装配到 <目录> 下匹配的 agent 技能目录(如 .claude/skills、.agent/skill、AgentHome/skills 等,清单见 src/core/agent-dirs.ts),无匹配则跳过;
|
|
17
|
-
|
|
17
|
+
随包版本是规范唯一权威:同名 SKILL.md 一律按随包版本刷新(本地修改会被覆盖并提示);随包没有的文件(项目扩展,如 PROJECT.md)默认保留,`--force` 时完全同步
|
|
18
18
|
- **首次调用规范**:首次调用任何 official 插件命令前,必须先运行 `v-cli agent docs <命令名>`,
|
|
19
19
|
掌握该插件包内 `AGENTS.md`;使用规范、快速流程与禁止事项以插件 AGENTS.md 为准。
|
|
20
20
|
- 官方插件命令(`v-cli xlmerge …`、`v-cli unity …`)在子进程中运行(stdio 继承):v-cli 只做路由,
|
package/README.md
CHANGED
|
@@ -214,7 +214,7 @@ kevlns 工具家族共享同一套发布约定(tag 驱动、CI 护栏、MIT)
|
|
|
214
214
|
|
|
215
215
|
| Package | Purpose | Status |
|
|
216
216
|
| --- | --- | --- |
|
|
217
|
-
| [`v-cli`](https://github.com/kevlns/v-cli) | 个人工具箱 CLI(本仓库) | v0.2.
|
|
217
|
+
| [`v-cli`](https://github.com/kevlns/v-cli) | 个人工具箱 CLI(本仓库) | v0.2.10 |
|
|
218
218
|
| [`xlmerge`](https://github.com/kevlns/xlmerge) | Git 中 .xlsx/.xlsm 冲突可视化解决工具 | v2.0.0 |
|
|
219
219
|
| [`u-cli-mod`](https://github.com/kevlns/u-cli-mod) | Unity 精确版本路由 + CLI + pipeline 包(Windows-first) | v0.2.0 |
|
|
220
220
|
|
package/dist/cli.mjs
CHANGED
|
@@ -627,7 +627,7 @@ import { createHash, randomBytes } from "crypto";
|
|
|
627
627
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
628
628
|
|
|
629
629
|
// src/version.ts
|
|
630
|
-
var VERSION = "0.2.
|
|
630
|
+
var VERSION = "0.2.10";
|
|
631
631
|
|
|
632
632
|
// src/core/agent-docs.ts
|
|
633
633
|
var BUNDLED_DOCS_FILE = "AGENTS.md";
|
|
@@ -926,9 +926,13 @@ function collectAgentSkillDirs(directory) {
|
|
|
926
926
|
}
|
|
927
927
|
return hits;
|
|
928
928
|
}
|
|
929
|
-
function
|
|
930
|
-
|
|
931
|
-
|
|
929
|
+
function syncSkillDir(srcRoot, destDir, opts = {}) {
|
|
930
|
+
if (opts.purgeExtras) {
|
|
931
|
+
fs4.rmSync(destDir, { recursive: true, force: true });
|
|
932
|
+
} else {
|
|
933
|
+
fs4.mkdirSync(destDir, { recursive: true });
|
|
934
|
+
}
|
|
935
|
+
fs4.cpSync(srcRoot, destDir, { recursive: true, force: true });
|
|
932
936
|
}
|
|
933
937
|
function readSkillFileAt(targetDir) {
|
|
934
938
|
try {
|
|
@@ -962,15 +966,12 @@ function performAgentSkillAssembly(opts) {
|
|
|
962
966
|
const target = path5.join(dir, SKILL_NAME);
|
|
963
967
|
const existing = readSkillFileAt(target);
|
|
964
968
|
const exists = existing !== void 0;
|
|
965
|
-
|
|
966
|
-
base.assembled.push({ dir, target, action: "kept", overwrite: false });
|
|
967
|
-
continue;
|
|
968
|
-
}
|
|
969
|
+
const localModified = exists && existing !== source.content;
|
|
969
970
|
const action = dryRun ? "assemble" : "assembled";
|
|
970
971
|
if (!dryRun) {
|
|
971
|
-
|
|
972
|
+
syncSkillDir(source.root, target, { purgeExtras: force });
|
|
972
973
|
}
|
|
973
|
-
base.assembled.push({ dir, target, action, overwrite: exists });
|
|
974
|
+
base.assembled.push({ dir, target, action, overwrite: exists, localModified });
|
|
974
975
|
}
|
|
975
976
|
return base;
|
|
976
977
|
}
|
|
@@ -981,11 +982,9 @@ function skillOutcomeText(outcome, dryRun) {
|
|
|
981
982
|
switch (outcome.status) {
|
|
982
983
|
case "assembled": {
|
|
983
984
|
const dirs = outcome.assembled.map((t) => t.dir).join(", ");
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
const dirs = outcome.assembled.map((t) => t.dir).join(", ");
|
|
988
|
-
return `[skill v-cli] \u4FDD\u7559\u672C\u5730\u5DF2\u4FEE\u6539\u7248\u672C\uFF08\u672A\u8986\u76D6\uFF09\uFF1A${dirs}\uFF1B\u5982\u9700\u7528\u968F\u5305\u7248\u672C\u8986\u76D6\u8BF7\u52A0 --force`;
|
|
985
|
+
const refreshed = outcome.assembled.filter((t) => t.localModified).map((t) => t.dir);
|
|
986
|
+
const note = refreshed.length > 0 ? `\uFF1B\u5176\u4E2D ${refreshed.length} \u4E2A\u672C\u5730\u5DF2\u4FEE\u6539\u7684 SKILL.md \u5DF2\u6309\u968F\u5305\u7248\u672C\u5237\u65B0\uFF08\u540C\u76EE\u5F55\u6269\u5C55\u6587\u4EF6\u4FDD\u7559\uFF09\uFF1A${refreshed.join(", ")}` : "";
|
|
987
|
+
return `[skill v-cli] ${verb} ${outcome.assembled.length} \u4E2A agent \u76EE\u5F55\uFF1A${dirs}${note}`;
|
|
989
988
|
}
|
|
990
989
|
case "skipped-none":
|
|
991
990
|
return "[skill v-cli] \u672A\u68C0\u6D4B\u5230\u5339\u914D\u7684 agent \u6280\u80FD\u76EE\u5F55\uFF0C\u8DF3\u8FC7\u88C5\u914D";
|
|
@@ -1116,9 +1115,9 @@ var INIT_HELP_TEXT = [
|
|
|
1116
1115
|
" [directory] \u76EE\u6807\u76EE\u5F55\uFF0C\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1B\u5FC5\u987B\u5DF2\u5B58\u5728\u4E14\u4E3A\u76EE\u5F55",
|
|
1117
1116
|
"",
|
|
1118
1117
|
"\u9ED8\u8BA4\u884C\u4E3A\uFF08\u65E0 --force\uFF09\uFF1A\u76EE\u6807\u5DF2\u5B58\u5728 AGENTS.md \u65F6\u62D2\u7EDD\u5E76\u9000\u51FA 1\uFF0C\u7EDD\u4E0D\u6539\u52A8\u73B0\u6709\u6587\u4EF6\u3002",
|
|
1119
|
-
" --force \u8986\u76D6\u5DF2\u5B58\u5728\u7684 AGENTS.md \
|
|
1120
|
-
" skill \
|
|
1121
|
-
" \
|
|
1118
|
+
" --force \u8986\u76D6\u5DF2\u5B58\u5728\u7684 AGENTS.md\uFF1Bskill \u76EE\u5F55\u505A\u5B8C\u5168\u540C\u6B65\uFF08\u6E05\u6389\u6269\u5C55\u6587\u4EF6\uFF09\uFF08\u539F\u5B50\u5199\u5165\uFF1A\u540C\u76EE\u5F55\u4E34\u65F6\u6587\u4EF6 + rename\uFF09",
|
|
1119
|
+
" skill \u540C\u6B65 \u968F\u5305\u7248\u672C\u662F\u89C4\u8303\u552F\u4E00\u6743\u5A01\uFF1A\u540C\u540D SKILL.md \u4E00\u5F8B\u6309\u968F\u5305\u7248\u672C\u5237\u65B0\uFF08\u672C\u5730\u4FEE\u6539\u4F1A\u88AB\u8986\u76D6\u5E76\u63D0\u793A\uFF09\uFF1B",
|
|
1120
|
+
" \u76EE\u6807\u76EE\u5F55\u4E2D\u968F\u5305\u6CA1\u6709\u7684\u6587\u4EF6\uFF08\u9879\u76EE\u6269\u5C55\uFF0C\u5982 PROJECT.md\uFF09\u9ED8\u8BA4\u4FDD\u7559\uFF0C--force \u65F6\u5B8C\u5168\u540C\u6B65\u3002",
|
|
1122
1121
|
" --dry-run \u53EA\u62A5\u544A\u76EE\u6807\u4E0E\u5C06\u6267\u884C\u7684\u52A8\u4F5C\uFF0C\u4E0D\u5199\u5165\u4EFB\u4F55\u6587\u4EF6",
|
|
1123
1122
|
" --json \u6210\u529F/\u5E72\u8DD1\u8F93\u51FA\u7A33\u5B9A JSON { ok, dryRun, action, directory, target, package, version, sha256, bytes }\uFF1B",
|
|
1124
1123
|
' \u62D2\u7EDD\uFF08\u5982\u5DF2\u5B58\u5728\u672A\u52A0 --force\uFF09\u8F93\u51FA { ok: false, action: "refused", reason, \u2026 } \u4E14\u9000\u51FA 1\uFF1B',
|
|
@@ -1189,7 +1188,7 @@ var agent = {
|
|
|
1189
1188
|
{ name: "directory", required: false, description: "\u76EE\u6807\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1B\u987B\u5DF2\u5B58\u5728\u4E14\u4E3A\u76EE\u5F55\uFF09" }
|
|
1190
1189
|
],
|
|
1191
1190
|
options: [
|
|
1192
|
-
{ flags: "--force", description: "\u8986\u76D6\u5DF2\u5B58\u5728\u7684 AGENTS.md \
|
|
1191
|
+
{ flags: "--force", description: "\u8986\u76D6\u5DF2\u5B58\u5728\u7684 AGENTS.md\uFF1Bskill \u76EE\u5F55\u505A\u5B8C\u5168\u540C\u6B65\uFF08\u6E05\u6389\u6269\u5C55\u6587\u4EF6\uFF09" },
|
|
1193
1192
|
{ flags: "--dry-run", description: "\u53EA\u62A5\u544A\u76EE\u6807\u4E0E\u52A8\u4F5C\uFF0C\u4E0D\u5199\u5165" },
|
|
1194
1193
|
{ flags: "--json", description: "\u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7ED3\u679C" }
|
|
1195
1194
|
],
|
|
@@ -1289,7 +1288,7 @@ var agent = {
|
|
|
1289
1288
|
}
|
|
1290
1289
|
process.stdout.write(docs.content);
|
|
1291
1290
|
});
|
|
1292
|
-
program.command("init").description("\u521D\u59CB\u5316 <\u76EE\u5F55>/AGENTS.md\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09\uFF1B\u5DF2\u5B58\u5728\u9ED8\u8BA4\u62D2\u7EDD\uFF0C--force \u8986\u76D6\uFF0C--dry-run \u9884\u89C8").argument("[directory]", "\u76EE\u6807\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1B\u5FC5\u987B\u5DF2\u5B58\u5728\u4E14\u4E3A\u76EE\u5F55\uFF09").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684 AGENTS.md \
|
|
1291
|
+
program.command("init").description("\u521D\u59CB\u5316 <\u76EE\u5F55>/AGENTS.md\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09\uFF1B\u5DF2\u5B58\u5728\u9ED8\u8BA4\u62D2\u7EDD\uFF0C--force \u8986\u76D6\uFF0C--dry-run \u9884\u89C8").argument("[directory]", "\u76EE\u6807\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1B\u5FC5\u987B\u5DF2\u5B58\u5728\u4E14\u4E3A\u76EE\u5F55\uFF09").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684 AGENTS.md\uFF1Bskill \u76EE\u5F55\u505A\u5B8C\u5168\u540C\u6B65\uFF08\u6E05\u6389\u6269\u5C55\u6587\u4EF6\uFF09").option("--dry-run", "\u53EA\u62A5\u544A\u76EE\u6807\u4E0E\u52A8\u4F5C\uFF0C\u4E0D\u5199\u5165\u4EFB\u4F55\u6587\u4EF6").option("--json", "\u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7ED3\u679C").addHelpText("after", INIT_HELP_TEXT).action(
|
|
1293
1292
|
(directory, opts) => {
|
|
1294
1293
|
const json = ctx.json || opts.json;
|
|
1295
1294
|
let docs;
|
|
@@ -1321,9 +1320,8 @@ var agent = {
|
|
|
1321
1320
|
dryRun: opts.dryRun,
|
|
1322
1321
|
force: opts.force
|
|
1323
1322
|
});
|
|
1324
|
-
const keptOnly = skill.assembled.length > 0 && skill.assembled.every((t) => t.action === "kept");
|
|
1325
1323
|
skillOutcome = skill.assembled.length > 0 ? {
|
|
1326
|
-
status:
|
|
1324
|
+
status: "assembled",
|
|
1327
1325
|
assembled: skill.assembled,
|
|
1328
1326
|
name: skill.skill.name,
|
|
1329
1327
|
sha256: skill.skill.sha256,
|
package/package.json
CHANGED
package/skills/v-cli/SKILL.md
CHANGED
|
@@ -41,7 +41,7 @@ description: >
|
|
|
41
41
|
- 产物与归属:
|
|
42
42
|
- 根 `AGENTS.md` 为**工具生成物**(建议纳入 `.gitignore`),禁止手改;需要更新内容时升级 v-cli 后重跑 init。
|
|
43
43
|
- 分支不变式(实测):① `AGENTS.md` 不存在 → 写入它**并**装配 skill;② `AGENTS.md` 已存在且未加 `--force` → **整体拒绝**(`action=refused`、`skill.status=skipped-init-failed`),不做任何改动;`--force` 会同时覆盖两者。
|
|
44
|
-
- **skill
|
|
44
|
+
- **skill 同步**:**随包版本是规范的唯一权威**——命中目录下已有 `v-cli/SKILL.md` 时一律按随包版本刷新(本地修改会被覆盖,工具在 `localModified=true` 时给出提示);目标目录中随包**没有**的文件默认保留,供项目放扩展说明(如 `PROJECT.md`);`--force` 时做完全同步(连扩展文件一起清掉,目录与随包逐文件一致)。因此项目**不要**直接改 `SKILL.md`,项目专属内容写进扩展文件或项目规则文档。
|
|
45
45
|
- 先 `--dry-run --json` 预览目标与动作(含 `skill.assembled[].action` 与 `overwrite`),再实际写入。
|
|
46
46
|
|
|
47
47
|
## 官方插件一:xlmerge(跨平台)
|
|
@@ -107,12 +107,11 @@ receipt 属工程本地生成物:新克隆 / 清理 Library 后即使 `Package
|
|
|
107
107
|
|
|
108
108
|
### 长任务命令:启动即让出,用状态命令轮询
|
|
109
109
|
|
|
110
|
-
-
|
|
110
|
+
- `run_tests` 这类同步长任务默认只等 **5 秒**:到点后任务仍在 Editor 内继续执行,工具打印输出日志路径(`<工程>/Library/editor-pipeline-cli/exec-logs/*.log`)并立即返回(退出码 0)。
|
|
111
111
|
- 让出后**不要重复发起同一命令**,改用状态命令轮询:测试 `-- command test_status`(直到读到 `summary`),烘焙 `-- command <xxx>_bake_status`。
|
|
112
112
|
- 需要同步拿到完整 `Summary` 时用 `--wait <秒>` 扩大等待(写在 `--` 之前,u-cli-mod 自行剥离,不会透传给 Unity CLI);`--wait 0` = 立即返回。
|
|
113
113
|
- **优先缩小范围**(最省事):`run_tests --mode EditMode --filter <命名空间或测试类>` 通常数秒内就同步返回完整 `Summary`,无需轮询。
|
|
114
114
|
- 让出后任务仍在跑,不要重复发起;如需取消用 `-- command cancel_tests`(运行中可能被拒,稍后重试)。
|
|
115
|
-
- 若仍见到 `Pipeline command 'run_tests' timed out after 30000ms`,说明本机 v-cli/u-cli-mod 尚未升级到 0.2.0;升级后该提示消失。
|
|
116
115
|
|
|
117
116
|
## 典型流程
|
|
118
117
|
|
|
@@ -129,4 +128,4 @@ v-cli unity exec <project> -- command read_console --types error,warning --count
|
|
|
129
128
|
v-cli unity exec <project> -- command run_tests --mode EditMode --filter <类名> # 8. 测试(小范围同步返回)
|
|
130
129
|
v-cli xlmerge --repo . detect # 配置表:只读检测
|
|
131
130
|
v-cli xlmerge --repo . launch # 有冲突时启动本地 UI,把 url 交给用户
|
|
132
|
-
```
|
|
131
|
+
```
|