speccore 8.3.312 → 8.3.332

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 (132) hide show
  1. package/dist/cli.js +4 -6
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/analyze.js +2 -2
  4. package/dist/commands/analyze.js.map +1 -1
  5. package/dist/commands/doc2spec.d.ts +12 -0
  6. package/dist/commands/doc2spec.d.ts.map +1 -1
  7. package/dist/commands/doc2spec.js +64 -17
  8. package/dist/commands/doc2spec.js.map +1 -1
  9. package/dist/commands/done.js +4 -1
  10. package/dist/commands/done.js.map +1 -1
  11. package/dist/commands/execute.d.ts.map +1 -1
  12. package/dist/commands/execute.js +37 -76
  13. package/dist/commands/execute.js.map +1 -1
  14. package/dist/commands/help.js +1 -0
  15. package/dist/commands/help.js.map +1 -1
  16. package/dist/commands/init.d.ts.map +1 -1
  17. package/dist/commands/init.js +299 -183
  18. package/dist/commands/init.js.map +1 -1
  19. package/dist/commands/iteration/create.js +9 -6
  20. package/dist/commands/iteration/create.js.map +1 -1
  21. package/dist/commands/iteration/taskify.d.ts +8 -0
  22. package/dist/commands/iteration/taskify.d.ts.map +1 -1
  23. package/dist/commands/iteration/taskify.js +56 -41
  24. package/dist/commands/iteration/taskify.js.map +1 -1
  25. package/dist/commands/review.js +2 -7
  26. package/dist/commands/review.js.map +1 -1
  27. package/dist/commands/run.js +11 -2
  28. package/dist/commands/run.js.map +1 -1
  29. package/dist/commands/spec2doc.d.ts +7 -0
  30. package/dist/commands/spec2doc.d.ts.map +1 -1
  31. package/dist/commands/spec2doc.js +32 -18
  32. package/dist/commands/spec2doc.js.map +1 -1
  33. package/dist/commands/task/new.d.ts +0 -9
  34. package/dist/commands/task/new.d.ts.map +1 -1
  35. package/dist/commands/task/new.js +6 -195
  36. package/dist/commands/task/new.js.map +1 -1
  37. package/dist/commands/unitize.d.ts +2 -0
  38. package/dist/commands/unitize.d.ts.map +1 -1
  39. package/dist/commands/unitize.js +79 -0
  40. package/dist/commands/unitize.js.map +1 -1
  41. package/dist/commands/update.d.ts.map +1 -1
  42. package/dist/commands/update.js +6 -0
  43. package/dist/commands/update.js.map +1 -1
  44. package/dist/core/agents/engine/agent-loader.d.ts +2 -0
  45. package/dist/core/agents/engine/agent-loader.d.ts.map +1 -1
  46. package/dist/core/agents/engine/agent-loader.js +8 -2
  47. package/dist/core/agents/engine/agent-loader.js.map +1 -1
  48. package/dist/core/analyze-engine.d.ts +11 -0
  49. package/dist/core/analyze-engine.d.ts.map +1 -1
  50. package/dist/core/analyze-engine.js +136 -112
  51. package/dist/core/analyze-engine.js.map +1 -1
  52. package/dist/core/ask-engine.d.ts.map +1 -1
  53. package/dist/core/ask-engine.js +22 -2
  54. package/dist/core/ask-engine.js.map +1 -1
  55. package/dist/core/asset-stamp.d.ts +40 -0
  56. package/dist/core/asset-stamp.d.ts.map +1 -0
  57. package/dist/core/asset-stamp.js +77 -0
  58. package/dist/core/asset-stamp.js.map +1 -0
  59. package/dist/core/change-detection.d.ts +1 -1
  60. package/dist/core/change-detection.d.ts.map +1 -1
  61. package/dist/core/change-detection.js +28 -1
  62. package/dist/core/change-detection.js.map +1 -1
  63. package/dist/core/code-graph/incremental-build.d.ts.map +1 -1
  64. package/dist/core/code-graph/incremental-build.js +2 -2
  65. package/dist/core/code-graph/incremental-build.js.map +1 -1
  66. package/dist/core/code-graph/index.d.ts.map +1 -1
  67. package/dist/core/code-graph/index.js +3 -2
  68. package/dist/core/code-graph/index.js.map +1 -1
  69. package/dist/core/code-graph/requirement-linker.js +2 -2
  70. package/dist/core/code-graph/requirement-linker.js.map +1 -1
  71. package/dist/core/code-scanner.d.ts +11 -0
  72. package/dist/core/code-scanner.d.ts.map +1 -1
  73. package/dist/core/code-scanner.js +103 -1
  74. package/dist/core/code-scanner.js.map +1 -1
  75. package/dist/core/constitution-builder.d.ts +24 -0
  76. package/dist/core/constitution-builder.d.ts.map +1 -1
  77. package/dist/core/constitution-builder.js +110 -88
  78. package/dist/core/constitution-builder.js.map +1 -1
  79. package/dist/core/doc-validator.d.ts.map +1 -1
  80. package/dist/core/doc-validator.js +14 -4
  81. package/dist/core/doc-validator.js.map +1 -1
  82. package/dist/core/git-integration.d.ts +14 -9
  83. package/dist/core/git-integration.d.ts.map +1 -1
  84. package/dist/core/git-integration.js +192 -93
  85. package/dist/core/git-integration.js.map +1 -1
  86. package/dist/core/global-knowledge.js +1 -1
  87. package/dist/core/global-knowledge.js.map +1 -1
  88. package/dist/core/intent-recognition.d.ts.map +1 -1
  89. package/dist/core/intent-recognition.js +40 -0
  90. package/dist/core/intent-recognition.js.map +1 -1
  91. package/dist/core/platform-registry.d.ts +2 -2
  92. package/dist/core/platform-registry.d.ts.map +1 -1
  93. package/dist/core/platform-registry.js +25 -2
  94. package/dist/core/platform-registry.js.map +1 -1
  95. package/dist/core/prompt-builder.js +1 -1
  96. package/dist/core/prompt-builder.js.map +1 -1
  97. package/dist/core/rag-engine.d.ts +25 -0
  98. package/dist/core/rag-engine.d.ts.map +1 -1
  99. package/dist/core/rag-engine.js +88 -3
  100. package/dist/core/rag-engine.js.map +1 -1
  101. package/dist/core/refresh-scheduler.js +39 -17
  102. package/dist/core/refresh-scheduler.js.map +1 -1
  103. package/dist/core/requirement-clarifier.js +1 -1
  104. package/dist/core/requirement-clarifier.js.map +1 -1
  105. package/dist/core/skeleton-residue.d.ts +25 -0
  106. package/dist/core/skeleton-residue.d.ts.map +1 -0
  107. package/dist/core/skeleton-residue.js +98 -0
  108. package/dist/core/skeleton-residue.js.map +1 -0
  109. package/dist/core/task-paths.d.ts +1 -1
  110. package/dist/core/task-paths.d.ts.map +1 -1
  111. package/dist/core/task-paths.js +5 -4
  112. package/dist/core/task-paths.js.map +1 -1
  113. package/dist/core/unified-config.d.ts +8 -0
  114. package/dist/core/unified-config.d.ts.map +1 -1
  115. package/dist/core/unified-config.js +3 -0
  116. package/dist/core/unified-config.js.map +1 -1
  117. package/dist/core/unit-context-assembler.d.ts.map +1 -1
  118. package/dist/core/unit-context-assembler.js +21 -45
  119. package/dist/core/unit-context-assembler.js.map +1 -1
  120. package/dist/core/unit-staffing.d.ts +28 -1
  121. package/dist/core/unit-staffing.d.ts.map +1 -1
  122. package/dist/core/unit-staffing.js +115 -20
  123. package/dist/core/unit-staffing.js.map +1 -1
  124. package/dist/utils/markdown-image.d.ts +12 -0
  125. package/dist/utils/markdown-image.d.ts.map +1 -0
  126. package/dist/utils/markdown-image.js +34 -0
  127. package/dist/utils/markdown-image.js.map +1 -0
  128. package/package.json +2 -1
  129. package/templates/html/speccore-ask-guide.html +1 -1
  130. package/templates/html/speccore-ask-pipeline.html +1 -1
  131. package/templates/html/speccore-ask-result.html +1 -1
  132. package/templates/html/speccore-help.html +2 -2
