@ai-setting/roy-agent-cli 1.5.49 → 1.5.50
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/bin/roy-agent.js +274 -25
- package/dist/index.js +274 -25
- package/dist/roy-agent-linux-x64/bin/roy-agent +0 -0
- package/package.json +2 -2
package/dist/bin/roy-agent.js
CHANGED
|
@@ -7290,7 +7290,7 @@ var require_dist = __commonJS((exports) => {
|
|
|
7290
7290
|
var require_package = __commonJS((exports, module) => {
|
|
7291
7291
|
module.exports = {
|
|
7292
7292
|
name: "@ai-setting/roy-agent-cli",
|
|
7293
|
-
version: "1.5.
|
|
7293
|
+
version: "1.5.50",
|
|
7294
7294
|
type: "module",
|
|
7295
7295
|
description: "CLI for roy-agent - Non-interactive command execution",
|
|
7296
7296
|
main: "./dist/index.js",
|
|
@@ -7317,7 +7317,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
7317
7317
|
},
|
|
7318
7318
|
dependencies: {
|
|
7319
7319
|
"@ai-setting/roy-agent-coder-harness": "^1.5.46",
|
|
7320
|
-
"@ai-setting/roy-agent-core": "^1.5.
|
|
7320
|
+
"@ai-setting/roy-agent-core": "^1.5.49",
|
|
7321
7321
|
"@ai-setting/roy-agent-ontology-harness": "^1.5.47",
|
|
7322
7322
|
chalk: "^5.6.2",
|
|
7323
7323
|
commander: "^14.0.3",
|
|
@@ -8216,7 +8216,7 @@ class TaskEventHandler {
|
|
|
8216
8216
|
logTaskCreated(payload) {
|
|
8217
8217
|
const task = payload.task;
|
|
8218
8218
|
console.log(`\uD83D\uDCDD Task created: #${task.id} - ${task.title}`);
|
|
8219
|
-
console.log(` Status: ${task.status}, Priority: ${task.priority}`);
|
|
8219
|
+
console.log(` Status: ${task.status}, Priority: ${task.priority}, Type: ${task.type || "normal"}`);
|
|
8220
8220
|
if (task.project_path) {
|
|
8221
8221
|
console.log(` Project: ${task.project_path}`);
|
|
8222
8222
|
}
|
|
@@ -8228,7 +8228,7 @@ class TaskEventHandler {
|
|
|
8228
8228
|
const task = payload.task;
|
|
8229
8229
|
const changes = payload.changes;
|
|
8230
8230
|
console.log(`✏️ Task updated: #${task.id} - ${task.title}`);
|
|
8231
|
-
console.log(` Status: ${task.status}, Progress: ${task.progress}%`);
|
|
8231
|
+
console.log(` Status: ${task.status}, Priority: ${task.priority}, Type: ${task.type || "normal"}, Progress: ${task.progress}%`);
|
|
8232
8232
|
if (changes) {
|
|
8233
8233
|
console.log(` Changes: ${JSON.stringify(changes)}`);
|
|
8234
8234
|
}
|
|
@@ -11578,6 +11578,10 @@ var ListCommand2 = {
|
|
|
11578
11578
|
type: "string",
|
|
11579
11579
|
choices: ["low", "medium", "high"],
|
|
11580
11580
|
description: "按优先级筛选"
|
|
11581
|
+
}).option("type", {
|
|
11582
|
+
type: "string",
|
|
11583
|
+
choices: ["normal", "cycle", "longterm"],
|
|
11584
|
+
description: "按任务类型筛选"
|
|
11581
11585
|
}).option("limit", { alias: "n", type: "number", default: 20, description: "返回数量" }).option("offset", { type: "number", default: 0, description: "偏移量" }).option("json", { alias: "j", type: "boolean", default: false, description: "JSON 输出" }).option("quiet", { alias: "q", type: "boolean", hidden: true }),
|
|
11582
11586
|
async handler(args) {
|
|
11583
11587
|
const output = new OutputService;
|
|
@@ -11597,6 +11601,7 @@ var ListCommand2 = {
|
|
|
11597
11601
|
const listOptions = {
|
|
11598
11602
|
status: args.status,
|
|
11599
11603
|
priority: args.priority,
|
|
11604
|
+
type: args.type,
|
|
11600
11605
|
limit: args.limit,
|
|
11601
11606
|
offset: args.offset
|
|
11602
11607
|
};
|
|
@@ -11608,6 +11613,7 @@ var ListCommand2 = {
|
|
|
11608
11613
|
title: t.title,
|
|
11609
11614
|
status: t.status,
|
|
11610
11615
|
priority: t.priority,
|
|
11616
|
+
type: t.type,
|
|
11611
11617
|
progress: t.progress,
|
|
11612
11618
|
current_status: t.current_status,
|
|
11613
11619
|
project_path: t.project_path,
|
|
@@ -11625,6 +11631,7 @@ var ListCommand2 = {
|
|
|
11625
11631
|
chalk16.bold("Title"),
|
|
11626
11632
|
chalk16.bold("Status"),
|
|
11627
11633
|
chalk16.bold("Priority"),
|
|
11634
|
+
chalk16.bold("Type"),
|
|
11628
11635
|
chalk16.bold("Progress")
|
|
11629
11636
|
].join(" │ ");
|
|
11630
11637
|
const rows = tasks.map((t, i) => {
|
|
@@ -11635,6 +11642,7 @@ var ListCommand2 = {
|
|
|
11635
11642
|
t.title.length > 30 ? t.title.slice(0, 27) + "..." : t.title,
|
|
11636
11643
|
statusColor(t.status),
|
|
11637
11644
|
priorityColor(t.priority),
|
|
11645
|
+
t.type || "normal",
|
|
11638
11646
|
`${t.progress}%`
|
|
11639
11647
|
].join(" │ ");
|
|
11640
11648
|
});
|
|
@@ -11701,7 +11709,7 @@ var GetCommand2 = {
|
|
|
11701
11709
|
output.log(chalk17.bold(`
|
|
11702
11710
|
Task #${result.task.id}: ${result.task.title}
|
|
11703
11711
|
`));
|
|
11704
|
-
output.log(`Status: ${chalk17.blue(result.task.status)} | Priority: ${result.task.priority} | Progress: ${result.task.progress}%`);
|
|
11712
|
+
output.log(`Status: ${chalk17.blue(result.task.status)} | Priority: ${result.task.priority} | Type: ${result.task.type} | Progress: ${result.task.progress}%`);
|
|
11705
11713
|
output.log(`Created: ${result.task.createdAt} | Updated: ${result.task.updatedAt}`);
|
|
11706
11714
|
output.log(`Project Path: ${result.task.project_path}`);
|
|
11707
11715
|
output.log(`Context: ${result.task.context}`);
|
|
@@ -11732,7 +11740,7 @@ Operations (${result.operations.length}):
|
|
|
11732
11740
|
output.log(chalk17.bold(`
|
|
11733
11741
|
Task #${task.id}: ${task.title}
|
|
11734
11742
|
`));
|
|
11735
|
-
output.log(`Status: ${chalk17.blue(task.status)} | Priority: ${task.priority} | Progress: ${task.progress}%`);
|
|
11743
|
+
output.log(`Status: ${chalk17.blue(task.status)} | Priority: ${task.priority} | Type: ${task.type} | Progress: ${task.progress}%`);
|
|
11736
11744
|
output.log(`Created: ${task.createdAt} | Updated: ${task.updatedAt}`);
|
|
11737
11745
|
output.log(`Project Path: ${task.project_path}`);
|
|
11738
11746
|
output.log(`Context: ${task.context}`);
|
|
@@ -11775,6 +11783,11 @@ var CreateCommand = {
|
|
|
11775
11783
|
choices: ["low", "medium", "high"],
|
|
11776
11784
|
default: "medium",
|
|
11777
11785
|
description: "优先级"
|
|
11786
|
+
}).option("type", {
|
|
11787
|
+
type: "string",
|
|
11788
|
+
choices: ["normal", "cycle", "longterm"],
|
|
11789
|
+
desc: "任务类型。normal=常规, cycle=周期任务(如周报), longterm=长期目标",
|
|
11790
|
+
default: "normal"
|
|
11778
11791
|
}).option("goals", {
|
|
11779
11792
|
alias: "g",
|
|
11780
11793
|
type: "string",
|
|
@@ -11813,6 +11826,7 @@ var CreateCommand = {
|
|
|
11813
11826
|
title: args.title,
|
|
11814
11827
|
description: args.description,
|
|
11815
11828
|
priority: args.priority,
|
|
11829
|
+
type: args.type,
|
|
11816
11830
|
goals_and_expected_deliverables: args.goals,
|
|
11817
11831
|
due_date: args.due,
|
|
11818
11832
|
tags: args.tags ? args.tags.split(",").map((t) => t.trim()) : undefined,
|
|
@@ -11829,6 +11843,7 @@ var CreateCommand = {
|
|
|
11829
11843
|
output.log(` Title: ${task.title}`);
|
|
11830
11844
|
output.log(` Status: ${task.status}`);
|
|
11831
11845
|
output.log(` Priority: ${task.priority}`);
|
|
11846
|
+
output.log(` Type: ${task.type}`);
|
|
11832
11847
|
output.log(` Created at: ${task.createdAt}`);
|
|
11833
11848
|
}
|
|
11834
11849
|
} catch (error) {
|
|
@@ -11850,7 +11865,7 @@ var UpdateCommand = {
|
|
|
11850
11865
|
type: "number",
|
|
11851
11866
|
describe: "任务 ID",
|
|
11852
11867
|
demandOption: true
|
|
11853
|
-
}).option("title", { alias: "t", type: "string", description: "标题" }).option("description", { alias: "d", type: "string", description: "描述" }).option("status", { alias: "s", type: "string", choices: ["todo", "active", "completed", "paused", "cancelled"], description: "状态" }).option("priority", { alias: "p", type: "string", choices: ["low", "medium", "high"], description: "优先级" }).option("progress", { type: "number", min: 0, max: 100, description: "进度 (0-100)" }).option("current_status", { alias: "c", type: "string", description: "当前状态描述" }).option("project-path", { type: "string", description: "项目路径" }).option("context", { type: "string", description: "任务上下文 (JSON 字符串)" }).option("json", { alias: "j", type: "boolean", default: false, description: "JSON 输出" }),
|
|
11868
|
+
}).option("title", { alias: "t", type: "string", description: "标题" }).option("description", { alias: "d", type: "string", description: "描述" }).option("status", { alias: "s", type: "string", choices: ["todo", "active", "completed", "paused", "cancelled"], description: "状态" }).option("priority", { alias: "p", type: "string", choices: ["low", "medium", "high"], description: "优先级" }).option("type", { type: "string", choices: ["normal", "cycle", "longterm"], description: "任务类型 (normal/cycle/longterm)" }).option("progress", { type: "number", min: 0, max: 100, description: "进度 (0-100)" }).option("current_status", { alias: "c", type: "string", description: "当前状态描述" }).option("project-path", { type: "string", description: "项目路径" }).option("context", { type: "string", description: "任务上下文 (JSON 字符串)" }).option("json", { alias: "j", type: "boolean", default: false, description: "JSON 输出" }),
|
|
11854
11869
|
async handler(args) {
|
|
11855
11870
|
const output = new OutputService;
|
|
11856
11871
|
const envService = new EnvironmentService(output);
|
|
@@ -11873,6 +11888,7 @@ var UpdateCommand = {
|
|
|
11873
11888
|
description: args.description,
|
|
11874
11889
|
status: args.status,
|
|
11875
11890
|
priority: args.priority,
|
|
11891
|
+
type: args.type,
|
|
11876
11892
|
progress: args.progress,
|
|
11877
11893
|
current_status: args.current_status,
|
|
11878
11894
|
project_path: args["project-path"],
|
|
@@ -11903,6 +11919,7 @@ var UpdateCommand = {
|
|
|
11903
11919
|
output.log(` Title: ${task.title}`);
|
|
11904
11920
|
output.log(` Status: ${task.status}`);
|
|
11905
11921
|
output.log(` Priority: ${task.priority}`);
|
|
11922
|
+
output.log(` Type: ${task.type}`);
|
|
11906
11923
|
output.log(` Progress: ${task.progress}%`);
|
|
11907
11924
|
output.log(` Project Path: ${task.project_path}`);
|
|
11908
11925
|
output.log(` Context: ${task.context}`);
|
|
@@ -12117,7 +12134,238 @@ Operations for Task #${task.id}: ${task.title}
|
|
|
12117
12134
|
}
|
|
12118
12135
|
};
|
|
12119
12136
|
|
|
12137
|
+
// src/commands/tasks/organize.ts
|
|
12138
|
+
var command = "organize";
|
|
12139
|
+
var desc = "整理系统中的任务(清理测试任务、聚合相似任务、构建任务树)";
|
|
12140
|
+
var builder = (yargs) => yargs.option("dry-run", {
|
|
12141
|
+
type: "boolean",
|
|
12142
|
+
desc: "试运行模式,只展示计划不执行",
|
|
12143
|
+
default: false
|
|
12144
|
+
}).option("delete-test", {
|
|
12145
|
+
type: "boolean",
|
|
12146
|
+
desc: "使用 AI 分析判断哪些是纯测试/示例任务并清理(避免误删正式任务)"
|
|
12147
|
+
}).option("aggregate", {
|
|
12148
|
+
type: "boolean",
|
|
12149
|
+
desc: "聚合相似任务(基于标题文本相似度)"
|
|
12150
|
+
}).option("build-tree", {
|
|
12151
|
+
type: "boolean",
|
|
12152
|
+
desc: "构建任务树(为散落的同类任务构建父任务)"
|
|
12153
|
+
}).option("auto", {
|
|
12154
|
+
type: "boolean",
|
|
12155
|
+
desc: "全自动模式,执行所有整理策略"
|
|
12156
|
+
}).example([
|
|
12157
|
+
["$0 tasks organize --dry-run", "试运行,只展示整理计划"],
|
|
12158
|
+
["$0 tasks organize --auto", "全自动整理"],
|
|
12159
|
+
["$0 tasks organize --delete-test", "用 AI 清理测试任务"]
|
|
12160
|
+
]);
|
|
12161
|
+
async function handleDeleteTest(store, allTasks, shouldExecute, report) {
|
|
12162
|
+
const testPatterns = [
|
|
12163
|
+
/^test\b/i,
|
|
12164
|
+
/^测试/i,
|
|
12165
|
+
/^示例/i,
|
|
12166
|
+
/^demo\b/i,
|
|
12167
|
+
/^sample\b/i,
|
|
12168
|
+
/event test/i,
|
|
12169
|
+
/test task/i
|
|
12170
|
+
];
|
|
12171
|
+
const excludePatterns = [
|
|
12172
|
+
/strict-task-agent/i,
|
|
12173
|
+
/集成测试/i,
|
|
12174
|
+
/bench测试/i,
|
|
12175
|
+
/测试用例/i,
|
|
12176
|
+
/typecheck/i,
|
|
12177
|
+
/traffic_test/i
|
|
12178
|
+
];
|
|
12179
|
+
const matched = allTasks.filter((t) => {
|
|
12180
|
+
const title = t.title;
|
|
12181
|
+
for (const pat of excludePatterns) {
|
|
12182
|
+
if (pat.test(title))
|
|
12183
|
+
return false;
|
|
12184
|
+
}
|
|
12185
|
+
for (const pat of testPatterns) {
|
|
12186
|
+
if (pat.test(title))
|
|
12187
|
+
return true;
|
|
12188
|
+
}
|
|
12189
|
+
return false;
|
|
12190
|
+
});
|
|
12191
|
+
if (matched.length === 0) {
|
|
12192
|
+
report.push("没有发现需要清理的测试任务");
|
|
12193
|
+
return;
|
|
12194
|
+
}
|
|
12195
|
+
report.push("发现 " + matched.length + " 个测试任务:");
|
|
12196
|
+
for (const task of matched) {
|
|
12197
|
+
report.push(" - #" + task.id + ": " + task.title + " (" + task.status + ")");
|
|
12198
|
+
}
|
|
12199
|
+
report.push("");
|
|
12200
|
+
report.push(" ℹ️ 提示:如需更智能的语义分析,请运行:");
|
|
12201
|
+
report.push(' roy-agent act "整理测试任务" --agent task-organizer');
|
|
12202
|
+
if (shouldExecute) {
|
|
12203
|
+
let count = 0;
|
|
12204
|
+
for (const task of matched) {
|
|
12205
|
+
try {
|
|
12206
|
+
await store.deleteTask(task.id);
|
|
12207
|
+
report.push(" ✅ 已删除: #" + task.id + " - " + task.title);
|
|
12208
|
+
count++;
|
|
12209
|
+
} catch (err) {
|
|
12210
|
+
report.push(" ❌ 删除失败: #" + task.id + " - " + err.message);
|
|
12211
|
+
}
|
|
12212
|
+
}
|
|
12213
|
+
report.push(" 共删除 " + count + " 个测试任务");
|
|
12214
|
+
}
|
|
12215
|
+
}
|
|
12216
|
+
async function handleAggregate(store, allTasks, shouldExecute, report) {
|
|
12217
|
+
function sim(a, b) {
|
|
12218
|
+
const s1 = new Set(a.toLowerCase().split(/[\s_-]+/));
|
|
12219
|
+
const s2 = new Set(b.toLowerCase().split(/[\s_-]+/));
|
|
12220
|
+
const inter = new Set([...s1].filter((w) => s2.has(w)));
|
|
12221
|
+
const union = new Set([...s1, ...s2]);
|
|
12222
|
+
return inter.size / union.size;
|
|
12223
|
+
}
|
|
12224
|
+
const visited = new Set;
|
|
12225
|
+
const groups = [];
|
|
12226
|
+
const THRESHOLD = 0.7;
|
|
12227
|
+
for (let i = 0;i < allTasks.length; i++) {
|
|
12228
|
+
if (visited.has(allTasks[i].id))
|
|
12229
|
+
continue;
|
|
12230
|
+
const group = [allTasks[i]];
|
|
12231
|
+
visited.add(allTasks[i].id);
|
|
12232
|
+
for (let j = i + 1;j < allTasks.length; j++) {
|
|
12233
|
+
if (visited.has(allTasks[j].id))
|
|
12234
|
+
continue;
|
|
12235
|
+
if (sim(allTasks[i].title, allTasks[j].title) >= THRESHOLD) {
|
|
12236
|
+
group.push(allTasks[j]);
|
|
12237
|
+
visited.add(allTasks[j].id);
|
|
12238
|
+
}
|
|
12239
|
+
}
|
|
12240
|
+
if (group.length > 1)
|
|
12241
|
+
groups.push(group);
|
|
12242
|
+
}
|
|
12243
|
+
if (groups.length === 0) {
|
|
12244
|
+
report.push("未发现相似任务");
|
|
12245
|
+
return;
|
|
12246
|
+
}
|
|
12247
|
+
report.push("发现 " + groups.length + " 组相似任务:");
|
|
12248
|
+
for (const g of groups) {
|
|
12249
|
+
report.push(" 组:");
|
|
12250
|
+
for (const t of g)
|
|
12251
|
+
report.push(" - #" + t.id + ": " + t.title);
|
|
12252
|
+
if (shouldExecute) {
|
|
12253
|
+
const tagName = "group:" + g[0].title.slice(0, 20).replace(/[\s_-]+/g, "-").toLowerCase();
|
|
12254
|
+
for (const t of g) {
|
|
12255
|
+
const currentTags = t.tags || [];
|
|
12256
|
+
if (!currentTags.includes(tagName)) {
|
|
12257
|
+
await store.updateTask(t.id, { tags: [...currentTags, tagName] });
|
|
12258
|
+
}
|
|
12259
|
+
}
|
|
12260
|
+
report.push(" -> 添加关联标签: " + tagName);
|
|
12261
|
+
}
|
|
12262
|
+
}
|
|
12263
|
+
}
|
|
12264
|
+
async function handleBuildTree(store, allTasks, shouldExecute, report) {
|
|
12265
|
+
const rootTasks = allTasks.filter((t) => !t.parent_task_id);
|
|
12266
|
+
if (rootTasks.length === 0) {
|
|
12267
|
+
report.push("所有任务已有父任务");
|
|
12268
|
+
return;
|
|
12269
|
+
}
|
|
12270
|
+
const stopWords = new Set(["test", "测试", "task", "任务", "add", "create", "fix"]);
|
|
12271
|
+
const groups = new Map;
|
|
12272
|
+
for (const task of rootTasks) {
|
|
12273
|
+
const words = task.title.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]/g, " ").split(/\s+/).filter(Boolean);
|
|
12274
|
+
const topicWords = words.filter((w) => !stopWords.has(w)).slice(0, 2);
|
|
12275
|
+
const topic = topicWords.join("-") || words[0] || "未分类";
|
|
12276
|
+
if (!groups.has(topic))
|
|
12277
|
+
groups.set(topic, []);
|
|
12278
|
+
groups.get(topic).push(task);
|
|
12279
|
+
}
|
|
12280
|
+
const toBuild = [...groups.entries()].filter(([, tasks]) => tasks.length >= 2);
|
|
12281
|
+
if (toBuild.length === 0) {
|
|
12282
|
+
report.push("没有需要构建父任务的主题组");
|
|
12283
|
+
return;
|
|
12284
|
+
}
|
|
12285
|
+
report.push("将为 " + toBuild.length + " 个主题组创建父任务:");
|
|
12286
|
+
for (const [topic, tasks] of toBuild) {
|
|
12287
|
+
const types = tasks.map((t) => t.type);
|
|
12288
|
+
const allCycle = types.every((t) => t === "cycle");
|
|
12289
|
+
const hasLongterm = types.some((t) => t === "longterm");
|
|
12290
|
+
let parentType = "normal";
|
|
12291
|
+
if (allCycle)
|
|
12292
|
+
parentType = "cycle";
|
|
12293
|
+
else if (hasLongterm)
|
|
12294
|
+
parentType = "longterm";
|
|
12295
|
+
const parentTitle = "[" + topic.toUpperCase() + "] " + topic + "相关工作";
|
|
12296
|
+
report.push(" \uD83D\uDCC2 主题: " + topic + " -> 父任务: " + parentTitle + " (" + parentType + ")");
|
|
12297
|
+
for (const t of tasks)
|
|
12298
|
+
report.push(" - #" + t.id + ": " + t.title);
|
|
12299
|
+
if (shouldExecute) {
|
|
12300
|
+
try {
|
|
12301
|
+
const parentTask = await store.createTask({
|
|
12302
|
+
title: parentTitle,
|
|
12303
|
+
description: "自动创建,聚合 " + tasks.length + ' 个 "' + topic + '" 相关子任务',
|
|
12304
|
+
type: parentType,
|
|
12305
|
+
priority: "medium",
|
|
12306
|
+
sessionId: "cli-organize",
|
|
12307
|
+
project_path: "organize",
|
|
12308
|
+
context: JSON.stringify({ type: "organize-auto", topic })
|
|
12309
|
+
});
|
|
12310
|
+
for (const t of tasks) {
|
|
12311
|
+
await store.updateTask(t.id, { parent_task_id: parentTask.id });
|
|
12312
|
+
}
|
|
12313
|
+
report.push(" ✅ 已创建父任务 #" + parentTask.id);
|
|
12314
|
+
} catch (err) {
|
|
12315
|
+
report.push(" ❌ 创建失败: " + err.message);
|
|
12316
|
+
}
|
|
12317
|
+
}
|
|
12318
|
+
}
|
|
12319
|
+
}
|
|
12320
|
+
var handler = async (args) => {
|
|
12321
|
+
console.log("\uD83D\uDD0D Task Organizer");
|
|
12322
|
+
const { getDefaultTaskDbPath, SQLiteTaskStore } = await import("@ai-setting/roy-agent-core");
|
|
12323
|
+
const store = new SQLiteTaskStore(getDefaultTaskDbPath());
|
|
12324
|
+
await store.initialize?.();
|
|
12325
|
+
const allTasks = await store.listTasks({ limit: 9999 });
|
|
12326
|
+
console.log(`
|
|
12327
|
+
\uD83D\uDCCA 系统中共有 ` + allTasks.length + ` 个任务
|
|
12328
|
+
`);
|
|
12329
|
+
const report = [];
|
|
12330
|
+
if (args.deleteTest || args.auto) {
|
|
12331
|
+
await handleDeleteTest(store, allTasks, !args.dryRun, report);
|
|
12332
|
+
}
|
|
12333
|
+
if (args.aggregate || args.auto) {
|
|
12334
|
+
await handleAggregate(store, allTasks, !args.dryRun, report);
|
|
12335
|
+
}
|
|
12336
|
+
if (args.buildTree || args.auto) {
|
|
12337
|
+
await handleBuildTree(store, allTasks, !args.dryRun, report);
|
|
12338
|
+
}
|
|
12339
|
+
console.log(`
|
|
12340
|
+
` + "=".repeat(60));
|
|
12341
|
+
console.log("\uD83D\uDCCB 整理报告");
|
|
12342
|
+
console.log("=".repeat(60));
|
|
12343
|
+
if (report.length === 0) {
|
|
12344
|
+
console.log(" ✨ 未指定整理策略。请使用以下选项:");
|
|
12345
|
+
console.log(" --delete-test 用 AI 清理测试任务");
|
|
12346
|
+
console.log(" --aggregate 聚合相似任务");
|
|
12347
|
+
console.log(" --build-tree 构建任务树");
|
|
12348
|
+
console.log(" --auto 全自动执行所有策略");
|
|
12349
|
+
console.log(" --dry-run 试运行预览");
|
|
12350
|
+
} else {
|
|
12351
|
+
console.log(report.join(`
|
|
12352
|
+
`));
|
|
12353
|
+
}
|
|
12354
|
+
console.log("=".repeat(60));
|
|
12355
|
+
if (args.dryRun) {
|
|
12356
|
+
console.log(`
|
|
12357
|
+
✨ 提示:去掉 --dry-run 参数执行实际整理操作`);
|
|
12358
|
+
}
|
|
12359
|
+
store.close();
|
|
12360
|
+
};
|
|
12361
|
+
|
|
12120
12362
|
// src/commands/tasks/index.ts
|
|
12363
|
+
var OrganizeCommand = {
|
|
12364
|
+
command,
|
|
12365
|
+
describe: desc,
|
|
12366
|
+
builder,
|
|
12367
|
+
handler
|
|
12368
|
+
};
|
|
12121
12369
|
var TasksCommand = {
|
|
12122
12370
|
command: "tasks",
|
|
12123
12371
|
describe: "任务管理 - 创建、追踪、管理任务",
|
|
@@ -12127,7 +12375,7 @@ var TasksCommand = {
|
|
|
12127
12375
|
array: true,
|
|
12128
12376
|
description: "Enable plugin (e.g., --plugin task-tag)",
|
|
12129
12377
|
global: false
|
|
12130
|
-
}).command(ListCommand2).command(GetCommand2).command(CreateCommand).command(UpdateCommand).command(DeleteCommand2).command(CompleteCommand).command(OperationsCommand).demandCommand().help(),
|
|
12378
|
+
}).command(ListCommand2).command(GetCommand2).command(CreateCommand).command(UpdateCommand).command(DeleteCommand2).command(CompleteCommand).command(OperationsCommand).command(OrganizeCommand).demandCommand().help(),
|
|
12131
12379
|
handler: () => {
|
|
12132
12380
|
console.log("Use 'roy-agent tasks --help' for usage information");
|
|
12133
12381
|
}
|
|
@@ -12204,10 +12452,10 @@ var ListCommand3 = {
|
|
|
12204
12452
|
}
|
|
12205
12453
|
};
|
|
12206
12454
|
const rows = filtered.map((s) => {
|
|
12207
|
-
const
|
|
12455
|
+
const desc2 = s.description.length > 50 ? s.description.slice(0, 47) + "..." : s.description;
|
|
12208
12456
|
return [
|
|
12209
12457
|
chalk23.cyan(s.name),
|
|
12210
|
-
|
|
12458
|
+
desc2,
|
|
12211
12459
|
sourceColor(s.source)(`[${s.source}]`)
|
|
12212
12460
|
].join(" | ");
|
|
12213
12461
|
});
|
|
@@ -12362,10 +12610,10 @@ var SearchCommand = {
|
|
|
12362
12610
|
const rows = results.map((s) => {
|
|
12363
12611
|
const matchedIn = s.name.toLowerCase().includes(term) ? "name" : "description";
|
|
12364
12612
|
const matchColor = matchedIn === "name" ? chalk25.green : chalk25.blue;
|
|
12365
|
-
const
|
|
12613
|
+
const desc2 = s.description.length > 40 ? s.description.slice(0, 37) + "..." : s.description;
|
|
12366
12614
|
return [
|
|
12367
12615
|
chalk25.cyan(s.name),
|
|
12368
|
-
|
|
12616
|
+
desc2,
|
|
12369
12617
|
matchColor(`[${matchedIn}]`)
|
|
12370
12618
|
].join(" | ");
|
|
12371
12619
|
});
|
|
@@ -12581,13 +12829,13 @@ var ListCommand4 = {
|
|
|
12581
12829
|
return chalk28.blue;
|
|
12582
12830
|
};
|
|
12583
12831
|
const rows = agents.map((a) => {
|
|
12584
|
-
const
|
|
12832
|
+
const desc2 = (a.description || "").length > 40 ? (a.description || "").slice(0, 37) + "..." : a.description || "-";
|
|
12585
12833
|
const workflowDisplay = a.type === "workflow" && a.workflow ? chalk28.cyan(a.workflow.length > 30 ? a.workflow.slice(0, 27) + "..." : a.workflow) : chalk28.gray("-");
|
|
12586
12834
|
return [
|
|
12587
12835
|
chalk28.cyan(a.name),
|
|
12588
12836
|
typeColor(a.type)(a.type),
|
|
12589
12837
|
workflowDisplay,
|
|
12590
|
-
|
|
12838
|
+
desc2
|
|
12591
12839
|
].join(" | ");
|
|
12592
12840
|
});
|
|
12593
12841
|
if (rows.length === 0) {
|
|
@@ -13301,8 +13549,8 @@ function formatCommandsTable(commands) {
|
|
|
13301
13549
|
const formatRow = (cmd) => {
|
|
13302
13550
|
const name = truncateVisual(cmd.name, NAME_WIDTH).padEnd(NAME_WIDTH);
|
|
13303
13551
|
const source = cmd.source.padEnd(SOURCE_WIDTH);
|
|
13304
|
-
const
|
|
13305
|
-
return `${name}${GAP}${source}${GAP}${
|
|
13552
|
+
const desc2 = truncateVisual(cmd.description || "-", DESC_WIDTH);
|
|
13553
|
+
return `${name}${GAP}${source}${GAP}${desc2}`;
|
|
13306
13554
|
};
|
|
13307
13555
|
const rows = commands.map(formatRow);
|
|
13308
13556
|
return [headerLine, sepLine, ...rows].join(`
|
|
@@ -14009,8 +14257,8 @@ function showHelp(output) {
|
|
|
14009
14257
|
output.log(` ${chalk42.cyan("-s, --sources")} 只显示配置源`);
|
|
14010
14258
|
output.log("");
|
|
14011
14259
|
output.log(chalk42.bold("Examples:"));
|
|
14012
|
-
for (const { command, description } of USAGE_COMMANDS) {
|
|
14013
|
-
output.log(` ${chalk42.cyan(
|
|
14260
|
+
for (const { command: command2, description } of USAGE_COMMANDS) {
|
|
14261
|
+
output.log(` ${chalk42.cyan(command2.padEnd(40))} ${chalk42.gray(description)}`);
|
|
14014
14262
|
}
|
|
14015
14263
|
}
|
|
14016
14264
|
async function showAllComponents(output, configService) {
|
|
@@ -14524,9 +14772,9 @@ var ToolsCommand = {
|
|
|
14524
14772
|
output.log(chalk46.bold.cyan(`
|
|
14525
14773
|
[${serverName}] ${serverTools.length} tools`));
|
|
14526
14774
|
for (const tool of serverTools) {
|
|
14527
|
-
const
|
|
14775
|
+
const desc2 = tool.description.length > 80 ? tool.description.slice(0, 77) + "..." : tool.description;
|
|
14528
14776
|
output.log(` ${chalk46.green("+")} ${chalk46.white(tool.name)}`);
|
|
14529
|
-
output.log(` ${chalk46.gray(
|
|
14777
|
+
output.log(` ${chalk46.gray(desc2)}`);
|
|
14530
14778
|
}
|
|
14531
14779
|
}
|
|
14532
14780
|
output.log(chalk46.gray(`
|
|
@@ -14646,10 +14894,10 @@ var ListCommand7 = {
|
|
|
14646
14894
|
chalk48.bold("Category")
|
|
14647
14895
|
].join(" | ");
|
|
14648
14896
|
const rows = tools.map((t) => {
|
|
14649
|
-
const
|
|
14897
|
+
const desc2 = t.description.length > 40 ? t.description.slice(0, 37) + "..." : t.description;
|
|
14650
14898
|
return [
|
|
14651
14899
|
chalk48.cyan(t.name),
|
|
14652
|
-
|
|
14900
|
+
desc2,
|
|
14653
14901
|
t.metadata?.category ? chalk48.gray(`[${t.metadata.category}]`) : "-"
|
|
14654
14902
|
].join(" | ");
|
|
14655
14903
|
});
|
|
@@ -17328,6 +17576,7 @@ var WorkflowGetCommand = {
|
|
|
17328
17576
|
import chalk62 from "chalk";
|
|
17329
17577
|
import fs4 from "fs";
|
|
17330
17578
|
import path7 from "path";
|
|
17579
|
+
import { parseWorkflowFile } from "@ai-setting/roy-agent-core/env/workflow/types";
|
|
17331
17580
|
var WorkflowUpdateCommand = {
|
|
17332
17581
|
command: "update <name>",
|
|
17333
17582
|
describe: "更新已存在的 Workflow",
|
|
@@ -17391,7 +17640,7 @@ var WorkflowUpdateCommand = {
|
|
|
17391
17640
|
process.exit(1);
|
|
17392
17641
|
}
|
|
17393
17642
|
const content = fs4.readFileSync(filePath, "utf-8");
|
|
17394
|
-
const { definition } = await
|
|
17643
|
+
const { definition } = await parseWorkflowFile(content, filePath);
|
|
17395
17644
|
updates.definition = definition;
|
|
17396
17645
|
}
|
|
17397
17646
|
const tags = a.tags ? a.tags.split(",").map((t) => t.trim()) : undefined;
|
|
@@ -18213,8 +18462,8 @@ function renderNodeTypesTable(nodes) {
|
|
|
18213
18462
|
for (const node of nodes) {
|
|
18214
18463
|
const type = node.type.padEnd(10);
|
|
18215
18464
|
const name = node.name.padEnd(18);
|
|
18216
|
-
const
|
|
18217
|
-
lines.push(`│ ${type} │ ${name} │ ${
|
|
18465
|
+
const desc2 = node.description.substring(0, 59).padEnd(59);
|
|
18466
|
+
lines.push(`│ ${type} │ ${name} │ ${desc2} │`);
|
|
18218
18467
|
}
|
|
18219
18468
|
lines.push("└────────────┴────────────────────┴─────────────────────────────────────────────────────────────┘");
|
|
18220
18469
|
return lines.join(`
|
package/dist/index.js
CHANGED
|
@@ -7289,7 +7289,7 @@ var require_dist = __commonJS((exports) => {
|
|
|
7289
7289
|
var require_package = __commonJS((exports, module) => {
|
|
7290
7290
|
module.exports = {
|
|
7291
7291
|
name: "@ai-setting/roy-agent-cli",
|
|
7292
|
-
version: "1.5.
|
|
7292
|
+
version: "1.5.50",
|
|
7293
7293
|
type: "module",
|
|
7294
7294
|
description: "CLI for roy-agent - Non-interactive command execution",
|
|
7295
7295
|
main: "./dist/index.js",
|
|
@@ -7316,7 +7316,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
7316
7316
|
},
|
|
7317
7317
|
dependencies: {
|
|
7318
7318
|
"@ai-setting/roy-agent-coder-harness": "^1.5.46",
|
|
7319
|
-
"@ai-setting/roy-agent-core": "^1.5.
|
|
7319
|
+
"@ai-setting/roy-agent-core": "^1.5.49",
|
|
7320
7320
|
"@ai-setting/roy-agent-ontology-harness": "^1.5.47",
|
|
7321
7321
|
chalk: "^5.6.2",
|
|
7322
7322
|
commander: "^14.0.3",
|
|
@@ -8215,7 +8215,7 @@ class TaskEventHandler {
|
|
|
8215
8215
|
logTaskCreated(payload) {
|
|
8216
8216
|
const task = payload.task;
|
|
8217
8217
|
console.log(`\uD83D\uDCDD Task created: #${task.id} - ${task.title}`);
|
|
8218
|
-
console.log(` Status: ${task.status}, Priority: ${task.priority}`);
|
|
8218
|
+
console.log(` Status: ${task.status}, Priority: ${task.priority}, Type: ${task.type || "normal"}`);
|
|
8219
8219
|
if (task.project_path) {
|
|
8220
8220
|
console.log(` Project: ${task.project_path}`);
|
|
8221
8221
|
}
|
|
@@ -8227,7 +8227,7 @@ class TaskEventHandler {
|
|
|
8227
8227
|
const task = payload.task;
|
|
8228
8228
|
const changes = payload.changes;
|
|
8229
8229
|
console.log(`✏️ Task updated: #${task.id} - ${task.title}`);
|
|
8230
|
-
console.log(` Status: ${task.status}, Progress: ${task.progress}%`);
|
|
8230
|
+
console.log(` Status: ${task.status}, Priority: ${task.priority}, Type: ${task.type || "normal"}, Progress: ${task.progress}%`);
|
|
8231
8231
|
if (changes) {
|
|
8232
8232
|
console.log(` Changes: ${JSON.stringify(changes)}`);
|
|
8233
8233
|
}
|
|
@@ -11577,6 +11577,10 @@ var ListCommand2 = {
|
|
|
11577
11577
|
type: "string",
|
|
11578
11578
|
choices: ["low", "medium", "high"],
|
|
11579
11579
|
description: "按优先级筛选"
|
|
11580
|
+
}).option("type", {
|
|
11581
|
+
type: "string",
|
|
11582
|
+
choices: ["normal", "cycle", "longterm"],
|
|
11583
|
+
description: "按任务类型筛选"
|
|
11580
11584
|
}).option("limit", { alias: "n", type: "number", default: 20, description: "返回数量" }).option("offset", { type: "number", default: 0, description: "偏移量" }).option("json", { alias: "j", type: "boolean", default: false, description: "JSON 输出" }).option("quiet", { alias: "q", type: "boolean", hidden: true }),
|
|
11581
11585
|
async handler(args) {
|
|
11582
11586
|
const output = new OutputService;
|
|
@@ -11596,6 +11600,7 @@ var ListCommand2 = {
|
|
|
11596
11600
|
const listOptions = {
|
|
11597
11601
|
status: args.status,
|
|
11598
11602
|
priority: args.priority,
|
|
11603
|
+
type: args.type,
|
|
11599
11604
|
limit: args.limit,
|
|
11600
11605
|
offset: args.offset
|
|
11601
11606
|
};
|
|
@@ -11607,6 +11612,7 @@ var ListCommand2 = {
|
|
|
11607
11612
|
title: t.title,
|
|
11608
11613
|
status: t.status,
|
|
11609
11614
|
priority: t.priority,
|
|
11615
|
+
type: t.type,
|
|
11610
11616
|
progress: t.progress,
|
|
11611
11617
|
current_status: t.current_status,
|
|
11612
11618
|
project_path: t.project_path,
|
|
@@ -11624,6 +11630,7 @@ var ListCommand2 = {
|
|
|
11624
11630
|
chalk16.bold("Title"),
|
|
11625
11631
|
chalk16.bold("Status"),
|
|
11626
11632
|
chalk16.bold("Priority"),
|
|
11633
|
+
chalk16.bold("Type"),
|
|
11627
11634
|
chalk16.bold("Progress")
|
|
11628
11635
|
].join(" │ ");
|
|
11629
11636
|
const rows = tasks.map((t, i) => {
|
|
@@ -11634,6 +11641,7 @@ var ListCommand2 = {
|
|
|
11634
11641
|
t.title.length > 30 ? t.title.slice(0, 27) + "..." : t.title,
|
|
11635
11642
|
statusColor(t.status),
|
|
11636
11643
|
priorityColor(t.priority),
|
|
11644
|
+
t.type || "normal",
|
|
11637
11645
|
`${t.progress}%`
|
|
11638
11646
|
].join(" │ ");
|
|
11639
11647
|
});
|
|
@@ -11700,7 +11708,7 @@ var GetCommand2 = {
|
|
|
11700
11708
|
output.log(chalk17.bold(`
|
|
11701
11709
|
Task #${result.task.id}: ${result.task.title}
|
|
11702
11710
|
`));
|
|
11703
|
-
output.log(`Status: ${chalk17.blue(result.task.status)} | Priority: ${result.task.priority} | Progress: ${result.task.progress}%`);
|
|
11711
|
+
output.log(`Status: ${chalk17.blue(result.task.status)} | Priority: ${result.task.priority} | Type: ${result.task.type} | Progress: ${result.task.progress}%`);
|
|
11704
11712
|
output.log(`Created: ${result.task.createdAt} | Updated: ${result.task.updatedAt}`);
|
|
11705
11713
|
output.log(`Project Path: ${result.task.project_path}`);
|
|
11706
11714
|
output.log(`Context: ${result.task.context}`);
|
|
@@ -11731,7 +11739,7 @@ Operations (${result.operations.length}):
|
|
|
11731
11739
|
output.log(chalk17.bold(`
|
|
11732
11740
|
Task #${task.id}: ${task.title}
|
|
11733
11741
|
`));
|
|
11734
|
-
output.log(`Status: ${chalk17.blue(task.status)} | Priority: ${task.priority} | Progress: ${task.progress}%`);
|
|
11742
|
+
output.log(`Status: ${chalk17.blue(task.status)} | Priority: ${task.priority} | Type: ${task.type} | Progress: ${task.progress}%`);
|
|
11735
11743
|
output.log(`Created: ${task.createdAt} | Updated: ${task.updatedAt}`);
|
|
11736
11744
|
output.log(`Project Path: ${task.project_path}`);
|
|
11737
11745
|
output.log(`Context: ${task.context}`);
|
|
@@ -11774,6 +11782,11 @@ var CreateCommand = {
|
|
|
11774
11782
|
choices: ["low", "medium", "high"],
|
|
11775
11783
|
default: "medium",
|
|
11776
11784
|
description: "优先级"
|
|
11785
|
+
}).option("type", {
|
|
11786
|
+
type: "string",
|
|
11787
|
+
choices: ["normal", "cycle", "longterm"],
|
|
11788
|
+
desc: "任务类型。normal=常规, cycle=周期任务(如周报), longterm=长期目标",
|
|
11789
|
+
default: "normal"
|
|
11777
11790
|
}).option("goals", {
|
|
11778
11791
|
alias: "g",
|
|
11779
11792
|
type: "string",
|
|
@@ -11812,6 +11825,7 @@ var CreateCommand = {
|
|
|
11812
11825
|
title: args.title,
|
|
11813
11826
|
description: args.description,
|
|
11814
11827
|
priority: args.priority,
|
|
11828
|
+
type: args.type,
|
|
11815
11829
|
goals_and_expected_deliverables: args.goals,
|
|
11816
11830
|
due_date: args.due,
|
|
11817
11831
|
tags: args.tags ? args.tags.split(",").map((t) => t.trim()) : undefined,
|
|
@@ -11828,6 +11842,7 @@ var CreateCommand = {
|
|
|
11828
11842
|
output.log(` Title: ${task.title}`);
|
|
11829
11843
|
output.log(` Status: ${task.status}`);
|
|
11830
11844
|
output.log(` Priority: ${task.priority}`);
|
|
11845
|
+
output.log(` Type: ${task.type}`);
|
|
11831
11846
|
output.log(` Created at: ${task.createdAt}`);
|
|
11832
11847
|
}
|
|
11833
11848
|
} catch (error) {
|
|
@@ -11849,7 +11864,7 @@ var UpdateCommand = {
|
|
|
11849
11864
|
type: "number",
|
|
11850
11865
|
describe: "任务 ID",
|
|
11851
11866
|
demandOption: true
|
|
11852
|
-
}).option("title", { alias: "t", type: "string", description: "标题" }).option("description", { alias: "d", type: "string", description: "描述" }).option("status", { alias: "s", type: "string", choices: ["todo", "active", "completed", "paused", "cancelled"], description: "状态" }).option("priority", { alias: "p", type: "string", choices: ["low", "medium", "high"], description: "优先级" }).option("progress", { type: "number", min: 0, max: 100, description: "进度 (0-100)" }).option("current_status", { alias: "c", type: "string", description: "当前状态描述" }).option("project-path", { type: "string", description: "项目路径" }).option("context", { type: "string", description: "任务上下文 (JSON 字符串)" }).option("json", { alias: "j", type: "boolean", default: false, description: "JSON 输出" }),
|
|
11867
|
+
}).option("title", { alias: "t", type: "string", description: "标题" }).option("description", { alias: "d", type: "string", description: "描述" }).option("status", { alias: "s", type: "string", choices: ["todo", "active", "completed", "paused", "cancelled"], description: "状态" }).option("priority", { alias: "p", type: "string", choices: ["low", "medium", "high"], description: "优先级" }).option("type", { type: "string", choices: ["normal", "cycle", "longterm"], description: "任务类型 (normal/cycle/longterm)" }).option("progress", { type: "number", min: 0, max: 100, description: "进度 (0-100)" }).option("current_status", { alias: "c", type: "string", description: "当前状态描述" }).option("project-path", { type: "string", description: "项目路径" }).option("context", { type: "string", description: "任务上下文 (JSON 字符串)" }).option("json", { alias: "j", type: "boolean", default: false, description: "JSON 输出" }),
|
|
11853
11868
|
async handler(args) {
|
|
11854
11869
|
const output = new OutputService;
|
|
11855
11870
|
const envService = new EnvironmentService(output);
|
|
@@ -11872,6 +11887,7 @@ var UpdateCommand = {
|
|
|
11872
11887
|
description: args.description,
|
|
11873
11888
|
status: args.status,
|
|
11874
11889
|
priority: args.priority,
|
|
11890
|
+
type: args.type,
|
|
11875
11891
|
progress: args.progress,
|
|
11876
11892
|
current_status: args.current_status,
|
|
11877
11893
|
project_path: args["project-path"],
|
|
@@ -11902,6 +11918,7 @@ var UpdateCommand = {
|
|
|
11902
11918
|
output.log(` Title: ${task.title}`);
|
|
11903
11919
|
output.log(` Status: ${task.status}`);
|
|
11904
11920
|
output.log(` Priority: ${task.priority}`);
|
|
11921
|
+
output.log(` Type: ${task.type}`);
|
|
11905
11922
|
output.log(` Progress: ${task.progress}%`);
|
|
11906
11923
|
output.log(` Project Path: ${task.project_path}`);
|
|
11907
11924
|
output.log(` Context: ${task.context}`);
|
|
@@ -12116,7 +12133,238 @@ Operations for Task #${task.id}: ${task.title}
|
|
|
12116
12133
|
}
|
|
12117
12134
|
};
|
|
12118
12135
|
|
|
12136
|
+
// src/commands/tasks/organize.ts
|
|
12137
|
+
var command = "organize";
|
|
12138
|
+
var desc = "整理系统中的任务(清理测试任务、聚合相似任务、构建任务树)";
|
|
12139
|
+
var builder = (yargs) => yargs.option("dry-run", {
|
|
12140
|
+
type: "boolean",
|
|
12141
|
+
desc: "试运行模式,只展示计划不执行",
|
|
12142
|
+
default: false
|
|
12143
|
+
}).option("delete-test", {
|
|
12144
|
+
type: "boolean",
|
|
12145
|
+
desc: "使用 AI 分析判断哪些是纯测试/示例任务并清理(避免误删正式任务)"
|
|
12146
|
+
}).option("aggregate", {
|
|
12147
|
+
type: "boolean",
|
|
12148
|
+
desc: "聚合相似任务(基于标题文本相似度)"
|
|
12149
|
+
}).option("build-tree", {
|
|
12150
|
+
type: "boolean",
|
|
12151
|
+
desc: "构建任务树(为散落的同类任务构建父任务)"
|
|
12152
|
+
}).option("auto", {
|
|
12153
|
+
type: "boolean",
|
|
12154
|
+
desc: "全自动模式,执行所有整理策略"
|
|
12155
|
+
}).example([
|
|
12156
|
+
["$0 tasks organize --dry-run", "试运行,只展示整理计划"],
|
|
12157
|
+
["$0 tasks organize --auto", "全自动整理"],
|
|
12158
|
+
["$0 tasks organize --delete-test", "用 AI 清理测试任务"]
|
|
12159
|
+
]);
|
|
12160
|
+
async function handleDeleteTest(store, allTasks, shouldExecute, report) {
|
|
12161
|
+
const testPatterns = [
|
|
12162
|
+
/^test\b/i,
|
|
12163
|
+
/^测试/i,
|
|
12164
|
+
/^示例/i,
|
|
12165
|
+
/^demo\b/i,
|
|
12166
|
+
/^sample\b/i,
|
|
12167
|
+
/event test/i,
|
|
12168
|
+
/test task/i
|
|
12169
|
+
];
|
|
12170
|
+
const excludePatterns = [
|
|
12171
|
+
/strict-task-agent/i,
|
|
12172
|
+
/集成测试/i,
|
|
12173
|
+
/bench测试/i,
|
|
12174
|
+
/测试用例/i,
|
|
12175
|
+
/typecheck/i,
|
|
12176
|
+
/traffic_test/i
|
|
12177
|
+
];
|
|
12178
|
+
const matched = allTasks.filter((t) => {
|
|
12179
|
+
const title = t.title;
|
|
12180
|
+
for (const pat of excludePatterns) {
|
|
12181
|
+
if (pat.test(title))
|
|
12182
|
+
return false;
|
|
12183
|
+
}
|
|
12184
|
+
for (const pat of testPatterns) {
|
|
12185
|
+
if (pat.test(title))
|
|
12186
|
+
return true;
|
|
12187
|
+
}
|
|
12188
|
+
return false;
|
|
12189
|
+
});
|
|
12190
|
+
if (matched.length === 0) {
|
|
12191
|
+
report.push("没有发现需要清理的测试任务");
|
|
12192
|
+
return;
|
|
12193
|
+
}
|
|
12194
|
+
report.push("发现 " + matched.length + " 个测试任务:");
|
|
12195
|
+
for (const task of matched) {
|
|
12196
|
+
report.push(" - #" + task.id + ": " + task.title + " (" + task.status + ")");
|
|
12197
|
+
}
|
|
12198
|
+
report.push("");
|
|
12199
|
+
report.push(" ℹ️ 提示:如需更智能的语义分析,请运行:");
|
|
12200
|
+
report.push(' roy-agent act "整理测试任务" --agent task-organizer');
|
|
12201
|
+
if (shouldExecute) {
|
|
12202
|
+
let count = 0;
|
|
12203
|
+
for (const task of matched) {
|
|
12204
|
+
try {
|
|
12205
|
+
await store.deleteTask(task.id);
|
|
12206
|
+
report.push(" ✅ 已删除: #" + task.id + " - " + task.title);
|
|
12207
|
+
count++;
|
|
12208
|
+
} catch (err) {
|
|
12209
|
+
report.push(" ❌ 删除失败: #" + task.id + " - " + err.message);
|
|
12210
|
+
}
|
|
12211
|
+
}
|
|
12212
|
+
report.push(" 共删除 " + count + " 个测试任务");
|
|
12213
|
+
}
|
|
12214
|
+
}
|
|
12215
|
+
async function handleAggregate(store, allTasks, shouldExecute, report) {
|
|
12216
|
+
function sim(a, b) {
|
|
12217
|
+
const s1 = new Set(a.toLowerCase().split(/[\s_-]+/));
|
|
12218
|
+
const s2 = new Set(b.toLowerCase().split(/[\s_-]+/));
|
|
12219
|
+
const inter = new Set([...s1].filter((w) => s2.has(w)));
|
|
12220
|
+
const union = new Set([...s1, ...s2]);
|
|
12221
|
+
return inter.size / union.size;
|
|
12222
|
+
}
|
|
12223
|
+
const visited = new Set;
|
|
12224
|
+
const groups = [];
|
|
12225
|
+
const THRESHOLD = 0.7;
|
|
12226
|
+
for (let i = 0;i < allTasks.length; i++) {
|
|
12227
|
+
if (visited.has(allTasks[i].id))
|
|
12228
|
+
continue;
|
|
12229
|
+
const group = [allTasks[i]];
|
|
12230
|
+
visited.add(allTasks[i].id);
|
|
12231
|
+
for (let j = i + 1;j < allTasks.length; j++) {
|
|
12232
|
+
if (visited.has(allTasks[j].id))
|
|
12233
|
+
continue;
|
|
12234
|
+
if (sim(allTasks[i].title, allTasks[j].title) >= THRESHOLD) {
|
|
12235
|
+
group.push(allTasks[j]);
|
|
12236
|
+
visited.add(allTasks[j].id);
|
|
12237
|
+
}
|
|
12238
|
+
}
|
|
12239
|
+
if (group.length > 1)
|
|
12240
|
+
groups.push(group);
|
|
12241
|
+
}
|
|
12242
|
+
if (groups.length === 0) {
|
|
12243
|
+
report.push("未发现相似任务");
|
|
12244
|
+
return;
|
|
12245
|
+
}
|
|
12246
|
+
report.push("发现 " + groups.length + " 组相似任务:");
|
|
12247
|
+
for (const g of groups) {
|
|
12248
|
+
report.push(" 组:");
|
|
12249
|
+
for (const t of g)
|
|
12250
|
+
report.push(" - #" + t.id + ": " + t.title);
|
|
12251
|
+
if (shouldExecute) {
|
|
12252
|
+
const tagName = "group:" + g[0].title.slice(0, 20).replace(/[\s_-]+/g, "-").toLowerCase();
|
|
12253
|
+
for (const t of g) {
|
|
12254
|
+
const currentTags = t.tags || [];
|
|
12255
|
+
if (!currentTags.includes(tagName)) {
|
|
12256
|
+
await store.updateTask(t.id, { tags: [...currentTags, tagName] });
|
|
12257
|
+
}
|
|
12258
|
+
}
|
|
12259
|
+
report.push(" -> 添加关联标签: " + tagName);
|
|
12260
|
+
}
|
|
12261
|
+
}
|
|
12262
|
+
}
|
|
12263
|
+
async function handleBuildTree(store, allTasks, shouldExecute, report) {
|
|
12264
|
+
const rootTasks = allTasks.filter((t) => !t.parent_task_id);
|
|
12265
|
+
if (rootTasks.length === 0) {
|
|
12266
|
+
report.push("所有任务已有父任务");
|
|
12267
|
+
return;
|
|
12268
|
+
}
|
|
12269
|
+
const stopWords = new Set(["test", "测试", "task", "任务", "add", "create", "fix"]);
|
|
12270
|
+
const groups = new Map;
|
|
12271
|
+
for (const task of rootTasks) {
|
|
12272
|
+
const words = task.title.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]/g, " ").split(/\s+/).filter(Boolean);
|
|
12273
|
+
const topicWords = words.filter((w) => !stopWords.has(w)).slice(0, 2);
|
|
12274
|
+
const topic = topicWords.join("-") || words[0] || "未分类";
|
|
12275
|
+
if (!groups.has(topic))
|
|
12276
|
+
groups.set(topic, []);
|
|
12277
|
+
groups.get(topic).push(task);
|
|
12278
|
+
}
|
|
12279
|
+
const toBuild = [...groups.entries()].filter(([, tasks]) => tasks.length >= 2);
|
|
12280
|
+
if (toBuild.length === 0) {
|
|
12281
|
+
report.push("没有需要构建父任务的主题组");
|
|
12282
|
+
return;
|
|
12283
|
+
}
|
|
12284
|
+
report.push("将为 " + toBuild.length + " 个主题组创建父任务:");
|
|
12285
|
+
for (const [topic, tasks] of toBuild) {
|
|
12286
|
+
const types = tasks.map((t) => t.type);
|
|
12287
|
+
const allCycle = types.every((t) => t === "cycle");
|
|
12288
|
+
const hasLongterm = types.some((t) => t === "longterm");
|
|
12289
|
+
let parentType = "normal";
|
|
12290
|
+
if (allCycle)
|
|
12291
|
+
parentType = "cycle";
|
|
12292
|
+
else if (hasLongterm)
|
|
12293
|
+
parentType = "longterm";
|
|
12294
|
+
const parentTitle = "[" + topic.toUpperCase() + "] " + topic + "相关工作";
|
|
12295
|
+
report.push(" \uD83D\uDCC2 主题: " + topic + " -> 父任务: " + parentTitle + " (" + parentType + ")");
|
|
12296
|
+
for (const t of tasks)
|
|
12297
|
+
report.push(" - #" + t.id + ": " + t.title);
|
|
12298
|
+
if (shouldExecute) {
|
|
12299
|
+
try {
|
|
12300
|
+
const parentTask = await store.createTask({
|
|
12301
|
+
title: parentTitle,
|
|
12302
|
+
description: "自动创建,聚合 " + tasks.length + ' 个 "' + topic + '" 相关子任务',
|
|
12303
|
+
type: parentType,
|
|
12304
|
+
priority: "medium",
|
|
12305
|
+
sessionId: "cli-organize",
|
|
12306
|
+
project_path: "organize",
|
|
12307
|
+
context: JSON.stringify({ type: "organize-auto", topic })
|
|
12308
|
+
});
|
|
12309
|
+
for (const t of tasks) {
|
|
12310
|
+
await store.updateTask(t.id, { parent_task_id: parentTask.id });
|
|
12311
|
+
}
|
|
12312
|
+
report.push(" ✅ 已创建父任务 #" + parentTask.id);
|
|
12313
|
+
} catch (err) {
|
|
12314
|
+
report.push(" ❌ 创建失败: " + err.message);
|
|
12315
|
+
}
|
|
12316
|
+
}
|
|
12317
|
+
}
|
|
12318
|
+
}
|
|
12319
|
+
var handler = async (args) => {
|
|
12320
|
+
console.log("\uD83D\uDD0D Task Organizer");
|
|
12321
|
+
const { getDefaultTaskDbPath, SQLiteTaskStore } = await import("@ai-setting/roy-agent-core");
|
|
12322
|
+
const store = new SQLiteTaskStore(getDefaultTaskDbPath());
|
|
12323
|
+
await store.initialize?.();
|
|
12324
|
+
const allTasks = await store.listTasks({ limit: 9999 });
|
|
12325
|
+
console.log(`
|
|
12326
|
+
\uD83D\uDCCA 系统中共有 ` + allTasks.length + ` 个任务
|
|
12327
|
+
`);
|
|
12328
|
+
const report = [];
|
|
12329
|
+
if (args.deleteTest || args.auto) {
|
|
12330
|
+
await handleDeleteTest(store, allTasks, !args.dryRun, report);
|
|
12331
|
+
}
|
|
12332
|
+
if (args.aggregate || args.auto) {
|
|
12333
|
+
await handleAggregate(store, allTasks, !args.dryRun, report);
|
|
12334
|
+
}
|
|
12335
|
+
if (args.buildTree || args.auto) {
|
|
12336
|
+
await handleBuildTree(store, allTasks, !args.dryRun, report);
|
|
12337
|
+
}
|
|
12338
|
+
console.log(`
|
|
12339
|
+
` + "=".repeat(60));
|
|
12340
|
+
console.log("\uD83D\uDCCB 整理报告");
|
|
12341
|
+
console.log("=".repeat(60));
|
|
12342
|
+
if (report.length === 0) {
|
|
12343
|
+
console.log(" ✨ 未指定整理策略。请使用以下选项:");
|
|
12344
|
+
console.log(" --delete-test 用 AI 清理测试任务");
|
|
12345
|
+
console.log(" --aggregate 聚合相似任务");
|
|
12346
|
+
console.log(" --build-tree 构建任务树");
|
|
12347
|
+
console.log(" --auto 全自动执行所有策略");
|
|
12348
|
+
console.log(" --dry-run 试运行预览");
|
|
12349
|
+
} else {
|
|
12350
|
+
console.log(report.join(`
|
|
12351
|
+
`));
|
|
12352
|
+
}
|
|
12353
|
+
console.log("=".repeat(60));
|
|
12354
|
+
if (args.dryRun) {
|
|
12355
|
+
console.log(`
|
|
12356
|
+
✨ 提示:去掉 --dry-run 参数执行实际整理操作`);
|
|
12357
|
+
}
|
|
12358
|
+
store.close();
|
|
12359
|
+
};
|
|
12360
|
+
|
|
12119
12361
|
// src/commands/tasks/index.ts
|
|
12362
|
+
var OrganizeCommand = {
|
|
12363
|
+
command,
|
|
12364
|
+
describe: desc,
|
|
12365
|
+
builder,
|
|
12366
|
+
handler
|
|
12367
|
+
};
|
|
12120
12368
|
var TasksCommand = {
|
|
12121
12369
|
command: "tasks",
|
|
12122
12370
|
describe: "任务管理 - 创建、追踪、管理任务",
|
|
@@ -12126,7 +12374,7 @@ var TasksCommand = {
|
|
|
12126
12374
|
array: true,
|
|
12127
12375
|
description: "Enable plugin (e.g., --plugin task-tag)",
|
|
12128
12376
|
global: false
|
|
12129
|
-
}).command(ListCommand2).command(GetCommand2).command(CreateCommand).command(UpdateCommand).command(DeleteCommand2).command(CompleteCommand).command(OperationsCommand).demandCommand().help(),
|
|
12377
|
+
}).command(ListCommand2).command(GetCommand2).command(CreateCommand).command(UpdateCommand).command(DeleteCommand2).command(CompleteCommand).command(OperationsCommand).command(OrganizeCommand).demandCommand().help(),
|
|
12130
12378
|
handler: () => {
|
|
12131
12379
|
console.log("Use 'roy-agent tasks --help' for usage information");
|
|
12132
12380
|
}
|
|
@@ -12203,10 +12451,10 @@ var ListCommand3 = {
|
|
|
12203
12451
|
}
|
|
12204
12452
|
};
|
|
12205
12453
|
const rows = filtered.map((s) => {
|
|
12206
|
-
const
|
|
12454
|
+
const desc2 = s.description.length > 50 ? s.description.slice(0, 47) + "..." : s.description;
|
|
12207
12455
|
return [
|
|
12208
12456
|
chalk23.cyan(s.name),
|
|
12209
|
-
|
|
12457
|
+
desc2,
|
|
12210
12458
|
sourceColor(s.source)(`[${s.source}]`)
|
|
12211
12459
|
].join(" | ");
|
|
12212
12460
|
});
|
|
@@ -12361,10 +12609,10 @@ var SearchCommand = {
|
|
|
12361
12609
|
const rows = results.map((s) => {
|
|
12362
12610
|
const matchedIn = s.name.toLowerCase().includes(term) ? "name" : "description";
|
|
12363
12611
|
const matchColor = matchedIn === "name" ? chalk25.green : chalk25.blue;
|
|
12364
|
-
const
|
|
12612
|
+
const desc2 = s.description.length > 40 ? s.description.slice(0, 37) + "..." : s.description;
|
|
12365
12613
|
return [
|
|
12366
12614
|
chalk25.cyan(s.name),
|
|
12367
|
-
|
|
12615
|
+
desc2,
|
|
12368
12616
|
matchColor(`[${matchedIn}]`)
|
|
12369
12617
|
].join(" | ");
|
|
12370
12618
|
});
|
|
@@ -12580,13 +12828,13 @@ var ListCommand4 = {
|
|
|
12580
12828
|
return chalk28.blue;
|
|
12581
12829
|
};
|
|
12582
12830
|
const rows = agents.map((a) => {
|
|
12583
|
-
const
|
|
12831
|
+
const desc2 = (a.description || "").length > 40 ? (a.description || "").slice(0, 37) + "..." : a.description || "-";
|
|
12584
12832
|
const workflowDisplay = a.type === "workflow" && a.workflow ? chalk28.cyan(a.workflow.length > 30 ? a.workflow.slice(0, 27) + "..." : a.workflow) : chalk28.gray("-");
|
|
12585
12833
|
return [
|
|
12586
12834
|
chalk28.cyan(a.name),
|
|
12587
12835
|
typeColor(a.type)(a.type),
|
|
12588
12836
|
workflowDisplay,
|
|
12589
|
-
|
|
12837
|
+
desc2
|
|
12590
12838
|
].join(" | ");
|
|
12591
12839
|
});
|
|
12592
12840
|
if (rows.length === 0) {
|
|
@@ -13300,8 +13548,8 @@ function formatCommandsTable(commands) {
|
|
|
13300
13548
|
const formatRow = (cmd) => {
|
|
13301
13549
|
const name = truncateVisual(cmd.name, NAME_WIDTH).padEnd(NAME_WIDTH);
|
|
13302
13550
|
const source = cmd.source.padEnd(SOURCE_WIDTH);
|
|
13303
|
-
const
|
|
13304
|
-
return `${name}${GAP}${source}${GAP}${
|
|
13551
|
+
const desc2 = truncateVisual(cmd.description || "-", DESC_WIDTH);
|
|
13552
|
+
return `${name}${GAP}${source}${GAP}${desc2}`;
|
|
13305
13553
|
};
|
|
13306
13554
|
const rows = commands.map(formatRow);
|
|
13307
13555
|
return [headerLine, sepLine, ...rows].join(`
|
|
@@ -14008,8 +14256,8 @@ function showHelp(output) {
|
|
|
14008
14256
|
output.log(` ${chalk42.cyan("-s, --sources")} 只显示配置源`);
|
|
14009
14257
|
output.log("");
|
|
14010
14258
|
output.log(chalk42.bold("Examples:"));
|
|
14011
|
-
for (const { command, description } of USAGE_COMMANDS) {
|
|
14012
|
-
output.log(` ${chalk42.cyan(
|
|
14259
|
+
for (const { command: command2, description } of USAGE_COMMANDS) {
|
|
14260
|
+
output.log(` ${chalk42.cyan(command2.padEnd(40))} ${chalk42.gray(description)}`);
|
|
14013
14261
|
}
|
|
14014
14262
|
}
|
|
14015
14263
|
async function showAllComponents(output, configService) {
|
|
@@ -14523,9 +14771,9 @@ var ToolsCommand = {
|
|
|
14523
14771
|
output.log(chalk46.bold.cyan(`
|
|
14524
14772
|
[${serverName}] ${serverTools.length} tools`));
|
|
14525
14773
|
for (const tool of serverTools) {
|
|
14526
|
-
const
|
|
14774
|
+
const desc2 = tool.description.length > 80 ? tool.description.slice(0, 77) + "..." : tool.description;
|
|
14527
14775
|
output.log(` ${chalk46.green("+")} ${chalk46.white(tool.name)}`);
|
|
14528
|
-
output.log(` ${chalk46.gray(
|
|
14776
|
+
output.log(` ${chalk46.gray(desc2)}`);
|
|
14529
14777
|
}
|
|
14530
14778
|
}
|
|
14531
14779
|
output.log(chalk46.gray(`
|
|
@@ -14645,10 +14893,10 @@ var ListCommand7 = {
|
|
|
14645
14893
|
chalk48.bold("Category")
|
|
14646
14894
|
].join(" | ");
|
|
14647
14895
|
const rows = tools.map((t) => {
|
|
14648
|
-
const
|
|
14896
|
+
const desc2 = t.description.length > 40 ? t.description.slice(0, 37) + "..." : t.description;
|
|
14649
14897
|
return [
|
|
14650
14898
|
chalk48.cyan(t.name),
|
|
14651
|
-
|
|
14899
|
+
desc2,
|
|
14652
14900
|
t.metadata?.category ? chalk48.gray(`[${t.metadata.category}]`) : "-"
|
|
14653
14901
|
].join(" | ");
|
|
14654
14902
|
});
|
|
@@ -17327,6 +17575,7 @@ var WorkflowGetCommand = {
|
|
|
17327
17575
|
import chalk62 from "chalk";
|
|
17328
17576
|
import fs4 from "fs";
|
|
17329
17577
|
import path7 from "path";
|
|
17578
|
+
import { parseWorkflowFile } from "@ai-setting/roy-agent-core/env/workflow/types";
|
|
17330
17579
|
var WorkflowUpdateCommand = {
|
|
17331
17580
|
command: "update <name>",
|
|
17332
17581
|
describe: "更新已存在的 Workflow",
|
|
@@ -17390,7 +17639,7 @@ var WorkflowUpdateCommand = {
|
|
|
17390
17639
|
process.exit(1);
|
|
17391
17640
|
}
|
|
17392
17641
|
const content = fs4.readFileSync(filePath, "utf-8");
|
|
17393
|
-
const { definition } = await
|
|
17642
|
+
const { definition } = await parseWorkflowFile(content, filePath);
|
|
17394
17643
|
updates.definition = definition;
|
|
17395
17644
|
}
|
|
17396
17645
|
const tags = a.tags ? a.tags.split(",").map((t) => t.trim()) : undefined;
|
|
@@ -18212,8 +18461,8 @@ function renderNodeTypesTable(nodes) {
|
|
|
18212
18461
|
for (const node of nodes) {
|
|
18213
18462
|
const type = node.type.padEnd(10);
|
|
18214
18463
|
const name = node.name.padEnd(18);
|
|
18215
|
-
const
|
|
18216
|
-
lines.push(`│ ${type} │ ${name} │ ${
|
|
18464
|
+
const desc2 = node.description.substring(0, 59).padEnd(59);
|
|
18465
|
+
lines.push(`│ ${type} │ ${name} │ ${desc2} │`);
|
|
18217
18466
|
}
|
|
18218
18467
|
lines.push("└────────────┴────────────────────┴─────────────────────────────────────────────────────────────┘");
|
|
18219
18468
|
return lines.join(`
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-setting/roy-agent-cli",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.50",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for roy-agent - Non-interactive command execution",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@ai-setting/roy-agent-coder-harness": "^1.5.46",
|
|
30
|
-
"@ai-setting/roy-agent-core": "^1.5.
|
|
30
|
+
"@ai-setting/roy-agent-core": "^1.5.49",
|
|
31
31
|
"@ai-setting/roy-agent-ontology-harness": "^1.5.47",
|
|
32
32
|
"chalk": "^5.6.2",
|
|
33
33
|
"commander": "^14.0.3",
|