workflow-loop 0.1.0__py3-none-any.whl

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 (60) hide show
  1. workflow_loop/__init__.py +6 -0
  2. workflow_loop/acceptance_records.py +338 -0
  3. workflow_loop/artifact_paths.py +278 -0
  4. workflow_loop/artifact_validation.py +1738 -0
  5. workflow_loop/bug_record.py +203 -0
  6. workflow_loop/cli.py +3257 -0
  7. workflow_loop/data/Standardized_Repository/acceptance/acceptance.md +119 -0
  8. workflow_loop/data/Standardized_Repository/acceptance/acceptance_plan.md +105 -0
  9. workflow_loop/data/Standardized_Repository/code_design/code_design.md +204 -0
  10. workflow_loop/data/Standardized_Repository/code_design/project_design_init.md +152 -0
  11. workflow_loop/data/Standardized_Repository/code_design/revise_code_design.md +32 -0
  12. workflow_loop/data/Standardized_Repository/code_design/update_code_design.md +94 -0
  13. workflow_loop/data/Standardized_Repository/global/document_writing.md +77 -0
  14. workflow_loop/data/Standardized_Repository/global/workflow_lifecycle.md +91 -0
  15. workflow_loop/data/Standardized_Repository/impl/code_implementation.md +85 -0
  16. workflow_loop/data/Standardized_Repository/impl/impl.md +164 -0
  17. workflow_loop/data/Standardized_Repository/qa/test.md +167 -0
  18. workflow_loop/data/Standardized_Repository/qa/test_code.md +121 -0
  19. workflow_loop/data/Standardized_Repository/qa/test_code_implementation.md +67 -0
  20. workflow_loop/data/Standardized_Repository/qa/test_plan.md +160 -0
  21. workflow_loop/data/Standardized_Repository/reproduce/reproduce.md +60 -0
  22. workflow_loop/data/Standardized_Repository/spec/spec.md +138 -0
  23. workflow_loop/data/Standardized_Repository/spike/spike.md +236 -0
  24. workflow_loop/data/Template_Repository/acceptance/acceptance_plan.md +142 -0
  25. workflow_loop/data/Template_Repository/acceptance/acceptance_result.md +108 -0
  26. workflow_loop/data/Template_Repository/code_design/code_design.md +260 -0
  27. workflow_loop/data/Template_Repository/code_design/project_design_init_evidence.md +39 -0
  28. workflow_loop/data/Template_Repository/impl/impl.md +112 -0
  29. workflow_loop/data/Template_Repository/qa/test.md +102 -0
  30. workflow_loop/data/Template_Repository/qa/test_plan.md +100 -0
  31. workflow_loop/data/Template_Repository/reproduce/reproduce.md +82 -0
  32. workflow_loop/data/Template_Repository/spec/spec.md +222 -0
  33. workflow_loop/data/Template_Repository/spike/spike.md +135 -0
  34. workflow_loop/installer.py +632 -0
  35. workflow_loop/journal.py +78 -0
  36. workflow_loop/path_composer.py +152 -0
  37. workflow_loop/process_runner.py +176 -0
  38. workflow_loop/project.py +397 -0
  39. workflow_loop/role_doc.py +133 -0
  40. workflow_loop/rollback.py +1738 -0
  41. workflow_loop/spike_validation.py +379 -0
  42. workflow_loop/stage_materials.py +169 -0
  43. workflow_loop/stages/__init__.py +45 -0
  44. workflow_loop/stages/base.py +164 -0
  45. workflow_loop/stages/stages.py +1191 -0
  46. workflow_loop/state.py +582 -0
  47. workflow_loop/test_entry.py +123 -0
  48. workflow_loop/test_execution.py +619 -0
  49. workflow_loop/test_mapping.py +568 -0
  50. workflow_loop/test_runner.py +134 -0
  51. workflow_loop/topic.py +114 -0
  52. workflow_loop/topic_relations.py +202 -0
  53. workflow_loop/traceability.py +533 -0
  54. workflow_loop/verification.py +971 -0
  55. workflow_loop-0.1.0.dist-info/METADATA +187 -0
  56. workflow_loop-0.1.0.dist-info/RECORD +60 -0
  57. workflow_loop-0.1.0.dist-info/WHEEL +5 -0
  58. workflow_loop-0.1.0.dist-info/entry_points.txt +2 -0
  59. workflow_loop-0.1.0.dist-info/licenses/LICENSE +21 -0
  60. workflow_loop-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,164 @@
