@xulthekl/team-flow 0.33.0 → 0.34.0

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 (34) hide show
  1. package/.claude/always/phase-guard.md +1 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/.cursor-plugin/marketplace.json +1 -1
  6. package/.cursor-plugin/plugin.json +1 -1
  7. package/.github/plugin/marketplace.json +2 -2
  8. package/AGENTS.md +2 -0
  9. package/CHANGELOG.md +35 -0
  10. package/CONTRIBUTING.md +44 -0
  11. package/GEMINI.md +1 -1
  12. package/INSTALL.md +1 -1
  13. package/README.md +1 -1
  14. package/docs/README_en.md +1 -1
  15. package/docs/solutions/INDEX.md +1 -0
  16. package/docs/solutions/cross-phase/2026-08-04-no-summary.md +17 -0
  17. package/gemini-extension.json +1 -1
  18. package/hooks/session-start +2 -2
  19. package/llms.txt +1 -1
  20. package/package.json +1 -1
  21. package/plugin.json +1 -1
  22. package/scripts/lib/conventions-generator.mjs +350 -0
  23. package/scripts/lib/test-record.mjs +65 -2
  24. package/skills/test-strategy/SKILL.md +37 -0
  25. package/skills/test-strategy/references/integration-test-contracts.md +237 -0
  26. package/skills/test-strategy/references/integration-test-isolation.md +346 -0
  27. package/skills/test-strategy/references/test-quality-rules.md +292 -0
  28. package/skills/workflow-bootstrap/SKILL.md +40 -3
  29. package/templates/agent-template.md +41 -0
  30. package/templates/conventions/_manifest.json +39 -0
  31. package/templates/conventions/glaf4-compliant/java-testing.md +367 -0
  32. package/templates/conventions/glaf4-compliant/spring-patterns.md +415 -0
  33. package/templates/conventions/js-testing.md +261 -0
  34. package/templates/conventions/python-testing.md +333 -0
@@ -1,3 +1,3 @@
1
- # team-flow v0.33.0 | 阶段: {{state}} | 工作流: {{workflow}}
1
+ # team-flow v0.34.0 | 阶段: {{state}} | 工作流: {{workflow}}
2
2
  当前阶段允许的操作由 workflow-start 路由规则定义。
3
3
  禁止跨越 DP gate 进入下一阶段。变更范围以 execution-contract.md 的 Intent Lock 为准。
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "team-flow",
11
11
  "description": "8-state spec workflow + compound global compounding + architecture-design (4A/DDD) + local HTML prototype + product-level orchestration + bootstrap + e2e + session handoff + workflow feedback. 24 skills + 15 agents with embedded TDD, SDD, code review, debugging, delta spec sync, and design-system-driven prototyping.",
12
- "version": "0.33.0",
12
+ "version": "0.34.0",
13
13
  "source": "./",
14
14
  "author": {
15
15
  "name": "LT",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "team-flow",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking). 24 skills + 15 agents, one install.",
5
5
  "source": "./",
6
6
  "author": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "team-flow",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "Spec-first workflow that bridges OpenSpec-style planning and Superpowers-style execution discipline.",
5
5
  "author": {
6
6
  "name": "MageByte",
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Unified workflow plugin marketplace for Cursor (team-flow: team-flow + compound + architecture-design + prototype).",
8
- "version": "0.33.0"
8
+ "version": "0.34.0"
9
9
  },