@@ -63,6 +63,8 @@ const ask_1 = require("./ask");
63
63
  const agents_1 = require("../core/agents");
64
64
  // v6.85.0+: RULES 规范库
65
65
  const rule_loader_1 = require("../core/rule-loader");
66
+ const task_utils_1 = require("../utils/task-utils");
67
+ const asset_stamp_1 = require("../core/asset-stamp");
66
68
  // v6.87.0+: COMMANDS 命令模板
67
69
  const command_loader_1 = require("../core/command-loader");
68
70
  // v6.88.0+: SKILLS + HOOKS
@@ -367,6 +369,8 @@ async function createDefaultFiles(projectRoot, speccoreDir) {
367
369
  ## 字段对照总表
368
370
 
369
371
  > **AI 必读**:以下表格明确 CONSTITUTION.md 各字段与 PROJECT.yaml 的对应关系,以及每个字段的准确语义。请勿混淆。
372
+ >
373
+ > **事实源(v8.3.322+)**:CLI 命令的机器执行只认 PROJECT.yaml;CONSTITUTION.md 是 AI 阅读契约,仅在 PROJECT.yaml 未声明对应字段时作兼容回退。两处内容需保持语义一致。
370
374
 
371
375
  ### 项目信息表字段
372
376
 
@@ -424,6 +428,8 @@ async function createDefaultFiles(projectRoot, speccoreDir) {
424
428
 
425
429
  ## 项目信息
426
430
 
431
+ > ⚠️ **机器事实源是 \`.speccore/PROJECT.yaml\` 的 \`platforms\`**(v8.3.323+):源码路径→端的映射(变更检测等)以 platforms[].code_path 为准;本表为 AI 契约与兼容回退,两处需保持一致。
432
+
427
433
  | 工程标识 | 工程类型 | 工程名 | 项目名称 | 项目描述 | 工程源码路径 | 涉及需求端 | 备注 |
428
434
  | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
429
435
  | ${projectName} | 待填写 | 待填写 | 待填写 | 待填写 | ./ | 待填写 | 待填写 |
@@ -532,32 +538,44 @@ async function createDefaultFiles(projectRoot, speccoreDir) {
532
538
 
533
539
  ## 技术栈
534
540
 
535
- ### 后端
536
- - 语言:Java / TypeScript / Go / Python
537
- - 框架:Spring Boot / NestJS / Gin / FastAPI
538
- - 数据库:MySQL / PostgreSQL / MongoDB
539
- - 缓存:Redis
541
+ > 填写规则:**每端一行,只写「已选定」的技术与版本**(决策式声明,不是选项菜单)。
542
+ > AI 生成代码时以本表为准;未填写的端回退到端级 TECH.md(analyze 产物)。
543
+ > 可选技术域见本节末尾,仅作约束参考——未出现在上表中的均视为未选用。
544
+
545
+ | 端 | 语言 | 框架 | 数据存储 | 依据(依赖清单文件) |
546
+ | :--- | :--- | :--- | :--- | :--- |
547
+ | backend-api | Java 17 | Spring Boot 3.x | MySQL 8 | pom.xml |
548
+ | admin-web | TypeScript | Vue 3 | — | package.json |
540
549
 
541
- ### 前端
542
- - 框架:Vue / React / Angular
543
- - 状态管理:Pinia / Redux / NgRx
544
- - UI 组件:Element Plus / Ant Design
550
+ > 可选技术域(约束参考,非已选):
551
+ > - 后端语言:Java / TypeScript / Go / Python;框架:Spring Boot / NestJS / Gin / FastAPI
552
+ > - 前端框架:Vue / React / Angular;状态管理:Pinia / Redux / NgRx;UI 组件:Element Plus / Ant Design
553
+ > - 数据存储:MySQL / PostgreSQL / MongoDB;缓存:Redis
545
554
 
546
555
  ## 命名规范
547
556
  - 接口:/api/v1/{模块}/{操作}
548
- - 错误码:4 位数字,按模块划分
549
- - 数据库:snake_case
550
- - 代码:camelCase / PascalCase
557
+ - 错误码:4 位数字,按「异常码体系」分段划分
558
+ - 数据库:snake_case;代码:camelCase;类/组件:PascalCase
559
+ - 目录:全小写短横线(user-service);文件名与默认导出组件同名
560
+ - Git 提交:type(scope): subject(feat/fix/docs/refactor/test)
551
561
 
552
562
  ## 异常码体系
553
- | 错误码 | 含义 | 场景 |
563
+
564
+ > 错误码为 4 位数字,按段划分——**分段规则给 AI 的是「生成能力」,不是几个示例**:
565
+
566
+ | 段 | 范围 | 归属 |
554
567
  | :--- | :--- | :--- |
555
- | 1001 | 用户不存在 | 登录时手机号未注册 |
556
- | 1002 | 密码错误 | 登录密码不匹配 |
557
- | ... | ... | ... |
568
+ | 1xxx | 1000-1999 | 用户模块 |
569
+ | 2xxx | 2000-2999 | 订单模块 |
570
+
571
+ - 首位 = 模块段,后三位 = 段内序号;错误码全项目唯一,跨端共用同一套编号
572
+ - 示例(演示用,按真实模块替换上表):1001 用户不存在 / 2001 订单不存在
558
573
 
559
574
  ## Git 分支策略
560
575
 
576
+ > ⚠️ **机器事实源是 \`.speccore/PROJECT.yaml\` 的 \`git\` 段**(v8.3.322+):CLI 命令(分支创建、PR、保护分支拦截)只认 PROJECT.yaml;
577
+ > 本节是 AI 阅读契约,仅在 PROJECT.yaml 未声明对应字段时作为兼容回退。修改策略请改 PROJECT.yaml,并保持本节语义一致。
578
+
561
579
  > 公共默认策略。各工程可在「Git 配置」表中覆盖。
562
580
 
563
581
  - 默认分支: main(可选: master / develop / trunk)
@@ -568,6 +586,15 @@ async function createDefaultFiles(projectRoot, speccoreDir) {
568
586
  - 保护分支上禁止直接 commit 和 push,只能通过 PR 合并
569
587
  - 支持精确匹配和通配符(如 release/*)
570
588
  `);
589
+ // v8.3.325: 自动检测技术栈并预填决策式技术栈表(模板刚生成,示例行可整体替换)
590
+ try {
591
+ const { enhanceConstitutionTechStack } = require('../core/constitution-builder');
592
+ await enhanceConstitutionTechStack(projectRoot, {
593
+ platformName: projectName,
594
+ freshTemplate: true,
595
+ });
596
+ }
597
+ catch { /* 检测失败不影响 init 主流程 */ }
571
598
  } // if CONSTITUTION.md 不存在
