speccore 5.25.2 → 5.26.3
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/README.md +115 -73
- package/dist/cli.js +123 -45
- package/dist/cli.js.map +1 -1
- package/dist/commands/ask.d.ts +4 -5
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +257 -292
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/dashboard.d.ts +12 -0
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +442 -77
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/dev.d.ts +2 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +292 -292
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doc2spec.d.ts +2 -0
- package/dist/commands/doc2spec.d.ts.map +1 -1
- package/dist/commands/doc2spec.js +22 -6
- package/dist/commands/doc2spec.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +47 -9
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/init.js +42 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/spec2doc.d.ts +11 -0
- package/dist/commands/spec2doc.d.ts.map +1 -0
- package/dist/commands/spec2doc.js +183 -0
- package/dist/commands/spec2doc.js.map +1 -0
- package/dist/commands/status-panel.d.ts +1 -0
- package/dist/commands/status-panel.d.ts.map +1 -1
- package/dist/commands/status-panel.js +97 -3
- package/dist/commands/status-panel.js.map +1 -1
- package/dist/commands/welcome.d.ts +10 -0
- package/dist/commands/welcome.d.ts.map +1 -1
- package/dist/commands/welcome.js +77 -30
- package/dist/commands/welcome.js.map +1 -1
- package/dist/core/ask-engine.d.ts +45 -0
- package/dist/core/ask-engine.d.ts.map +1 -0
- package/dist/core/ask-engine.js +405 -0
- package/dist/core/ask-engine.js.map +1 -0
- package/dist/core/ask-host-ai.d.ts +33 -0
- package/dist/core/ask-host-ai.d.ts.map +1 -0
- package/dist/core/ask-host-ai.js +156 -0
- package/dist/core/ask-host-ai.js.map +1 -0
- package/dist/core/ask-llm.d.ts +12 -0
- package/dist/core/ask-llm.d.ts.map +1 -0
- package/dist/core/ask-llm.js +166 -0
- package/dist/core/ask-llm.js.map +1 -0
- package/dist/core/dev-llm.d.ts +34 -0
- package/dist/core/dev-llm.d.ts.map +1 -0
- package/dist/core/dev-llm.js +209 -0
- package/dist/core/dev-llm.js.map +1 -0
- package/dist/core/help-panel.d.ts +1 -1
- package/dist/core/help-panel.d.ts.map +1 -1
- package/dist/core/help-panel.js +6 -5
- package/dist/core/help-panel.js.map +1 -1
- package/dist/core/intent-recognition.js +3 -3
- package/dist/core/intent-recognition.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +5 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/welcome.js
CHANGED
|
@@ -1,52 +1,99 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.welcomeCommand = welcomeCommand;
|
|
4
2
|
/**
|
|
5
|
-
* welcome — SpecCore
|
|
6
|
-
*
|
|
3
|
+
* welcome — SpecCore 项目名片 + 使用引导
|
|
4
|
+
* 终端模式:Unicode 框线;AI 模式(HTML):彩色卡片架构图
|
|
7
5
|
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.welcomeCommand = welcomeCommand;
|
|
8
|
+
exports.renderWelcomeHtml = renderWelcomeHtml;
|
|
8
9
|
const logger_1 = require("../utils/logger");
|
|
9
10
|
const path_1 = require("path");
|
|
10
11
|
const fs_extra_1 = require("fs-extra");
|
|
11
12
|
const context_1 = require("../core/context");
|
|
13
|
+
const C = { r: '\x1b[0m', b: '\x1b[1m', d: '\x1b[2m', cyan: '\x1b[36m', green: '\x1b[32m', yellow: '\x1b[33m', magenta: '\x1b[35m', gray: '\x1b[90m', blue: '\x1b[34m' };
|
|
14
|
+
const B = { tl: '╭', tr: '╮', bl: '╰', br: '╯', h: '─', v: '│', dot: '◆', arrow: '→' };
|
|
15
|
+
function box(title, body, w = 60) {
|
|
16
|
+
const top = `${C.cyan}${B.tl}${B.h.repeat(2)} ${C.b}${title}${C.r} ${B.h.repeat(Math.max(0, w - 5 - title.length))}${B.tr}${C.r}`;
|
|
17
|
+
const mid = body.map(l => `${C.cyan}${B.v}${C.r} ${l}`).join('\n');
|
|
18
|
+
const bot = `${C.cyan}${B.bl}${B.h.repeat(w - 2)}${B.br}${C.r}`;
|
|
19
|
+
return [top, mid, bot].join('\n');
|
|
20
|
+
}
|
|
12
21
|
async function welcomeCommand(_options) {
|
|
13
22
|
const version = require('../../package.json').version;
|
|
14
|
-
// ── 名片 ──
|
|
15
|
-
logger_1.logger.info(`
|
|
16
|
-
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
|
|
17
|
-
█▌ SpecCore · Code by Spec, Not by Vibe ▐▌
|
|
18
|
-
█▌ ▐▌
|
|
19
|
-
█▌ 需求 ─→ 拆分 ─→ 计划 ─→ 执行 ─→ 交付 ▐▌
|
|
20
|
-
█▌ 规范驱动 · 人机协同 · 可追溯闭环 ▐▌
|
|
21
|
-
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
|
22
|
-
`);
|
|
23
|
-
// ── 状态行 ──
|
|
24
23
|
const isInit = await (0, fs_extra_1.pathExists)((0, path_1.join)(process.cwd(), '.speccore'));
|
|
24
|
+
const iteration = await (0, context_1.getDefaultIteration)('');
|
|
25
|
+
const iterName = (!iteration || iteration.includes('---') || iteration.length < 2) ? '' : iteration;
|
|
26
|
+
if (!process.stdout.isTTY) {
|
|
27
|
+
let taskCount = 0;
|
|
28
|
+
if (iterName) {
|
|
29
|
+
try {
|
|
30
|
+
const entries = await (0, fs_extra_1.readdir)(`期次-${iterName}`, { withFileTypes: true });
|
|
31
|
+
taskCount = entries.filter(e => e.isDirectory() && e.name.startsWith('Task-')).length;
|
|
32
|
+
}
|
|
33
|
+
catch { }
|
|
34
|
+
}
|
|
35
|
+
let phase = 'doc';
|
|
36
|
+
if (iterName) {
|
|
37
|
+
const reqDoc = (0, path_1.join)(`期次-${iterName}`, '00-需求文档', 'REQUIREMENT.md');
|
|
38
|
+
if (!(await (0, fs_extra_1.pathExists)(reqDoc)))
|
|
39
|
+
phase = 'doc';
|
|
40
|
+
else if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(`期次-${iterName}`, '00-需求文档', 'ANALYSIS.md'))))
|
|
41
|
+
phase = 'analyze';
|
|
42
|
+
else if (taskCount === 0)
|
|
43
|
+
phase = 'split';
|
|
44
|
+
else
|
|
45
|
+
phase = 'execute';
|
|
46
|
+
}
|
|
47
|
+
const html = renderWelcomeHtml(version, isInit, iterName, phase, taskCount);
|
|
48
|
+
const outPath = _options.output || (0, path_1.join)(process.cwd(), 'speccore-welcome.html');
|
|
49
|
+
await (0, fs_extra_1.writeFile)(outPath, html);
|
|
50
|
+
logger_1.logger.info(`✅ 已生成: ${outPath}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
logger_1.logger.info('');
|
|
54
|
+
logger_1.logger.info(`${C.cyan}╔══════════════════════════════════════════════════════════╗${C.r}`);
|
|
55
|
+
logger_1.logger.info(`${C.cyan}║${C.r} ${C.b}${C.cyan}SpecCore${C.r} ${C.gray}· Code by Spec, Not by Vibe${C.r} ${C.gray}v${version}${C.r}${' '.repeat(23 - version.length)}${C.cyan}║${C.r}`);
|
|
56
|
+
logger_1.logger.info(`${C.cyan}╚══════════════════════════════════════════════════════════╝${C.r}`);
|
|
57
|
+
logger_1.logger.info('');
|
|
25
58
|
if (!isInit) {
|
|
26
|
-
logger_1.logger.info(
|
|
59
|
+
logger_1.logger.info(box('📦 项目状态', ['', `${C.gray}尚未初始化${C.r}`, '', `${C.cyan}◆ 快速开始:${C.r} speccore init`]));
|
|
60
|
+
logger_1.logger.info('');
|
|
61
|
+
showAskGuide();
|
|
27
62
|
return;
|
|
28
63
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
logger_1.logger.info(
|
|
64
|
+
if (!iterName) {
|
|
65
|
+
logger_1.logger.info(box('📦 项目状态', [`${C.gray}无活跃期次${C.r}`, `${C.b}speccore iteration create -n Q1${C.r}`]));
|
|
66
|
+
logger_1.logger.info('');
|
|
67
|
+
showAskGuide();
|
|
32
68
|
return;
|
|
33
69
|
}
|
|
34
70
|
let taskCount = 0;
|
|
35
71
|
try {
|
|
36
|
-
const entries = await (0, fs_extra_1.readdir)(`期次-${
|
|
72
|
+
const entries = await (0, fs_extra_1.readdir)(`期次-${iterName}`, { withFileTypes: true });
|
|
37
73
|
taskCount = entries.filter(e => e.isDirectory() && e.name.startsWith('Task-')).length;
|
|
38
74
|
}
|
|
39
75
|
catch { }
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
76
|
+
logger_1.logger.info(box(`📦 项目状态 · ${iterName}`, [`${C.gray}任务数: ${taskCount}${C.r}`, `${C.b}speccore dev --auto${C.r}`]));
|
|
77
|
+
logger_1.logger.info('');
|
|
78
|
+
showAskGuide();
|
|
79
|
+
}
|
|
80
|
+
function showAskGuide() {
|
|
81
|
+
logger_1.logger.info(box('🧠 AI 万能入口 · speccore ask', [
|
|
82
|
+
'',
|
|
83
|
+
`${C.green}📖${C.r} ${C.b}命令解释${C.r} "dashboard 怎么用"`,
|
|
84
|
+
`${C.yellow}🗺️${C.r} ${C.b}任务指引${C.r} "我想做一个登录功能"`,
|
|
85
|
+
`${C.green}🎯${C.r} ${C.b}意图匹配${C.r} "查看进度"`,
|
|
86
|
+
`${C.magenta}⚡${C.r} ${C.b}复杂编排${C.r} "计划任务晚8点分批"`,
|
|
87
|
+
]));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* HTML 项目名片 — 复刻 ask 架构图风格(彩色卡片 + 中央 ask 节点 + 4 模式分支)
|
|
91
|
+
*/
|
|
92
|
+
function renderWelcomeHtml(version, isInit, iterName, phase, taskCount) {
|
|
93
|
+
const phaseLabel = phase === 'doc' ? '📝 需要导入需求文档' : phase === 'analyze' ? '🧠 需要 AI 分析' : phase === 'split' ? '📦 需要拆分任务' : `⚡ 执行中 (${taskCount} 任务)`;
|
|
94
|
+
const now = new Date().toISOString().split('T')[0];
|
|
95
|
+
const phases = ['导入', '分析', '拆分', '计划', '执行', '交付'];
|
|
96
|
+
const doneIdx = ['doc', 'analyze', 'split', 'execute'].indexOf(phase) + (phase === 'execute' ? 1 : 0);
|
|
97
|
+
return `<!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore — 项目名片</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;padding:40px 20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.015) 2px,rgba(0,240,255,.015) 4px)}.stars{position:fixed;inset:0;pointer-events:none;background:radial-gradient(1px 1px at 20% 30%,rgba(255,255,255,.3),transparent),radial-gradient(1.5px 1.5px at 60% 70%,rgba(14,165,233,.4),transparent)}.card{max-width:720px;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:40px;position:relative;overflow:hidden}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}.center-node{width:90px;height:90px;border-radius:50%;border:2px solid var(--cyan);display:flex;align-items:center;justify-content:center;background:rgba(14,165,233,.08);margin:24px auto;font-family:Orbitron,sans-serif;font-size:20px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;position:relative;z-index:2}.modes-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:20px 0}.mode-card{border-radius:10px;padding:14px;position:relative;overflow:hidden;background:rgba(255,255,255,.02)}.mode-card.m1{border:1.5px solid var(--green)}.mode-card.m2{border:1.5px solid var(--orange)}.mode-card.m3{border:1.5px solid var(--cyan)}.mode-card.m4{border:1.5px solid var(--purple)}.mode-card .mode-title{font-weight:600;margin:6px 0;font-size:13px}.mode-card.m1 .mode-title{color:var(--green)}.mode-card.m2 .mode-title{color:var(--orange)}.mode-card.m3 .mode-title{color:var(--cyan)}.mode-card.m4 .mode-title{color:var(--purple)}.mode-card .mode-icon{font-size:18px;margin-right:4px}.mode-card .mode-desc{font-size:10px;color:var(--muted);margin:4px 0}.mode-card .mode-tag{display:inline-block;padding:2px 8px;font-size:9px;border-radius:4px;background:rgba(20,184,166,.1);color:var(--green);margin-top:6px}.mode-card.m1 .mode-tag{background:rgba(20,184,166,.08);color:var(--green)}.mode-card.m2 .mode-tag{background:rgba(249,115,22,.08);color:var(--orange)}.mode-card.m3 .mode-tag{background:rgba(14,165,233,.08);color:var(--cyan)}.mode-card.m4 .mode-tag{background:rgba(99,102,241,.08);color:var(--purple)}.status-row{display:flex;align-items:center;gap:8px;margin:8px 0;padding:10px 14px;background:rgba(14,165,233,.04);border:1px solid rgba(14,165,233,.1);border-radius:8px}.flow{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.flow-dot{width:10px;height:10px;border-radius:50%}.flow-dot.done{background:var(--green);box-shadow:0 0 8px var(--green)}.flow-dot.pending{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2)}.flow-arrow{color:var(--muted);font-size:10px}.flow-label{font-size:10px;color:var(--muted)}.flow-label.done{color:var(--green)}.cmd-row{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}.cmd-pill{padding:3px 10px;border-radius:4px;font-size:10px;background:rgba(14,165,233,.1);color:var(--cyan);border:1px solid rgba(14,165,233,.15)}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{font-family:'Orbitron',sans-serif;font-size:32px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px;text-align:center}.sub{color:var(--muted);font-size:11px;letter-spacing:1px;text-align:center;margin-top:4px}.section-title{font-size:10px;font-weight:700;color:var(--cyan);text-transform:uppercase;letter-spacing:2px;margin:20px 0 10px}.confirm-bar{text-align:center;padding:18px;margin:24px 0 8px;background:linear-gradient(135deg,var(--cyan) 0%,#0284c7 100%);border-radius:40px;color:#fff;font-weight:600;font-size:14px;box-shadow:0 0 30px rgba(14,165,233,.3);cursor:pointer;letter-spacing:1px}.section{margin:14px 0;padding:14px;background:rgba(255,255,255,.02);border:1px solid rgba(255,255,255,.04);border-radius:10px}</style></head><body><div class="scanlines"></div><div class="stars"></div><div class="card"><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE</h1><div class="sub">Code by Spec, Not by Vibe · v${version}${iterName ? ' · ' + iterName : ''}</div><div class="status-row"><span>📍</span><div><div style="font-size:11px;font-weight:600">${phaseLabel}</div><div style="font-size:9px;color:var(--muted)">${isInit ? (iterName ? '当前期次: ' + iterName + (taskCount > 0 ? ' · ' + taskCount + ' 任务' : '') : '已初始化 · 无活跃期次') : '未初始化'}</div></div></div><div class="section-title">🔄 核心流水线</div><div class="section"><div class="flow">${phases.map((n, i) => '<span class="flow-dot ' + (i < doneIdx ? 'done' : 'pending') + '"></span><span class="flow-label ' + (i < doneIdx ? 'done' : '') + '">' + n + '</span>' + (i < 5 ? '<span class="flow-arrow">→</span>' : '')).join('')}</div></div><div class="section-title">🧠 ask — SpecCore 万能 AI 入口</div><div class="modes-grid"><div class="mode-card m1"><div class="mode-title"><span class="mode-icon">📖</span>命令解释</div><div class="mode-desc">"dashboard 怎么用"<br>"init 有哪些参数"</div><div class="mode-tag">知识库匹配</div></div><div class="mode-card m2"><div class="mode-title"><span class="mode-icon">🗺️</span>任务指引</div><div class="mode-desc">"我想做一个登录功能"<br>"怎么开始新项目"</div><div class="mode-tag">工作流生成</div></div><div class="mode-card m3"><div class="mode-title"><span class="mode-icon">🎯</span>意图匹配</div><div class="mode-desc">"查看进度" → dashboard<br>"审查代码" → validate</div><div class="mode-tag">38意图 + AI</div></div><div class="mode-card m4"><div class="mode-title"><span class="mode-icon">⚡</span>复杂编排</div><div class="mode-desc">"计划所有任务晚8点分批"<br>"做完分析→拆分→PR"</div><div class="mode-tag">Pipeline 引擎</div></div></div><div class="confirm-bar">确认进入 · 输入 <code style="background:rgba(255,255,255,.2);padding:2px 8px;border-radius:4px">speccore ask "你的需求"</code> 开始</div><div class="section-title">━━ 常用命令 ━━</div><div class="cmd-row"><span class="cmd-pill">speccore dashboard</span><span class="cmd-pill">speccore dev --auto</span><span class="cmd-pill">speccore ask "描述"</span><span class="cmd-pill">speccore help</span></div><div class="footer">由 SpecCore 驱动 v${version} · ${now}</div></div></body></html>`;
|
|
51
98
|
}
|
|
52
99
|
//# sourceMappingURL=welcome.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/commands/welcome.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/commands/welcome.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ask — SpecCore 万能 AI 入口引擎
|
|
3
|
+
* 四种模式:命令解释(explain) / 任务指引(guide) / 意图匹配(match) / 复杂编排(pipeline)
|
|
4
|
+
*/
|
|
5
|
+
/** ask 模式 */
|
|
6
|
+
export type AskMode = 'explain' | 'guide' | 'match' | 'pipeline';
|
|
7
|
+
/** 命令知识条目 */
|
|
8
|
+
export interface CommandKnowledge {
|
|
9
|
+
name: string;
|
|
10
|
+
aliases: string[];
|
|
11
|
+
description: string;
|
|
12
|
+
usage: string;
|
|
13
|
+
examples: string[];
|
|
14
|
+
related: string[];
|
|
15
|
+
triggers: string[];
|
|
16
|
+
}
|
|
17
|
+
/** Pipeline 步骤 */
|
|
18
|
+
export interface PipelineStep {
|
|
19
|
+
order: number;
|
|
20
|
+
command: string;
|
|
21
|
+
args: string;
|
|
22
|
+
explanation: string;
|
|
23
|
+
dependsOn?: number;
|
|
24
|
+
}
|
|
25
|
+
/** Pipeline 计划 */
|
|
26
|
+
export interface PipelinePlan {
|
|
27
|
+
steps: PipelineStep[];
|
|
28
|
+
input: string;
|
|
29
|
+
confirm: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Ask 结果 */
|
|
32
|
+
export interface AskResult {
|
|
33
|
+
mode: AskMode;
|
|
34
|
+
summary: string;
|
|
35
|
+
detail: string;
|
|
36
|
+
commands: string[];
|
|
37
|
+
pipeline?: PipelinePlan;
|
|
38
|
+
}
|
|
39
|
+
declare const COMMAND_KB: CommandKnowledge[];
|
|
40
|
+
declare const WORKFLOWS: Record<string, PipelineStep[]>;
|
|
41
|
+
/** 判断问句属于哪种模式 */
|
|
42
|
+
export declare function classifyMode(input: string): AskMode;
|
|
43
|
+
export declare function askEngine(input: string): Promise<AskResult>;
|
|
44
|
+
export { COMMAND_KB, WORKFLOWS };
|
|
45
|
+
//# sourceMappingURL=ask-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-engine.d.ts","sourceRoot":"","sources":["../../src/core/ask-engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,aAAa;AACb,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjE,aAAa;AACb,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,kBAAkB;AAClB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,kBAAkB;AAClB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,aAAa;AACb,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAMD,QAAA,MAAM,UAAU,EAAE,gBAAgB,EAuCjC,CAAC;AAMF,QAAA,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CA6B7C,CAAC;AAMF,iBAAiB;AACjB,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAyCnD;AA+KD,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAqCjE;AAgFD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ask — SpecCore 万能 AI 入口引擎
|
|
4
|
+
* 四种模式:命令解释(explain) / 任务指引(guide) / 意图匹配(match) / 复杂编排(pipeline)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.WORKFLOWS = exports.COMMAND_KB = void 0;
|
|
8
|
+
exports.classifyMode = classifyMode;
|
|
9
|
+
exports.askEngine = askEngine;
|
|
10
|
+
const logger_1 = require("../utils/logger");
|
|
11
|
+
const intent_recognition_1 = require("./intent-recognition");
|
|
12
|
+
const ask_llm_1 = require("./ask-llm");
|
|
13
|
+
const ask_host_ai_1 = require("./ask-host-ai");
|
|
14
|
+
// ============================================================
|
|
15
|
+
// 命令知识库
|
|
16
|
+
// ============================================================
|
|
17
|
+
const COMMAND_KB = [
|
|
18
|
+
{ name: 'init', aliases: ['in'], description: '初始化 SpecCore 项目,创建 .speccore 目录和配置',
|
|
19
|
+
usage: 'speccore init [--interactive] [--name <name>]', examples: ['speccore init', 'speccore init --name my-project'], related: ['dev', 'config'], triggers: ['初始化', 'init', '开始', '新建项目', '创建项目'] },
|
|
20
|
+
{ name: 'doc2spec', aliases: ['d2s'], description: '导入 PRD/Word 文档,AI + Pandoc 双路转换为 SpecCore MD',
|
|
21
|
+
usage: 'speccore doc2spec -f <file> --iter <iteration> [--task <task>] [--no-ai]', examples: ['speccore doc2spec -f PRD.docx --iter Q3', 'speccore doc2spec -f 需求.docx --iter Q2 --task T-01 --no-ai'], related: ['spec2doc', 'analyze'], triggers: ['导入', 'doc2spec', 'word转', '文档转换', 'PRD', '需求文档'] },
|
|
22
|
+
{ name: 'spec2doc', aliases: ['s2d'], description: 'SpecCore MD 导出为 Word/PDF/HTML/PPTX',
|
|
23
|
+
usage: 'speccore spec2doc [-i <iteration>] [-t <task>] [-f <format>] [-o <output>]', examples: ['speccore spec2doc -i Q3 -o 需求.docx', 'speccore spec2doc -t T-01 -f html'], related: ['doc2spec'], triggers: ['导出', 'spec2doc', '生成文档', '导出word', '导出pdf'] },
|
|
24
|
+
{ name: 'dashboard', aliases: ['db', 'sp'], description: '项目仪表盘:期次状态/进度/健康度,--scope global 全量视图',
|
|
25
|
+
usage: 'speccore dashboard [--scope global|iteration] [--export html] [--health] [--lifecycle]', examples: ['speccore dashboard', 'speccore dashboard --scope global --export html'], related: ['analyze', 'health'], triggers: ['看板', '仪表盘', 'dashboard', '进度', '状态', '全局', '全量'] },
|
|
26
|
+
{ name: 'analyze', aliases: ['al'], description: 'AI 统一分析:需求文档+源码→分析报告,--audit 审计模式',
|
|
27
|
+
usage: 'speccore analyze [--task <id>] [--iteration <name>] [--audit]', examples: ['speccore analyze', 'speccore analyze --task T-01 --audit'], related: ['dashboard', 'validate'], triggers: ['分析', 'analyze', '审计', 'audit', '检查'] },
|
|
28
|
+
{ name: 'execute', aliases: ['ex'], description: '执行开发任务:依赖排序+分批+交互引导+计划联动',
|
|
29
|
+
usage: 'speccore execute [--task <id>] [--batch-size <n>] [--auto]', examples: ['speccore execute', 'speccore execute --batch-size 3'], related: ['plan', 'done'], triggers: ['执行', 'execute', '开发', '开始做', '干活'] },
|
|
30
|
+
{ name: 'plan', aliases: ['pl'], description: '生成执行计划+管理历史:创建/交互/列表/详情/取消',
|
|
31
|
+
usage: 'speccore plan [--all] [--task <id>] [--interactive]', examples: ['speccore plan --all', 'speccore plan --interactive'], related: ['execute', 'schedule'], triggers: ['计划', 'plan', '调度', '安排', '规划'] },
|
|
32
|
+
{ name: 'split', aliases: ['sp'], description: '拆分需求为独立 Task:预览→逐一确认/一键创建',
|
|
33
|
+
usage: 'speccore split [-f <file>] [--preview]', examples: ['speccore split -f REQUIREMENT.md', 'speccore split --preview'], related: ['task', 'plan'], triggers: ['拆分', 'split', '分解', '划分', '拆'] },
|
|
34
|
+
{ name: 'pr', aliases: ['mr'], description: '创建 Pull Request:提交预览+文件选择+交互确认',
|
|
35
|
+
usage: 'speccore pr [--task <id>] [--auto]', examples: ['speccore pr', 'speccore pr --task T-01 --auto'], related: ['done', 'execute'], triggers: ['pr', 'pull request', '提交', '合并', 'MR'] },
|
|
36
|
+
{ name: 'validate', aliases: ['vl'], description: '合规验证:检查 Spec 完整性与一致性',
|
|
37
|
+
usage: 'speccore validate [--iteration <name>]', examples: ['speccore validate', 'speccore validate --iteration Q2'], related: ['analyze', 'audit'], triggers: ['验证', 'validate', '检查', '合规', '校验'] },
|
|
38
|
+
{ name: 'sync', aliases: ['sy'], description: '双向同步:代码↔Spec,--global 同步到全局层',
|
|
39
|
+
usage: 'speccore sync [--global] [--iteration <name>]', examples: ['speccore sync', 'speccore sync --global'], related: ['dev'], triggers: ['同步', 'sync', '对齐', '更新'] },
|
|
40
|
+
{ name: 'change', aliases: ['ch'], description: '需求变更:联动更新所有关联 Spec,支持口语化输入',
|
|
41
|
+
usage: 'speccore change "<description>" [--task <id>]', examples: ['speccore change "把登录改成验证码登录"', 'speccore change "加上支付功能" --task T-03'], related: ['analyze'], triggers: ['变更', 'change', '修改', '改', '更新需求'] },
|
|
42
|
+
{ name: 'done', aliases: ['dn'], description: '收尾归档:校验→同步→审计,--all 批量归档',
|
|
43
|
+
usage: 'speccore done [--task <id>] [--all] [--interactive]', examples: ['speccore done --task T-01', 'speccore done --all'], related: ['execute', 'pr'], triggers: ['完成', 'done', '归档', '结束', '做完'] },
|
|
44
|
+
{ name: 'dev', aliases: ['d'], description: '智能级联:--auto 全自动流水线 detect→execute',
|
|
45
|
+
usage: 'speccore dev [--auto] [--from <phase>] [--to <phase>]', examples: ['speccore dev --auto', 'speccore dev --from analyze --to execute'], related: ['execute', 'plan'], triggers: ['dev', '流水线', '自动', '级联'] },
|
|
46
|
+
{ name: 'task', aliases: ['tk'], description: '任务管理:创建/列表/状态。子命令: new, list, status',
|
|
47
|
+
usage: 'speccore task new --name <name> [--id <id>] | speccore task list | speccore task status', examples: ['speccore task new --name "用户登录"', 'speccore task list'], related: ['plan', 'execute'], triggers: ['task', '任务', '创建任务', '新建'] },
|
|
48
|
+
{ name: 'iteration', aliases: ['it'], description: '期次管理:创建/拆分/列表。子命令: create, split, list',
|
|
49
|
+
usage: 'speccore iteration create -n <name> | speccore iteration split | speccore iteration list', examples: ['speccore iteration create -n Q3', 'speccore iteration list'], related: ['task', 'plan'], triggers: ['期次', 'iteration', '迭代', 'sprint'] },
|
|
50
|
+
{ name: 'search', aliases: ['sh'], description: '全文搜索:跨所有 Spec 文件关键词检索',
|
|
51
|
+
usage: 'speccore search <query> [--task <id>] [--iteration <name>]', examples: ['speccore search "登录"', 'speccore search "支付" --iteration Q2'], related: ['track'], triggers: ['搜索', 'search', '查找', '检索', 'grep'] },
|
|
52
|
+
{ name: 'track', aliases: ['trk'], description: '合并 trace + tracker: REQ→Task→Code 全链路追踪',
|
|
53
|
+
usage: 'speccore track [--req <id>] [--task <id>] [--full]', examples: ['speccore track --req REQ-001', 'speccore track --full'], related: ['search', 'analyze'], triggers: ['追踪', 'track', 'trace', '链路', '追溯'] },
|
|
54
|
+
{ name: 'rename', aliases: ['rn'], description: '重命名期次/任务,自动更新所有关联引用',
|
|
55
|
+
usage: 'speccore rename [--iteration <old> <new>] [--task <old> <new>]', examples: ['speccore rename --iteration Q2 Q3', 'speccore rename --task T-01 T-10'], related: ['sync'], triggers: ['重命名', 'rename', '改名', '更名'] },
|
|
56
|
+
];
|
|
57
|
+
exports.COMMAND_KB = COMMAND_KB;
|
|
58
|
+
// ============================================================
|
|
59
|
+
// 任务指引 — 预定义工作流
|
|
60
|
+
// ============================================================
|
|
61
|
+
const WORKFLOWS = {
|
|
62
|
+
'new feature': [
|
|
63
|
+
{ order: 1, command: 'init', args: '', explanation: '初始化项目(如果还没有)', dependsOn: undefined },
|
|
64
|
+
{ order: 2, command: 'doc2spec', args: '-f PRD.docx --iter {iteration}', explanation: '导入 PRD 文档,AI 分析生成需求规格', dependsOn: 1 },
|
|
65
|
+
{ order: 3, command: 'analyze', args: '--iteration {iteration} --audit', explanation: 'AI 分析需求,生成审计报告', dependsOn: 2 },
|
|
66
|
+
{ order: 4, command: 'split', args: '-f REQUIREMENT.md', explanation: '将需求拆分为独立开发任务', dependsOn: 3 },
|
|
67
|
+
{ order: 5, command: 'plan', args: '--all', explanation: '生成任务执行计划,确定优先级和依赖', dependsOn: 4 },
|
|
68
|
+
{ order: 6, command: 'execute', args: '--auto', explanation: '按计划依次执行开发任务', dependsOn: 5 },
|
|
69
|
+
{ order: 7, command: 'pr', args: '--auto', explanation: '代码提交后创建 Pull Request', dependsOn: 6 },
|
|
70
|
+
{ order: 8, command: 'done', args: '--all', explanation: '全部完成后归档收尾', dependsOn: 7 },
|
|
71
|
+
],
|
|
72
|
+
'bugfix': [
|
|
73
|
+
{ order: 1, command: 'task', args: 'new --name "{bug}" --type bugfix', explanation: '创建 Bug 修复任务', dependsOn: undefined },
|
|
74
|
+
{ order: 2, command: 'analyze', args: '--task {task} --audit', explanation: '分析 Bug 影响范围', dependsOn: 1 },
|
|
75
|
+
{ order: 3, command: 'execute', args: '--task {task}', explanation: '执行修复', dependsOn: 2 },
|
|
76
|
+
{ order: 4, command: 'validate', args: '', explanation: '验证修复完整性', dependsOn: 3 },
|
|
77
|
+
{ order: 5, command: 'pr', args: '--task {task}', explanation: '提交修复 PR', dependsOn: 4 },
|
|
78
|
+
{ order: 6, command: 'done', args: '--task {task}', explanation: '归档修复记录', dependsOn: 5 },
|
|
79
|
+
],
|
|
80
|
+
'batch execute': [
|
|
81
|
+
{ order: 1, command: 'plan', args: '--all', explanation: '生成所有待执行任务的计划', dependsOn: undefined },
|
|
82
|
+
{ order: 2, command: 'schedule', args: 'create --at "{time}" --batch-size {batch}', explanation: '创建定时调度,指定执行时间和批次大小', dependsOn: 1 },
|
|
83
|
+
{ order: 3, command: 'execute', args: '--auto --batch-size {batch}', explanation: '按计划分批自动执行', dependsOn: 2 },
|
|
84
|
+
],
|
|
85
|
+
'code review': [
|
|
86
|
+
{ order: 1, command: 'validate', args: '', explanation: '合规检查 Spec 完整性', dependsOn: undefined },
|
|
87
|
+
{ order: 2, command: 'analyze', args: '--audit', explanation: '深度审计分析', dependsOn: 1 },
|
|
88
|
+
{ order: 3, command: 'pr', args: '--auto', explanation: '生成 PR 审查', dependsOn: 2 },
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
exports.WORKFLOWS = WORKFLOWS;
|
|
92
|
+
// ============================================================
|
|
93
|
+
// 引擎核心
|
|
94
|
+
// ============================================================
|
|
95
|
+
/** 判断问句属于哪种模式 */
|
|
96
|
+
function classifyMode(input) {
|
|
97
|
+
const lower = input.toLowerCase();
|
|
98
|
+
// 模式1: 命令解释 — 询问特定命令用法
|
|
99
|
+
const explainPatterns = [
|
|
100
|
+
/(dashboard|dev|init|execute|plan|pr|sync|validate|analyze|split|search|track|rename|doc2spec|spec2doc|ask)\s*(命令|用法|怎么用|是什么|功能|参数|选项)/,
|
|
101
|
+
/怎么用\s*(dashboard|dev|init|execute|plan|pr|sync|validate|analyze|split|search|track)/,
|
|
102
|
+
/(dashboard|dev|init|execute|plan|pr|sync|validate|analyze|split|search|track)\s*有哪些/,
|
|
103
|
+
/解释[一下]?\s*(dashboard|dev|init|execute|plan|pr|sync|validate|analyze|split|search|track)/,
|
|
104
|
+
/(what|how).*use.*(dashboard|dev|init|execute|plan|pr|sync)/i,
|
|
105
|
+
];
|
|
106
|
+
if (explainPatterns.some(p => p.test(lower)))
|
|
107
|
+
return 'explain';
|
|
108
|
+
// 模式4: 复杂编排 — 包含多个动作词 + 时序/数量词
|
|
109
|
+
const pipelineKeywords = ['然后', '再', '接着', '最后', '同时', '之后',
|
|
110
|
+
'then', 'after', 'finally', '同时执行', 'pipeline'];
|
|
111
|
+
const actionWords = ['计划', '执行', '分批', '定时', '安排', '调度',
|
|
112
|
+
'plan', 'execute', 'schedule', 'batch'];
|
|
113
|
+
const hasTiming = /晚.*点|早上.*点|明天|今天|后天|下周|周[一到日]|(\d+)[点时]/i.test(lower);
|
|
114
|
+
const hasBatch = /分批|批次|batch|一批|一组/i.test(lower);
|
|
115
|
+
const actionCount = actionWords.filter(w => lower.includes(w)).length;
|
|
116
|
+
const pipelineCount = pipelineKeywords.filter(w => lower.includes(w)).length;
|
|
117
|
+
if ((actionCount >= 2) || (actionCount >= 1 && (hasTiming || hasBatch)) || pipelineCount >= 2)
|
|
118
|
+
return 'pipeline';
|
|
119
|
+
// 模式2: 任务指引 — 问"怎么做/如何/我想做"
|
|
120
|
+
const guidePatterns = [
|
|
121
|
+
/怎么[做弄搞]/,
|
|
122
|
+
/如何/,
|
|
123
|
+
/步骤/,
|
|
124
|
+
/流程/,
|
|
125
|
+
/从[哪零]开始/,
|
|
126
|
+
/我想[做弄搞]/,
|
|
127
|
+
/帮我[做弄搞]/,
|
|
128
|
+
/how\s+(to|do|can\s+i)/i,
|
|
129
|
+
/什么流程/,
|
|
130
|
+
/需要.*命令/,
|
|
131
|
+
];
|
|
132
|
+
if (guidePatterns.some(p => p.test(lower)))
|
|
133
|
+
return 'guide';
|
|
134
|
+
// 默认:意图匹配
|
|
135
|
+
return 'match';
|
|
136
|
+
}
|
|
137
|
+
/** 匹配命令知识 */
|
|
138
|
+
function matchCommandInKB(input) {
|
|
139
|
+
const lower = input.toLowerCase();
|
|
140
|
+
// 精确匹配命令名
|
|
141
|
+
for (const cmd of COMMAND_KB) {
|
|
142
|
+
if (lower.includes(cmd.name))
|
|
143
|
+
return cmd;
|
|
144
|
+
for (const alias of cmd.aliases) {
|
|
145
|
+
if (lower.includes(alias) && alias.length > 1)
|
|
146
|
+
return cmd;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// 触发词匹配
|
|
150
|
+
let best = null;
|
|
151
|
+
let bestScore = 0;
|
|
152
|
+
for (const cmd of COMMAND_KB) {
|
|
153
|
+
const score = cmd.triggers.filter(t => lower.includes(t)).length;
|
|
154
|
+
if (score > bestScore) {
|
|
155
|
+
bestScore = score;
|
|
156
|
+
best = cmd;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return bestScore > 0 ? best : null;
|
|
160
|
+
}
|
|
161
|
+
/** 模式1: 命令解释 */
|
|
162
|
+
function handleExplain(input) {
|
|
163
|
+
const cmd = matchCommandInKB(input);
|
|
164
|
+
if (!cmd) {
|
|
165
|
+
return { mode: 'explain', summary: '未找到匹配的命令', detail: `没有找到与 "${input}" 相关的命令。请尝试:\n speccore help — 查看所有命令\n speccore ask "dashboard 怎么用"`, commands: [] };
|
|
166
|
+
}
|
|
167
|
+
const detail = [
|
|
168
|
+
`📖 ${cmd.name} ${cmd.aliases.length ? '(' + cmd.aliases.join('/') + ')' : ''}`,
|
|
169
|
+
` 描述: ${cmd.description}`,
|
|
170
|
+
` 用法: ${cmd.usage}`,
|
|
171
|
+
``,
|
|
172
|
+
` 示例:`,
|
|
173
|
+
...cmd.examples.map(e => ` $ ${e}`),
|
|
174
|
+
``,
|
|
175
|
+
` 关联命令: ${cmd.related.join(', ')}`,
|
|
176
|
+
``,
|
|
177
|
+
`💡 更多参数: speccore ${cmd.name} --help`,
|
|
178
|
+
].join('\n');
|
|
179
|
+
return { mode: 'explain', summary: `${cmd.name} 命令详解`, detail, commands: [cmd.name] };
|
|
180
|
+
}
|
|
181
|
+
/** 模式2: 任务指引 */
|
|
182
|
+
function handleGuide(input) {
|
|
183
|
+
// 匹配工作流
|
|
184
|
+
let matchedWorkflow = null;
|
|
185
|
+
let workflowName = '';
|
|
186
|
+
if (/bug|修复|fix|defect/i.test(input)) {
|
|
187
|
+
matchedWorkflow = WORKFLOWS['bugfix'];
|
|
188
|
+
workflowName = 'Bug 修复流程';
|
|
189
|
+
}
|
|
190
|
+
else if (/审查|review|检查代码|code review/i.test(input)) {
|
|
191
|
+
matchedWorkflow = WORKFLOWS['code review'];
|
|
192
|
+
workflowName = '代码审查流程';
|
|
193
|
+
}
|
|
194
|
+
else if (/新功能|feature|登录|注册|支付|创建.*功能|做.*功能/i.test(input)) {
|
|
195
|
+
matchedWorkflow = WORKFLOWS['new feature'];
|
|
196
|
+
workflowName = '新功能开发全流程';
|
|
197
|
+
}
|
|
198
|
+
else if (/批量|分批|batch|队列/i.test(input)) {
|
|
199
|
+
matchedWorkflow = WORKFLOWS['batch execute'];
|
|
200
|
+
workflowName = '批量执行流程';
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
// 默认:新功能全流程
|
|
204
|
+
matchedWorkflow = WORKFLOWS['new feature'];
|
|
205
|
+
workflowName = '推荐标准开发流程';
|
|
206
|
+
}
|
|
207
|
+
const steps = matchedWorkflow.map(s => ` ${s.order}. speccore ${s.command}${s.args ? ' ' + s.args : ''}` +
|
|
208
|
+
`\n → ${s.explanation}`).join('\n\n');
|
|
209
|
+
const detail = [
|
|
210
|
+
`🗺️ ${workflowName}`,
|
|
211
|
+
``,
|
|
212
|
+
steps,
|
|
213
|
+
``,
|
|
214
|
+
`---`,
|
|
215
|
+
`执行方式:`,
|
|
216
|
+
` 逐步执行: 按顺序手动执行每一步`,
|
|
217
|
+
` 一键执行: speccore dev --auto(自动检测并推进)`,
|
|
218
|
+
` 编排执行: speccore ask "完整描述你的需求" --pipeline`,
|
|
219
|
+
].join('\n');
|
|
220
|
+
return {
|
|
221
|
+
mode: 'guide',
|
|
222
|
+
summary: `已为你规划「${workflowName}」(${matchedWorkflow.length} 步)`,
|
|
223
|
+
detail,
|
|
224
|
+
commands: matchedWorkflow.map(s => s.command),
|
|
225
|
+
pipeline: { steps: matchedWorkflow, input, confirm: false },
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/** 模式3: 意图匹配(当前 ask 逻辑) */
|
|
229
|
+
async function handleMatch(input) {
|
|
230
|
+
// 优先用 KB 精确匹配
|
|
231
|
+
const kbMatch = matchCommandInKB(input);
|
|
232
|
+
const results = await (0, intent_recognition_1.recognizeIntent)(input);
|
|
233
|
+
const best = results[0];
|
|
234
|
+
// 如果 KB 有匹配且置信度高于意图识别,用 KB
|
|
235
|
+
if (kbMatch && (!best || best.confidence < 70)) {
|
|
236
|
+
return { mode: 'match', summary: `✅ 推荐: ${kbMatch.name}`, detail: `🎯 推荐命令: speccore ${kbMatch.name}\n${kbMatch.description}\n\n用法: ${kbMatch.usage}\n\n示例:\n${kbMatch.examples.map(e => ' $ ' + e).join('\n')}`, commands: [kbMatch.name] };
|
|
237
|
+
}
|
|
238
|
+
if (results.length === 0) {
|
|
239
|
+
if (kbMatch) {
|
|
240
|
+
return { mode: 'match', summary: `建议使用 ${kbMatch.name}`, detail: `💡 推荐命令: speccore ${kbMatch.name}\n${kbMatch.description}\n\n用法: ${kbMatch.usage}`, commands: [kbMatch.name] };
|
|
241
|
+
}
|
|
242
|
+
return { mode: 'match', summary: '未识别到匹配命令', detail: '我无法完全理解你的意图。试试:\n speccore help — 查看命令列表\n 或更详细地描述你想做什么', commands: [] };
|
|
243
|
+
}
|
|
244
|
+
const cmdName = kbMatch?.name || best.command || best.intent;
|
|
245
|
+
return {
|
|
246
|
+
mode: 'match',
|
|
247
|
+
summary: `匹配到: ${best.intent} (${best.confidence}%)`,
|
|
248
|
+
detail: kbMatch ? `🎯 推荐命令: speccore ${kbMatch.name}\n${kbMatch.description}\n\n用法: ${kbMatch.usage}` : `🎯 speccore ${cmdName}`,
|
|
249
|
+
commands: [cmdName],
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/** 模式4: 复杂编排 */
|
|
253
|
+
function handlePipeline(input) {
|
|
254
|
+
const lower = input.toLowerCase();
|
|
255
|
+
// 匹配批量执行流程
|
|
256
|
+
if (/计划.*执行|plan.*execute|分批|batch|定时|schedule|晚.*点|早上|几点/.test(lower)) {
|
|
257
|
+
const steps = WORKFLOWS['batch execute'];
|
|
258
|
+
return {
|
|
259
|
+
mode: 'pipeline',
|
|
260
|
+
summary: `已编排「批量执行流程」(${steps.length} 步)`,
|
|
261
|
+
detail: buildPipelineDetail(steps, input),
|
|
262
|
+
commands: steps.map(s => s.command),
|
|
263
|
+
pipeline: { steps, input, confirm: true },
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// 匹配新功能流程
|
|
267
|
+
if (/功能|feature|开发|新.*模块|做.*个/.test(lower)) {
|
|
268
|
+
const steps = WORKFLOWS['new feature'];
|
|
269
|
+
return {
|
|
270
|
+
mode: 'pipeline',
|
|
271
|
+
summary: `已编排「新功能开发流程」(${steps.length} 步)`,
|
|
272
|
+
detail: buildPipelineDetail(steps, input),
|
|
273
|
+
commands: steps.map(s => s.command),
|
|
274
|
+
pipeline: { steps, input, confirm: true },
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
// 默认返回 guide
|
|
278
|
+
return handleGuide(input);
|
|
279
|
+
}
|
|
280
|
+
function buildPipelineDetail(steps, input) {
|
|
281
|
+
return [
|
|
282
|
+
`📋 执行计划预览 (来源: "${input}")`,
|
|
283
|
+
``,
|
|
284
|
+
...steps.map(s => ` ${s.order}. \x1b[36mspeccore ${s.command}${s.args ? ' ' + s.args : ''}\x1b[0m` +
|
|
285
|
+
(s.dependsOn ? ` ← 依赖步骤 ${s.dependsOn}` : '') +
|
|
286
|
+
`\n ${s.explanation}`),
|
|
287
|
+
``,
|
|
288
|
+
`---`,
|
|
289
|
+
`⚠️ 请确认后执行。输入 y 确认,或修改参数后重试。`,
|
|
290
|
+
].join('\n');
|
|
291
|
+
}
|
|
292
|
+
// ============================================================
|
|
293
|
+
// 统一入口
|
|
294
|
+
// ============================================================
|
|
295
|
+
async function askEngine(input) {
|
|
296
|
+
// ── 第一层: 自有 LLM (OpenAI/Ollama) ──
|
|
297
|
+
try {
|
|
298
|
+
const llmResult = await (0, ask_llm_1.askWithLlm)(input);
|
|
299
|
+
if (llmResult && llmResult.commands.length > 0) {
|
|
300
|
+
logger_1.logger.info(`🧠 自有 LLM: ${modeLabel(llmResult.mode)}`);
|
|
301
|
+
if (!llmResult.detail || llmResult.detail.length < 20) {
|
|
302
|
+
const enriched = enrichWithRules(llmResult, input);
|
|
303
|
+
return enriched;
|
|
304
|
+
}
|
|
305
|
+
return llmResult;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch (e) {
|
|
309
|
+
logger_1.logger.warn(`自有 LLM 不可用: ${e.message}`);
|
|
310
|
+
}
|
|
311
|
+
// ── 第二层: 宿主 AI (WorkBuddy/TRAE/Qoder) ──
|
|
312
|
+
try {
|
|
313
|
+
const hostResult = await (0, ask_host_ai_1.tryHostAi)('ask', input);
|
|
314
|
+
if (hostResult) {
|
|
315
|
+
logger_1.logger.info(`🤖 宿主 AI: ${modeLabel((hostResult.mode || 'match'))}`);
|
|
316
|
+
return hostResult;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch (e) { /* 宿主 AI 不可用,继续 */ }
|
|
320
|
+
// ── 第三层: 规则引擎兜底 ──
|
|
321
|
+
const mode = classifyMode(input);
|
|
322
|
+
logger_1.logger.info(`📐 规则识别: ${modeLabel(mode)}`);
|
|
323
|
+
switch (mode) {
|
|
324
|
+
case 'explain': return handleExplain(input);
|
|
325
|
+
case 'guide': return handleGuide(input);
|
|
326
|
+
case 'pipeline': return handlePipeline(input);
|
|
327
|
+
case 'match':
|
|
328
|
+
default: return handleMatch(input);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/** 用规则引擎补充 LLM 结果的内容 */
|
|
332
|
+
function enrichWithRules(llmResult, input) {
|
|
333
|
+
const mode = llmResult.mode || 'match';
|
|
334
|
+
switch (mode) {
|
|
335
|
+
case 'explain': {
|
|
336
|
+
const cmd = matchCommandInKB(input);
|
|
337
|
+
if (cmd) {
|
|
338
|
+
return { ...llmResult, detail: buildExplainDetail(cmd) };
|
|
339
|
+
}
|
|
340
|
+
return llmResult;
|
|
341
|
+
}
|
|
342
|
+
case 'guide': {
|
|
343
|
+
const wf = matchWorkflow(input);
|
|
344
|
+
if (wf) {
|
|
345
|
+
return { ...llmResult, detail: buildGuideDetail(wf.name, wf.steps), pipeline: wf.steps.length > 0 ? { steps: wf.steps, input, confirm: false } : undefined };
|
|
346
|
+
}
|
|
347
|
+
return llmResult;
|
|
348
|
+
}
|
|
349
|
+
case 'pipeline': {
|
|
350
|
+
const wf = matchWorkflow(input);
|
|
351
|
+
if (wf) {
|
|
352
|
+
return { ...llmResult, detail: buildPipelineDetail(wf.steps, input), pipeline: { steps: wf.steps, input, confirm: true } };
|
|
353
|
+
}
|
|
354
|
+
return llmResult;
|
|
355
|
+
}
|
|
356
|
+
default:
|
|
357
|
+
return llmResult;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function buildExplainDetail(cmd) {
|
|
361
|
+
return [
|
|
362
|
+
`📖 ${cmd.name} ${cmd.aliases.length ? '(' + cmd.aliases.join('/') + ')' : ''}`,
|
|
363
|
+
` 描述: ${cmd.description}`,
|
|
364
|
+
` 用法: ${cmd.usage}`,
|
|
365
|
+
``,
|
|
366
|
+
` 示例:`,
|
|
367
|
+
...cmd.examples.map(e => ` $ ${e}`),
|
|
368
|
+
``,
|
|
369
|
+
` 关联命令: ${cmd.related.join(', ')}`,
|
|
370
|
+
``,
|
|
371
|
+
`💡 更多参数: speccore ${cmd.name} --help`,
|
|
372
|
+
].join('\n');
|
|
373
|
+
}
|
|
374
|
+
function buildGuideDetail(name, steps) {
|
|
375
|
+
const s = steps.map(s => ` ${s.order}. speccore ${s.command}${s.args ? ' ' + s.args : ''}` +
|
|
376
|
+
`\n → ${s.explanation}`).join('\n\n');
|
|
377
|
+
return [
|
|
378
|
+
`🗺️ ${name}`,
|
|
379
|
+
``,
|
|
380
|
+
s,
|
|
381
|
+
``,
|
|
382
|
+
`---`,
|
|
383
|
+
`执行方式:`,
|
|
384
|
+
` 逐步执行: 按顺序手动执行每一步`,
|
|
385
|
+
` 一键执行: speccore dev --auto(自动检测并推进)`,
|
|
386
|
+
` 编排执行: speccore ask "完整描述你的需求" --pipeline`,
|
|
387
|
+
].join('\n');
|
|
388
|
+
}
|
|
389
|
+
function matchWorkflow(input) {
|
|
390
|
+
const lower = input.toLowerCase();
|
|
391
|
+
if (/bug|修复|fix|defect/i.test(lower))
|
|
392
|
+
return { name: 'Bug 修复流程', steps: WORKFLOWS['bugfix'] };
|
|
393
|
+
if (/审查|review|检查代码|code review/i.test(lower))
|
|
394
|
+
return { name: '代码审查流程', steps: WORKFLOWS['code review'] };
|
|
395
|
+
if (/新功能|feature|登录|注册|支付|创建.*功能|做.*功能/i.test(lower))
|
|
396
|
+
return { name: '新功能开发全流程', steps: WORKFLOWS['new feature'] };
|
|
397
|
+
if (/批量|分批|batch|队列|计划.*执行|定时/i.test(lower))
|
|
398
|
+
return { name: '批量执行流程', steps: WORKFLOWS['batch execute'] };
|
|
399
|
+
return { name: '推荐标准开发流程', steps: WORKFLOWS['new feature'] };
|
|
400
|
+
}
|
|
401
|
+
function modeLabel(mode) {
|
|
402
|
+
const labels = { explain: '📖 命令解释', guide: '🗺️ 任务指引', match: '🎯 意图匹配', pipeline: '⚡ 复杂编排' };
|
|
403
|
+
return labels[mode];
|
|
404
|
+
}
|
|
405
|
+
//# sourceMappingURL=ask-engine.js.map
|