10
10
  "plugins": [
11
11
  {
@@ -2,7 +2,7 @@
2
2
  "name": "team-flow",
3
3
  "displayName": "team-flow",
4
4
  "description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking). 24 skills + 15 agents, one install.",
5
- "version": "0.33.0",
5
+ "version": "0.34.0",
6
6
  "author": {
7
7
  "name": "LT",
8
8
  "url": "https://github.com/LT"
@@ -6,13 +6,13 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Unified workflow plugins and skills for AI coding agents (team-flow: team-flow + compound + architecture-design + prototype).",
9
- "version": "0.33.0"
9
+ "version": "0.34.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "team-flow",
14
14
  "description": "Unified workflow with planning artifacts, execution contracts, TDD, review gates, systematic debugging, delta spec sync, architecture-design, and local HTML prototyping.",
15
- "version": "0.33.0",
15
+ "version": "0.34.0",
16
16
  "source": ".",
17
17
  "author": {
18
18
  "name": "LT",
package/AGENTS.md CHANGED
@@ -210,6 +210,8 @@ STRATEGY.md CONCEPTS.md 产品策略(BA) / 领域词汇
210
210
 
211
211
  ### Agents 索引(v0.7 新增,v0.30.0 增至 15 个)
212
212
 
213
+ > **agent 文件设计规范见 CONTRIBUTING.md §6 + `templates/agent-template.md`**(v0.33.0):frontmatter 必须合法 YAML(非法时 Claude Code 静默降级,skills: 预加载与 tools: 限制全部失效);description 单句、禁 `<example>` 块;新增/修改 agent 必过 frontmatter-lint + 实证探针。
214
+
213
215
  | Agent | 职责 | Tools | 触发场景 |
214
216
  |-------|------|-------|---------|
215
217
  | architecture-design | 架构设计门控 agent——五项检查 + 三件套产出 + SQL 制品(workflow-start 子代理调用,判断+执行一体化) | Read/Bash/Grep/Glob/Write | workflow-start exploring→specifying 状态转换时(架构设计门控,v0.27.2) |
package/CHANGELOG.md CHANGED
@@ -6,6 +6,41 @@ The format loosely follows Keep a Changelog.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.34.0] - 2026-08-04
10
+
11
+ ### Added(测试能力增强——吸收 glaf4-test 通用能力 + conventions 机制,设计见工作区级文档 team-flow-workspace/docs/plan/test-capability-enhancement-design.md)
12
+
13
+ #### P0:组合覆盖声明(test-strategy SKILL.md)
14
+ - **§8 组合覆盖声明**:多参数方法(param_count > 1)必须声明 `pairwise`,有分支逻辑必须声明 `branch`;contract-builder 生成矩阵后强制对账
15
+
16
+ #### P1:测试质量规则 + failure 分类法
17
+ - **skills/test-strategy/references/test-quality-rules.md**:从 glaf4-test scan-generated-tests.py 抽取 16 条通用规则(断言质量、调试代码残留、测试状态、测试数据、测试结构、矩阵对账、语言特定)
18
+ - **scripts/lib/test-record.mjs**:新增 `classifyFailure` 函数,测试失败时自动分类为 6 类(assertion_failure / runtime_error / framework_error / compile_error / dependency_blocker / unknown),记录到 test_result
19
+
20
+ #### P2:社交测试契约 + 测试隔离分级
21
+ - **skills/test-strategy/references/integration-test-contracts.md**:5 种契约类型(入口/协作者/数据/中间件/清理),集成测试的组织方法论
22
+ - **skills/test-strategy/references/integration-test-isolation.md**:4 级隔离策略(L1 进程内 / L2 事务 / L3 手动清理 / L4 无隔离),基础设施隔离策略
23
+
24
+ #### P2:conventions 机制建设(v0.34.0 核心特性)
25
+ - **templates/conventions/**:plugin 内置 conventions 模板
26
+ - `glaf4-compliant/java-testing.md`:Java 测试规范(JUnit 5 + Mockito),符合 glaf4-test 要求
27
+ - `glaf4-compliant/spring-patterns.md`:Spring Boot 测试规范,符合 glaf4-test 要求
28
+ - `js-testing.md`:JavaScript 测试规范(Jest/Vitest)
29
+ - `python-testing.md`:Python 测试规范(Pytest)
30
+ - `_manifest.json`:模板清单(版本、描述、适用技术栈)
31
+ - **scripts/lib/conventions-generator.mjs**:conventions 生成器脚本
32
+ - 技术栈自动检测(Java/JavaScript/Python)
33
+ - conventions 模板选择和生成
34
+ - 版本管理机制(.versions.json)
35
+ - team-flow.config.json 自动更新
36
+ - 支持存量项目(自动识别)和全新项目(交互式引导)
37
+ - **skills/workflow-bootstrap/SKILL.md**:增加 B1.5 阶段(Conventions Generator)
38
+
39
+ ### Tests
40
+ - **tests/lib/conventions-generator.test.mjs**:15 个测试(detectTechStack/selectTemplates/generateConventions/updateConfig)
41
+ - 全量回归:571/571 通过(含 15 个新增测试)
42
+ - check-versions ✅
43
+
9
44
  ## [0.33.0] - 2026-08-03
10
45
 
11
46
  ### Fixed(skills 注入恢复——frontmatter YAML 非法导致预加载静默失效,设计见工作区级文档 team-flow-workspace/docs/architecture-api-db-design-enhancement-v0.13.md §54)
package/CONTRIBUTING.md CHANGED
@@ -86,6 +86,50 @@ Skill text should help an agent decide:
86
86
 
87
87
  Avoid vague motivational language when an operational rule would be clearer.
88
88
 
89
+ ### 6. Agent file design spec (v0.33.0+)
90
+
91
+ Background: before v0.33.0, every agent's YAML frontmatter was invalid (an
92
+ `<example>` block at column 0 inside the `description` field). Claude Code
93
+ degrades SILENTLY on invalid frontmatter — `skills:` preload and `tools:`
94
+ restrictions are dropped with no warning, and the agent body alone is kept.
95
+ The defect survived the entire plugin lifetime. `tests/lib/frontmatter-lint.test.mjs`
96
+ (npm test) is the machine gate; this spec is the human gate.
97
+
98
+ Copy `templates/agent-template.md` when creating a new agent. Hard rules:
99
+
100
+ 1. **`description` is a single-line string.** No `>-` block scalars, no
101
+ `<example>` blocks — the official Anthropic plugin-dev agents use that
102
+ pattern and it is a trap (it breaks YAML indentation and silently disables
103
+ the whole frontmatter). If the text must contain an ASCII `: `, wrap the
104
+ entire value in double quotes. team-flow agents are dispatched explicitly
105
+ by `workflow-start`, so example-driven auto-triggering buys nothing.
106
+ 2. **`name` must equal the file name** (minus `.md`). On degraded parsing the
107
+ registry falls back to the file name — a mismatch means silent mislabeling.
108
+ 3. **Declare `tools` explicitly.** Since v0.33.0 the restriction is enforced;
109
+ the subagent holds ONLY the declared tools (no MCP tools unless listed).
110
+ 4. **`skills` entries must resolve.** Each entry must match an existing
111
+ `skills/<name>/SKILL.md` (bare name, same as glaf4-test's proven pattern).
112
+ A dangling entry means a silent no-preload.
113
+ 5. **Body ≤ 100 lines, WHO/WHAT only.** No SOP/methodology in the body — that
114
+ belongs to the preloaded Skill. If the body says "Your preloaded Skill
115
+ contains the detailed methodology", the `skills:` field MUST declare it.
116
+
117
+ Anti-patterns (forbidden):
118
+
119
+ - `<example>` blocks anywhere in frontmatter
120
+ - Unquoted ASCII `: ` inside `description` values
121
+ - Copying frontmatter style from other plugins without running the lint
122
+
123
+ Verification (mandatory for new/changed agents):
124
+
125
+ 1. `npm test` — the frontmatter-lint gate must pass.
126
+ 2. **Empirical probe** — dispatch the agent once and verify with a BEHAVIORAL
127
+ probe (ask it to recite a rule that exists only in the preloaded Skill or
128
+ the agent body). Do NOT rely on exact-string introspection questions — they
129
+ produce false negatives. Do not write "mechanism works" claims into any doc
130
+ without this probe. See design doc §54.6 (workspace-level
131
+ `docs/architecture-api-db-design-enhancement-v0.13.md`).
132
+
89
133
  ## Pull Request Guidance
90
134
 
91
135
  When opening a change, explain:
package/GEMINI.md CHANGED
@@ -8,7 +8,7 @@ The workflow is self-contained and does not require OpenSpec or Superpowers at r
8
8
 
9
9
 
10
10
  <!-- team-flow-phase-guard-start -->
11
- # team-flow v0.33.0 | 阶段: {{state}} | 工作流: {{workflow}}
11
+ # team-flow v0.34.0 | 阶段: {{state}} | 工作流: {{workflow}}
12
12
  当前阶段允许的操作由 workflow-start 路由规则定义。
13
13
  禁止跨越 DP gate 进入下一阶段。变更范围以 execution-contract.md 的 Intent Lock 为准。
14
14
  <!-- team-flow-phase-guard-end -->
package/INSTALL.md CHANGED
@@ -7,7 +7,7 @@
7
7
  - [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec) — 规划引擎(Schema 验证、Delta Spec、工件解析)
8
8
  - [obra/superpowers](https://github.com/obra/superpowers) — 执行纪律(TDD 铁律、SDD、系统化调试、代码审查)
9
9
 
10
- 当前发布版本:**v0.33.0**。
10
+ 当前发布版本:**v0.34.0**。
11
11
 
12
12
  ---
13
13
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # team-flow
2
2
 
3
- > 当前版本:`v0.33.0`
3
+ > 当前版本:`v0.34.0`
4
4
 
5
5
  > 统一插件:**team-flow**(spec 驱动开发)+ **compound-engineering 核心子集**(全局复利)+ **architecture-design**(4A+DDD 增量设计)+ **prototype**(本地 HTML 原型)+ **e2e**(AC 驱动 E2E)+ **workflow-orchestrator**(产品级编排)+ **workflow-bootstrap**(既有项目接入)。一次安装,七套能力协同。
6
6
 
package/docs/README_en.md CHANGED
@@ -126,7 +126,7 @@ npm install -g team-flow
126
126
 
127
127
  ### Version
128
128
 
129
- - Current: `v0.33.0`
129
+ - Current: `v0.34.0`
130
130
  - v0.9.1 highlights: DP-4 execution-mode recommendations, a portable runtime across 17 platforms, and a raw-package smoke with no plugin-root variable.
131
131
  - Self-contained — no OpenSpec or Superpowers runtime required
132
132
  - Upstream: [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec), [obra/superpowers](https://github.com/obra/superpowers)
@@ -2,6 +2,7 @@
2
2
  <!-- 每条一行,按 severity 降序,≤150 行硬上限 -->
3
3
  | date | phase | domain | type | severity | summary | file |
4
4
  |------|-------|--------|------|----------|---------|------|
5
+ | 2026-08-04 | cross-phase | general | insight | medium | (no summary) | cross-phase/2026-08-04-no-summary.md |
5
6
  | 2026-08-03 | cross-phase | general | insight | medium | (no summary) | cross-phase/2026-08-03-no-summary.md |
6
7
  | 2026-08-01 | cross-phase | general | insight | medium | (no summary) | cross-phase/2026-08-01-no-summary.md |
7
8
  | 2026-07-31 | cross-phase | general | insight | medium | (no summary) | cross-phase/2026-07-31-no-summary.md |
@@ -0,0 +1,17 @@
1
+ ---
2
+ phase: cross-phase
3
+ domain: general
4
+ type: insight
5
+ severity: medium
6
+ date: 2026-08-04
7
+ source:
8
+ ---
9
+
10
+ ## 问题描述
11
+ (no summary)
12
+
13
+ ## 根因/模式
14
+ (待补充)
15
+
16
+ ## 预防措施/应用方式
17
+ (待补充)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "team-flow",
3
3
  "description": "Unified workflow plugin: team-flow (spec-driven dev) + compound-engineering core subset + architecture-design (4A/DDD) + prototype (local HTML). 24 skills, one install.",
4
- "version": "0.33.0",
4
+ "version": "0.34.0",
5
5
  "contextFileName": "GEMINI.md"
6
6
  }
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env bash
2
- # v0.33.0: auto-sync CLI version with plugin version
2
+ # v0.34.0: auto-sync CLI version with plugin version
3
3
  set -e
4
4
 
5
5
  # ═══════════════════════════════════════════════════════════════
6
6
  # Plugin version (update this when releasing new versions)
7
7
  # ═══════════════════════════════════════════════════════════════
8
- PLUGIN_VERSION="0.33.0"
8
+ PLUGIN_VERSION="0.34.0"
9
9
 
10
10
  # ═══════════════════════════════════════════════════════════════
11
11
  # Step 1: Auto-sync CLI version with plugin version
package/llms.txt CHANGED
@@ -3,7 +3,7 @@
3
3
  ## Overview
4
4
  spec-superflow is a self-contained workflow integration plugin for Claude Code, Cursor, OpenAI Codex CLI/App, GitHub Copilot CLI, Gemini CLI, OpenCode, WorkBuddy, and Trae. It merges spec-driven planning artifacts (proposal, specs, design, tasks) with disciplined execution guardrails (TDD, review gates, controlled handoff) into one unified workflow.
5
5
 
6
- Current version: v0.33.0.
6
+ Current version: v0.34.0.
7
7
 
8
8
  ## Key Documents
9
9
  - README.md: Chinese homepage with full usage guide and FAQ
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xulthekl/team-flow",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "Unified plugin (24 skills + 15 agents) integrating team-flow, compound-engineering, architecture-design, prototype, design-system, workflow-orchestrator, workflow-bootstrap, e2e, session-handoff, workflow-feedback for multi-agent coding tools.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "team-flow",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking). 24 skills + 15 agents, one install.",
5
5
  "author": {
6
6
  "name": "LT"
@@ -0,0 +1,350 @@
1
+ #!/usr/bin/env node
2
+ // scripts/lib/conventions-generator.mjs — conventions 生成器(v0.34.0 新增)
3
+ //
4
+ // 根据项目技术栈自动生成测试规范 conventions,符合 glaf4-test 要求。
5
+ // 支持存量项目(自动识别)和全新项目(交互式引导)。
6
+ //
7
+ // 使用方式:
8
+ // node scripts/lib/conventions-generator.mjs --root <项目根目录> [--interactive]
9
+ //
10
+ // 设计来源:test-capability-enhancement-design v1.0 §四
11
+
12
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
13
+ import path, { join } from 'node:path';
14
+ import { parseArgs } from 'node:util';
15
+
16
+ // ── 常量 ─────────────────────────────────────────────────────────────────────
17
+
18
+ const TEMPLATE_DIR = join(import.meta.dirname, '../../templates/conventions');
19
+ const GLAF4_TEMPLATE_DIR = join(TEMPLATE_DIR, 'glaf4-compliant');
20
+
21
+ // 技术栈检测特征
22
+ const TECH_STACK_SIGNATURES = {
23
+ java: ['pom.xml', 'build.gradle', 'build.gradle.kts'],
24
+ javascript: ['package.json', 'yarn.lock', 'pnpm-lock.yaml'],
25
+ python: ['requirements.txt', 'pyproject.toml', 'setup.py', 'Pipfile'],
26
+ };
27
+
28
+ // 测试框架检测特征
29
+ const TEST_FRAMEWORK_SIGNATURES = {
30
+ 'junit5-mockito': { file: 'pom.xml', content: /junit-jupiter|org\.junit\.jupiter/ },
31
+ jest: { file: 'package.json', content: /"jest"|"@jest\/|vitest/ },
32
+ pytest: { file: 'requirements.txt', content: /pytest/ },
33
+ };
34
+
35
+ // 应用框架检测特征
36
+ const APP_FRAMEWORK_SIGNATURES = {
37
+ 'spring-boot': { file: 'pom.xml', content: /spring-boot|org\.springframework\.boot/ },
38
+ express: { file: 'package.json', content: /"express"/ },
39
+ django: { file: 'requirements.txt', content: /django/ },
40
+ };
41
+
42
+ // ── 技术栈检测 ─────────────────────────────────────────────────────────────
43
+
44
+ /**
45
+ * 检测项目技术栈
46
+ * @param {string} root 项目根目录
47
+ * @returns {{ language: string|null, buildTool: string|null, testFramework: string|null, appFramework: string|null }}
48
+ */
49
+ export function detectTechStack(root) {
50
+ const result = {
51
+ language: null,
52
+ buildTool: null,
53
+ testFramework: null,
54
+ appFramework: null,
55
+ };
56
+
57
+ // 检测语言
58
+ for (const [lang, files] of Object.entries(TECH_STACK_SIGNATURES)) {
59
+ if (files.some(f => existsSync(join(root, f)))) {
60
+ result.language = lang;
61
+ break;
62
+ }
63
+ }
64
+
65
+ // 检测构建工具
66
+ if (existsSync(join(root, 'pom.xml'))) result.buildTool = 'maven';
67
+ else if (existsSync(join(root, 'build.gradle')) || existsSync(join(root, 'build.gradle.kts'))) result.buildTool = 'gradle';
68
+ else if (existsSync(join(root, 'package.json'))) result.buildTool = 'npm';
69
+ else if (existsSync(join(root, 'yarn.lock'))) result.buildTool = 'yarn';
70
+ else if (existsSync(join(root, 'pnpm-lock.yaml'))) result.buildTool = 'pnpm';
71
+ else if (existsSync(join(root, 'requirements.txt')) || existsSync(join(root, 'pyproject.toml'))) result.buildTool = 'pip';
72
+ else if (existsSync(join(root, 'Pipfile'))) result.buildTool = 'pipenv';
73
+
74
+ // 检测测试框架
75
+ for (const [fw, sig] of Object.entries(TEST_FRAMEWORK_SIGNATURES)) {
76
+ const filePath = join(root, sig.file);
77
+ if (existsSync(filePath)) {
78
+ const content = readFileSync(filePath, 'utf-8');
79
+ if (sig.content.test(content)) {
80
+ result.testFramework = fw;
81
+ break;
82
+ }
83
+ }
84
+ }
85
+
86
+ // 检测应用框架
87
+ for (const [fw, sig] of Object.entries(APP_FRAMEWORK_SIGNATURES)) {
88
+ const filePath = join(root, sig.file);
89
+ if (existsSync(filePath)) {
90
+ const content = readFileSync(filePath, 'utf-8');
91
+ if (sig.content.test(content)) {
92
+ result.appFramework = fw;
93
+ break;
94
+ }
95
+ }
96
+ }
97
+
98
+ return result;
99
+ }
100
+
101
+ // ── 模板选择 ─────────────────────────────────────────────────────────────
102
+
103
+ /**
104
+ * 根据技术栈选择 conventions 模板
105
+ * @param {{ language: string|null, buildTool: string|null, testFramework: string|null, appFramework: string|null }} techStack
106
+ * @returns {string[]} 模板文件名列表
107
+ */
108
+ export function selectTemplates(techStack) {
109
+ const templates = [];
110
+
111
+ if (techStack.language === 'java') {
112
+ // Java 项目:使用 glaf4-compliant 模板
113
+ if (existsSync(join(GLAF4_TEMPLATE_DIR, 'java-testing.md'))) {
114
+ templates.push('glaf4-compliant/java-testing.md');
115
+ }
116
+ if (techStack.appFramework === 'spring-boot') {
117
+ if (existsSync(join(GLAF4_TEMPLATE_DIR, 'spring-patterns.md'))) {
118
+ templates.push('glaf4-compliant/spring-patterns.md');
119
+ }
120
+ }
121
+ } else if (techStack.language === 'javascript') {
122
+ templates.push('js-testing.md');
123
+ } else if (techStack.language === 'python') {
124
+ templates.push('python-testing.md');
125
+ }
126
+
127
+ return templates;
128
+ }
129
+
130
+ // ── conventions 生成 ─────────────────────────────────────────────────────
131
+
132
+ /**
133
+ * 生成 conventions 文件
134
+ * @param {string} root 项目根目录
135
+ * @param {{ language: string|null, buildTool: string|null, testFramework: string|null, appFramework: string|null }} techStack
136
+ * @param {string[]} templates 模板文件名列表
137
+ * @returns {{ created: string[], skipped: string[] }}
138
+ */
139
+ export function generateConventions(root, techStack, templates) {
140
+ const conventionsDir = join(root, '.team-flow', 'conventions');
141
+ const versionsFile = join(conventionsDir, '.versions.json');
142
+
143
+ // 创建目录
144
+ mkdirSync(conventionsDir, { recursive: true });
145
+
146
+ // 读取现有版本信息
147
+ let versions = {};
148
+ if (existsSync(versionsFile)) {
149
+ try {
150
+ versions = JSON.parse(readFileSync(versionsFile, 'utf-8'));
151
+ } catch {
152
+ versions = {};
153
+ }
154
+ }
155
+ if (!versions.conventions) versions.conventions = {};
156
+
157
+ const created = [];
158
+ const skipped = [];
159
+
160
+ for (const template of templates) {
161
+ const templatePath = join(TEMPLATE_DIR, template);
162
+ const fileName = path.basename(template);
163
+ const targetPath = join(conventionsDir, fileName);
164
+
165
+ // 检查是否已存在且未自定义
166
+ if (existsSync(targetPath)) {
167
+ const existingVersion = versions.conventions[fileName];
168
+ if (existingVersion && !existingVersion.customized) {
169
+ // 读取模板版本
170
+ const templateContent = readFileSync(templatePath, 'utf-8');
171
+ const versionMatch = templateContent.match(/version:\s*(\d+\.\d+\.\d+)/);
172
+ const templateVersion = versionMatch ? versionMatch[1] : '1.0.0';
173
+
174
+ if (existingVersion.source_version === templateVersion) {
175
+ skipped.push(fileName);
176
+ continue;
177
+ }
178
+ }
179
+ }
180
+
181
+ // 复制模板
182
+ const templateContent = readFileSync(templatePath, 'utf-8');
183
+ writeFileSync(targetPath, templateContent, 'utf-8');
184
+
185
+ // 更新版本信息
186
+ const versionMatch = templateContent.match(/version:\s*(\d+\.\d+\.\d+)/);
187
+ const templateVersion = versionMatch ? versionMatch[1] : '1.0.0';
188
+
189
+ versions.conventions[fileName] = {
190
+ source_version: templateVersion,
191
+ installed_at: new Date().toISOString().split('T')[0],
192
+ customized: false,
193
+ last_checked: new Date().toISOString().split('T')[0],
194
+ source: template,
195
+ };
196
+
197
+ created.push(fileName);
198
+ }
199
+
200
+ // 写入版本信息
201
+ writeFileSync(versionsFile, JSON.stringify(versions, null, 2), 'utf-8');
202
+
203
+ return { created, skipped };
204
+ }
205
+
206
+ // ── 更新 team-flow.config.json ─────────────────────────────────────────
207
+
208
+ /**
209
+ * 更新 team-flow.config.json 的 conventions 字段
210
+ * @param {string} root 项目根目录
211
+ * @param {string[]} conventionsFiles conventions 文件名列表
212
+ */
213
+ export function updateConfig(root, conventionsFiles) {
214
+ const teamFlowDir = join(root, '.team-flow');
215
+ const configPath = join(teamFlowDir, 'team-flow.config.json');
216
+
217
+ // 确保目录存在
218
+ mkdirSync(teamFlowDir, { recursive: true });
219
+
220
+ let config = {};
221
+ if (existsSync(configPath)) {
222
+ try {
223
+ config = JSON.parse(readFileSync(configPath, 'utf-8'));
224
+ } catch {
225
+ config = {};
226
+ }
227
+ }
228
+
229
+ if (!config.conventions) config.conventions = {};
230
+
231
+ for (const file of conventionsFiles) {
232
+ const key = file.replace(/\.md$/, '').replace(/\//g, '-');
233
+ config.conventions[key] = `.team-flow/conventions/${file}`;
234
+ }
235
+
236
+ writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
237
+ }
238
+
239
+ // ── 交互式引导 ─────────────────────────────────────────────────────────────
240
+
241
+ /**
242
+ * 交互式引导用户选择技术栈(全新项目)
243
+ * @returns {Promise<{ language: string, buildTool: string, testFramework: string, appFramework: string }>}
244
+ */
245
+ export async function interactiveSetup() {
246
+ // 注意:在实际使用中,这里需要使用 readline 或 inquirer 等库
247
+ // 这里提供默认值,实际实现需要集成到 workflow-bootstrap 的交互流程中
248
+ console.log('\n=== 全新项目技术栈配置 ===\n');
249
+ console.log('由于当前为脚本模式,使用默认配置:');
250
+ console.log(' - 编程语言:Java');
251
+ console.log(' - 构建工具:Maven');
252
+ console.log(' - 测试框架:JUnit 5 + Mockito');
253
+ console.log(' - 应用框架:Spring Boot');
254
+ console.log('\n如需自定义配置,请在 workflow-bootstrap 中使用交互式模式。\n');
255
+
256
+ return {
257
+ language: 'java',
258
+ buildTool: 'maven',
259
+ testFramework: 'junit5-mockito',
260
+ appFramework: 'spring-boot',
261
+ };
262
+ }
263
+
264
+ // ── CLI ─────────────────────────────────────────────────────────────────────
265
+
266
+ export async function run(args) {
267
+ const { positionals, values } = parseArgs({
268
+ args,
269
+ options: {
270
+ root: { type: 'string', default: '.' },
271
+ interactive: { type: 'boolean', default: false },
272
+ json: { type: 'boolean', default: false },
273
+ },
274
+ allowPositionals: true,
275
+ });
276
+
277
+ const root = path.resolve(values.root);
278
+
279
+ // 检查项目根目录
280
+ if (!existsSync(root)) {
281
+ console.error(`项目根目录不存在: ${root}`);
282
+ process.exit(1);
283
+ }
284
+
285
+ // 检查 conventions 是否已存在
286
+ const conventionsDir = join(root, '.team-flow', 'conventions');
287
+ if (existsSync(conventionsDir) && readdirSync(conventionsDir).length > 0) {
288
+ console.log('⚠️ conventions 已存在,跳过生成');
289
+ console.log(` 路径: ${conventionsDir}`);
290
+ process.exit(0);
291
+ }
292
+
293
+ // 检测技术栈
294
+ let techStack = detectTechStack(root);
295
+
296
+ // 如果未检测到技术栈且启用交互式模式
297
+ if (!techStack.language && values.interactive) {
298
+ techStack = await interactiveSetup();
299
+ }
300
+
301
+ // 如果仍未检测到技术栈
302
+ if (!techStack.language) {
303
+ console.error('❌ 未检测到技术栈特征');
304
+ console.error(' 请指定项目根目录,或使用 --interactive 模式手动配置');
305
+ process.exit(1);
306
+ }
307
+
308
+ // 选择模板
309
+ const templates = selectTemplates(techStack);
310
+
311
+ if (templates.length === 0) {
312
+ console.error('❌ 未找到匹配的 conventions 模板');
313
+ console.error(` 技术栈: ${JSON.stringify(techStack)}`);
314
+ process.exit(1);
315
+ }
316
+
317
+ // 生成 conventions
318
+ const result = generateConventions(root, techStack, templates);
319
+
320
+ // 更新配置
321
+ updateConfig(root, result.created);
322
+
323
+ // 输出结果
324
+ if (values.json) {
325
+ console.log(JSON.stringify({
326
+ ok: true,
327
+ techStack,
328
+ templates,
329
+ created: result.created,
330
+ skipped: result.skipped,
331
+ conventionsDir,
332
+ }));
333
+ } else {
334
+ console.log('✅ conventions 生成完成');
335
+ console.log(` 技术栈: ${techStack.language} + ${techStack.testFramework}`);
336
+ console.log(` 创建: ${result.created.join(', ')}`);
337
+ if (result.skipped.length > 0) {
338
+ console.log(` 跳过: ${result.skipped.join(', ')}`);
339
+ }
340
+ console.log(` 路径: ${conventionsDir}`);
341
+ }
342
+ }
343
+
344
+ // 直接运行
345
+ if (import.meta.url === `file://${process.argv[1]}`) {
346
+ run(process.argv.slice(2)).catch(err => {
347
+ console.error(err);
348
+ process.exit(1);
349
+ });
350
+ }