572
599
  // PROJECT files
573
600
  await (0, fs_extra_1.writeFile)((0, path_1.join)(speccoreDir, 'PROJECT', 'INDEX.md'), `# 项目索引
@@ -586,9 +613,18 @@ async function createDefaultFiles(projectRoot, speccoreDir) {
586
613
  `);
587
614
  await (0, fs_extra_1.writeFile)((0, path_1.join)(speccoreDir, 'PROJECT', 'TEAM.md'), `# 团队与 Git 映射
588
615
 
589
- | 成员 | Git 用户名 | 角色 | 技术栈 | 负责模块 |
590
- | :--- | :--- | :--- | :--- | :--- |
591
- | | | | | |
616
+ > **全员名册(全局基座,v8.3.319+)**: 成员在此登记后,所有迭代的 STAFFING.md 自动继承。
617
+ > 各迭代 STAFFING.md 只写差异(同名成员整体覆盖其方向/比例);本表是团队人员的唯一事实源。
618
+
619
+ | 成员 | Git 用户名 | 角色 | 技术栈 | 负责模块 | 平台方向 | 投入比例 | 状态 |
620
+ | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
621
+ | | | | | | | | |
622
+
623
+ > 说明:
624
+ > - **平台方向**: 后台 / 小程序 / Web / APP,多个用逗号分隔(也可直接写标准端名)
625
+ > - **投入比例**: 0-100%(缺省按 100),用于 taskify 时自动分配和负荷均衡
626
+ > - **状态**: 在职(缺省)/ 出项目——出项目成员不参与自动填充(analyze 候选推导、taskify 负荷均衡自动跳过)
627
+ > - 旧版本表(无「平台方向」列)兼容读取:缺此列时全局基座不参与合并,各迭代 STAFFING.md 独立生效
592
628
  `);
593
629
  // ITERATIONS/README.md
