@gordon.gan/specflow 1.4.2-beta → 1.4.3-beta
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 +1 -1
- package/dist/integrations/claude/adapter.js +2 -0
- package/dist/integrations/codex/adapter.js +3 -0
- package/dist/integrations/cursor/adapter.js +2 -0
- package/dist/integrations/shared/parity-comparator.js +1 -0
- package/dist/integrations/shared/parity-manifest.js +3 -0
- package/dist/integrations/shared/runtime-assets.d.ts +13 -0
- package/dist/integrations/shared/runtime-assets.js +41 -3
- package/package.json +1 -1
- package/prompts/approval/database-guidance.md +39 -15
- package/prompts/approval/generate.md +12 -10
- package/skills/GUIDANCE_PACKS.md +49 -0
- package/skills/database/README.md +22 -4
- package/skills/guidance-packs.yaml +10 -0
- package/skills/specflow-approval/SKILL.md +12 -7
- package/templates/approval.md +3 -3
package/README.md
CHANGED
|
@@ -126,7 +126,7 @@ npm install -g @gordon.gan/specflow
|
|
|
126
126
|
npm install -g github:Gordon-Gan-Jiang/specflow
|
|
127
127
|
|
|
128
128
|
# 验证
|
|
129
|
-
specflow --version # 以 npm / package.json 为准(当前 1.4.
|
|
129
|
+
specflow --version # 以 npm / package.json 为准(当前 1.4.3-beta)
|
|
130
130
|
specflow --help
|
|
131
131
|
```
|
|
132
132
|
|
|
@@ -69,6 +69,7 @@ async function inspectClaude(projectRoot) {
|
|
|
69
69
|
const promptsDir = join(projectRoot, '.claude', 'specflow', 'prompts');
|
|
70
70
|
const schemasDir = join(projectRoot, '.claude', 'specflow', 'schemas');
|
|
71
71
|
const templatesDir = join(projectRoot, '.claude', 'specflow', 'templates');
|
|
72
|
+
const guidanceDir = join(projectRoot, '.claude', 'specflow', 'guidance');
|
|
72
73
|
const supported = [];
|
|
73
74
|
const skillContentsByCommand = {};
|
|
74
75
|
for (const command of COMMAND_CATALOG) {
|
|
@@ -98,6 +99,7 @@ async function inspectClaude(projectRoot) {
|
|
|
98
99
|
runtimePromptsDir: { exists: await directoryExists(promptsDir), hash: await hashDirectoryTree(promptsDir) },
|
|
99
100
|
runtimeSchemasDir: { exists: await directoryExists(schemasDir), hash: await hashDirectoryTree(schemasDir) },
|
|
100
101
|
runtimeTemplatesDir: { exists: await directoryExists(templatesDir), hash: await hashDirectoryTree(templatesDir) },
|
|
102
|
+
runtimeGuidanceDir: { exists: await directoryExists(guidanceDir), hash: await hashDirectoryTree(guidanceDir) },
|
|
101
103
|
},
|
|
102
104
|
};
|
|
103
105
|
}
|
|
@@ -40,6 +40,7 @@ function renderCodexAgentsBlock() {
|
|
|
40
40
|
'- Use artifacts under specflow/changes/<change>/ before coding',
|
|
41
41
|
'- Workflow skills: $specflow-explore, $specflow-propose, $specflow-refine, $specflow-apply, $specflow-review, $specflow-test, $specflow-verify, $specflow-archive, $specflow-fix, $specflow-snap',
|
|
42
42
|
'- Runtime prompts live under .agents/specflow/prompts/',
|
|
43
|
+
'- Guidance packs (non-IDE skills) live under .agents/specflow/guidance/',
|
|
43
44
|
'',
|
|
44
45
|
].join('\n');
|
|
45
46
|
}
|
|
@@ -96,6 +97,7 @@ async function inspectCodex(projectRoot) {
|
|
|
96
97
|
const promptsDir = join(projectRoot, '.agents', 'specflow', 'prompts');
|
|
97
98
|
const schemasDir = join(projectRoot, '.agents', 'specflow', 'schemas');
|
|
98
99
|
const templatesDir = join(projectRoot, '.agents', 'specflow', 'templates');
|
|
100
|
+
const guidanceDir = join(projectRoot, '.agents', 'specflow', 'guidance');
|
|
99
101
|
let agentsFileExists = false;
|
|
100
102
|
try {
|
|
101
103
|
const agentsContent = await fs.readFile(agentsFile, 'utf-8');
|
|
@@ -134,6 +136,7 @@ async function inspectCodex(projectRoot) {
|
|
|
134
136
|
runtimePromptsDir: { exists: await directoryExists(promptsDir), hash: await hashDirectoryTree(promptsDir) },
|
|
135
137
|
runtimeSchemasDir: { exists: await directoryExists(schemasDir), hash: await hashDirectoryTree(schemasDir) },
|
|
136
138
|
runtimeTemplatesDir: { exists: await directoryExists(templatesDir), hash: await hashDirectoryTree(templatesDir) },
|
|
139
|
+
runtimeGuidanceDir: { exists: await directoryExists(guidanceDir), hash: await hashDirectoryTree(guidanceDir) },
|
|
137
140
|
},
|
|
138
141
|
};
|
|
139
142
|
}
|
|
@@ -89,6 +89,7 @@ async function inspectCursor(projectRoot) {
|
|
|
89
89
|
const promptsDir = join(projectRoot, '.cursor', 'specflow', 'prompts');
|
|
90
90
|
const schemasDir = join(projectRoot, '.cursor', 'specflow', 'schemas');
|
|
91
91
|
const templatesDir = join(projectRoot, '.cursor', 'specflow', 'templates');
|
|
92
|
+
const guidanceDir = join(projectRoot, '.cursor', 'specflow', 'guidance');
|
|
92
93
|
const supported = [];
|
|
93
94
|
const skillContentsByCommand = {};
|
|
94
95
|
for (const command of COMMAND_CATALOG) {
|
|
@@ -119,6 +120,7 @@ async function inspectCursor(projectRoot) {
|
|
|
119
120
|
runtimePromptsDir: { exists: await directoryExists(promptsDir), hash: await hashDirectoryTree(promptsDir) },
|
|
120
121
|
runtimeSchemasDir: { exists: await directoryExists(schemasDir), hash: await hashDirectoryTree(schemasDir) },
|
|
121
122
|
runtimeTemplatesDir: { exists: await directoryExists(templatesDir), hash: await hashDirectoryTree(templatesDir) },
|
|
123
|
+
runtimeGuidanceDir: { exists: await directoryExists(guidanceDir), hash: await hashDirectoryTree(guidanceDir) },
|
|
122
124
|
},
|
|
123
125
|
};
|
|
124
126
|
}
|
|
@@ -4,6 +4,7 @@ import { CAPABILITY_MANIFEST, IDE_ASSET_MANIFEST } from './parity-manifest.js';
|
|
|
4
4
|
const PARITY_COMPARABLE_ASSET_KEYS = [
|
|
5
5
|
'runtimeSchemasDir',
|
|
6
6
|
'runtimeTemplatesDir',
|
|
7
|
+
'runtimeGuidanceDir',
|
|
7
8
|
];
|
|
8
9
|
export function validateReportAgainstManifest(report) {
|
|
9
10
|
const deltas = [];
|
|
@@ -42,6 +42,7 @@ export const IDE_ASSET_MANIFEST = [
|
|
|
42
42
|
'runtimePromptsDir',
|
|
43
43
|
'runtimeSchemasDir',
|
|
44
44
|
'runtimeTemplatesDir',
|
|
45
|
+
'runtimeGuidanceDir',
|
|
45
46
|
],
|
|
46
47
|
},
|
|
47
48
|
{
|
|
@@ -53,6 +54,7 @@ export const IDE_ASSET_MANIFEST = [
|
|
|
53
54
|
'runtimePromptsDir',
|
|
54
55
|
'runtimeSchemasDir',
|
|
55
56
|
'runtimeTemplatesDir',
|
|
57
|
+
'runtimeGuidanceDir',
|
|
56
58
|
],
|
|
57
59
|
},
|
|
58
60
|
{
|
|
@@ -63,6 +65,7 @@ export const IDE_ASSET_MANIFEST = [
|
|
|
63
65
|
'runtimePromptsDir',
|
|
64
66
|
'runtimeSchemasDir',
|
|
65
67
|
'runtimeTemplatesDir',
|
|
68
|
+
'runtimeGuidanceDir',
|
|
66
69
|
],
|
|
67
70
|
},
|
|
68
71
|
];
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
import type { IdeTarget } from './types.js';
|
|
2
|
+
export declare function ideRootDir(ide: IdeTarget): string;
|
|
3
|
+
interface GuidancePackSpec {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly source: string;
|
|
6
|
+
readonly installAs: string;
|
|
7
|
+
readonly consumers?: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Loads guidance pack registry from skills/guidance-packs.yaml.
|
|
11
|
+
* Missing or empty registry → no packs (non-fatal).
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadGuidancePacks(packageRoot: string): Promise<readonly GuidancePackSpec[]>;
|
|
2
14
|
export declare function copyRuntimeAssets(packageRoot: string, projectRoot: string, ide: IdeTarget): Promise<readonly string[]>;
|
|
15
|
+
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
1
2
|
import { join } from 'node:path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
2
4
|
import { copyDirRecursive, copyDirRecursiveRendered } from './asset-copy.js';
|
|
3
5
|
import { renderIdeContent } from './skill-renderer.js';
|
|
4
|
-
function ideRootDir(ide) {
|
|
6
|
+
export function ideRootDir(ide) {
|
|
5
7
|
if (ide === 'claude') {
|
|
6
8
|
return '.claude';
|
|
7
9
|
}
|
|
@@ -10,12 +12,48 @@ function ideRootDir(ide) {
|
|
|
10
12
|
}
|
|
11
13
|
return '.agents';
|
|
12
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Loads guidance pack registry from skills/guidance-packs.yaml.
|
|
17
|
+
* Missing or empty registry → no packs (non-fatal).
|
|
18
|
+
*/
|
|
19
|
+
export async function loadGuidancePacks(packageRoot) {
|
|
20
|
+
const registryPath = join(packageRoot, 'skills', 'guidance-packs.yaml');
|
|
21
|
+
let content;
|
|
22
|
+
try {
|
|
23
|
+
content = await fs.readFile(registryPath, 'utf-8');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
const parsed = yaml.load(content);
|
|
29
|
+
if (!parsed || !Array.isArray(parsed.packs)) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
return parsed.packs.filter((pack) => typeof pack?.id === 'string' &&
|
|
33
|
+
typeof pack?.source === 'string' &&
|
|
34
|
+
typeof pack?.installAs === 'string');
|
|
35
|
+
}
|
|
36
|
+
async function copyGuidancePacks(packageRoot, specflowRoot) {
|
|
37
|
+
const packs = await loadGuidancePacks(packageRoot);
|
|
38
|
+
for (const pack of packs) {
|
|
39
|
+
const src = join(packageRoot, ...pack.source.split('/'));
|
|
40
|
+
const dest = join(specflowRoot, ...pack.installAs.split('/'));
|
|
41
|
+
await copyDirRecursive(src, dest);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
13
44
|
export async function copyRuntimeAssets(packageRoot, projectRoot, ide) {
|
|
14
|
-
const
|
|
45
|
+
const ideRoot = ideRootDir(ide);
|
|
46
|
+
const root = join(projectRoot, ideRoot, 'specflow');
|
|
15
47
|
const promptsSrc = join(packageRoot, 'prompts');
|
|
16
48
|
const promptsDest = join(root, 'prompts');
|
|
17
49
|
await copyDirRecursiveRendered(promptsSrc, promptsDest, (content) => renderIdeContent(content, ide));
|
|
18
50
|
await copyDirRecursive(join(packageRoot, 'schemas'), join(root, 'schemas'));
|
|
19
51
|
await copyDirRecursive(join(packageRoot, 'templates'), join(root, 'templates'));
|
|
20
|
-
|
|
52
|
+
await copyGuidancePacks(packageRoot, root);
|
|
53
|
+
return [
|
|
54
|
+
`${ideRoot}/specflow/prompts`,
|
|
55
|
+
`${ideRoot}/specflow/schemas`,
|
|
56
|
+
`${ideRoot}/specflow/templates`,
|
|
57
|
+
`${ideRoot}/specflow/guidance`,
|
|
58
|
+
];
|
|
21
59
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Approval · Database Guidance Router
|
|
2
2
|
|
|
3
3
|
> Used by `/specflow:approval` when generating §4.4 (数据结构 / 数据模型).
|
|
4
|
-
>
|
|
4
|
+
> **Guidance pack**: `database`(见 `skills/guidance-packs.yaml` / `skills/GUIDANCE_PACKS.md`)。
|
|
5
|
+
> **业务仓落地**: `{ide}/specflow/guidance/database/`(`specflow init` 同步;**不是** IDE skill)。
|
|
5
6
|
> **禁止**依赖远程 skill 仓库(禁止 `npx skills add` / clone / 运行时 fetch)。
|
|
6
|
-
> **Not** an MCP tool — on hit, `Read` local matched skill files; on miss, LLM-only §4.4.
|
|
7
|
+
> **Not** an MCP tool — on hit, `Read` local matched skill files; on miss, LLM-only §4.4.
|
|
8
|
+
> **禁止**写成「invoke `/mysql` skill」——一律 `Read` 路径。
|
|
7
9
|
|
|
8
10
|
---
|
|
9
11
|
|
|
@@ -28,18 +30,35 @@ Scan the **project under review** (change's repo root), not SpecFlow itself. Col
|
|
|
28
30
|
**Multi-hit**: pick primary OLTP store for §4.4 (prefer `mysql` / `postgresql` / `oracle` over
|
|
29
31
|
`redis` / `elasticsearch`). Mention secondary stores in §4.7/架构 if relevant.
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. Resolve guidance root (path priority)
|
|
36
|
+
|
|
37
|
+
Before reading pack files, resolve `guidanceRoot` for stack `<stack>`:
|
|
38
|
+
|
|
39
|
+
| Priority | Path | When |
|
|
40
|
+
|----------|------|------|
|
|
41
|
+
| 1 | `.cursor/specflow/guidance/database/<stack>/` | Cursor IDE assets present |
|
|
42
|
+
| 1 | `.claude/specflow/guidance/database/<stack>/` | Claude IDE assets present |
|
|
43
|
+
| 1 | `.agents/specflow/guidance/database/<stack>/` | Codex IDE assets present |
|
|
44
|
+
| 2 | `skills/database/<stack>/` | SpecFlow package / self-repo fallback (relative to SpecFlow package root) |
|
|
45
|
+
| 3 | *(missing)* | `LLM-fallback` |
|
|
46
|
+
|
|
47
|
+
If multiple IDE roots exist, prefer the IDE the user is running in; otherwise the first existing path among cursor → claude → agents.
|
|
48
|
+
|
|
49
|
+
**Announce** after detection + resolve:
|
|
32
50
|
|
|
33
51
|
```text
|
|
34
52
|
DB stack for approval: <mysql|postgresql|oracle|redis|elasticsearch|none>
|
|
35
|
-
Guidance:
|
|
53
|
+
Guidance: <.cursor|claude|agents>/specflow/guidance/database/<stack>/SKILL.md
|
|
54
|
+
| skills/database/<stack>/SKILL.md | LLM-fallback
|
|
36
55
|
```
|
|
37
56
|
|
|
38
57
|
---
|
|
39
58
|
|
|
40
|
-
##
|
|
59
|
+
## 3. On hit — load **local** guidance (Read, do not invent, do not fetch)
|
|
41
60
|
|
|
42
|
-
Base
|
|
61
|
+
Base = resolved `guidanceRoot` above. From that directory:
|
|
43
62
|
|
|
44
63
|
| Stack | Must Read | Also Read when §4.4 needs it |
|
|
45
64
|
|-------|-----------|------------------------------|
|
|
@@ -49,31 +68,36 @@ Base: `skills/database/<stack>/`(相对 SpecFlow 仓库根;离线可读)
|
|
|
49
68
|
| `redis` | `SKILL.md` | Only if change is cache/key design — **not** a substitute for relational DDL |
|
|
50
69
|
| `elasticsearch` | `SKILL.md` | Only if change is index/mapping — **not** a substitute for relational DDL |
|
|
51
70
|
|
|
71
|
+
Point to files **from the router entry** (no reference→reference chains).
|
|
72
|
+
|
|
52
73
|
Apply guidance to §4.4 output:
|
|
53
74
|
|
|
54
75
|
1. Prefer engine/charset/collation idioms from the local skill (MySQL: InnoDB + utf8mb4…).
|
|
55
76
|
2. Prefer type/index gotchas from the skill (e.g. DECIMAL for money, no FLOAT amounts).
|
|
56
77
|
3. Keep SpecFlow hard rules (ER, full CREATE TABLE, 本迭代用法, G3/G4) — skill **supplements**, does not replace.
|
|
57
78
|
|
|
58
|
-
Cite in §4.4
|
|
79
|
+
Cite in §4.4 总则 the **actual** path used, e.g.
|
|
80
|
+
`DB 技能: .cursor/specflow/guidance/database/mysql` 或 `skills/database/mysql (package fallback)`.
|
|
59
81
|
|
|
60
82
|
---
|
|
61
83
|
|
|
62
|
-
##
|
|
84
|
+
## 4. On miss — LLM fallback
|
|
63
85
|
|
|
64
|
-
If `DB stack = none
|
|
86
|
+
If `DB stack = none`, or stack set but **no** guidance root resolves:
|
|
65
87
|
|
|
66
88
|
1. **Do not** force-load mysql/postgresql skills.
|
|
67
89
|
2. Generate §4.4 with SpecFlow rules only (`generate.md` §4.4 + Quality Gates G3/G4).
|
|
68
90
|
3. If design/tasks claim a DB but signals are absent → `WARNING` in §8:
|
|
69
91
|
`design 声称落库但未检测到 DB 栈信号 — 已用 LLM 通用 DDL;建议 refine 标明引擎`.
|
|
70
|
-
4.
|
|
92
|
+
4. If stack detected but guidance files missing → `WARNING` in §8:
|
|
93
|
+
`dbStack=<stack> 但未找到 guidance/database — 已用 LLM-fallback;建议 specflow init --force-assets`.
|
|
94
|
+
5. Pure CLI/config changes → keep `不涉及数据库变更(...)`.
|
|
71
95
|
|
|
72
96
|
---
|
|
73
97
|
|
|
74
|
-
##
|
|
98
|
+
## 5. Why not remote skills / MCP / IDE skills?
|
|
75
99
|
|
|
76
|
-
- **Remote**: approval must work offline
|
|
77
|
-
|
|
78
|
-
- **
|
|
79
|
-
|
|
100
|
+
- **Remote**: approval must work offline; maintain pack in this repo + init sync.
|
|
101
|
+
- **MCP tools**: markdown guidance, not APIs; routing chooses which local files to `Read`.
|
|
102
|
+
- **IDE skills**: packs must **not** appear under `.cursor/skills` / `.claude/skills` / `.agents/skills`
|
|
103
|
+
(noise + false discoverability). They live only under `{ide}/specflow/guidance/`.
|
|
@@ -590,11 +590,12 @@ sequenceDiagram
|
|
|
590
590
|
**适用范围**:涉及持久化、状态存储、数据模型的变更。纯 CLI/库项目若无数据库,覆盖配置结构 / 状态文件 / 缓存结构 / YAML schema 等"数据模型"(走下方「非库表路径」)。
|
|
591
591
|
|
|
592
592
|
> **DB 技能路由(先于起草)**:执行 `prompts/approval/database-guidance.md`。
|
|
593
|
-
> - **命中** `mysql` / `postgresql` / `oracle`(及确需时的 redis/es)
|
|
594
|
-
> `
|
|
595
|
-
>
|
|
596
|
-
> -
|
|
597
|
-
> -
|
|
593
|
+
> - **命中** `mysql` / `postgresql` / `oracle`(及确需时的 redis/es):按路径优先级 `Read`
|
|
594
|
+
> `{ide}/specflow/guidance/database/<stack>/SKILL.md`(init 安装的 guidance pack)
|
|
595
|
+
> 或包内回退 `skills/database/<stack>/SKILL.md`,以及路由表中的 DDL/索引/JSON 参考。
|
|
596
|
+
> - **未命中**(`dbStack=none`)或文件缺失:不硬套某厂商 skill,**交给大模型**按下方 SpecFlow 硬门槛生成。
|
|
597
|
+
> - 技能是 **Read 知识包**,不是 MCP tool / IDE skill;不得「invoke `/mysql`」。
|
|
598
|
+
> - 在总则「DB 技能」列注明**实际路径**(如 `.cursor/specflow/guidance/database/mysql`)或 `LLM-fallback`。
|
|
598
599
|
|
|
599
600
|
> **质量硬门槛(库表路径)**:只要本变更读写/依赖任何数据库表(含"零 DDL、只改读写语义"),§4.4 **必须**按下列结构输出,不得用一句话带过、不得省略 ER / DDL / 字段说明表。参考质量标杆:`scenario-job-compile` 类审批文档的「表与数据设计」章(总则结论表 → ER → 表一览 → 逐表 DDL+字段表 → 非表字段与回滚)。
|
|
600
601
|
|
|
@@ -627,7 +628,7 @@ sequenceDiagram
|
|
|
627
628
|
| 新增 / 修改 / 删除列 | 列清单 / **无** |
|
|
628
629
|
| 新增索引 | 索引清单 / **无** |
|
|
629
630
|
| DDL 来源 | 仓库基线路径 或 本迭代新增 |
|
|
630
|
-
| DB 技能 | `skills/database/<stack>`(
|
|
631
|
+
| DB 技能 | `{ide}/specflow/guidance/database/<stack>` / `skills/database/<stack>`(fallback) / `LLM-fallback` |
|
|
631
632
|
|
|
632
633
|
紧接一段 **本迭代变更语句** 代码块:
|
|
633
634
|
|
|
@@ -1207,10 +1208,11 @@ specflow init --artifact-language <language>
|
|
|
1207
1208
|
summary table. PASS/SKIPPED → one short phrase; WARNING/FAIL → ≤3 concrete bullets.
|
|
1208
1209
|
|
|
1209
1210
|
16. **§4.4 database skill routing**: before drafting relational DDL, run
|
|
1210
|
-
`prompts/approval/database-guidance.md`. On stack hit, Read
|
|
1211
|
-
`
|
|
1212
|
-
LLM-only SpecFlow §4.4 rules.
|
|
1213
|
-
|
|
1211
|
+
`prompts/approval/database-guidance.md`. On stack hit, resolve then Read
|
|
1212
|
+
`{ide}/specflow/guidance/database/<stack>/…` (init guidance pack) or package
|
|
1213
|
+
fallback `skills/database/<stack>/…`; on miss, LLM-only SpecFlow §4.4 rules.
|
|
1214
|
+
Do not invent MCP tools; do not `npx skills add`; do not install packs under
|
|
1215
|
+
IDE `skills/` discovery. Record the **actual path** or `LLM-fallback` in §4.4.1.
|
|
1214
1216
|
|
|
1215
1217
|
17. **§4.4 / §4.5 outline hygiene (hard rule)**: Markdown TOC must stay shallow.
|
|
1216
1218
|
- §4.4 headings only: `#### 4.4.1–4.4.4` + per-table `##### \`table\`(中文名)`.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Guidance Packs(两层技能模型)
|
|
2
|
+
|
|
3
|
+
SpecFlow 区分两类能力包,避免把内部知识暴露成可 `/` 调用的 IDE skill。
|
|
4
|
+
|
|
5
|
+
## 两层模型
|
|
6
|
+
|
|
7
|
+
| 层 | 包内位置 | 业务仓落地 | IDE 可发现 |
|
|
8
|
+
|----|----------|------------|------------|
|
|
9
|
+
| **Workflow skill** | `skills/specflow-*` + `COMMAND_CATALOG` | `.cursor/skills/specflow-*`(及 claude/agents) | 是 |
|
|
10
|
+
| **Guidance pack** | `skills/<pack>/` + 本注册表 | `{ide}/specflow/guidance/<pack>/` | **否** |
|
|
11
|
+
|
|
12
|
+
Workflow skill(如 `/specflow:approval`)通过路由文档指示 Agent **`Read` 文件路径**加载 guidance;禁止写成「invoke `/mysql` skill」。
|
|
13
|
+
|
|
14
|
+
设计原则对齐 Anthropic Agent Skills 的 progressive disclosure(元数据 → 正文 → 按需 Read `references/`),并复用 SpecFlow 已有的 runtime assets(与 `prompts/` / `templates/` 同级安装)。
|
|
15
|
+
|
|
16
|
+
## 注册表
|
|
17
|
+
|
|
18
|
+
[`guidance-packs.yaml`](guidance-packs.yaml) 列出所有需随 `specflow init` / `--force-assets` 同步的 pack:
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
packs:
|
|
22
|
+
- id: database
|
|
23
|
+
source: skills/database # 相对 SpecFlow 包根
|
|
24
|
+
installAs: guidance/database # 相对 {ide}/specflow/
|
|
25
|
+
consumers: [approval] # 文档用:哪些 workflow 会 Read
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 新增一个 Guidance Pack
|
|
29
|
+
|
|
30
|
+
1. 在 `skills/<id>/` 放置 `SKILL.md`(及可选 `references/`、`examples/`)。
|
|
31
|
+
2. 在 `guidance-packs.yaml` 增加一行。
|
|
32
|
+
3. 在消费方 workflow 的 prompt/SKILL 中写明解析顺序:
|
|
33
|
+
- `{ide}/specflow/guidance/<id>/…`(业务仓标准路径)
|
|
34
|
+
- 回退:包内 `skills/<id>/…`(SpecFlow 自研仓)
|
|
35
|
+
- 仍缺失:显式 fallback + WARNING
|
|
36
|
+
4. 「调用」语义:`Read …/SKILL.md`(及入口直接点名的 references),禁止链式跳转、禁止 MCP、禁止远程 `npx skills add`。
|
|
37
|
+
|
|
38
|
+
## 共享 vs 包内 references
|
|
39
|
+
|
|
40
|
+
| 场景 | 放哪里 |
|
|
41
|
+
|------|--------|
|
|
42
|
+
| 多个 workflow 共用 | Guidance pack(本机制) |
|
|
43
|
+
| 仅单一 skill 使用 | 该 skill 目录下的 `references/`(Anthropic 包内资源) |
|
|
44
|
+
|
|
45
|
+
## 当前 packs
|
|
46
|
+
|
|
47
|
+
| id | consumers | 说明 |
|
|
48
|
+
|----|-----------|------|
|
|
49
|
+
| `database` | approval | §4.4 按 `dbStack` Read mysql/postgresql/oracle/redis/elasticsearch |
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
# SpecFlow 本地数据库技能 (`skills/database/`)
|
|
2
2
|
|
|
3
|
-
本目录是 **SpecFlow
|
|
3
|
+
本目录是 **Guidance Pack** `database`:SpecFlow 仓库内长期维护的数据库参考知识,供 `/specflow:approval` 生成 §4.4 时按项目栈按需 `Read`。
|
|
4
|
+
|
|
5
|
+
详见 [`../GUIDANCE_PACKS.md`](../GUIDANCE_PACKS.md) 与 [`../guidance-packs.yaml`](../guidance-packs.yaml)。
|
|
4
6
|
|
|
5
7
|
## 硬性约定
|
|
6
8
|
|
|
7
9
|
| 项 | 约定 |
|
|
8
10
|
|----|------|
|
|
9
|
-
| 运行时依赖 |
|
|
11
|
+
| 运行时依赖 | **无远程仓库依赖**。审批流程只读本地文件,禁止 `npx skills add`、禁止 clone/fetch 上游 |
|
|
10
12
|
| 维护方式 | 在本仓库直接改 `SKILL.md` / `references/` / `examples/`,随 SpecFlow 发版 |
|
|
11
|
-
| 加载方式 | `prompts/approval/database-guidance.md` 路由:命中栈 → Read
|
|
12
|
-
|
|
|
13
|
+
| 加载方式 | `prompts/approval/database-guidance.md` 路由:命中栈 → Read;未命中 → LLM-fallback |
|
|
14
|
+
| init 安装目标 | `{ide}/specflow/guidance/database/`(与 prompts/templates 同级) |
|
|
15
|
+
| IDE 全局技能 | **不**安装到 `.cursor/skills` / `.claude/skills` / `.agents/skills`(避免噪音与误发现) |
|
|
16
|
+
|
|
17
|
+
## 路径解析(业务仓)
|
|
18
|
+
|
|
19
|
+
1. `.cursor/specflow/guidance/database/<stack>/`(或 `.claude` / `.agents`)
|
|
20
|
+
2. 回退:包内 `skills/database/<stack>/`(SpecFlow 自研仓)
|
|
21
|
+
3. 仍缺失:`LLM-fallback` + §8 WARNING(建议 `specflow init --force-assets`)
|
|
22
|
+
|
|
23
|
+
「调用」语义:`Read …/SKILL.md`(及路由直接点名的 references),**禁止** `invoke /mysql`。
|
|
13
24
|
|
|
14
25
|
## 目录
|
|
15
26
|
|
|
@@ -24,6 +35,13 @@ skills/database/
|
|
|
24
35
|
README.md # 本文件
|
|
25
36
|
```
|
|
26
37
|
|
|
38
|
+
业务仓 init 后对应:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
.cursor/specflow/guidance/database/mysql/SKILL.md
|
|
42
|
+
…
|
|
43
|
+
```
|
|
44
|
+
|
|
27
45
|
## 历史种子(非依赖)
|
|
28
46
|
|
|
29
47
|
初版内容种子自 [full-stack-skills/database-skills](https://github.com/full-stack-skills/database-skills)(Apache-2.0)。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Guidance packs: private knowledge installed under {ide}/specflow/guidance/
|
|
2
|
+
# NOT copied into IDE skills discovery paths (.cursor/skills, .claude/skills, .agents/skills).
|
|
3
|
+
# See skills/GUIDANCE_PACKS.md
|
|
4
|
+
|
|
5
|
+
packs:
|
|
6
|
+
- id: database
|
|
7
|
+
source: skills/database
|
|
8
|
+
installAs: guidance/database
|
|
9
|
+
consumers:
|
|
10
|
+
- approval
|
|
@@ -95,10 +95,11 @@ Announce: "Generating technical approval document for change `<name>` (phase=ref
|
|
|
95
95
|
Read these files and follow them:
|
|
96
96
|
|
|
97
97
|
1. `.claude/specflow/prompts/approval/generate.md` (or repo `prompts/approval/generate.md`)
|
|
98
|
-
2. `prompts/approval/database-guidance.md` — DB
|
|
99
|
-
`
|
|
100
|
-
tool**: on `dbStack` hit, `Read`
|
|
101
|
-
LLM-only §4.4.
|
|
98
|
+
2. `prompts/approval/database-guidance.md` — DB **guidance pack** router for packs under
|
|
99
|
+
`{ide}/specflow/guidance/database/` (installed by init; **not** an IDE skill) with
|
|
100
|
+
package fallback `skills/database/`. **Not an MCP tool**: on `dbStack` hit, `Read`
|
|
101
|
+
matched `SKILL.md` + focused references; on `none` or missing files, LLM-only §4.4.
|
|
102
|
+
Never "invoke `/mysql` skill" — always `Read` a resolved path.
|
|
102
103
|
|
|
103
104
|
`generate.md` + `database-guidance.md` together specify:
|
|
104
105
|
|
|
@@ -116,7 +117,9 @@ Read these files and follow them:
|
|
|
116
117
|
pain-point diagram, User Journey, Non-Goals with reasons)
|
|
117
118
|
- Document order: §1 绪论 → §2 评估 → §3 架构 → §4 详细设计 → **§5 验收标准** → §6 测试 → …
|
|
118
119
|
- **Quality Gates G1–G4** + **Style & Tone** (hard rules in generate.md Part E)
|
|
119
|
-
- **DB guidance router** (`database-guidance.md` +
|
|
120
|
+
- **DB guidance router** (`database-guidance.md` + guidance pack `database`): match project
|
|
121
|
+
stack → resolve `{ide}/specflow/guidance/database/<stack>/` (or package `skills/database/`)
|
|
122
|
+
→ `Read`; miss → LLM-fallback. Packs are **not** installed under IDE `skills/` discovery.
|
|
120
123
|
stack → Read in-repo skill; no hit → LLM fallback; **never** fetch remote skills / MCP wrap
|
|
121
124
|
- Anchor-file extraction and code-reading rules (depth: anchor file only, no recursion)
|
|
122
125
|
|
|
@@ -283,8 +286,10 @@ Order and hard requirements (from `generate.md` §4.1–4.8):
|
|
|
283
286
|
3. **业务场景时序** — each scenario: purpose + diagram + **设计要点说明** (required notes;
|
|
284
287
|
bare diagrams fail quality).
|
|
285
288
|
4. **数据结构** — Before drafting §4.4: follow `database-guidance.md`. If `dbStack` hit,
|
|
286
|
-
`Read` `
|
|
287
|
-
|
|
289
|
+
resolve then `Read` `{ide}/specflow/guidance/database/<stack>/SKILL.md` (init-installed
|
|
290
|
+
guidance pack) or package fallback `skills/database/<stack>/SKILL.md` (+ refs as needed).
|
|
291
|
+
If `none` or files missing, LLM-only with SpecFlow §4.4 hard bar (ER + full CREATE TABLE…).
|
|
292
|
+
Cite the actual path in §4.4 总则. **Never** install/invoke database as an IDE skill.
|
|
288
293
|
**Outline**: only `4.4.1–4.4.4` + `##### table`; DDL/字段说明/JSON = `**bold**`, not headings.
|
|
289
294
|
5. **接口设计** — inventory + fields + examples + errors…
|
|
290
295
|
**Outline**: only `4.5.1–4.5.3` + `##### In`; 请求体字段/示例/错误 = `**bold**`, not headings.
|
package/templates/approval.md
CHANGED
|
@@ -222,8 +222,8 @@ sequenceDiagram
|
|
|
222
222
|
|
|
223
223
|
### 4.4 数据结构 / 数据模型变更 (Data Structures)
|
|
224
224
|
|
|
225
|
-
<!-- 库表硬门槛 + DB
|
|
226
|
-
|
|
225
|
+
<!-- 库表硬门槛 + DB guidance pack:init 安装到 {ide}/specflow/guidance/database/;
|
|
226
|
+
路由见 prompts/approval/database-guidance.md。总则表填写实际「DB 技能」路径。
|
|
227
227
|
大纲硬门槛:仅 4.4.1–4.4.4 + ##### 表名;DDL/字段说明/JSON 用 **加粗**,禁止再开标题。 -->
|
|
228
228
|
|
|
229
229
|
#### 4.4.1 总则与本迭代结构变更结论
|
|
@@ -235,7 +235,7 @@ sequenceDiagram
|
|
|
235
235
|
| 新增/修改/删除列 | <清单 / 无> |
|
|
236
236
|
| 新增索引 | <清单 / 无> |
|
|
237
237
|
| DDL 来源 | <migrations 路径 / 本迭代新增> |
|
|
238
|
-
| DB 技能 |
|
|
238
|
+
| DB 技能 | <.cursor|…/guidance/database/mysql 或 LLM-fallback> |
|
|
239
239
|
|
|
240
240
|
```sql
|
|
241
241
|
-- 本迭代变更语句
|