@gordon.gan/specflow 1.3.3-beta → 1.4.1

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.
Files changed (85) hide show
  1. package/README.md +6 -2
  2. package/dist/integrations/shared/capability-evidence.js +37 -1
  3. package/dist/integrations/shared/command-catalog.js +1 -0
  4. package/dist/integrations/shared/parity-manifest.js +6 -0
  5. package/package.json +1 -1
  6. package/prompts/approval/database-guidance.md +79 -0
  7. package/prompts/approval/generate.md +1191 -0
  8. package/skills/database/LICENSE +405 -0
  9. package/skills/database/ORIGIN.md +6 -0
  10. package/skills/database/README.md +30 -0
  11. package/skills/database/elasticsearch/LICENSE.txt +202 -0
  12. package/skills/database/elasticsearch/SKILL.md +199 -0
  13. package/skills/database/elasticsearch/examples/01-fulltext-search.md +215 -0
  14. package/skills/database/elasticsearch/examples/02-aggregation-report.md +206 -0
  15. package/skills/database/elasticsearch/examples/03-reindex-zero-downtime.md +200 -0
  16. package/skills/database/elasticsearch/examples/04-cluster-monitoring.md +204 -0
  17. package/skills/database/elasticsearch/references/01-query-dsl-fulltext.md +162 -0
  18. package/skills/database/elasticsearch/references/02-query-dsl-term.md +210 -0
  19. package/skills/database/elasticsearch/references/03-aggregations-metric.md +161 -0
  20. package/skills/database/elasticsearch/references/04-aggregations-bucket.md +236 -0
  21. package/skills/database/elasticsearch/references/05-mapping-types.md +134 -0
  22. package/skills/database/elasticsearch/references/06-analyzers.md +187 -0
  23. package/skills/database/elasticsearch/references/07-cluster-ops.md +225 -0
  24. package/skills/database/elasticsearch/references/08-elk-integration.md +170 -0
  25. package/skills/database/mysql/SKILL.md +195 -0
  26. package/skills/database/mysql/examples/01-connection-pool.md +75 -0
  27. package/skills/database/mysql/examples/02-slow-query-optimization.md +98 -0
  28. package/skills/database/mysql/examples/03-master-slave-setup.md +144 -0
  29. package/skills/database/mysql/examples/04-backup-strategy.md +212 -0
  30. package/skills/database/mysql/references/01-functions-string.md +103 -0
  31. package/skills/database/mysql/references/02-functions-date.md +152 -0
  32. package/skills/database/mysql/references/03-functions-aggregate-window.md +167 -0
  33. package/skills/database/mysql/references/04-functions-json.md +129 -0
  34. package/skills/database/mysql/references/05-sql-ddl-types.md +235 -0
  35. package/skills/database/mysql/references/06-index-optimization.md +232 -0
  36. package/skills/database/mysql/references/07-replication-ha.md +213 -0
  37. package/skills/database/mysql/references/08-backup-restore.md +207 -0
  38. package/skills/database/mysql/references/09-advanced-features.md +345 -0
  39. package/skills/database/oracle/LICENSE.txt +202 -0
  40. package/skills/database/oracle/SKILL.md +238 -0
  41. package/skills/database/oracle/examples/01-plsql-procedure.md +90 -0
  42. package/skills/database/oracle/examples/02-awr-analysis.md +99 -0
  43. package/skills/database/oracle/examples/03-rman-backup.md +108 -0
  44. package/skills/database/oracle/examples/04-dataguard-setup.md +146 -0
  45. package/skills/database/oracle/references/01-functions-string.md +91 -0
  46. package/skills/database/oracle/references/02-functions-date.md +71 -0
  47. package/skills/database/oracle/references/03-analytic-functions.md +103 -0
  48. package/skills/database/oracle/references/04-plsql-guide.md +303 -0
  49. package/skills/database/oracle/references/05-performance-tuning.md +164 -0
  50. package/skills/database/oracle/references/06-backup-recovery.md +115 -0
  51. package/skills/database/oracle/references/07-dataguard-rac.md +76 -0
  52. package/skills/database/oracle/references/08-security.md +170 -0
  53. package/skills/database/oracle/references/09-sql-syntax.md +152 -0
  54. package/skills/database/oracle/references/10-features.md +174 -0
  55. package/skills/database/postgresql/LICENSE.txt +202 -0
  56. package/skills/database/postgresql/SKILL.md +182 -0
  57. package/skills/database/postgresql/examples/.gitkeep +0 -0
  58. package/skills/database/postgresql/examples/01-jsonb-query.md +72 -0
  59. package/skills/database/postgresql/examples/02-cte-recursive.md +110 -0
  60. package/skills/database/postgresql/examples/03-performance-tuning.md +114 -0
  61. package/skills/database/postgresql/examples/04-streaming-replication.md +113 -0
  62. package/skills/database/postgresql/references/.gitkeep +0 -0
  63. package/skills/database/postgresql/references/01-functions-string.md +174 -0
  64. package/skills/database/postgresql/references/02-functions-datetime.md +54 -0
  65. package/skills/database/postgresql/references/03-functions-aggregate-window.md +142 -0
  66. package/skills/database/postgresql/references/04-functions-jsonb.md +117 -0
  67. package/skills/database/postgresql/references/05-fulltext-search.md +109 -0
  68. package/skills/database/postgresql/references/06-index-types.md +95 -0
  69. package/skills/database/postgresql/references/07-partition-fdw.md +133 -0
  70. package/skills/database/postgresql/references/08-replication-backup.md +215 -0
  71. package/skills/database/redis/LICENSE.txt +202 -0
  72. package/skills/database/redis/SKILL.md +922 -0
  73. package/skills/database/redis/examples/01-cache-usage.md +104 -0
  74. package/skills/database/redis/examples/02-session-storage.md +72 -0
  75. package/skills/database/redis/examples/03-leaderboard.md +63 -0
  76. package/skills/database/redis/examples/04-redis-cluster-setup.md +70 -0
  77. package/skills/database/redis/examples/05-stream-queue.md +65 -0
  78. package/skills/database/redis/references/command-quick-ref.md +180 -0
  79. package/skills/database/redis/references/commands-admin-key.md +413 -0
  80. package/skills/database/redis/references/commands-set-sorted-advanced.md +539 -0
  81. package/skills/database/redis/references/commands-string-hash-list.md +458 -0
  82. package/skills/database/redis/references/memory-optimization.md +150 -0
  83. package/skills/database/redis/references/redis-conf-production.md +139 -0
  84. package/skills/specflow-approval/SKILL.md +427 -0
  85. package/templates/approval.md +464 -0