594
630
  await (0, fs_extra_1.writeFile)((0, path_1.join)(speccoreDir, 'ITERATIONS', 'README.md'), `# 迭代索引
@@ -656,77 +692,11 @@ async function createDefaultFiles(projectRoot, speccoreDir) {
656
692
  },
657
693
  },
658
694
  }, null, 2));
659
- // CODE_REVIEW.md
660
- await (0, fs_extra_1.writeFile)((0, path_1.join)(speccoreDir, 'RULES', 'CODE_REVIEW.md'), `# 代码审查规则
661
-
662
- ## 审查维度
663
- 1. 规范遵循
664
- 2. 代码质量
665
- 3. 测试覆盖
666
- 4. 性能指标
667
- 5. 安全性
668
-
669
- ## 评分标准
670
- | 等级 | 分数 | 说明 |
671
- | :--- | :--- | :--- |
672
- | A | 90-100 | 优秀 |
673
- | B | 75-89 | 良好 |
674
- | C | 60-74 | 合格 |
675
- | D | <60 | 不合格 |
676
- `);
677
- // POST_COMPLETION.md (Feature 完成后的维护流程)
678
- await (0, fs_extra_1.writeFile)((0, path_1.join)(speccoreDir, 'RULES', 'POST_COMPLETION.md'), `# Feature 完成后的维护流程
679
-
680
- > 当 Feature 已签署 ✅ 已完成 后,本文件定义其线上运行与维护期的标准流程。
681
-
682
- ## 1. Feature 状态扩展
683
-
684
- | 状态 | 图标 | 含义 | 触发条件 |
685
- | :--- | :--- | :--- | :--- |
686
- | 已完成 | ✅ | Spec 与代码完全对齐,已上线 | 开发完成 + 验收通过 |
687
- | 待反向同步 | ⚠️ | 代码已改但 Spec 未同步 | 紧急补丁后 |
688
- | 维护中 | 🔄 | 正在回归或功能增强 | 分配维护任务后 |
689
- | 已废弃 | 🚫 | 功能下线,不再维护 | 业务下线 + 代码移除 |
690
-
691
- ## 2. 补丁反向同步流程(⚠️ → ✅)
692
-
693
- 1. AI 读取当前代码,对比 Spec 文件,生成差异报告
694
- 2. 逐项更新:REQ.md、API_CONTRACT.yaml、TASK.md
695
- 3. 更新变更履历
696
- 4. 更新 PROJECT_GRAPH.md 状态
697
-
698
- ## 3. Bug 修复流程(✅ → 🔄 → ✅)
699
-
700
- 1. 标记状态为 🔄 维护中
701
- 2. 根因分析 → 追加到 TASK.md「线上问题记录」
702
- 3. 沉淀到 PATTERNS/ 模式库
703
- 4. 回归验证 → 恢复状态到 ✅
704
-
705
- ## 4. 功能增强流程(✅ → 🔄 → ✅)
706
-
707
- 1. 标记状态为 🔄 维护中
708
- 2. 在 REQ.md 追加新需求
709
- 3. 更新 API_CONTRACT.yaml
710
- 4. 更新 TASK.md 和 E2E-TEST-SPEC.md
711
- 5. 完成后改回 ✅
712
-
713
- ## 5. 功能下线流程(✅ → 🚫)
714
-
715
- 1. 状态改为 🚫 已废弃
716
- 2. PATTERNS/ 标记相关模式为「仅作历史参考」
717
- 3. 代码保留至少一个迭代周期
718
- 4. 最后一个周期后删除代码和 Spec
719
-
720
- ## 6. 维护检查清单
721
-
722
- - [ ] 是否已更新所有受影响的 Spec 文件?
723
- - [ ] 是否已在变更履历中追加记录?
724
- - [ ] 是否已更新 PROJECT_GRAPH.md 状态?
725
- - [ ] 是否已沉淀到 PATTERNS/ 模式库?
726
- - [ ] 是否已回归 E2E-TEST-SPEC.md 测试场景?
727
-
728
- 若有任何一项为"否",不得将状态改回 ✅ 已完成。
729
- `);
695
+ // CODE_REVIEW.md / POST_COMPLETION.md(内容由 EXTRA_BUILTIN_RULES 常量统一维护,
696
+ // 首次 init 无条件写入;update 路径由 initRulesDir 缺失补写)
697
+ for (const rule of EXTRA_BUILTIN_RULES) {
698
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(speccoreDir, 'RULES', rule.name), rule.content);
699
+ }
730
700
  // v8.3.41+: 用户自定义分析文档模板说明
731
701
  const templatesReadmePath = (0, path_1.join)(speccoreDir, 'templates', 'README.md');
732
702
  if (!(await (0, fs_extra_1.pathExists)(templatesReadmePath))) {
@@ -894,76 +864,6 @@ async function createGlobalFiles(speccoreDir) {
894
864
  | 缩写 | 全称 | 说明 |
895
865
  | :--- | :--- | :--- |
896
866
  | _待补充_ | - | - |
897
- `);
898
- // v8.3.307+: TaskChain 内置约束集(.speccore/GLOBAL/CONSTRAINTS/)
899
- // 「共同前提约束」的落盘:同类任务每次执行前重新加载,保证上下文不漂移
900
- const { BUILTIN_CONSTRAINTS, CUSTOM_TYPES_DIR } = await Promise.resolve().then(() => __importStar(require('../core/task-type-registry')));
901
- const constraintsDir = (0, path_1.join)(globalDir, 'CONSTRAINTS');
902
- await (0, fs_extra_1.ensureDir)(constraintsDir);
903
- for (const [name, content] of Object.entries(BUILTIN_CONSTRAINTS)) {
904
- await (0, fs_extra_1.writeFile)((0, path_1.join)(constraintsDir, `${name}.md`), content);
905
- }
906
- // v8.3.308+: 自定义任务类型目录(开放类型系统引导文档)
907
- // 用户在此声明自己的任务类型(如 summary/ppt/translation),非系统定义类型
908
- // 默认与代码世界绝缘(不建分支/不写源码),spec 声明 code: true 才切代码形态
909
- const customTypesDir = (0, path_1.join)(globalDir, 'TASK_TYPES');
910
- await (0, fs_extra_1.ensureDir)(customTypesDir);
911
- await (0, fs_extra_1.writeFile)((0, path_1.join)(customTypesDir, 'README.md'), `# 自定义任务类型(v8.3.308+ 开放类型系统)
912
-
913
- > 系统内置 8 种类型(feature/bugfix/refactor/research/doc/script/data/presentation)。
914
- > 本目录声明**用户自定义类型**——写总结、做 PPT、翻译、任何非编程工作都可以是任务。
915
-
916
- ## 核心规则
917
-
918
- **非系统定义的类型,默认与代码世界绝缘**:
919
-
920
- - 不创建 git 分支
921
- - 不写源码路径、不读全局代码上下文
922
- - 不需要端子目录与技术规格
923
- - 仅在任务 spec 中**显式声明** \`code: true\`(或「需要写代码: true」)时才切代码形态
924
-
925
- ## 如何声明一个自定义类型
926
-
927
- 创建 \`{类型名}.md\`(如 \`summary.md\`),YAML frontmatter 声明定义:
928
-
929
- \`\`\`markdown
930
- ---
931
- label: 总结编写
932
- category: doc
933
- outputDir: docs/summaries/
934
- acceptance: 结构含「成果/问题/下一步」+ 数据有来源
935
- needsBranch: false
936
- needsPlatforms: false
937
- needsTechSpec: false
938
- constraints: [doc-standards]
939
- ---
940
- 正文:类型说明(可选)。
941
- \`\`\`
942
-
943
- 字段说明:
944
-
945
- | 字段 | 默认 | 说明 |
946
- | :--- | :--- | :--- |
947
- | label | 类型名 | 中文显示名 |
948
- | category | custom | 泛化类别(code/doc/research/script/data/custom) |
949
- | outputDir | outputs/ | 产出目录(相对项目根) |
950
- | acceptance | 按 spec 验收 | 验收方式描述 |
951
- | needsBranch | false | 是否创建 git 分支 |
952
- | needsPlatforms | false | 是否按端拆分子目录 |
953
- | needsTechSpec | false | 是否需要技术规格 |
954
- | constraints | [] | 默认约束集(对应 CONSTRAINTS/ 下的文件) |
955
-
956
- ## 任务 spec 的显式覆盖
957
-
958
- 任务 spec frontmatter 可覆盖类型默认:
959
-
960
- \`\`\`markdown
961
- ---
962
- type: summary
963
- code: true # 显式声明要写代码 → 建分支 + 写源码
964
- constraints: [coding-standards, common-rules]
965
- ---
966
- \`\`\`
967
867
  `);
968
868
  }