1
+ import os
2
+ import shutil
3
+ from abc import ABC, abstractmethod
4
+ from dataclasses import dataclass
5
+
6
+ # spike stage 的临时代码、样本和原始输出目录(相对项目根)
7
+ # spike stage on_advance 时删除这个目录下的所有内容
8
+ SPIKE_TMP_DIR = os.path.join(".workflow_loop", "spike_tmp")
9
+
10
+
11
+ # 阶段材料说明:relative_path 相对 .workflow_loop/;None 表示该阶段没有这类材料,
12
+ # missing_note 用直白话明示"无",不打印不存在的伪路径。
13
+ @dataclass
14
+ class MaterialSpec:
15
+ relative_path: str | None
16
+ purpose: str
17
+ missing_note: str = ""
18
+
19
+
20
+ # Stage 策略基类(ABC)
21
+ # 每个 stage = 一个工作流环节(如 spec、acceptance_plan、test_code)
22
+ # 知道:自己叫什么、期望产出什么文件、加载哪些阶段材料、怎么校验产出、推进时做啥
23
+ # 加新 stage = 加一个子类,在 path_composer.py 的路径列表里插入
24
+ class StageStrategy(ABC):
25
+ # stage 标识名,存到 state.json 的 stage_path 和 stages 的 key
26
+ @abstractmethod
27
+ def name(self) -> str: ...
28
+
29
+ # 期望产出的文件路径列表(相对项目根),可能多个
30
+ # 用途:code_validate 检查文件存在 + discuss 打印"需产出 xxx"
31
+ @abstractmethod
32
+ def artifact_paths(self) -> list[str]: ...
33
+
34
+ # 角色文档路径(相对 .workflow_loop/),穿刺返回 None(role_doc.py 硬编码)
35
+ @abstractmethod
36
+ def role_doc_path(self) -> str | None: ...
37
+
38
+ # 阶段主文档路径(相对 .workflow_loop/)。已校准阶段指向产物文档模板;
39
+ # 方法名保留 prompt_doc_path 兼容旧代码,后续全仓迁移时统一重命名。
40
+ @abstractmethod
41
+ def prompt_doc_path(self) -> str | None: ...
42
+
43
+ # 阶段规范文档路径(相对 .workflow_loop/)。已校准阶段指向阶段工作规范。
44
+ @abstractmethod
45
+ def standard_doc_path(self) -> str | None: ...
46
+
47
+ # 第一道门的额外校验。默认阶段只记录讨论完成;impl 用它检查
48
+ # 全部实施前计划和“计划确认前代码没有变化”。
49
+ def discussion_validate(self, project_root: str, workflow_state) -> tuple[bool, str]:
50
+ return (True, "")
51
+
52
+ # 门禁的代码侧校验(第 2 道闸)
53
+ # 默认实现:检查 artifact_paths() 里的所有文件是否都存在
54
+ # 子类可重写做更复杂校验(查目录下有特定文件、查内容哈希等)
55
+ def code_validate(self, project_root: str) -> tuple[bool, str]:
56
+ # 收集不存在的文件
57
+ missing = []
58
+ # 遍历期望产出路径
59
+ for rel_path in self.artifact_paths():
60
+ # 拼完整路径
61
+ full_path = os.path.join(project_root, rel_path)
62
+ # 文件不存在 → 加入 missing
63
+ if not os.path.exists(full_path):
64
+ missing.append(rel_path)
65
+ # 全部存在 → 通过
66
+ if not missing:
67
+ return (True, f"所有期望文件存在: {self.artifact_paths()}")
68
+ # 有缺失 → 不通过
69
+ return (False, f"文件未产出: {missing}")
70
+
71
+ # stage 推进时的钩子(gate --confirmed 通过后、推进到下一 stage 前调用)
72
+ # 默认 no-op;spike stage 重写:删除 .workflow_loop/spike_tmp/ 下所有临时内容
73
+ def on_advance(self, project_root: str) -> list[str]:
74
+ return []
75
+
76
+ # 需要证明“本阶段确实修改过”的文件范围。
77
+ # 第一道门记录这些文件的哈希,第二道门比较当前内容;默认阶段不要求变化校验。
78
+ def change_tracked_paths(self, project_root: str) -> list[str]:
79
+ return []
80
+
81
+ # 附加阶段材料路径列表(discuss 命令额外加载)
82
+ # 默认空列表;project_design_init 和特定阶段按需加载共享材料。
83
+ def additional_doc_paths(self) -> list[tuple[str, str]]:
84
+ return []
85
+
86
+ # 附加阶段规范路径(只有规范,没有对应产物模板时使用)。
87
+ # 例如 impl 阶段在实施计划之外,还要加载代码开发规范。
88
+ def additional_standard_doc_paths(self) -> list[str]:
89
+ return []
90
+
91
+ # 统一阶段材料清单:按当前阶段配置生成模板、工作规范和附加材料的说明。
92
+ # 没有模板或规范时返回明示"无"的项,不创建伪路径。
93
+ # 所有环节共用这一个接口;新增环节不需要在命令入口复制拼接逻辑。
94
+ def materials(self) -> list[MaterialSpec]:
95
+ specs: list[MaterialSpec] = []
96
+ template_path = self.prompt_doc_path()
97
+ specs.append(
98
+ MaterialSpec(
99
+ relative_path=template_path,
100
+ purpose="当前阶段产物文档模板:规定最终文档应有的章节、字段和内容边界",
101
+ missing_note="" if template_path else "本阶段没有产物文档模板(不生成独立正式产物)",
102
+ )
103
+ )
104
+ standard_path = self.standard_doc_path()
105
+ specs.append(
106
+ MaterialSpec(
107
+ relative_path=standard_path,
108
+ purpose="当前阶段工作规范:规定 AI 怎样调查、讨论、执行和检查",
109
+ missing_note="" if standard_path else "本阶段没有阶段工作规范",
110
+ )
111
+ )
112
+ for extra_template, extra_standard in self.additional_doc_paths():
113
+ specs.append(
114
+ MaterialSpec(
115
+ relative_path=extra_template,
116
+ purpose="附加产物文档模板",
117
+ )
118
+ )
119
+ specs.append(
120
+ MaterialSpec(
121
+ relative_path=extra_standard,
122
+ purpose="附加阶段工作规范",
123
+ )
124
+ )
125
+ for extra_standard in self.additional_standard_doc_paths():
126
+ specs.append(
127
+ MaterialSpec(
128
+ relative_path=extra_standard,
129
+ purpose="附加开发规范:本阶段动手实现时必须遵守的代码写法",
130
+ )
131
+ )
132
+ return specs
133
+
134
+ # 该 stage 的指令文本,打印给 AI 看
135
+ @abstractmethod
136
+ def instruction(self) -> str: ...
137
+
138
+
139
+ # 清理 spike stage 的临时代码、样本和原始输出
140
+ # 删除 .workflow_loop/spike_tmp/ 下的所有内容(保留目录本身)
141
+ # 在 spike stage 的 on_advance 里调用(gate spike --confirmed 时)
142
+ # 这样临时代码在推进到 acceptance_plan 前被自动清理,只保留穿刺清单和结论文档
143
+ def clean_spike_tmp(project_root: str) -> list[str]:
144
+ # 拼出 spike_tmp 的完整路径
145
+ tmp_dir = os.path.join(project_root, SPIKE_TMP_DIR)
146
+ # 目录不存在 → 没啥可清理的
147
+ if not os.path.exists(tmp_dir):
148
+ return []
149
+ # 收集被清理的路径
150
+ cleaned = []
151
+ # 遍历 spike_tmp 下的所有条目
152
+ for entry in os.listdir(tmp_dir):
153
+ # 拼出条目路径
154
+ entry_path = os.path.join(tmp_dir, entry)
155
+ # 是目录 → 递归删
156
+ if os.path.isdir(entry_path):
157
+ shutil.rmtree(entry_path)
158
+ # 是文件 → 删单个文件
159
+ else:
160
+ os.remove(entry_path)
161
+ # 记录被清理的条目名
162
+ cleaned.append(entry)
163
+ # 返回被清理的路径列表(供 journal 记录)
164
+ return cleaned