package/README.md CHANGED
@@ -72,6 +72,8 @@ explore(可选)→ propose → refine → apply → review → test → veri
72
72
  │ ↓ │
73
73
  │ refine ≥2 轮精化:挑战假设 / 新方案 / 探边界 / 质疑 scope │
74
74
  │ ↓ │
75
+ │ approval [可选] AI 7 维闭环检查 + 设计质量 + 可实施性 → approval.md 供审批 │
76
+ │ ↓ │
75
77
  │ apply Phase A 重写 tasks.md → Phase B 逐任务 TDD 执行 │
76
78
  │ (可选 /specflow:apply --yes:少打断,成功后串行验收) │
77
79
  │ ↓ │
@@ -124,7 +126,7 @@ npm install -g @gordon.gan/specflow
124
126
  npm install -g github:Gordon-Gan-Jiang/specflow
125
127
 
126
128
  # 验证
127
- specflow --version # 以 npm / package.json 为准(当前 1.3.3-beta
129
+ specflow --version # 以 npm / package.json 为准(当前 1.4.1
128
130
  specflow --help
129
131
  ```
130
132
 
@@ -257,13 +259,14 @@ specflow init
257
259
 
258
260
  ## IDE 工作流命令
259
261
 
260
- 共 **10 个**技能,命名因 IDE 而异:
262
+ 共 **11 个**技能,命名因 IDE 而异:
261
263
 
262
264
  | 阶段 | Claude Code | Cursor | Codex |
263
265
  |------|-------------|--------|-------|
264
266
  | 探索(可选) | `/specflow:explore` | `specflow:explore` | `$specflow-explore` |
265
267
  | 规划 | `/specflow:propose` | `specflow:propose` | `$specflow-propose` |
266
268
  | 精化 | `/specflow:refine` | `specflow:refine` | `$specflow-refine` |
269
+ | 审批(可选) | `/specflow:approval` | `specflow:approval` | `$specflow-approval` |
267
270
  | 构建 | `/specflow:apply` | `specflow:apply` | `$specflow-apply` |
268
271
  | 审查 | `/specflow:review` | `specflow:review` | `$specflow-review` |
269
272
  | 测试 | `/specflow:test` | `specflow:test` | `$specflow-test` |
@@ -279,6 +282,7 @@ specflow init
279
282
  | **explore** | 读代码、比方案、定边界;产出 `explore.md`,confirmed 后 handoff 到 propose |
280
283
  | **propose** | 一次产出 proposal、delta specs、design、tasks(第一轮深度思考,非占位骨架);叙述语言跟 `artifacts.language` |
281
284
  | **refine** | 内部多轮循环(≥2 轮,AI 判断收敛);可更新任意 artifact |
285
+ | **approval** | refine 后可选:AI 对四件套做 7 维闭环性检查(含代码落地性、基线对照)+ 设计质量评估 + 可实施性评估,生成 `approval.md` 供人工审批;不改 phase,不阻塞 apply |
282
286
  | **apply** | Phase A 重写 tasks.md;Phase B 按语言路由 ECC 审查 + TDD 逐任务执行;可选 `--yes` |
283
287
  | **review** | 代码审查,对照 specs 检查回归 |
284
288
  | **test** | 单元 + 集成 + E2E + 回归测试 |
@@ -7,6 +7,11 @@ const MARKER_RULES = [
7
7
  { id: 'sub.propose.first_iteration', skill: 'propose', includes: ['first-iteration deep-analysis pass'] },
8
8
  { id: 'sub.refine.multi_round', skill: 'refine', includes: ['auto-multi-round loop', '## LOOP (Stages 2-4)'] },
9
9
  { id: 'sub.refine.challenge_scope', skill: 'refine', includes: ['Challenge Behaviors #3 and #4', 'question scope'] },
10
+ { id: 'sub.approval.closed_loop', skill: 'approval', includes: ['Closed-Loop Verification', 'Pass 1'] },
11
+ { id: 'sub.approval.implementability', skill: 'approval', includes: ['Implementability Assessment', 'Completeness'] },
12
+ { id: 'sub.approval.no_phase_change', skill: 'approval', includes: ['does NOT advance phase', 'phase stays `refined`'] },
13
+ { id: 'sub.approval.code_grounding', skill: 'approval', includes: ['Code Grounding', 'Pass 6'] },
14
+ { id: 'sub.approval.design_quality', skill: 'approval', includes: ['Design Quality Assessment', 'Over-Engineering'] },
10
15
  { id: 'sub.apply.phase_a', skill: 'apply', includes: ['## Phase A: Task Rewrite'] },
11
16
  { id: 'sub.apply.phase_b', skill: 'apply', includes: ['## Phase B: Subagent TDD Execution'] },
12
17
  { id: 'sub.apply.gap_detection', skill: 'apply', includes: ['Gap Detection'] },
@@ -19,8 +24,39 @@ const MARKER_RULES = [
19
24
  { id: 'failure.explore.proposal_exists_redirect', skill: 'explore', includes: ['explore is too late', 'refine'] },
20
25
  { id: 'failure.propose.explore_draft_gate', skill: 'propose', includes: ['Status: draft', 'REFUSE to proceed'] },
21
26
  { id: 'failure.apply.phase_gate', skill: 'apply', includes: ['HARD GATE (prerequisite)', 'phase is not `refined`, REFUSE'] },
27
+ { id: 'failure.approval.phase_gate', skill: 'approval', includes: ['phase must be `refined`', 'REFUSE to proceed'] },
22
28
  { id: 'failure.verify.explicit_skip_marker', skill: 'verify', includes: ['Pass 2: skipped (no baseline'] },
23
29
  ];
30
+ /**
31
+ * Checks whether a marker phrase appears in `content` as an independent token.
32
+ *
33
+ * Uses explicit character-class boundaries (not regex `\b`) so phrases that
34
+ * contain punctuation (e.g. "## LOOP (Stages 2-4)", "Pass 2: skipped (no
35
+ * baseline") are matched reliably, while a longer word that merely *contains*
36
+ * the phrase (e.g. "Code GroundingXX" vs "Code Grounding") is NOT treated as
37
+ * a match. This prevents capability evidence from false-positive on accidental
38
+ * substrings.
39
+ */
40
+ function containsIndependentPhrase(content, phrase) {
41
+ if (phrase.length === 0) {
42
+ return false;
43
+ }
44
+ const boundary = /[A-Za-z0-9_]/;
45
+ const escaped = phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
46
+ const re = new RegExp(escaped, 'g');
47
+ let match;
48
+ while ((match = re.exec(content)) !== null) {
49
+ const before = match.index > 0 ? content[match.index - 1] : '';
50
+ const afterIndex = match.index + phrase.length;
51
+ const after = afterIndex < content.length ? content[afterIndex] : '';
52
+ const beforeBoundary = before !== '' && boundary.test(before);
53
+ const afterBoundary = after !== '' && boundary.test(after);
54
+ if (!beforeBoundary && !afterBoundary) {
55
+ return true;
56
+ }
57
+ }
58
+ return false;
59
+ }
24
60
  export function deriveCapabilityIds(supportedCommandIds, skillContentsByCommand) {
25
61
  const capabilityIds = new Set();
26
62
  for (const commandId of supportedCommandIds) {
@@ -28,7 +64,7 @@ export function deriveCapabilityIds(supportedCommandIds, skillContentsByCommand)
28
64
  }
29
65
  for (const rule of MARKER_RULES) {
30
66
  const content = skillContentsByCommand[rule.skill] ?? '';
31
- const ok = rule.includes.every((needle) => content.includes(needle));
67
+ const ok = rule.includes.every((needle) => containsIndependentPhrase(content, needle));
32
68
  if (ok) {
33
69
  capabilityIds.add(rule.id);
34
70
  }
@@ -2,6 +2,7 @@ export const COMMAND_CATALOG = [
2
2
  { id: 'explore', description: 'Think-before-propose exploration when requirements are fuzzy' },
3
3
  { id: 'propose', description: 'Create proposal and spec artifacts for a change' },
4
4
  { id: 'refine', description: 'Refine and iterate on spec artifacts' },
5
+ { id: 'approval', description: 'Post-refine technical approval document with AI closed-loop check' },
5
6
  { id: 'apply', description: 'Implement tasks from a change spec' },
6
7
  { id: 'review', description: 'Review code changes against spec' },
7
8
  { id: 'test', description: 'Run tests and verify coverage' },
@@ -13,6 +13,11 @@ export const CAPABILITY_MANIFEST = [
13
13
  { id: 'sub.propose.first_iteration', commandId: 'propose', level: 'sub-capability', required: true },
14
14
  { id: 'sub.refine.multi_round', commandId: 'refine', level: 'sub-capability', required: true },
15
15
  { id: 'sub.refine.challenge_scope', commandId: 'refine', level: 'sub-capability', required: true },
16
+ { id: 'sub.approval.closed_loop', commandId: 'approval', level: 'sub-capability', required: true },
17
+ { id: 'sub.approval.implementability', commandId: 'approval', level: 'sub-capability', required: true },
18
+ { id: 'sub.approval.no_phase_change', commandId: 'approval', level: 'sub-capability', required: true },
19
+ { id: 'sub.approval.code_grounding', commandId: 'approval', level: 'sub-capability', required: true },
20
+ { id: 'sub.approval.design_quality', commandId: 'approval', level: 'sub-capability', required: true },
16
21
  { id: 'sub.apply.phase_a', commandId: 'apply', level: 'sub-capability', required: true },
17
22
  { id: 'sub.apply.phase_b', commandId: 'apply', level: 'sub-capability', required: true },
18
23
  { id: 'sub.apply.gap_detection', commandId: 'apply', level: 'sub-capability', required: true },
@@ -25,6 +30,7 @@ export const CAPABILITY_MANIFEST = [
25
30
  { id: 'failure.explore.proposal_exists_redirect', commandId: 'explore', level: 'failure-path', required: true },
26
31
  { id: 'failure.propose.explore_draft_gate', commandId: 'propose', level: 'failure-path', required: true },
27
32
  { id: 'failure.apply.phase_gate', commandId: 'apply', level: 'failure-path', required: true },
33
+ { id: 'failure.approval.phase_gate', commandId: 'approval', level: 'failure-path', required: true },
28
34
  { id: 'failure.verify.explicit_skip_marker', commandId: 'verify', level: 'failure-path', required: true },
29
35
  ];
30
36
  export const IDE_ASSET_MANIFEST = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gordon.gan/specflow",
3
- "version": "1.3.3-beta",
3
+ "version": "1.4.1",
4
4
  "type": "module",
5
5
  "description": "SpecFlow — unified spec-driven development: OpenSpec planning + Superpowers execution in one CLI and cross-IDE workflow",
6
6
  "keywords": [
@@ -0,0 +1,79 @@
1
+ # Approval · Database Guidance Router
2
+
3
+ > Used by `/specflow:approval` when generating §4.4 (数据结构 / 数据模型).
4
+ > **本地技能**: `skills/database/`(本仓库长期维护)。
5
+ > **禁止**依赖远程 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
+
8
+ ---
9
+
10
+ ## 1. Detect project database stack
11
+
12
+ Scan the **project under review** (change's repo root), not SpecFlow itself. Collect signals
13
+ (non-recursive first; optional one-level into `docker-compose*.yml` / `migrations/`).
14
+
15
+ | Signal | Suggested stack |
16
+ |--------|-----------------|
17
+ | `go.mod` / deps: `go-sql-driver/mysql`, `gorm.io` + mysql DSN, `ENGINE=InnoDB` in `*.sql` | `mysql` |
18
+ | `package.json`: `mysql2`, `mysql`, `@prisma/client` + datasource mysql, drizzle mysql | `mysql` |
19
+ | `pyproject` / requirements: `PyMySQL`, `mysqlclient`, `aiomysql` | `mysql` |
20
+ | `go.mod`: `jackc/pgx`, `lib/pq`; `package.json`: `pg`, `postgres`; Prisma/drizzle postgres | `postgresql` |
21
+ | `docker-compose`: image `postgres` / `mysql` / `mariadb` / `redis` / `elasticsearch` | matching image |
22
+ | SQL files with `ENGINE=InnoDB` / `CHARSET=utf8mb4` | `mysql` |
23
+ | SQL with `JSONB`, `SERIAL`, `gen_random_uuid()` | `postgresql` |
24
+ | Oracle JDBC / `oracledb` / `go-ora` | `oracle` |
25
+ | `ioredis` / `redis` client / `go-redis` | `redis` (cache/KV — usually **not** §4.4 relational DDL) |
26
+ | `@elastic/elasticsearch` / OpenSearch client | `elasticsearch` (search — usually not relational DDL) |
27
+
28
+ **Multi-hit**: pick primary OLTP store for §4.4 (prefer `mysql` / `postgresql` / `oracle` over
29
+ `redis` / `elasticsearch`). Mention secondary stores in §4.7/架构 if relevant.
30
+
31
+ **Announce** after detection:
32
+
33
+ ```text
34
+ DB stack for approval: <mysql|postgresql|oracle|redis|elasticsearch|none>
35
+ Guidance: skills/database/<stack>/SKILL.md | LLM-fallback
36
+ ```
37
+
38
+ ---
39
+
40
+ ## 2. On hit — load **local** guidance (Read, do not invent, do not fetch)
41
+
42
+ Base: `skills/database/<stack>/`(相对 SpecFlow 仓库根;离线可读)
43
+
44
+ | Stack | Must Read | Also Read when §4.4 needs it |
45
+ |-------|-----------|------------------------------|
46
+ | `mysql` | `SKILL.md` | `references/05-sql-ddl-types.md`, `references/06-index-optimization.md`; JSON → `references/04-functions-json.md` |
47
+ | `postgresql` | `SKILL.md` | `references/06-index-types.md`; JSONB → `references/04-functions-jsonb.md` |
48
+ | `oracle` | `SKILL.md` | `references/09-sql-syntax.md`, `references/10-features.md` |
49
+ | `redis` | `SKILL.md` | Only if change is cache/key design — **not** a substitute for relational DDL |
50
+ | `elasticsearch` | `SKILL.md` | Only if change is index/mapping — **not** a substitute for relational DDL |
51
+
52
+ Apply guidance to §4.4 output:
53
+
54
+ 1. Prefer engine/charset/collation idioms from the local skill (MySQL: InnoDB + utf8mb4…).
55
+ 2. Prefer type/index gotchas from the skill (e.g. DECIMAL for money, no FLOAT amounts).
56
+ 3. Keep SpecFlow hard rules (ER, full CREATE TABLE, 本迭代用法, G3/G4) — skill **supplements**, does not replace.
57
+
58
+ Cite in §4.4 总则, e.g. `DB 技能: skills/database/mysql (本地)`.
59
+
60
+ ---
61
+
62
+ ## 3. On miss — LLM fallback
63
+
64
+ If `DB stack = none` (no durable store signals, or only unknown/custom DB):
65
+
66
+ 1. **Do not** force-load mysql/postgresql skills.
67
+ 2. Generate §4.4 with SpecFlow rules only (`generate.md` §4.4 + Quality Gates G3/G4).
68
+ 3. If design/tasks claim a DB but signals are absent → `WARNING` in §8:
69
+ `design 声称落库但未检测到 DB 栈信号 — 已用 LLM 通用 DDL;建议 refine 标明引擎`.
70
+ 4. Pure CLI/config changes → keep `不涉及数据库变更(...)`.
71
+
72
+ ---
73
+
74
+ ## 4. Why not remote skills / MCP tools?
75
+
76
+ - **Remote**: approval must work offline and must not drift with upstream installs; maintain
77
+ `skills/database/` in this repo.
78
+ - **MCP tools**: these packs are markdown guidance, not APIs; routing chooses which local
79
+ files to `Read`.