969
869
  /**
@@ -1544,6 +1444,22 @@ async function initAgentsDir(projectRoot) {
1544
1444
  if (!(await (0, fs_extra_1.pathExists)(destPath))) {
1545
1445
  await (0, fs_extra_1.writeFile)(destPath, agent.content);
1546
1446
  }
1447
+ else {
1448
+ // v8.3.315+: 版本戳驱动同步 — 内置内容带当前版本戳:
1449
+ // 有旧戳 → 旧版 CLI 生成 → 备份刷新
1450
+ // 无戳且命中旧版特征(「# 角色:」标题、缺 systemPrompt frontmatter)→ 老项目首升级 → 备份刷新
1451
+ // 无戳且无旧版特征 → 用户自定义 → 保留
1452
+ const existing = await (0, fs_extra_1.readFile)(destPath, 'utf-8');
1453
+ // 旧版特征 = 缺 systemPrompt frontmatter 且带「# 角色:」标题(新版无此标题)
1454
+ const decision = (0, asset_stamp_1.decideStampedSync)(existing, agent.content, c => !/^---\s*[\s\S]*?systemPrompt:/m.test(c) && /#\s*角色[::]\s*\(?/m.test(c));
1455
+ if (decision === 'refresh') {
1456
+ await safeWriteWithBackup(destPath, agent.content);
1457
+ logger_1.logger.info(` 🔄 刷新旧版角色定义: ${agent.name}.md(原文件已备份)`);
1458
+ }
1459
+ else if (decision === 'restamp') {
1460
+ await (0, fs_extra_1.writeFile)(destPath, agent.content);
1461
+ }
1462
+ }
1547
1463
  }
1548
1464
  // 复制注册表(不覆盖用户已自定义的)
1549
1465
  const registryContent = await (0, agents_1.getBuiltinRegistryContent)();
@@ -1552,6 +1468,19 @@ async function initAgentsDir(projectRoot) {
1552
1468
  if (!(await (0, fs_extra_1.pathExists)(registryPath))) {
1553
1469
  await (0, fs_extra_1.writeFile)(registryPath, registryContent);
1554
1470
  }
1471
+ else {
1472
+ // v8.3.315+: 版本戳驱动 + 缺失型旧特征兜底(老项目无戳且缺「叠加 RULES/」列)
1473
+ // 已注册的自定义角色如有丢失可从备份文件恢复。
1474
+ const existing = await (0, fs_extra_1.readFile)(registryPath, 'utf-8');
1475
+ const decision = (0, asset_stamp_1.decideStampedSync)(existing, registryContent, c => !/叠加\s+RULES\//.test(c));
1476
+ if (decision === 'refresh') {
1477
+ await safeWriteWithBackup(registryPath, registryContent);
1478
+ logger_1.logger.info(' 🔄 刷新旧版 AGENTS 注册表: _INDEX.md(原文件已备份,自定义角色请从备份合并)');
1479
+ }
1480
+ else if (decision === 'restamp') {
1481
+ await (0, fs_extra_1.writeFile)(registryPath, registryContent);
1482
+ }
1483
+ }
1555
1484
  }
1556
1485
  // 复制模板(不覆盖用户已自定义的)
1557
1486
  const templateContent = await (0, agents_1.getBuiltinTemplateContent)();
@@ -1573,17 +1502,110 @@ const OBSOLETE_MARKERS = [
1573
1502
  { pattern: /speccore\s+split|split\s+-I/, desc: 'split 死命令(v8.3.231+ 应为 taskify)' },
1574
1503
  { pattern: /taskify\s+-I/, desc: 'taskify -I(应为 -i)' },
1575
1504
  { pattern: /CONSTITUTION\.md\s+指定的源码路径(?!\s*\/\s*PROJECT\.yaml)/, desc: '缺少 PROJECT.yaml 引用' },
1576
- { pattern: /禁止在迭代目录下创建\s+10-backend/, desc: '旧表述:迭代目录(应为 任务目录)' },
1505
+ { pattern: /禁止在迭代目录下创建\s+10-backend/, desc: '旧表述:迭代目录(应为任务目录)' },
1506
+ { pattern: /dev\s+后生成/, desc: '旧流水线表述(dev 已更名 run,v8.3.280+)' },
1507
+ { pattern: /必须开始新对话/, desc: 'SPECCORE_CONTINUE 旧文案(应为优先在同一会话继续)' },
1577
1508
  ];
1578
- function detectObsoleteContent(content) {
1509
+ /**
1510
+ * v8.3.46+: 智能过时检测(命中型)
1511
+ * v8.3.314+: 支持 requiredPatterns 缺失型检测 — 新版模板独有的关键内容块,旧版文件缺失即视为过时
1512
+ */
1513
+ function detectObsoleteContent(content, requiredPatterns = []) {
1579
1514
  const markers = [];
1580
1515
  for (const marker of OBSOLETE_MARKERS) {
1581
1516
  if (marker.pattern.test(content)) {
1582
1517
  markers.push(marker.desc);
1583
1518
  }
1584
1519
  }
1520
+ for (const pattern of requiredPatterns) {
1521
+ if (!pattern.test(content)) {
1522
+ markers.push('缺少新版关键内容');
1523
+ }
1524
+ }
1585
1525
  return { hasObsolete: markers.length > 0, markers };
1586
1526
  }
