speccore 8.3.285 → 8.3.290
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/skills/spec-run/SKILL.md +16 -0
- package/.agents/skills/spec-task-create/SKILL.md +15 -0
- package/.agents/skills/spec-unitize/SKILL.md +16 -0
- package/README.md +14 -1
- package/dist/cli.js +48 -12
- package/dist/cli.js.map +1 -1
- package/dist/commands/code-index.d.ts.map +1 -1
- package/dist/commands/code-index.js +20 -9
- package/dist/commands/code-index.js.map +1 -1
- package/dist/commands/doc2spec.js +32 -60
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/execute.d.ts +1 -0
- package/dist/commands/execute.d.ts.map +1 -1
- package/dist/commands/execute.js +14 -1
- package/dist/commands/execute.js.map +1 -1
- package/dist/commands/help.js +14 -5
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +193 -25
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/status-panel.d.ts.map +1 -1
- package/dist/commands/status-panel.js +115 -37
- package/dist/commands/status-panel.js.map +1 -1
- package/dist/commands/task/new.d.ts +16 -0
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +232 -14
- package/dist/commands/task/new.js.map +1 -1
- package/dist/core/analyze-engine.d.ts.map +1 -1
- package/dist/core/analyze-engine.js +6 -10
- package/dist/core/analyze-engine.js.map +1 -1
- package/dist/core/ask-llm.d.ts +7 -0
- package/dist/core/ask-llm.d.ts.map +1 -1
- package/dist/core/ask-llm.js +45 -0
- package/dist/core/ask-llm.js.map +1 -1
- package/dist/core/code-graph/incremental-build.d.ts +2 -0
- package/dist/core/code-graph/incremental-build.d.ts.map +1 -1
- package/dist/core/code-graph/incremental-build.js +6 -5
- package/dist/core/code-graph/incremental-build.js.map +1 -1
- package/dist/core/code-graph/index.d.ts +2 -0
- package/dist/core/code-graph/index.d.ts.map +1 -1
- package/dist/core/code-graph/index.js +12 -5
- package/dist/core/code-graph/index.js.map +1 -1
- package/dist/core/code-scanner.d.ts +19 -4
- package/dist/core/code-scanner.d.ts.map +1 -1
- package/dist/core/code-scanner.js +193 -77
- package/dist/core/code-scanner.js.map +1 -1
- package/dist/core/excel-extract.d.ts +16 -2
- package/dist/core/excel-extract.d.ts.map +1 -1
- package/dist/core/excel-extract.js +54 -12
- package/dist/core/excel-extract.js.map +1 -1
- package/dist/core/global-counters.d.ts.map +1 -1
- package/dist/core/global-counters.js +19 -7
- package/dist/core/global-counters.js.map +1 -1
- package/dist/core/intent-recognition.d.ts.map +1 -1
- package/dist/core/intent-recognition.js +173 -27
- package/dist/core/intent-recognition.js.map +1 -1
- package/dist/core/plan-store.d.ts +1 -0
- package/dist/core/plan-store.d.ts.map +1 -1
- package/dist/core/plan-store.js.map +1 -1
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +161 -134
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/stage-aliases.d.ts +40 -0
- package/dist/core/stage-aliases.d.ts.map +1 -0
- package/dist/core/stage-aliases.js +110 -0
- package/dist/core/stage-aliases.js.map +1 -0
- package/dist/core/structured-extractor.d.ts.map +1 -1
- package/dist/core/structured-extractor.js +7 -0
- package/dist/core/structured-extractor.js.map +1 -1
- package/dist/utils/synonyms.d.ts.map +1 -1
- package/dist/utils/synonyms.js +15 -0
- package/dist/utils/synonyms.js.map +1 -1
- package/package.json +1 -1
|
@@ -29,6 +29,18 @@ export interface ExcelBugRow {
|
|
|
29
29
|
severity?: string;
|
|
30
30
|
/** 模块列(若表头识别到,可喂给 .meta/feature 关联功能模块) */
|
|
31
31
|
module?: string;
|
|
32
|
+
/** 标题列(若表头识别到,作为任务名;v8.3.288+ 消费,此前识别后未用) */
|
|
33
|
+
title?: string;
|
|
34
|
+
/** 描述列(若表头识别到,作为任务描述主体;v8.3.288+) */
|
|
35
|
+
desc?: string;
|
|
36
|
+
/** 涉及端列(若表头识别到,「所有端」/「api,web」) */
|
|
37
|
+
platforms?: string;
|
|
38
|
+
/** Bug 编号列(若表头识别到;留空则导入时自动生成 YYYYMMDD-XXXX) */
|
|
39
|
+
bugId?: string;
|
|
40
|
+
/** 提出人列(若表头识别到,区别于负责人=处理人) */
|
|
41
|
+
reporter?: string;
|
|
42
|
+
/** 负责人列(若表头识别到,作为任务处理人写入 .meta/owner) */
|
|
43
|
+
owner?: string;
|
|
32
44
|
}
|
|
33
45
|
/**
|
|
34
46
|
* 提取 Excel 的 bug 行(文本 + 内嵌图片 + 优先级/严重度/模块列)
|
|
@@ -37,8 +49,10 @@ export interface ExcelBugRow {
|
|
|
37
49
|
*/
|
|
38
50
|
export declare function extractExcelBugs(filePath: string): Promise<ExcelBugRow[] | null>;
|
|
39
51
|
/**
|
|
40
|
-
* 纯文本回退:用
|
|
41
|
-
*
|
|
52
|
+
* 纯文本回退:用 exceljs 读 Excel,只拿单元格文本(无图片)
|
|
53
|
+
* 供结构化解析失败时的降级路径
|
|
54
|
+
* (v8.3.288 前用 xlsx 库,但 xlsx 从未进入 package.json,回退链实际是断的——
|
|
55
|
+
* exceljs 缺失时这里也必然失败;统一改为 exceljs)
|
|
42
56
|
*/
|
|
43
57
|
export declare function extractExcelTextOnly(filePath: string): Promise<string[] | null>;
|
|
44
58
|
//# sourceMappingURL=excel-extract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"excel-extract.d.ts","sourceRoot":"","sources":["../../src/core/excel-extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"excel-extract.d.ts","sourceRoot":"","sources":["../../src/core/excel-extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmCD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAiFtF;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CA0BrF"}
|
|
@@ -17,8 +17,18 @@ const COLUMN_HINTS = {
|
|
|
17
17
|
priority: /优先级|优先|priority|紧急程度|等级|level|p\d/i,
|
|
18
18
|
severity: /严重度|严重程度|severity|s\d/i,
|
|
19
19
|
module: /所属模块|功能模块|模块|子系统|feature|module/i,
|
|
20
|
-
title
|
|
20
|
+
// v8.3.288+: desc 先于 title 检测——「Bug 描述」列含「Bug」,若 title 先测 会被
|
|
21
|
+
// /bug/i 抢走误当标题列;描述类词与标题列互斥,先测 desc 不会误伤「Bug 标 题」
|
|
21
22
|
desc: /描述|说明|详情|现象|复现|description|detail|desc/i,
|
|
23
|
+
// v8.3.288+: bugId 先于 title 检测——「Bug 编号」含「Bug」,防被 title 的 /bug/i 抢
|
|
24
|
+
bugId: /缺陷编号|缺陷.?id|bug.?编号|bug.?id|issue.?id|^编号$|^id$/i,
|
|
25
|
+
title: /标题|名称|问题|摘要|主题|缺陷名|title|name|bug/i,
|
|
26
|
+
// v8.3.288+: 涉及端列(「所有端」/「api,web」),决定该任务的端子任务集
|
|
27
|
+
platforms: /涉及端|影响端|端范围|所有端|所属端|平台|platforms?|platform/i,
|
|
28
|
+
// v8.3.288+: 提出人列(区别于「负责人」=处理人;整词匹配防误伤)
|
|
29
|
+
reporter: /提出人|报告人|提交人|上报人|发现人|reporter|creator/i,
|
|
30
|
+
// v8.3.288+: 负责人列(处理人,写入 .meta/owner;排在 reporter 后防「提出人」被抢)
|
|
31
|
+
owner: /负责人|处理人|指派给|分配给|owner|assignee/i,
|
|
22
32
|
};
|
|
23
33
|
/** 提取单元格文本(字符串/数字/富文本/公式) */
|
|
24
34
|
function cellText(v) {
|
|
@@ -65,7 +75,13 @@ async function extractExcelBugs(filePath) {
|
|
|
65
75
|
if (!text)
|
|
66
76
|
return;
|
|
67
77
|
for (const [field, re] of Object.entries(COLUMN_HINTS)) {
|
|
68
|
-
if (colHints[field]
|
|
78
|
+
if (colHints[field] !== undefined)
|
|
79
|
+
continue;
|
|
80
|
+
// v8.3.288+: 列独占——该列已被其他字段占用则跳过,
|
|
81
|
+
// 防「Bug 编号/Bug 描述」含「Bug」被 title 的 /bug/i 同时抢走
|
|
82
|
+
if (Object.values(colHints).includes(colNumber))
|
|
83
|
+
continue;
|
|
84
|
+
if (re.test(text)) {
|
|
69
85
|
colHints[field] = colNumber;
|
|
70
86
|
}
|
|
71
87
|
}
|
|
@@ -110,6 +126,12 @@ async function extractExcelBugs(filePath) {
|
|
|
110
126
|
priority: get('priority'),
|
|
111
127
|
severity: get('severity'),
|
|
112
128
|
module: get('module'),
|
|
129
|
+
title: get('title'),
|
|
130
|
+
desc: get('desc'),
|
|
131
|
+
platforms: get('platforms'),
|
|
132
|
+
bugId: get('bugId'),
|
|
133
|
+
reporter: get('reporter'),
|
|
134
|
+
owner: get('owner'),
|
|
113
135
|
});
|
|
114
136
|
});
|
|
115
137
|
return rows;
|
|
@@ -119,19 +141,39 @@ async function extractExcelBugs(filePath) {
|
|
|
119
141
|
}
|
|
120
142
|
}
|
|
121
143
|
/**
|
|
122
|
-
* 纯文本回退:用
|
|
123
|
-
*
|
|
144
|
+
* 纯文本回退:用 exceljs 读 Excel,只拿单元格文本(无图片)
|
|
145
|
+
* 供结构化解析失败时的降级路径
|
|
146
|
+
* (v8.3.288 前用 xlsx 库,但 xlsx 从未进入 package.json,回退链实际是断的——
|
|
147
|
+
* exceljs 缺失时这里也必然失败;统一改为 exceljs)
|
|
124
148
|
*/
|
|
125
149
|
async function extractExcelTextOnly(filePath) {
|
|
150
|
+
let ExcelJS;
|
|
126
151
|
try {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
152
|
+
ExcelJS = require('exceljs');
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
const workbook = new ExcelJS.Workbook();
|
|
159
|
+
await workbook.xlsx.readFile(filePath);
|
|
160
|
+
const worksheet = workbook.worksheets[0];
|
|
161
|
+
if (!worksheet)
|
|
162
|
+
return null;
|
|
163
|
+
const rows = [];
|
|
164
|
+
worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
|
|
165
|
+
if (rowNumber <= 1)
|
|
166
|
+
return; // 跳过表头
|
|
167
|
+
const texts = [];
|
|
168
|
+
row.eachCell({ includeEmpty: false }, (cell) => {
|
|
169
|
+
const t = cellText(cell.value).trim();
|
|
170
|
+
if (t)
|
|
171
|
+
texts.push(t);
|
|
172
|
+
});
|
|
173
|
+
if (texts.length > 0)
|
|
174
|
+
rows.push(texts.join(' — '));
|
|
175
|
+
});
|
|
176
|
+
return rows;
|
|
135
177
|
}
|
|
136
178
|
catch {
|
|
137
179
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"excel-extract.js","sourceRoot":"","sources":["../../src/core/excel-extract.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;
|
|
1
|
+
{"version":3,"file":"excel-extract.js","sourceRoot":"","sources":["../../src/core/excel-extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-counters.d.ts","sourceRoot":"","sources":["../../src/core/global-counters.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"global-counters.d.ts","sourceRoot":"","sources":["../../src/core/global-counters.ts"],"names":[],"mappings":"AASA,UAAU,QAAQ;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAcrD;AAsFD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAOxG;AAED,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAWpG;AAED,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAQpG;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlD"}
|
|
@@ -12,6 +12,7 @@ exports.initCounters = initCounters;
|
|
|
12
12
|
*/
|
|
13
13
|
const fs_extra_1 = require("fs-extra");
|
|
14
14
|
const path_1 = require("path");
|
|
15
|
+
const pinyin_pro_1 = require("pinyin-pro");
|
|
15
16
|
function path() {
|
|
16
17
|
return (0, path_1.join)(process.cwd(), '.speccore', 'local', 'counters.json');
|
|
17
18
|
}
|
|
@@ -97,19 +98,27 @@ async function scanMaxIds() {
|
|
|
97
98
|
catch { /* 工作区不可读时返回 0 */ }
|
|
98
99
|
return { iterations, tasks, plans };
|
|
99
100
|
}
|
|
100
|
-
/** 中英文名称转 slug
|
|
101
|
+
/** 中英文名称转 slug(保留英文/数字,纯中文时拼音兜底) */
|
|
101
102
|
function toSlug(name) {
|
|
102
103
|
// 去掉 Iteration- 前缀
|
|
103
104
|
const clean = name.replace(/^Iteration-/, '');
|
|
104
105
|
// 优先提取连续的英文/数字片段(如 "User管理" → "User")
|
|
105
106
|
const latinMatches = clean.match(/[a-zA-Z0-9]+/g);
|
|
106
107
|
if (latinMatches && latinMatches.length > 0) {
|
|
107
|
-
return latinMatches.join('-').toLowerCase().slice(0,
|
|
108
|
+
return latinMatches.join('-').toLowerCase().slice(0, 40);
|
|
108
109
|
}
|
|
109
|
-
// 纯中文且无英文 → hash
|
|
110
|
+
// 纯中文且无英文 → 拼音兜底(v8.3.286+:替代无语义 hash 乱码「iter-cl0w」,
|
|
111
|
+
// 同一输入拼音稳定,幂等性不变)
|
|
112
|
+
// v8.3.289+: 去掉 iter- 前缀——toSlug 被 nextTaskId/nextPlanId 复用,
|
|
113
|
+
// 「iter-」混进任务目录名产生 Task-001-iter-zhifuxiugai 噪音;
|
|
114
|
+
// 迭代 ID 本身已带 Iteration- 前缀,无需二次标记
|
|
110
115
|
if (/[\u4e00-\u9fff]/.test(clean)) {
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
return (0, pinyin_pro_1.pinyin)(clean, { toneType: 'none', type: 'array' })
|
|
117
|
+
.map((s) => s.replace(/[^a-z0-9]/gi, ''))
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.join('-')
|
|
120
|
+
.toLowerCase()
|
|
121
|
+
.slice(0, 24);
|
|
113
122
|
}
|
|
114
123
|
return 'project';
|
|
115
124
|
}
|
|
@@ -127,7 +136,10 @@ async function nextTaskId(name, topic) {
|
|
|
127
136
|
await save(c);
|
|
128
137
|
const padded = String(c.tasks).padStart(3, '0');
|
|
129
138
|
const keyword = topic || name;
|
|
130
|
-
|
|
139
|
+
// v8.3.289+: 上限 20→40,与 toSlug 拉丁片段上限对齐——
|
|
140
|
+
// LLM 英译 slug 2~5 词可达 30+ 字符(booking-order-status-not-synced),
|
|
141
|
+
// 20 字符截断会吃掉词尾造成语义残片
|
|
142
|
+
const suffix = keyword ? `-${toSlug(keyword).slice(0, 40)}` : '';
|
|
131
143
|
return { id: `Task-${padded}${suffix}`, num: c.tasks };
|
|
132
144
|
}
|
|
133
145
|
async function nextPlanId(name, topic) {
|
|
@@ -136,7 +148,7 @@ async function nextPlanId(name, topic) {
|
|
|
136
148
|
await save(c);
|
|
137
149
|
const padded = String(c.plans).padStart(3, '0');
|
|
138
150
|
const keyword = topic || name;
|
|
139
|
-
const suffix = keyword ? `-${toSlug(keyword).slice(0,
|
|
151
|
+
const suffix = keyword ? `-${toSlug(keyword).slice(0, 40)}` : '';
|
|
140
152
|
return { id: `Plan-${padded}${suffix}`, num: c.plans };
|
|
141
153
|
}
|
|
142
154
|
async function initCounters() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-counters.js","sourceRoot":"","sources":["../../src/core/global-counters.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"global-counters.js","sourceRoot":"","sources":["../../src/core/global-counters.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-recognition.d.ts","sourceRoot":"","sources":["../../src/core/intent-recognition.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,WAAW;AACX,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,SAAS,GACT,KAAK,GACL,QAAQ,GACR,kBAAkB,GAClB,SAAS,GACT,OAAO,GACP,aAAa,GACb,IAAI,GACJ,MAAM,GACN,QAAQ,GACR,MAAM,GACN,WAAW,GACX,SAAS,GACT,gBAAgB,GAChB,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,GACT,UAAU,GACV,MAAM,GACN,OAAO,GACP,cAAc,GACd,kBAAkB,GAClB,uBAAuB,GACvB,gBAAgB,GAChB,eAAe,GACf,SAAS,GACT,QAAQ,GACR,UAAU,GACV,WAAW,GACX,OAAO,GACP,QAAQ,GACR,UAAU,GACV,cAAc,GACd,cAAc,GACd,SAAS,GACT,UAAU,GACV,YAAY,GACZ,SAAS,GACT,gBAAgB,GAChB,MAAM,CAAC;AAEX,aAAa;AACb,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,YAAY,EAAE,OAAO,CAAC;IACtB,8FAA8F;IAC9F,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,aAAa;AACb,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"intent-recognition.d.ts","sourceRoot":"","sources":["../../src/core/intent-recognition.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,WAAW;AACX,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,SAAS,GACT,KAAK,GACL,QAAQ,GACR,kBAAkB,GAClB,SAAS,GACT,OAAO,GACP,aAAa,GACb,IAAI,GACJ,MAAM,GACN,QAAQ,GACR,MAAM,GACN,WAAW,GACX,SAAS,GACT,gBAAgB,GAChB,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,GACT,UAAU,GACV,MAAM,GACN,OAAO,GACP,cAAc,GACd,kBAAkB,GAClB,uBAAuB,GACvB,gBAAgB,GAChB,eAAe,GACf,SAAS,GACT,QAAQ,GACR,UAAU,GACV,WAAW,GACX,OAAO,GACP,QAAQ,GACR,UAAU,GACV,cAAc,GACd,cAAc,GACd,SAAS,GACT,UAAU,GACV,YAAY,GACZ,SAAS,GACT,gBAAgB,GAChB,MAAM,CAAC;AAEX,aAAa;AACb,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,YAAY,EAAE,OAAO,CAAC;IACtB,8FAA8F;IAC9F,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,aAAa;AACb,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAqqBD;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAsJ5E;AA4OD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAIhF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,EAAE,CAExD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE/E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,EAAE,CAExE;AA8BD,yBAAyB;AACzB,eAAO,MAAM,iBAAiB,iBAG5B,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAU1D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAI7D"}
|
|
@@ -78,12 +78,21 @@ const COMMAND_MAPPINGS = [
|
|
|
78
78
|
},
|
|
79
79
|
// 创建层
|
|
80
80
|
// 创建迭代(必须在通用创建之前,优先级更高)
|
|
81
|
+
// v8.3.286+: triggers 补口语化虚词变体——「创建迭代」「新建迭代」被「一个/个/新」隔断后
|
|
82
|
+
// 仍能命中;英文变体覆盖「speccore iteration create」这类输入。
|
|
83
|
+
// (宽 trigger「新建/创建」故意不收录:那是 task new 的词,靠共现加权决胜,见 recognizeIntent)
|
|
81
84
|
{
|
|
82
85
|
id: 'iteration create',
|
|
83
86
|
intent: 'iteration_create',
|
|
84
87
|
priority: 92,
|
|
85
|
-
triggers: [
|
|
86
|
-
|
|
88
|
+
triggers: [
|
|
89
|
+
'创建迭代', '新建迭代', '创建sprint', '新建sprint', '开新迭代', '新开迭代',
|
|
90
|
+
'创建一个迭代', '新建一个迭代', '创建新迭代', '新建新迭代',
|
|
91
|
+
'创建个迭代', '新建个迭代', '开一个新迭代', '新开一个迭代', '开个新迭代',
|
|
92
|
+
'创建期次', '新建期次', '创建一个期次', '新建一个期次',
|
|
93
|
+
'iteration create', 'create iteration', 'create sprint', 'new iteration', 'new sprint',
|
|
94
|
+
],
|
|
95
|
+
patterns: ['创建(.+)迭代', '新建(.+)迭代', '创建一个(.+)迭代', '新建一个(.+)迭代', '创建一个叫(.+)的迭代', '创建sprint(.+)', '开(.+)迭代', '迭代叫(.+)'],
|
|
87
96
|
description: '创建新迭代 — 生成 STAFFING + 产品需求 + 需求文档目录',
|
|
88
97
|
args: '--name=<name> --owner=<owner>',
|
|
89
98
|
},
|
|
@@ -511,6 +520,13 @@ const CONTEXT_RULES = {
|
|
|
511
520
|
noContextMessage: '当前无活跃迭代,请先创建迭代',
|
|
512
521
|
withContextEnhancement: (ctx) => `当前迭代: ${ctx.currentIteration},准备执行待开发任务`,
|
|
513
522
|
},
|
|
523
|
+
// v8.3.286+: 创建迭代在活跃迭代场景下同样常见(新迭代衔接),补上上下文加成,
|
|
524
|
+
// 避免「新建一个迭代」在有活跃迭代时被 execute 的上下文 +15 反超。
|
|
525
|
+
'iteration create': {
|
|
526
|
+
intent: 'iteration_create',
|
|
527
|
+
noContextMessage: '',
|
|
528
|
+
withContextEnhancement: (ctx) => `当前迭代: ${ctx.currentIteration},新迭代创建后按需切换活跃迭代`,
|
|
529
|
+
},
|
|
514
530
|
query_progress: {
|
|
515
531
|
intent: 'query_progress',
|
|
516
532
|
noContextMessage: '当前无活跃迭代,无法查看进度',
|
|
@@ -534,6 +550,95 @@ const CONTEXT_RULES = {
|
|
|
534
550
|
// ============================================================
|
|
535
551
|
// 意图识别引擎
|
|
536
552
|
// ============================================================
|
|
553
|
+
/**
|
|
554
|
+
* 口语虚词归一化(v8.3.287+)
|
|
555
|
+
* 剥离口语填充短语,让词组 trigger 在被「一下/一个/帮我」隔断时仍能连续命中。
|
|
556
|
+
* 保守原则:只剥完整短语,不剥单字歧义词(的/再/下/请/个/先——「再分析」是 trigger、
|
|
557
|
+
* 「下一步」是 next trigger、单字剥离会误伤「优先/个别」等)。
|
|
558
|
+
* 参数提取(extractParams)仍用原输入,捕获组内容不受归一化污染。
|
|
559
|
+
*/
|
|
560
|
+
const ORAL_FILLERS = ['请帮我', '麻烦你', '帮我', '给我', '一下', '一个', '一项', '一条', '一份'];
|
|
561
|
+
function normalizeInput(input) {
|
|
562
|
+
let out = input;
|
|
563
|
+
for (const filler of ORAL_FILLERS) {
|
|
564
|
+
out = out.split(filler).join('');
|
|
565
|
+
}
|
|
566
|
+
return out;
|
|
567
|
+
}
|
|
568
|
+
const ANCHOR_RULES = [
|
|
569
|
+
// 迭代锚点:创建类动词 + 迭代/sprint/期次 → iteration_create 强信号
|
|
570
|
+
// (排除「XX迭代的功能模块」:迭代后紧跟「的」时迭代是定语不是宾语)
|
|
571
|
+
{
|
|
572
|
+
kind: 'anchor', intent: 'iteration_create',
|
|
573
|
+
anchors: /(?:迭代|sprint|期次)(?!的)/,
|
|
574
|
+
verbs: /(?:创建|新建|新开|开新|开启|建立|建|开)/,
|
|
575
|
+
bonus: 35,
|
|
576
|
+
},
|
|
577
|
+
// 项目锚点:句子以「项目」结尾 + 初始化类动词 → init
|
|
578
|
+
// (「项目管理/项目计划」等定语结构不以「项目」结尾,不受影响)
|
|
579
|
+
{
|
|
580
|
+
kind: 'anchor', intent: 'init',
|
|
581
|
+
anchors: /项目[,。\s]*$/,
|
|
582
|
+
verbs: /(?:创建|新建|建立|初始化|迁移)/,
|
|
583
|
+
bonus: 20,
|
|
584
|
+
},
|
|
585
|
+
// 任务锚点:创建类动词 + 任务名词 → new_task(多端任务)
|
|
586
|
+
{
|
|
587
|
+
kind: 'anchor', intent: 'new_task',
|
|
588
|
+
anchors: /任务/,
|
|
589
|
+
verbs: /(?:新建|创建|做一个?|添加)/,
|
|
590
|
+
bonus: 25,
|
|
591
|
+
},
|
|
592
|
+
// 功能锚点:做一个/添加/实现 + 功能类名词 → create
|
|
593
|
+
// (修「做一个支付模块」被 execute 宽 trigger「做」抢走)
|
|
594
|
+
{
|
|
595
|
+
kind: 'anchor', intent: 'create',
|
|
596
|
+
anchors: /(?:功能|模块|页面|接口|服务|系统)/,
|
|
597
|
+
verbs: /(?:做一个?|添加|实现|新增)/,
|
|
598
|
+
bonus: 20,
|
|
599
|
+
},
|
|
600
|
+
// 文档锚点:导入/转换 + 文档类名词 → doc2spec
|
|
601
|
+
// (修「导入一下文档」只靠 pattern 分导致低置信度;25 分使其跨过 85 high 线)
|
|
602
|
+
{
|
|
603
|
+
kind: 'anchor', intent: 'doc2spec',
|
|
604
|
+
anchors: /(?:文档|PRD|word|docx)/,
|
|
605
|
+
verbs: /(?:导入|转换|转)/,
|
|
606
|
+
bonus: 25,
|
|
607
|
+
},
|
|
608
|
+
// 需求文档锚点:切分 + 需求文档/功能单元 → unitize
|
|
609
|
+
{
|
|
610
|
+
kind: 'anchor', intent: 'split-units',
|
|
611
|
+
anchors: /(?:需求文档|功能单元)/,
|
|
612
|
+
verbs: /(?:切分|切)/,
|
|
613
|
+
bonus: 20,
|
|
614
|
+
},
|
|
615
|
+
// 反向让位:task new 的宽 pattern「创建(.+)」吞掉迭代名词 → 夺回误加分
|
|
616
|
+
{
|
|
617
|
+
kind: 'capturePenalty', intents: ['create', 'new_task'],
|
|
618
|
+
anchors: /(?:迭代|sprint|期次)(?!的)/,
|
|
619
|
+
bonus: 35,
|
|
620
|
+
},
|
|
621
|
+
// 反向让位:宽捕获以「项目」结尾 → 项目初始化优先(「项目管理」定语不受影响)
|
|
622
|
+
{
|
|
623
|
+
kind: 'capturePenalty', intents: ['create', 'new_task'],
|
|
624
|
+
anchors: /项目[,。\s]*$/,
|
|
625
|
+
bonus: 35,
|
|
626
|
+
},
|
|
627
|
+
// 短语让位:「创建任务/新建任务」短语明确 → 多端任务优先于通用创建
|
|
628
|
+
// (-40:须同时抵消 287 功能锚点 +20 与上下文加成,否则「新建任务,做一个支付模块」
|
|
629
|
+
// 中 create 仍与 new_task 并列封顶 100,按 priority 反而排前)
|
|
630
|
+
{
|
|
631
|
+
kind: 'phrasePenalty', intent: 'create',
|
|
632
|
+
anchors: /(?:创建|新建|做一个?|添加).{0,2}任务/,
|
|
633
|
+
bonus: 40,
|
|
634
|
+
},
|
|
635
|
+
];
|
|
636
|
+
/** 迭代工作意图集(v8.3.287+):活跃迭代场景下统一享 +15 上下文加成,此前仅 4 个意图有 */
|
|
637
|
+
const ITERATION_CONTEXT_INTENTS = new Set([
|
|
638
|
+
'execute', 'iteration_create', 'analyze', 'split', 'split-units',
|
|
639
|
+
'plan', 'review', 'change', 'create', 'new_task', 'bugfix',
|
|
640
|
+
'req_doc', 'doc2spec', 'research', 'query_progress', 'done',
|
|
641
|
+
]);
|
|
537
642
|
/**
|
|
538
643
|
* 从用户自然语言输入中识别意图
|
|
539
644
|
*/
|
|
@@ -545,22 +650,29 @@ async function recognizeIntent(input) {
|
|
|
545
650
|
}
|
|
546
651
|
const results = [];
|
|
547
652
|
const inputLower = input.toLowerCase();
|
|
653
|
+
// v8.3.287+: 口语虚词归一化——词组 trigger 被隔断时在归一化副本恢复连续命中
|
|
654
|
+
const normInput = normalizeInput(input);
|
|
655
|
+
const normInputLower = normInput.toLowerCase();
|
|
548
656
|
for (const mapping of COMMAND_MAPPINGS) {
|
|
549
657
|
let totalScore = 0;
|
|
550
658
|
const matched = [];
|
|
551
|
-
// 1.
|
|
659
|
+
// 1. 关键词直接匹配(原输入 + 归一化副本双集合,任一命中计分一次,绝不双计)
|
|
552
660
|
for (const trigger of mapping.triggers) {
|
|
553
|
-
|
|
554
|
-
|
|
661
|
+
const tl = trigger.toLowerCase();
|
|
662
|
+
const hit = input.includes(trigger) || inputLower.includes(tl) ||
|
|
663
|
+
(normInput !== input && (normInput.includes(trigger) || normInputLower.includes(tl)));
|
|
664
|
+
if (hit) {
|
|
665
|
+
// v8.3.287+: 宽触发词(≤2 字符)降权 20→12,长词组保持 20——
|
|
666
|
+
// 「做/跑/开」等单字词不再轻松碾压「做一个/跑流水线」
|
|
667
|
+
totalScore += trigger.length <= 2 ? 12 : 20;
|
|
555
668
|
matched.push(`关键词: "${trigger}"`);
|
|
556
669
|
}
|
|
557
670
|
}
|
|
558
|
-
// 2.
|
|
671
|
+
// 2. 正则模式匹配(双集合,任一命中计分一次)
|
|
559
672
|
for (const pattern of mapping.patterns) {
|
|
560
673
|
try {
|
|
561
674
|
const regex = new RegExp(pattern);
|
|
562
|
-
|
|
563
|
-
if (match) {
|
|
675
|
+
if (regex.test(input) || (normInput !== input && regex.test(normInput))) {
|
|
564
676
|
totalScore += 30;
|
|
565
677
|
matched.push(`模式: "${pattern}"`);
|
|
566
678
|
}
|
|
@@ -569,29 +681,52 @@ async function recognizeIntent(input) {
|
|
|
569
681
|
// 忽略无效正则
|
|
570
682
|
}
|
|
571
683
|
}
|
|
684
|
+
// 2.5 名词锚点共现规则(v8.3.287+:统一表,体系化 286 的硬编码补丁)
|
|
685
|
+
for (const rule of ANCHOR_RULES) {
|
|
686
|
+
if (rule.kind === 'anchor') {
|
|
687
|
+
if (mapping.intent !== rule.intent)
|
|
688
|
+
continue;
|
|
689
|
+
if (!rule.anchors.test(input) || !rule.verbs.test(input))
|
|
690
|
+
continue;
|
|
691
|
+
totalScore += rule.bonus;
|
|
692
|
+
matched.push(`锚点共现: +${rule.bonus}`);
|
|
693
|
+
}
|
|
694
|
+
else if (rule.kind === 'capturePenalty') {
|
|
695
|
+
if (!rule.intents.includes(mapping.intent))
|
|
696
|
+
continue;
|
|
697
|
+
const wideCapture = input.match(/(?:创建|新建|新增|添加|做一个?)(.+)/);
|
|
698
|
+
if (!wideCapture || !rule.anchors.test(wideCapture[1] || ''))
|
|
699
|
+
continue;
|
|
700
|
+
totalScore -= rule.bonus;
|
|
701
|
+
matched.push(`锚点让位: -${rule.bonus}`);
|
|
702
|
+
}
|
|
703
|
+
else {
|
|
704
|
+
// phrasePenalty
|
|
705
|
+
if (mapping.intent !== rule.intent)
|
|
706
|
+
continue;
|
|
707
|
+
if (!rule.anchors.test(input))
|
|
708
|
+
continue;
|
|
709
|
+
totalScore -= rule.bonus;
|
|
710
|
+
matched.push(`锚点让位: -${rule.bonus}`);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
572
713
|
if (totalScore > 0) {
|
|
573
714
|
// 3. 优先级加成
|
|
574
715
|
totalScore += mapping.priority * 0.3;
|
|
575
|
-
// 4.
|
|
716
|
+
// 4. 上下文感知增强(v8.3.287+:迭代工作意图集统一享 +15,不再只限 4 个意图)
|
|
576
717
|
let contextAware = false;
|
|
577
718
|
const contextRule = CONTEXT_RULES[mapping.id];
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
else if (mapping.intent === 'execute' ||
|
|
591
|
-
mapping.intent === 'query_progress') {
|
|
592
|
-
totalScore -= 20; // 无上下文降权
|
|
593
|
-
matched.push('上下文感知: 无活跃迭代');
|
|
594
|
-
}
|
|
719
|
+
const ctxIntent = contextRule?.intent || mapping.intent;
|
|
720
|
+
// v6.97.0+ 修复:用户明确说全局分析时,不因活跃迭代给迭代级意图加分
|
|
721
|
+
const hasGlobalScope = /全局|全量|所有项目|所有工程|整体架构|跨端|整个系统/.test(input);
|
|
722
|
+
if (activeIteration && !hasGlobalScope && ITERATION_CONTEXT_INTENTS.has(ctxIntent)) {
|
|
723
|
+
totalScore += 15;
|
|
724
|
+
contextAware = true;
|
|
725
|
+
matched.push('上下文感知: 有活跃迭代');
|
|
726
|
+
}
|
|
727
|
+
else if (!activeIteration && (ctxIntent === 'execute' || ctxIntent === 'query_progress')) {
|
|
728
|
+
totalScore -= 20; // 无上下文降权
|
|
729
|
+
matched.push('上下文感知: 无活跃迭代');
|
|
595
730
|
}
|
|
596
731
|
// 5. 语境加成/减分:区分 speccore 域内 vs 域外表达
|
|
597
732
|
// 5a. 开发术语加成(+10):输入包含 speccore 领域的专业词汇
|
|
@@ -633,7 +768,7 @@ async function recognizeIntent(input) {
|
|
|
633
768
|
}
|
|
634
769
|
}
|
|
635
770
|
// 按置信度降序排列;同分时 trigger 精确度(命中短语总长)降序;再同则 priority 降序
|
|
636
|
-
|
|
771
|
+
const sorted = results.sort((a, b) => {
|
|
637
772
|
if (b.confidence !== a.confidence)
|
|
638
773
|
return b.confidence - a.confidence;
|
|
639
774
|
if ((b.triggerSpecificity || 0) !== (a.triggerSpecificity || 0)) {
|
|
@@ -641,6 +776,17 @@ async function recognizeIntent(input) {
|
|
|
641
776
|
}
|
|
642
777
|
return b.priority - a.priority;
|
|
643
778
|
});
|
|
779
|
+
// v8.3.287+: 同 (intent, command) 对去重——analyze 有双映射(真重复);
|
|
780
|
+
// 但 task new(create/new_task)、welcome(demo/welcome)、dashboard(global_status/dashboard)
|
|
781
|
+
// 是不同意图共享命令名,必须保留,否则 new_task 会被 create 吞掉。
|
|
782
|
+
const seenCandidates = new Set();
|
|
783
|
+
return sorted.filter((r) => {
|
|
784
|
+
const key = `${r.intent}|${r.command}`;
|
|
785
|
+
if (seenCandidates.has(key))
|
|
786
|
+
return false;
|
|
787
|
+
seenCandidates.add(key);
|
|
788
|
+
return true;
|
|
789
|
+
});
|
|
644
790
|
}
|
|
645
791
|
/**
|
|
646
792
|
* 从输入中提取参数
|