1527
+ /**
1528
+ * v8.3.314+: 不在 getBuiltinRuleContents 列表内的内置规则。
1529
+ * 首次 init(createDefaultFiles)与 update(initRulesDir)都必须确保其存在,
1530
+ * 否则 AGENTS.md 的引用会出现断链(update 路径此前只补列表内文件)。
1531
+ */
1532
+ const EXTRA_BUILTIN_RULES = [
1533
+ {
1534
+ name: 'CODE_REVIEW.md',
1535
+ content: `# 代码审查规则
1536
+
1537
+ ## 审查维度
1538
+ 1. 规范遵循
1539
+ 2. 代码质量
1540
+ 3. 测试覆盖
1541
+ 4. 性能指标
1542
+ 5. 安全性
1543
+
1544
+ ## 评分标准
1545
+ | 等级 | 分数 | 说明 |
1546
+ | :--- | :--- | :--- |
1547
+ | A | 90-100 | 优秀 |
1548
+ | B | 75-89 | 良好 |
1549
+ | C | 60-74 | 合格 |
1550
+ | D | <60 | 不合格 |
1551
+ `,
1552
+ },
1553
+ {
1554
+ name: 'POST_COMPLETION.md',
1555
+ content: `# Feature 完成后的维护流程
1556
+
1557
+ > 当 Feature 已签署 ✅ 已完成 后,本文件定义其线上运行与维护期的标准流程。
1558
+
1559
+ ## 1. Feature 状态扩展
1560
+
1561
+ | 状态 | 图标 | 含义 | 触发条件 |
1562
+ | :--- | :--- | :--- | :--- |
1563
+ | 已完成 | ✅ | Spec 与代码完全对齐,已上线 | 开发完成 + 验收通过 |
1564
+ | 待反向同步 | ⚠️ | 代码已改但 Spec 未同步 | 紧急补丁后 |
1565
+ | 维护中 | 🔄 | 正在回归或功能增强 | 分配维护任务后 |
1566
+ | 已废弃 | 🚫 | 功能下线,不再维护 | 业务下线 + 代码移除 |
1567
+
1568
+ ## 2. 补丁反向同步流程(⚠️ → ✅)
1569
+
1570
+ 1. AI 读取当前代码,对比 Spec 文件,生成差异报告
1571
+ 2. 逐项更新:REQ.md、API_CONTRACT.yaml、TASK.md
1572
+ 3. 更新变更履历
1573
+ 4. 更新 PROJECT_GRAPH.md 状态
1574
+
1575
+ ## 3. Bug 修复流程(✅ → 🔄 → ✅)
1576
+
1577
+ 1. 标记状态为 🔄 维护中
1578
+ 2. 根因分析 → 追加到 TASK.md「线上问题记录」
1579
+ 3. 沉淀到 PATTERNS/ 模式库
1580
+ 4. 回归验证 → 恢复状态到 ✅
1581
+
1582
+ ## 4. 功能增强流程(✅ → 🔄 → ✅)
1583
+
1584
+ 1. 标记状态为 🔄 维护中
1585
+ 2. 在 REQ.md 追加新需求
1586
+ 3. 更新 API_CONTRACT.yaml
1587
+ 4. 更新 TASK.md 和 E2E-TEST-SPEC.md
1588
+ 5. 完成后改回 ✅
1589
+
1590
+ ## 5. 功能下线流程(✅ → 🚫)
1591
+
1592
+ 1. 状态改为 🚫 已废弃
1593
+ 2. PATTERNS/ 标记相关模式为「仅作历史参考」
1594
+ 3. 代码保留至少一个迭代周期
1595
+ 4. 最后一个周期后删除代码和 Spec
1596
+
1597
+ ## 6. 维护检查清单
1598
+
1599
+ - [ ] 是否已更新所有受影响的 Spec 文件?
1600
+ - [ ] 是否已在变更履历中追加记录?
1601
+ - [ ] 是否已更新 PROJECT_GRAPH.md 状态?
1602
+ - [ ] 是否已沉淀到 PATTERNS/ 模式库?
1603
+ - [ ] 是否已回归 E2E-TEST-SPEC.md 测试场景?
1604
+
1605
+ 若有任何一项为"否",不得将状态改回 ✅ 已完成。
1606
+ `,
1607
+ },
1608
+ ];
1587
1609
  /**
1588
1610
  * v6.85.0+: 初始化 RULES 规范库
1589
1611
  * 将内置默认编码规范复制到 .speccore/RULES/ 目录
@@ -1602,9 +1624,11 @@ async function initRulesDir(projectRoot) {
1602
1624
  }
1603
1625
  // v6.98.0+: 创建 AGENTS.md 投影用的 .inline.md 文件
1604
1626
  // v8.3.46+: 智能过时检测 — 发现已知过时标记时自动覆盖
1627
+ // v8.3.314+: required 缺失型检测 — 新版模板独有内容块缺失时同样覆盖
1605
1628
  const inlineTemplates = [
1606
1629
  {
1607
1630
  name: '01-PROJECT_STRUCTURE.inline.md',
1631
+ required: [/SOURCE\.md/],
1608
1632
  content: `## 项目结构
1609
1633
 
1610
1634
  \`\`\`
@@ -1613,6 +1637,7 @@ Iteration-NNN-name/ ← 迭代目录
1613
1637
  ├── 010-requirements/ ← 需求层
1614
1638
  │ ├── sources/ converted/ ← [只读] 原始 PRD / doc2spec 转换
1615
1639
  │ ├── features/{功能单元}/ ← unitize 切分产出(功能单元目录 = analyze 对齐锚点)
1640
+ │ │ └── SOURCE.md ← 需求原文切片(旧版为 README.md)
1616
1641
  │ ├── bugs/ refactors/ research/ ← 三类需求文档(与任务类型对应)
1617
1642
  │ └── CLARIFY_REPORT.md ← 澄清报告
1618
1643
  ├── 020-specs/ ← 需求分析(analyze 输出)
@@ -1682,6 +1707,7 @@ Iteration-NNN-name/ ← 迭代目录
1682
1707
  | \`[SPECCORE_STEP_FAIL: <cmd>]\` | Pipeline 步骤失败 | 提示用户选择重试/跳过/停止 |
1683
1708
  | \`[SPECCORE_AMBIGUOUS: <cmd1> \\| <cmd2>]\` | 意图模糊 | 展示匹配选项让用户选择 |
1684
1709
  | \`[SPECCORE_CONTINUE: <path>]\` | 批次执行完成,需续批 | **优先在同一会话继续**(按标记中的命令执行下一批);上下文紧张时开新对话,先读取 \`<path>\` 恢复上下文再续批 |`,
1710
+ required: [/SPECCORE_NEEDS_INFO/],
1685
1711
  },
1686
1712
  {
1687
1713
  name: '03-COMMAND_CHEATSHEET.inline.md',
@@ -1708,22 +1734,39 @@ speccore run --demand deploy # 逃生舱:显式声明是需求(
1708
1734
  speccore analyze -g # 快捷糖:等价 speccore global analyze
1709
1735
  speccore unitize prd.md # 文件位置参数;doc2spec prd.docx 同理
1710
1736
  speccore verify deploy # 测试阶段位置参数(dev/pr/deploy/release)
1711
- \`\`\``
1737
+ \`\`\``,
1738
+ required: [/speccore\s+run\s+#/],
1712
1739
  },
1713
1740
  ];
1741
+ // v8.3.314+: 补写 getBuiltinRuleContents 列表之外的内置规则(CODE_REVIEW/POST_COMPLETION)。
1742
+ // update 路径此前只补列表内文件,旧项目缺失这两份时 AGENTS.md 引用断链。
1743
+ for (const rule of EXTRA_BUILTIN_RULES) {
1744
+ const destPath = (0, path_1.join)(rulesDir, rule.name);
1745
+ if (!(await (0, fs_extra_1.pathExists)(destPath))) {
1746
+ await (0, fs_extra_1.writeFile)(destPath, rule.content);
1747
+ }
1748
+ }
1714
1749
  for (const tpl of inlineTemplates) {
1715
1750
  const destPath = (0, path_1.join)(rulesDir, tpl.name);
1751
+ const stampedContent = (0, asset_stamp_1.stampContent)(tpl.content);
1716
1752
  const exists = await (0, fs_extra_1.pathExists)(destPath);
1717
1753
  if (!exists) {
1718
- await (0, fs_extra_1.writeFile)(destPath, tpl.content);
1754
+ await (0, fs_extra_1.writeFile)(destPath, stampedContent);
1719
1755
  }
1720
- else if (tpl.name.endsWith('.inline.md')) {
1721
- // v8.3.46+: 智能过时检测 — 发现已知过时标记时自动覆盖
1756
+ else {
1757
+ // v8.3.315+: 版本戳驱动同步(统一决策表 decideStampedSync)
1758
+ // 有旧戳 → 旧版 CLI 生成 → 备份刷新(不再枚举旧特征,改模板即自动迁移)
1759
+ // 无戳 → 旧特征兜底:过时标记命中 / 缺新版关键内容(required)→ 备份刷新
1760
+ // 同版本戳或用户自定义 → 保留
1761
+ // 覆盖一律 safeWriteWithBackup:旧版特征检测存在误判可能,备份保底可回滚
1722
1762
  const existingContent = await (0, fs_extra_1.readFile)(destPath, 'utf-8');
1723
- const { hasObsolete, markers } = detectObsoleteContent(existingContent);
1724
- if (hasObsolete) {
1725
- logger_1.logger.info(` 🔄 检测到过时内容 [${tpl.name}]: ${markers.join('、')},已自动更新`);
1726
- await (0, fs_extra_1.writeFile)(destPath, tpl.content);
1763
+ const decision = (0, asset_stamp_1.decideStampedSync)(existingContent, stampedContent, c => detectObsoleteContent(c, tpl.required).hasObsolete);
1764
+ if (decision === 'refresh') {
1765
+ logger_1.logger.info(` 🔄 检测到旧版内容 [${tpl.name}],已备份并更新`);
1766
+ await safeWriteWithBackup(destPath, stampedContent);
1767
+ }
1768
+ else if (decision === 'restamp') {
1769
+ await (0, fs_extra_1.writeFile)(destPath, stampedContent);
1727
1770
  }
1728
1771
  }
1729
1772
  }
@@ -1813,12 +1856,12 @@ async function syncAgentsMd(projectRoot, force = false) {
1813
1856
  const agentRows = [];
1814
1857
  if (await (0, fs_extra_1.pathExists)(agentsDir)) {
1815
1858
  const files = (await (0, fs_extra_1.readdir)(agentsDir))
1816
- .filter(f => f.endsWith('.md') && !f.startsWith('_') && !f.startsWith('.'))
1859
+ .filter(f => f.endsWith('.md') && !f.startsWith('_') && !f.startsWith('.') && !(0, task_utils_1.isTimestampBackup)(f))
1817
1860
  .sort();
1818
1861
  for (const f of files) {
1819
1862
  if (f.endsWith('.inline.md')) {
1820
1863
  const content = await (0, fs_extra_1.readFile)((0, path_1.join)(agentsDir, f), 'utf-8');
1821
- agentInlines.push(content.trim());
1864
+ agentInlines.push((0, asset_stamp_1.stripAssetStamp)(content).trim());
1822
1865
  }
1823
1866
  else {
1824
1867
  const content = await (0, fs_extra_1.readFile)((0, path_1.join)(agentsDir, f), 'utf-8');
@@ -1858,12 +1901,13 @@ async function syncAgentsMd(projectRoot, force = false) {
1858
1901
  const ruleLinks = [];
1859
1902
  if (await (0, fs_extra_1.pathExists)(rulesDir)) {
1860
1903
  const files = (await (0, fs_extra_1.readdir)(rulesDir))
1861
- .filter(f => f.endsWith('.md') && !f.startsWith('_') && !f.startsWith('.'))
1904
+ .filter(f => f.endsWith('.md') && !f.startsWith('_') && !f.startsWith('.') && !(0, task_utils_1.isTimestampBackup)(f))
1862
1905
  .sort();
1863
1906
  for (const f of files) {
1864
1907
  if (f.endsWith('.inline.md')) {
1865
1908
  const content = await (0, fs_extra_1.readFile)((0, path_1.join)(rulesDir, f), 'utf-8');
1866
- ruleInlines.push(content.trim());
1909
+ // v8.3.315+: 剥掉资产版本戳(投影内容不携带 CLI 内部戳)
1910
+ ruleInlines.push((0, asset_stamp_1.stripAssetStamp)(content).trim());
1867
1911
  }
1868
1912
  else {
1869
1913
  const name = f.replace(/\.md$/, '').replace(/[-_]/g, ' ');
@@ -1906,10 +1950,12 @@ async function createSampleIteration(projectRoot) {
1906
1950
  await (0, fs_extra_1.writeFile)((0, path_1.join)(iterDir, 'STAFFING.md'), [
1907
1951
  '# 示例 人员排期配置',
1908
1952
  '',
1909
- '| 成员 | 平台方向 | 投入比例 |',
1910
- '| :--- | :--- | :--- |',
1911
- '| 张三 | APP, H5 | 80% |',
1912
- '| 李四 | admin, 小程序 | 70% |',
1953
+ '> 全员基座见 .speccore/PROJECT/TEAM.md(全局名册,自动继承);本文件只写本迭代差异/覆盖',
1954
+ '',
1955
+ '| 成员 | 平台方向 | 投入比例 | 状态 |',
1956
+ '| :--- | :--- | :--- | :--- |',
1957
+ '| 张三 | APP, H5 | 80% | |',
1958
+ '| 李四 | admin, 小程序 | 70% | |',
1913
1959
  '',
1914
1960
  '> 编辑此文件后重新运行 taskify 即可更新默认分配',
1915
1961
  ].join('\n'));
@@ -2165,7 +2211,7 @@ function generateAIRulesContent() {
2165
2211
  '1. **/spec:ask 是智能路由入口** — 用户说"新建迭代"、"分析需求" → 调用 `speccore ask`,不要自己写 mkdir/analyze',
2166
2212
  '2. **不要跨命令猜测** — 每个斜杠命令只做它描述的事,不要自动级联后续步骤',
2167
2213
  '3. **参数从命令描述获取** — /spec:execute 的描述中有完整的参数说明',
2168
- '4. **上下文不足时读取文件** — 查看 .speccore/CONSTITUTION.md、STAFFING.md 等',
2214
+ '4. **上下文不足时读取文件** — 查看 .speccore/CONSTITUTION.md、STAFFING.md、.speccore/PROJECT/TEAM.md(全员名册)等',
2169
2215
  '',
2170
2216
  '## 核心流水线',
2171
2217
  '',
@@ -2342,6 +2388,8 @@ examples/
2342
2388
  ├── README.md ← 本文件
2343
2389
  ├── config/ ← 配置文件示例
2344
2390
  │ ├── CONSTITUTION-EXAMPLE.md ← CONSTITUTION.md 完整示例(多工程)
2391
+ │ ├── TEAM-EXAMPLE.md ← TEAM.md 全员名册示例(7 列,含状态)
2392
+ │ ├── STAFFING-EXAMPLE.md ← STAFFING.md 迭代排期示例(差异覆盖,含状态)
2345
2393
  │ ├── PROJECT-EXAMPLE.yaml ← PROJECT.yaml 完整示例(多工程)
2346
2394
  │ ├── SPECCORE-YML-EXAMPLE.yml ← .speccore.yml 主配置完整示例(v8.3.296+)
2347
2395
  │ ├── GIT-CONFIG-EXAMPLE.txt ← 子任务 .meta/git-config 格式示例
@@ -2368,8 +2416,9 @@ examples/
2368
2416
  8. 查看 \`config/DEPLOY-EXAMPLE.yaml\`,了解部署配置格式(用于 \`speccore deploy\`)
2369
2417
  9. 查看 \`config/VERIFY-EXAMPLE.yaml\`,了解测试验证配置格式(用于 \`speccore verify --config\`)
2370
2418
  10. 查看 \`config/SPECCORE-YML-EXAMPLE.yml\`,了解主配置 .speccore.yml 全部字段(质量门禁/冒烟三时机/流水线/AI provider)
2371
- 11. 查看 \`ci/github-actions.yml\`,复制到 \`.github/workflows/\` 启用 CI 校验
2372
- 12. 修改后运行 \`speccore update\` 自动同步到 PROJECT.yaml
2419
+ 11. 查看 \`config/TEAM-EXAMPLE.md\` 与 \`config/STAFFING-EXAMPLE.md\`,了解人员配置两级继承(TEAM 全员基座 + STAFFING 迭代差异),「状态」列支持出项目成员免分配
2420
+ 12. 查看 \`ci/github-actions.yml\`,复制到 \`.github/workflows/\` 启用 CI 校验
2421
+ 13. 修改后运行 \`speccore update\` 更新配置结构(Git 策略以 \`.speccore/PROJECT.yaml\` 的 \`git\` 段为机器事实源)
2373
2422
 
2374
2423
  ## 注意事项
2375
2424
 
@@ -2381,7 +2430,7 @@ examples/
2381
2430
  const constitutionExample = `## 字段对照总表
2382
2431
 
2383
2432
  > **AI 必读**:以下表格明确 CONSTITUTION.md 各字段与 PROJECT.yaml 的对应关系。
2384
- > 人类只需填写 CONSTITUTION.md,PROJECT.yaml 由 CLI 自动生成/同步。
2433
+ > 机器执行以 PROJECT.yaml 为事实源(CLI 只读 PROJECT.yaml);CONSTITUTION.md 是 AI 阅读契约,仅在 PROJECT.yaml 未声明对应字段时作兼容回退。两处内容需保持语义一致。
2385
2434
 
2386
2435
  ### 项目信息表字段
2387
2436
 
@@ -2433,6 +2482,8 @@ examples/
2433
2482
 
2434
2483
  ## 项目信息
2435
2484
 
2485
+ > ⚠️ **机器事实源是 \`.speccore/PROJECT.yaml\` 的 \`platforms\`**(v8.3.323+):源码路径→端的映射(变更检测等)以 platforms[].code_path 为准;本表为 AI 契约与兼容回退,两处需保持一致。
2486
+
2436
2487
  | 工程标识 | 工程类型 | 工程名 | 项目名称 | 项目描述 | 工程源码路径 | 涉及需求端 | 备注 |
2437
2488
  | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
2438
2489
  | admin-web | Web管理后台 | 后台管理 | 运营后台 | 运营人员使用的后台管理系统 | ./packages/admin | 后台管理端需求文档 | 核心系统 |
@@ -2452,6 +2503,35 @@ examples/
2452
2503
 
2453
2504
  ---
2454
2505
 
2506
+ ## 技术栈
2507
+
2508
+ > 填写规则:**每端一行,只写「已选定」的技术与版本**(决策式声明,不是选项菜单)。
2509
+ > AI 生成代码时以本表为准;未填写的端回退到端级 TECH.md(analyze 产物)。
2510
+
2511
+ | 端 | 语言 | 框架 | 数据存储 | 依据(依赖清单文件) |
2512
+ | :--- | :--- | :--- | :--- | :--- |
2513
+ | backend-api | Java 17 | Spring Boot 3.x | MySQL 8 | pom.xml |
2514
+ | admin-web | TypeScript | Vue 3 | — | package.json |
2515
+ | h5-mobile | TypeScript | Vue 3 | — | package.json |
2516
+ | miniapp | JavaScript | 原生小程序 | — | package.json |
2517
+
2518
+ > 可选技术域(约束参考,非已选):后端语言 Java/TypeScript/Go/Python;框架 Spring Boot/NestJS/Gin/FastAPI;前端框架 Vue/React/Angular;数据存储 MySQL/PostgreSQL/MongoDB;缓存 Redis。
2519
+
2520
+ ## 异常码体系
2521
+
2522
+ > 错误码为 4 位数字,按段划分——**分段规则给 AI 的是「生成能力」,不是几个示例**:
2523
+
2524
+ | 段 | 范围 | 归属 |
2525
+ | :--- | :--- | :--- |
2526
+ | 1xxx | 1000-1999 | 用户模块 |
2527
+ | 2xxx | 2000-2999 | 订单模块 |
2528
+ | 3xxx | 3000-3999 | 支付模块 |
2529
+
2530
+ - 首位 = 模块段,后三位 = 段内序号;错误码全项目唯一,跨端共用同一套编号
2531
+ - 示例(演示用,按真实模块替换上表):1001 用户不存在 / 2001 订单不存在 / 3001 支付超时
2532
+
2533
+ ---
2534
+
2455
2535
  ## Git 公共配置
2456
2536
 
2457
2537
  > 公共默认值。各工程在「Git 配置」表中只写与公共配置不同的字段,未填写的字段自动使用此处默认值。
@@ -2541,10 +2621,46 @@ examples/
2541
2621
 
2542
2622
  > 📌 **使用说明**:
2543
2623
  > 1. 复制本示例内容到 \`CONSTITUTION.md\`,根据实际项目修改
2544
- > 2. 修改后运行 \`speccore update\` 自动同步到 PROJECT.yaml
2624
+ > 2. 修改后运行 \`speccore update\` 更新配置结构(Git 策略以 \`.speccore/PROJECT.yaml\` 的 \`git\` 段为机器事实源)
2545
2625
  > 3. 子任务目录下的 \`.meta/git-config\` 可覆盖全局配置(见目录结构说明)
2546
2626
  `;
2547
2627
  await (0, fs_extra_1.writeFile)((0, path_1.join)(configDir, 'CONSTITUTION-EXAMPLE.md'), constitutionExample);
2628
+ // v8.3.324: 人员配置示例(两级继承:TEAM 全员基座 + STAFFING 迭代差异,含「状态」列)
2629
+ const teamExample = `# TEAM.md — 团队与 Git 映射(全员名册,示例)
2630
+
2631
+ > **全员名册(全局基座,v8.3.319+)**: 成员在此登记后,所有迭代的 STAFFING.md 自动继承。
2632
+ > 各迭代 STAFFING.md 只写差异(同名成员整体覆盖其方向/比例/状态);本表是团队人员的唯一事实源。
2633
+
2634
+ | 成员 | Git 用户名 | 角色 | 技术栈 | 负责模块 | 平台方向 | 投入比例 | 状态 |
2635
+ | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
2636
+ | 张三 | zhangsan | 后端 | Java/Spring Boot | 订单模块 | backend-api | 100% | 在职 |
2637
+ | 李四 | lisi | 前端 | Vue 3 | 商城页面 | admin-web, h5-mobile | 80% | 在职 |
2638
+ | 王五 | wangwu | 前端 | 原生小程序 | 小程序 | miniapp | 60% | 在职 |
2639
+ | 赵六 | zhaoliu | 后端 | Go | 消息推送 | backend-api | 0% | 出项目 |
2640
+
2641
+ > 说明:
2642
+ > - **平台方向**: 后台 / 小程序 / Web / APP,多个用逗号分隔(也可直接写标准端名)
2643
+ > - **投入比例**: 0-100%(缺省按 100),用于 taskify 时自动分配和负荷均衡
2644
+ > - **状态**: 在职(缺省)/ 出项目——出项目成员不参与自动填充(analyze 候选推导、taskify 负荷均衡自动跳过);迭代层写「在职」可临时复活(如赵六回归某期)
2645
+ `;
2646
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(configDir, 'TEAM-EXAMPLE.md'), teamExample);
2647
+ const staffingExample = `# STAFFING.md — 迭代人员排期(差异覆盖层,示例)
2648
+
2649
+ > **本文件只写差异**: 与基座 TEAM.md 同名的成员整体覆盖其方向/比例/状态;基座成员未列出的默认参与本迭代。
2650
+ > 全员名册见 .speccore/PROJECT/TEAM.md(全局基座,自动继承)。
2651
+
2652
+ | 成员 | 平台方向 | 投入比例 | 状态 |
2653
+ | :--- | :--- | :--- | :--- |
2654
+ | 李四 | admin-web | 100% | 在职 |
2655
+ | 赵六 | backend-api | 50% | 在职 |
2656
+
2657
+ > 说明:
2658
+ > - **平台方向**: 后台 / 小程序 / Web / APP,多个用逗号分隔(也可直接写标准端名)
2659
+ > - **投入比例**: 0-100%,用于 taskify 时自动分配和负荷均衡;写 0% 表示本迭代不参与
2660
+ > - **状态**: 在职(缺省)/ 出项目——出项目成员不参与自动填充;留空则继承基座状态。示例中赵六基座「出项目」,本迭代写「在职 50%」= 临时回归
2661
+ > - 编辑此文件后重新运行 taskify 即可更新默认分配
2662
+ `;
2663
+ await (0, fs_extra_1.writeFile)((0, path_1.join)(configDir, 'STAFFING-EXAMPLE.md'), staffingExample);
2548
2664
  // PROJECT.yaml 完整示例(多工程)
2549
2665
  const projectExample = `# PROJECT.yaml — 项目配置(由 CLI 自动生成,不建议手动编辑)
2550
2666
  # 如需修改,请编辑 CONSTITUTION.md 后运行 speccore update