hermes-task-framework 1.0.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.
- hermes_task_framework-1.0.0.dist-info/METADATA +7 -0
- hermes_task_framework-1.0.0.dist-info/RECORD +56 -0
- hermes_task_framework-1.0.0.dist-info/WHEEL +5 -0
- hermes_task_framework-1.0.0.dist-info/licenses/LICENSE +1 -0
- hermes_task_framework-1.0.0.dist-info/top_level.txt +1 -0
- task-framework/__init__.py +2 -0
- task-framework/skills/task-external-repos-pattern/SKILL.md +165 -0
- task-framework/skills/task-framework/CHANGELOG.md +45 -0
- task-framework/skills/task-framework/SKILL.md +1365 -0
- task-framework/skills/task-framework/docs/TASKS.md +3 -0
- task-framework/skills/task-framework/docs/architecture.dot +65 -0
- task-framework/skills/task-framework/docs/architecture.svg +188 -0
- task-framework/skills/task-framework/docs/product-requirements.md +65 -0
- task-framework/skills/task-framework/references/auto-runner.md +32 -0
- task-framework/skills/task-framework/references/composites/code-review-session.md +30 -0
- task-framework/skills/task-framework/references/composites/research.md +45 -0
- task-framework/skills/task-framework/references/composites/software-dev.md +41 -0
- task-framework/skills/task-framework/references/document-analysis-workflow.md +95 -0
- task-framework/skills/task-framework/references/file-safety-lesson.md +38 -0
- task-framework/skills/task-framework/references/generating-output-documents.md +166 -0
- task-framework/skills/task-framework/references/operations/code-write.md +30 -0
- task-framework/skills/task-framework/references/operations/document-write.md +185 -0
- task-framework/skills/task-framework/references/operations/info-search.md +27 -0
- task-framework/skills/task-framework/references/operations/web-research.md +57 -0
- task-framework/skills/task-framework/references/policy-time-metadata.md +137 -0
- task-framework/skills/task-framework/references/research-workflow.md +220 -0
- task-framework/skills/task-framework/references/task-format-validation.md +25 -0
- task-framework/skills/task-framework/references/task-hash-naming.md +40 -0
- task-framework/skills/task-framework/references/task-lifecycle-example.md +122 -0
- task-framework/skills/task-framework/references/task-overview-discovery.md +31 -0
- task-framework/skills/task-framework/references/task-types/analysis.md +60 -0
- task-framework/skills/task-framework/references/task-types/external-audit.md +56 -0
- task-framework/skills/task-framework/references/task-types/video-production-pipeline.md +77 -0
- task-framework/skills/task-framework/scripts/__init__.py +0 -0
- task-framework/skills/task-framework/scripts/__pycache__/manage_task.cpython-312.pyc +0 -0
- task-framework/skills/task-framework/scripts/__pycache__/task_ref.cpython-312.pyc +0 -0
- task-framework/skills/task-framework/scripts/__pycache__/update-index.cpython-311.pyc +0 -0
- task-framework/skills/task-framework/scripts/__pycache__/update-index.cpython-312.pyc +0 -0
- task-framework/skills/task-framework/scripts/convert_md_to_pdf.py +236 -0
- task-framework/skills/task-framework/scripts/manage_task.py +442 -0
- task-framework/skills/task-framework/scripts/task-runner.sh +42 -0
- task-framework/skills/task-framework/scripts/task_ref.py +119 -0
- task-framework/skills/task-framework/scripts/update-index.py +293 -0
- task-framework/skills/task-framework/templates/TASK.md +114 -0
- task-framework/skills/task-framework/templates/TASK_MEMORY.md +27 -0
- task-framework/skills/task-framework/templates/run.py +187 -0
- task-framework/skills/task-lifecycle-edge-cases/SKILL.md +84 -0
- task-framework/skills/task-lifecycle-edge-cases/references/task-5d5a1a-recovery-example.md +67 -0
- task-framework/skills/task-lifecycle-portability/SKILL.md +128 -0
- task-framework/skills/task-lifecycle-portability/references/design-session-20260611.md +32 -0
- task-framework/skills/task-lifecycle-portability/references/output-model-design.md +55 -0
- task-framework/skills/task-lifecycle-portability/references/pipeline-output-transition.md +41 -0
- task-framework/skills/task-lifecycle-portability/references/task-recovery-5d5a1a-example.md +27 -0
- task-framework/skills/task-lifecycle-portability/references/task-recovery-procedure.md +63 -0
- task-framework/skills/task-timestamp-convention/SKILL.md +72 -0
- task-framework/skills/task-tracker/SKILL.md +80 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
digraph task_framework {
|
|
2
|
+
rankdir=TB;
|
|
3
|
+
bgcolor="#1a1a2e";
|
|
4
|
+
fontcolor="#e0e0e0";
|
|
5
|
+
fontname="Consolas";
|
|
6
|
+
nodesep=0.5;
|
|
7
|
+
ranksep=0.8;
|
|
8
|
+
|
|
9
|
+
node [shape=box style="filled,rounded" fontname="Consolas" fontsize=11];
|
|
10
|
+
|
|
11
|
+
subgraph cluster_0 {
|
|
12
|
+
label="方法论 (Methodology)";
|
|
13
|
+
style=filled;
|
|
14
|
+
fillcolor="#16213e";
|
|
15
|
+
fontcolor="#e0e0e0";
|
|
16
|
+
color="#0f3460";
|
|
17
|
+
|
|
18
|
+
decompose [label="任务分解\ndecompose()" fillcolor="#0f3460" fontcolor="#e0e0e0"];
|
|
19
|
+
catalog [label="操作目录\noperations/" fillcolor="#0f3460" fontcolor="#e0e0e0"];
|
|
20
|
+
composites [label="组合模式\ncomposites/" fillcolor="#0f3460" fontcolor="#e0e0e0"];
|
|
21
|
+
strategies [label="执行策略\nA/B/C/D" fillcolor="#0f3460" fontcolor="#e0e0e0"];
|
|
22
|
+
|
|
23
|
+
decompose -> catalog [color="#00a8ff" style=dashed];
|
|
24
|
+
decompose -> composites [color="#00a8ff" style=dashed];
|
|
25
|
+
decompose -> strategies [color="#00a8ff" style=dashed];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
subgraph cluster_1 {
|
|
29
|
+
label="容器 (Container)";
|
|
30
|
+
style=filled;
|
|
31
|
+
fillcolor="#1b2a3a";
|
|
32
|
+
fontcolor="#e0e0e0";
|
|
33
|
+
color="#0f3460";
|
|
34
|
+
|
|
35
|
+
taskdir [label="tasks/<ts>.<name>/" fillcolor="#1a3a5c" fontcolor="#e0e0e0"];
|
|
36
|
+
taskmd [label="TASK.md\n(checklist + BREAK)" fillcolor="#1a3a5c" fontcolor="#e0e0e0"];
|
|
37
|
+
readme [label="README.md\n(goal + summary)" fillcolor="#1a3a5c" fontcolor="#e0e0e0"];
|
|
38
|
+
logs [label="logs/\n(output + error)" fillcolor="#1a3a5c" fontcolor="#e0e0e0"];
|
|
39
|
+
docs [label="docs/\n(research findings)" fillcolor="#1a3a5c" fontcolor="#e0e0e0"];
|
|
40
|
+
inbox [label="inbox/ + declined/\n(proposal lifecycle)" fillcolor="#1a3a5c" fontcolor="#e0e0e0"];
|
|
41
|
+
|
|
42
|
+
taskdir -> taskmd [color="#00a8ff"];
|
|
43
|
+
taskdir -> readme [color="#00a8ff"];
|
|
44
|
+
taskdir -> logs [color="#00a8ff"];
|
|
45
|
+
taskdir -> docs [color="#00a8ff"];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
subgraph cluster_2 {
|
|
49
|
+
label="工具 (Tooling)";
|
|
50
|
+
style=filled;
|
|
51
|
+
fillcolor="#1e2a3a";
|
|
52
|
+
fontcolor="#e0e0e0";
|
|
53
|
+
color="#0f3460";
|
|
54
|
+
|
|
55
|
+
runner [label="task-runner.sh\n(日志封装)" fillcolor="#2a4a7c" fontcolor="#e0e0e0"];
|
|
56
|
+
pdfconv [label="convert_md_to_pdf.py\n(文档生成)" fillcolor="#2a4a7c" fontcolor="#e0e0e0"];
|
|
57
|
+
taskmd_tpl [label="templates/TASK.md\n(模板)" fillcolor="#2a4a7c" fontcolor="#e0e0e0"];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Cross-layer connections
|
|
61
|
+
strategies -> taskdir [label="创建" color="#e0a800" style=dashed];
|
|
62
|
+
catalog -> taskmd [label="填入 checklist" color="#e0a800" style=dashed];
|
|
63
|
+
taskmd -> runner [label="执行" color="#e0a800" style=dashed];
|
|
64
|
+
docs -> pdfconv [label="导出 PDF" color="#e0a800" style=dashed];
|
|
65
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
4
|
+
<!-- Generated by graphviz version 2.43.0 (0)
|
|
5
|
+
-->
|
|
6
|
+
<!-- Title: task_framework Pages: 1 -->
|
|
7
|
+
<svg width="700pt" height="527pt"
|
|
8
|
+
viewBox="0.00 0.00 700.00 527.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
9
|
+
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 523)">
|
|
10
|
+
<title>task_framework</title>
|
|
11
|
+
<polygon fill="#1a1a2e" stroke="transparent" points="-4,4 -4,-523 696,-523 696,4 -4,4"/>
|
|
12
|
+
<g id="clust1" class="cluster">
|
|
13
|
+
<title>cluster_0</title>
|
|
14
|
+
<polygon fill="#16213e" stroke="#0f3460" points="314,-341 314,-511 649,-511 649,-341 314,-341"/>
|
|
15
|
+
<text text-anchor="middle" x="481.5" y="-495.8" font-family="Consolas" font-size="14.00" fill="#e0e0e0">方法论 (Methodology)</text>
|
|
16
|
+
</g>
|
|
17
|
+
<g id="clust2" class="cluster">
|
|
18
|
+
<title>cluster_1</title>
|
|
19
|
+
<polygon fill="#1b2a3a" stroke="#0f3460" points="11,-127 11,-297 676,-297 676,-127 11,-127"/>
|
|
20
|
+
<text text-anchor="middle" x="343.5" y="-281.8" font-family="Consolas" font-size="14.00" fill="#e0e0e0">容器 (Container)</text>
|
|
21
|
+
</g>
|
|
22
|
+
<g id="clust3" class="cluster">
|
|
23
|
+
<title>cluster_2</title>
|
|
24
|
+
<polygon fill="#1e2a3a" stroke="#0f3460" points="8,-8 8,-83 491,-83 491,-8 8,-8"/>
|
|
25
|
+
<text text-anchor="middle" x="249.5" y="-67.8" font-family="Consolas" font-size="14.00" fill="#e0e0e0">工具 (Tooling)</text>
|
|
26
|
+
</g>
|
|
27
|
+
<!-- decompose -->
|
|
28
|
+
<g id="node1" class="node">
|
|
29
|
+
<title>decompose</title>
|
|
30
|
+
<path fill="#0f3460" stroke="black" d="M501.5,-480C501.5,-480 434.5,-480 434.5,-480 428.5,-480 422.5,-474 422.5,-468 422.5,-468 422.5,-456 422.5,-456 422.5,-450 428.5,-444 434.5,-444 434.5,-444 501.5,-444 501.5,-444 507.5,-444 513.5,-450 513.5,-456 513.5,-456 513.5,-468 513.5,-468 513.5,-474 507.5,-480 501.5,-480"/>
|
|
31
|
+
<text text-anchor="middle" x="468" y="-465.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">任务分解</text>
|
|
32
|
+
<text text-anchor="middle" x="468" y="-453.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">decompose()</text>
|
|
33
|
+
</g>
|
|
34
|
+
<!-- catalog -->
|
|
35
|
+
<g id="node2" class="node">
|
|
36
|
+
<title>catalog</title>
|
|
37
|
+
<path fill="#0f3460" stroke="black" d="M628.5,-385C628.5,-385 561.5,-385 561.5,-385 555.5,-385 549.5,-379 549.5,-373 549.5,-373 549.5,-361 549.5,-361 549.5,-355 555.5,-349 561.5,-349 561.5,-349 628.5,-349 628.5,-349 634.5,-349 640.5,-355 640.5,-361 640.5,-361 640.5,-373 640.5,-373 640.5,-379 634.5,-385 628.5,-385"/>
|
|
38
|
+
<text text-anchor="middle" x="595" y="-370.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">操作目录</text>
|
|
39
|
+
<text text-anchor="middle" x="595" y="-358.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">operations/</text>
|
|
40
|
+
</g>
|
|
41
|
+
<!-- decompose->catalog -->
|
|
42
|
+
<g id="edge1" class="edge">
|
|
43
|
+
<title>decompose->catalog</title>
|
|
44
|
+
<path fill="none" stroke="#00a8ff" stroke-dasharray="5,2" d="M491.29,-443.94C511.49,-429.16 540.89,-407.62 563.24,-391.26"/>
|
|
45
|
+
<polygon fill="#00a8ff" stroke="#00a8ff" points="565.42,-394 571.42,-385.26 561.29,-388.35 565.42,-394"/>
|
|
46
|
+
</g>
|
|
47
|
+
<!-- composites -->
|
|
48
|
+
<g id="node3" class="node">
|
|
49
|
+
<title>composites</title>
|
|
50
|
+
<path fill="#0f3460" stroke="black" d="M501.5,-385C501.5,-385 434.5,-385 434.5,-385 428.5,-385 422.5,-379 422.5,-373 422.5,-373 422.5,-361 422.5,-361 422.5,-355 428.5,-349 434.5,-349 434.5,-349 501.5,-349 501.5,-349 507.5,-349 513.5,-355 513.5,-361 513.5,-361 513.5,-373 513.5,-373 513.5,-379 507.5,-385 501.5,-385"/>
|
|
51
|
+
<text text-anchor="middle" x="468" y="-370.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">组合模式</text>
|
|
52
|
+
<text text-anchor="middle" x="468" y="-358.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">composites/</text>
|
|
53
|
+
</g>
|
|
54
|
+
<!-- decompose->composites -->
|
|
55
|
+
<g id="edge2" class="edge">
|
|
56
|
+
<title>decompose->composites</title>
|
|
57
|
+
<path fill="none" stroke="#00a8ff" stroke-dasharray="5,2" d="M468,-443.94C468,-430.39 468,-411.18 468,-395.47"/>
|
|
58
|
+
<polygon fill="#00a8ff" stroke="#00a8ff" points="471.5,-395.26 468,-385.26 464.5,-395.26 471.5,-395.26"/>
|
|
59
|
+
</g>
|
|
60
|
+
<!-- strategies -->
|
|
61
|
+
<g id="node4" class="node">
|
|
62
|
+
<title>strategies</title>
|
|
63
|
+
<path fill="#0f3460" stroke="black" d="M374,-385C374,-385 334,-385 334,-385 328,-385 322,-379 322,-373 322,-373 322,-361 322,-361 322,-355 328,-349 334,-349 334,-349 374,-349 374,-349 380,-349 386,-355 386,-361 386,-361 386,-373 386,-373 386,-379 380,-385 374,-385"/>
|
|
64
|
+
<text text-anchor="middle" x="354" y="-370.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">执行策略</text>
|
|
65
|
+
<text text-anchor="middle" x="354" y="-358.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">A/B/C/D</text>
|
|
66
|
+
</g>
|
|
67
|
+
<!-- decompose->strategies -->
|
|
68
|
+
<g id="edge3" class="edge">
|
|
69
|
+
<title>decompose->strategies</title>
|
|
70
|
+
<path fill="none" stroke="#00a8ff" stroke-dasharray="5,2" d="M447.09,-443.94C429.13,-429.29 403.03,-408 383.04,-391.69"/>
|
|
71
|
+
<polygon fill="#00a8ff" stroke="#00a8ff" points="385.12,-388.87 375.16,-385.26 380.7,-394.3 385.12,-388.87"/>
|
|
72
|
+
</g>
|
|
73
|
+
<!-- taskmd -->
|
|
74
|
+
<g id="node6" class="node">
|
|
75
|
+
<title>taskmd</title>
|
|
76
|
+
<path fill="#1a3a5c" stroke="black" d="M655.5,-171C655.5,-171 534.5,-171 534.5,-171 528.5,-171 522.5,-165 522.5,-159 522.5,-159 522.5,-147 522.5,-147 522.5,-141 528.5,-135 534.5,-135 534.5,-135 655.5,-135 655.5,-135 661.5,-135 667.5,-141 667.5,-147 667.5,-147 667.5,-159 667.5,-159 667.5,-165 661.5,-171 655.5,-171"/>
|
|
77
|
+
<text text-anchor="middle" x="595" y="-156.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">TASK.md</text>
|
|
78
|
+
<text text-anchor="middle" x="595" y="-144.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(checklist + BREAK)</text>
|
|
79
|
+
</g>
|
|
80
|
+
<!-- catalog->taskmd -->
|
|
81
|
+
<g id="edge9" class="edge">
|
|
82
|
+
<title>catalog->taskmd</title>
|
|
83
|
+
<path fill="none" stroke="#e0a800" stroke-dasharray="5,2" d="M595,-348.65C595,-311.83 595,-225.64 595,-181.34"/>
|
|
84
|
+
<polygon fill="#e0a800" stroke="#e0a800" points="598.5,-181.29 595,-171.29 591.5,-181.29 598.5,-181.29"/>
|
|
85
|
+
<text text-anchor="middle" x="643.5" y="-244.3" font-family="Times,serif" font-size="14.00">填入 checklist</text>
|
|
86
|
+
</g>
|
|
87
|
+
<!-- taskdir -->
|
|
88
|
+
<g id="node5" class="node">
|
|
89
|
+
<title>taskdir</title>
|
|
90
|
+
<path fill="#1a3a5c" stroke="black" d="M411,-266C411,-266 297,-266 297,-266 291,-266 285,-260 285,-254 285,-254 285,-242 285,-242 285,-236 291,-230 297,-230 297,-230 411,-230 411,-230 417,-230 423,-236 423,-242 423,-242 423,-254 423,-254 423,-260 417,-266 411,-266"/>
|
|
91
|
+
<text text-anchor="middle" x="354" y="-245.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">tasks/<ts>.<name>/</text>
|
|
92
|
+
</g>
|
|
93
|
+
<!-- strategies->taskdir -->
|
|
94
|
+
<g id="edge8" class="edge">
|
|
95
|
+
<title>strategies->taskdir</title>
|
|
96
|
+
<path fill="none" stroke="#e0a800" stroke-dasharray="5,2" d="M354,-348.99C354,-329.92 354,-298.75 354,-276.28"/>
|
|
97
|
+
<polygon fill="#e0a800" stroke="#e0a800" points="357.5,-276.03 354,-266.03 350.5,-276.03 357.5,-276.03"/>
|
|
98
|
+
<text text-anchor="middle" x="368.5" y="-308.8" font-family="Times,serif" font-size="14.00">创建</text>
|
|
99
|
+
</g>
|
|
100
|
+
<!-- taskdir->taskmd -->
|
|
101
|
+
<g id="edge4" class="edge">
|
|
102
|
+
<title>taskdir->taskmd</title>
|
|
103
|
+
<path fill="none" stroke="#00a8ff" d="M398.2,-229.94C438.5,-214.39 498.15,-191.38 541.2,-174.76"/>
|
|
104
|
+
<polygon fill="#00a8ff" stroke="#00a8ff" points="542.6,-177.97 550.67,-171.11 540.08,-171.44 542.6,-177.97"/>
|
|
105
|
+
</g>
|
|
106
|
+
<!-- readme -->
|
|
107
|
+
<g id="node7" class="node">
|
|
108
|
+
<title>readme</title>
|
|
109
|
+
<path fill="#1a3a5c" stroke="black" d="M474.5,-171C474.5,-171 373.5,-171 373.5,-171 367.5,-171 361.5,-165 361.5,-159 361.5,-159 361.5,-147 361.5,-147 361.5,-141 367.5,-135 373.5,-135 373.5,-135 474.5,-135 474.5,-135 480.5,-135 486.5,-141 486.5,-147 486.5,-147 486.5,-159 486.5,-159 486.5,-165 480.5,-171 474.5,-171"/>
|
|
110
|
+
<text text-anchor="middle" x="424" y="-156.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">README.md</text>
|
|
111
|
+
<text text-anchor="middle" x="424" y="-144.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(goal + summary)</text>
|
|
112
|
+
</g>
|
|
113
|
+
<!-- taskdir->readme -->
|
|
114
|
+
<g id="edge5" class="edge">
|
|
115
|
+
<title>taskdir->readme</title>
|
|
116
|
+
<path fill="none" stroke="#00a8ff" d="M366.84,-229.94C377.43,-215.87 392.62,-195.69 404.68,-179.67"/>
|
|
117
|
+
<polygon fill="#00a8ff" stroke="#00a8ff" points="407.79,-181.36 411.01,-171.26 402.2,-177.15 407.79,-181.36"/>
|
|
118
|
+
</g>
|
|
119
|
+
<!-- logs -->
|
|
120
|
+
<g id="node8" class="node">
|
|
121
|
+
<title>logs</title>
|
|
122
|
+
<path fill="#1a3a5c" stroke="black" d="M132.5,-171C132.5,-171 31.5,-171 31.5,-171 25.5,-171 19.5,-165 19.5,-159 19.5,-159 19.5,-147 19.5,-147 19.5,-141 25.5,-135 31.5,-135 31.5,-135 132.5,-135 132.5,-135 138.5,-135 144.5,-141 144.5,-147 144.5,-147 144.5,-159 144.5,-159 144.5,-165 138.5,-171 132.5,-171"/>
|
|
123
|
+
<text text-anchor="middle" x="82" y="-156.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">logs/</text>
|
|
124
|
+
<text text-anchor="middle" x="82" y="-144.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(output + error)</text>
|
|
125
|
+
</g>
|
|
126
|
+
<!-- taskdir->logs -->
|
|
127
|
+
<g id="edge6" class="edge">
|
|
128
|
+
<title>taskdir->logs</title>
|
|
129
|
+
<path fill="none" stroke="#00a8ff" d="M304.11,-229.94C258.24,-214.26 190.18,-190.99 141.5,-174.34"/>
|
|
130
|
+
<polygon fill="#00a8ff" stroke="#00a8ff" points="142.63,-171.03 132.03,-171.11 140.36,-177.65 142.63,-171.03"/>
|
|
131
|
+
</g>
|
|
132
|
+
<!-- docs -->
|
|
133
|
+
<g id="node9" class="node">
|
|
134
|
+
<title>docs</title>
|
|
135
|
+
<path fill="#1a3a5c" stroke="black" d="M313.5,-171C313.5,-171 192.5,-171 192.5,-171 186.5,-171 180.5,-165 180.5,-159 180.5,-159 180.5,-147 180.5,-147 180.5,-141 186.5,-135 192.5,-135 192.5,-135 313.5,-135 313.5,-135 319.5,-135 325.5,-141 325.5,-147 325.5,-147 325.5,-159 325.5,-159 325.5,-165 319.5,-171 313.5,-171"/>
|
|
136
|
+
<text text-anchor="middle" x="253" y="-156.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">docs/</text>
|
|
137
|
+
<text text-anchor="middle" x="253" y="-144.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(research findings)</text>
|
|
138
|
+
</g>
|
|
139
|
+
<!-- taskdir->docs -->
|
|
140
|
+
<g id="edge7" class="edge">
|
|
141
|
+
<title>taskdir->docs</title>
|
|
142
|
+
<path fill="none" stroke="#00a8ff" d="M335.48,-229.94C319.77,-215.48 297.06,-194.57 279.44,-178.35"/>
|
|
143
|
+
<polygon fill="#00a8ff" stroke="#00a8ff" points="281.48,-175.46 271.75,-171.26 276.74,-180.61 281.48,-175.46"/>
|
|
144
|
+
</g>
|
|
145
|
+
<!-- runner -->
|
|
146
|
+
<g id="node11" class="node">
|
|
147
|
+
<title>runner</title>
|
|
148
|
+
<path fill="#2a4a7c" stroke="black" d="M471.5,-52C471.5,-52 384.5,-52 384.5,-52 378.5,-52 372.5,-46 372.5,-40 372.5,-40 372.5,-28 372.5,-28 372.5,-22 378.5,-16 384.5,-16 384.5,-16 471.5,-16 471.5,-16 477.5,-16 483.5,-22 483.5,-28 483.5,-28 483.5,-40 483.5,-40 483.5,-46 477.5,-52 471.5,-52"/>
|
|
149
|
+
<text text-anchor="middle" x="428" y="-37.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">task-runner.sh</text>
|
|
150
|
+
<text text-anchor="middle" x="428" y="-25.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(日志封装)</text>
|
|
151
|
+
</g>
|
|
152
|
+
<!-- taskmd->runner -->
|
|
153
|
+
<g id="edge10" class="edge">
|
|
154
|
+
<title>taskmd->runner</title>
|
|
155
|
+
<path fill="none" stroke="#e0a800" stroke-dasharray="5,2" d="M570.72,-134.99C541.65,-114.62 492.87,-80.44 460.55,-57.81"/>
|
|
156
|
+
<polygon fill="#e0a800" stroke="#e0a800" points="462.51,-54.9 452.31,-52.03 458.49,-60.64 462.51,-54.9"/>
|
|
157
|
+
<text text-anchor="middle" x="540.5" y="-94.8" font-family="Times,serif" font-size="14.00">执行</text>
|
|
158
|
+
</g>
|
|
159
|
+
<!-- pdfconv -->
|
|
160
|
+
<g id="node12" class="node">
|
|
161
|
+
<title>pdfconv</title>
|
|
162
|
+
<path fill="#2a4a7c" stroke="black" d="M324,-52C324,-52 196,-52 196,-52 190,-52 184,-46 184,-40 184,-40 184,-28 184,-28 184,-22 190,-16 196,-16 196,-16 324,-16 324,-16 330,-16 336,-22 336,-28 336,-28 336,-40 336,-40 336,-46 330,-52 324,-52"/>
|
|
163
|
+
<text text-anchor="middle" x="260" y="-37.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">convert_md_to_pdf.py</text>
|
|
164
|
+
<text text-anchor="middle" x="260" y="-25.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(文档生成)</text>
|
|
165
|
+
</g>
|
|
166
|
+
<!-- docs->pdfconv -->
|
|
167
|
+
<g id="edge11" class="edge">
|
|
168
|
+
<title>docs->pdfconv</title>
|
|
169
|
+
<path fill="none" stroke="#e0a800" stroke-dasharray="5,2" d="M254.02,-134.99C255.16,-115.92 257.02,-84.75 258.37,-62.28"/>
|
|
170
|
+
<polygon fill="#e0a800" stroke="#e0a800" points="261.88,-62.22 258.98,-52.03 254.89,-61.81 261.88,-62.22"/>
|
|
171
|
+
<text text-anchor="middle" x="288" y="-94.8" font-family="Times,serif" font-size="14.00">导出 PDF</text>
|
|
172
|
+
</g>
|
|
173
|
+
<!-- inbox -->
|
|
174
|
+
<g id="node10" class="node">
|
|
175
|
+
<title>inbox</title>
|
|
176
|
+
<path fill="#1a3a5c" stroke="black" d="M198,-266C198,-266 70,-266 70,-266 64,-266 58,-260 58,-254 58,-254 58,-242 58,-242 58,-236 64,-230 70,-230 70,-230 198,-230 198,-230 204,-230 210,-236 210,-242 210,-242 210,-254 210,-254 210,-260 204,-266 198,-266"/>
|
|
177
|
+
<text text-anchor="middle" x="134" y="-251.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">inbox/ + declined/</text>
|
|
178
|
+
<text text-anchor="middle" x="134" y="-239.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(proposal lifecycle)</text>
|
|
179
|
+
</g>
|
|
180
|
+
<!-- taskmd_tpl -->
|
|
181
|
+
<g id="node13" class="node">
|
|
182
|
+
<title>taskmd_tpl</title>
|
|
183
|
+
<path fill="#2a4a7c" stroke="black" d="M135.5,-52C135.5,-52 28.5,-52 28.5,-52 22.5,-52 16.5,-46 16.5,-40 16.5,-40 16.5,-28 16.5,-28 16.5,-22 22.5,-16 28.5,-16 28.5,-16 135.5,-16 135.5,-16 141.5,-16 147.5,-22 147.5,-28 147.5,-28 147.5,-40 147.5,-40 147.5,-46 141.5,-52 135.5,-52"/>
|
|
184
|
+
<text text-anchor="middle" x="82" y="-37.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">templates/TASK.md</text>
|
|
185
|
+
<text text-anchor="middle" x="82" y="-25.2" font-family="Consolas" font-size="11.00" fill="#e0e0e0">(模板)</text>
|
|
186
|
+
</g>
|
|
187
|
+
</g>
|
|
188
|
+
</svg>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Task Framework — 产品需求文档
|
|
2
|
+
|
|
3
|
+
> **版本:** v1.0
|
|
4
|
+
> **状态:** 已投入使用
|
|
5
|
+
> **最后修改:** 2026-06-03 21:50
|
|
6
|
+
|
|
7
|
+
## 一、概述
|
|
8
|
+
|
|
9
|
+
Task Framework 是 Hermes Personal Suite 的核心技能之一,提供从任务创建、执行到归档的完整工作流。它覆盖三层能力:
|
|
10
|
+
|
|
11
|
+
- **方法论** — 如何把一句话需求拆成可执行的操作
|
|
12
|
+
- **容器** — 如何在文件系统中有序组织任务产物
|
|
13
|
+
- **工具** — 如何复用执行脚本和模板
|
|
14
|
+
|
|
15
|
+
## 二、能力范围
|
|
16
|
+
|
|
17
|
+
### 2.1 任务生命周期管理
|
|
18
|
+
|
|
19
|
+
| 阶段 | 能力 | 入口 |
|
|
20
|
+
|------|------|------|
|
|
21
|
+
| 提议 | 收件箱接收任务 idea | `tasks/inbox/` |
|
|
22
|
+
| 创建 | 自动生成时间戳目录、README、TASK.md | `task_create` |
|
|
23
|
+
| 执行 | 支持 4 种执行策略 | Inline / Script / Subagent / Cron |
|
|
24
|
+
| 跟踪 | CHECKLIST 逐项推进,BREAK 暂停点 | TASK.md |
|
|
25
|
+
| 暂停/恢复 | 跨会话持续跟踪 | Status 标记 |
|
|
26
|
+
| 完成/取消 | 归档或删除 | `task_setstatus` |
|
|
27
|
+
|
|
28
|
+
### 2.2 操作分解
|
|
29
|
+
|
|
30
|
+
将复杂任务拆解为标准操作:
|
|
31
|
+
|
|
32
|
+
- `info-search` — 多源信息搜索
|
|
33
|
+
- `code-write` — 代码实现
|
|
34
|
+
- `paper-reproduce` — 论文复现
|
|
35
|
+
- `file-concat` / `file-convert` — 文件加工
|
|
36
|
+
- `document-write` — 文档编写
|
|
37
|
+
- `code-review` — 代码审查
|
|
38
|
+
- `data-analysis` — 数据分析
|
|
39
|
+
- `infra-setup` — 基础设施
|
|
40
|
+
|
|
41
|
+
### 2.3 组合模式
|
|
42
|
+
|
|
43
|
+
预定义的常见工作流序列:
|
|
44
|
+
|
|
45
|
+
- `software-dev` — 调研→设计→编码→审查
|
|
46
|
+
- `research` — 搜索→分析→报告
|
|
47
|
+
- `code-review-session` — 审查→记录→更新
|
|
48
|
+
|
|
49
|
+
## 三、用户故事
|
|
50
|
+
|
|
51
|
+
| ID | 用户故事 |
|
|
52
|
+
|----|----------|
|
|
53
|
+
| US-01 | 作为用户,我希望一句话告诉助手我要做什么,助手自动拆成可执行的 checklist |
|
|
54
|
+
| US-02 | 作为用户,我希望任务在执行中途可以暂停,我确认后再继续 |
|
|
55
|
+
| US-03 | 作为用户,我希望每次执行的输出自动保存,方便追溯 |
|
|
56
|
+
| US-04 | 作为用户,我希望临时想到的任务可以先放到收件箱,稍后再决定是否做 |
|
|
57
|
+
| US-05 | 作为用户,我希望不同类型的任务(调研、编码、文档)有不同的 checklist 模板 |
|
|
58
|
+
|
|
59
|
+
## 四、与 Hermes 生态的关系
|
|
60
|
+
|
|
61
|
+
| 组件 | 关系 |
|
|
62
|
+
|------|------|
|
|
63
|
+
| `quality-gate` skill | 任务修改后自动触发质量门禁 |
|
|
64
|
+
| `GIT.md` rule | git 操作前置同步(Pre-Change Sync)和后置清理(Post-Change Workflow) |
|
|
65
|
+
| `dump-to-stage` skill | 任务的记忆备份不冲突 — task-framework 管任务内容,dump-to-stage 管系统状态 |
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Auto-Runner (run.py) Pattern
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
Multi-phase tasks with a checklist in TASK.md. Create a single `run.py` at the task root that dispatches to individual phase scripts.
|
|
6
|
+
|
|
7
|
+
## Structure
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
./run.py — auto: find first unchecked item & execute
|
|
11
|
+
./run.py phase<N> — run specific phase
|
|
12
|
+
./run.py list — show checklist status
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Auto Mode Logic
|
|
16
|
+
|
|
17
|
+
1. Read TASK.md checklist, find first `[ ]` item
|
|
18
|
+
2. If it's a **BREAK**, mark it `[x]` and continue to next item
|
|
19
|
+
3. Execute phases until next `[ ] BREAK` or end of list
|
|
20
|
+
4. Mark each completed phase as `[x]`
|
|
21
|
+
|
|
22
|
+
## Phase Runners
|
|
23
|
+
|
|
24
|
+
Each phase runner calls an individual script (e.g. `scripts/gen_tts.py`, `scripts/record_timeline.py`, `scripts/composite.py`).
|
|
25
|
+
|
|
26
|
+
## Unimplemented Phases
|
|
27
|
+
|
|
28
|
+
Phases without an implementation should return `True` (skip, don't fail) so the auto-runner can progress past them to the next BREAK.
|
|
29
|
+
|
|
30
|
+
## Venv
|
|
31
|
+
|
|
32
|
+
Use `~/.venvs/playwright/bin/python` if available (has playwright, edge-tts, matplotlib, Pillow).
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Composite: Code Review Session
|
|
2
|
+
|
|
3
|
+
For a batch review of changes — diff analysis, quality gate, security scan, and report generation.
|
|
4
|
+
|
|
5
|
+
## Sequence
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
1. 加载 TASK.md / 确认审查范围
|
|
9
|
+
2. code-review → 逐个文件审阅(diff, security, quality gate)
|
|
10
|
+
3. document-write → 写 review/SUMMARY.md(S-XXX 建议表)
|
|
11
|
+
4. 更新 TASK.md 状态
|
|
12
|
+
5. (optional) quality-gate → 跑完整质量门禁
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Checklist Template
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
- [ ] Phase 1 — Understand what changed (git diff, scope)
|
|
19
|
+
- [ ] Phase 2 — Review each file (logic, security, style)
|
|
20
|
+
- [ ] Phase 3 — Run quality gate
|
|
21
|
+
- [ ] Phase 4 — Write review/SUMMARY.md with S-XXX items
|
|
22
|
+
- [ ] BREAK: 审查结果是否接受?
|
|
23
|
+
- [ ] Phase 5 — Fix critical issues / mark non-blockers
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Pitfalls
|
|
27
|
+
|
|
28
|
+
- **Scope confusion** — confirm which changes are being reviewed before starting. A session with mixed concerns produces unusable review output
|
|
29
|
+
- **S-XXX numbering** — each issue gets a unique S-XXX ID. New session → continue from last S-XXX, don't restart at S-001
|
|
30
|
+
- **Don't skip quality gate** — review without quality gate misses automated issues (lint, type errors, test failures)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Composite: Research Task
|
|
2
|
+
|
|
3
|
+
For open-ended investigation — competitor analysis, policy study, tech feasibility exploration.
|
|
4
|
+
|
|
5
|
+
## Sequence
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
1. info-search → 多源搜索(竞品、论文、政策、产品)
|
|
9
|
+
2. data-analysis → 整理发现、归类、对比
|
|
10
|
+
3. document-write → 写出调研报告
|
|
11
|
+
4. (optional) paper-reproduce → 如有论文需要复现
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Directory Structure
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
tasks/<ts>.<name>/
|
|
18
|
+
├── README.md ← 调研总结(最初空,随进度更新)
|
|
19
|
+
├── TASK.md ← 分解后的操作 checklist
|
|
20
|
+
├── docs/
|
|
21
|
+
│ ├── competitor-<company>.md ← 每家公司一份
|
|
22
|
+
│ ├── paper-<short-title>.md ← 每篇论文一份
|
|
23
|
+
│ ├── policy-<region>.md ← 每个政策/报告一份
|
|
24
|
+
│ └── architecture-proposal.md ← 方案建议
|
|
25
|
+
└── logs/
|
|
26
|
+
└── ...
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Checklist Template
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
- [ ] Phase 1 — Define scope & targets
|
|
33
|
+
- [ ] Phase 2 — Collect sources (info-search)
|
|
34
|
+
- [ ] Phase 3 — Organize & analyze findings
|
|
35
|
+
- [ ] Phase 4 — Write summary report
|
|
36
|
+
- [ ] BREAK: 调研结果是否足够?
|
|
37
|
+
- [ ] Phase 5 — (optional) Architecture proposal / recommendation
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Pitfalls
|
|
41
|
+
|
|
42
|
+
- **Scope creep** — agree on search scope before starting, or research goes infinite
|
|
43
|
+
- **Source freshness** — note retrieval date on each doc; stale info = worse than no info
|
|
44
|
+
- **Organize as you go** — don't wait until the end to write docs/ files. Write one file per source immediately after collecting it
|
|
45
|
+
- **Summary table in README** — after collecting all docs, update README.md with a table linking each doc
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Composite: Software Development
|
|
2
|
+
|
|
3
|
+
Standard round-trip for implementing a feature from scratch.
|
|
4
|
+
|
|
5
|
+
## Sequence
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
1. info-search → 调研现有方案、技术选型、竞品参考
|
|
9
|
+
2. document-write → 写四份文档(产品需求 / 产品设计 / 技术需求 / 技术设计)
|
|
10
|
+
3. code-write → 实现(建议 TDD:先写测试再写代码)
|
|
11
|
+
4. code-review → 自审查提交前的完整改动
|
|
12
|
+
5. project-tasks → 更新 TASK.md,标记完成
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
> **Note on docs:** The user prefers a four-doc split for feature work: 产品需求 (PRD), 产品设计 (product design), 技术需求 (TRD), 技术设计 (technical design). See `references/operations/document-write.md` for details. For small/straightforward features, a PRD+TRD pair may suffice — use judgment.
|
|
16
|
+
|
|
17
|
+
## Loop Patterns
|
|
18
|
+
|
|
19
|
+
The sequence isn't always linear. Common loops:
|
|
20
|
+
|
|
21
|
+
- **PRD iteration**: 2 ↔ 用户 — 需求讨论 → 改 PRD → 再讨论
|
|
22
|
+
- **Dev iteration**: 3 ↔ 4 — review 发现问题 → 修复 → 重新 review
|
|
23
|
+
- **Architecture re-evaluation**: 3 → 1 — 实现中发现更好的方案 → 重新调研
|
|
24
|
+
|
|
25
|
+
## Checklist Template
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
- [ ] Phase 1 — Research & design (info-search + document-write)
|
|
29
|
+
- [ ] BREAK: 方案确认后再实现
|
|
30
|
+
- [ ] Phase 2 — Implementation (code-write with TDD)
|
|
31
|
+
- [ ] Phase 3 — Review & fix (code-review)
|
|
32
|
+
- [ ] BREAK: 审查结果是否接受?
|
|
33
|
+
- [ ] Phase 4 — Finalize & update task status
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Pitfalls
|
|
37
|
+
|
|
38
|
+
- **Starting coding without design** — always do info-search + document-write first. Writing code without a plan is the #1 cause of rework.
|
|
39
|
+
- **Forgetting BREAK points** — PRD review and code review both need a checkpoint. Add BREAK between phases.
|
|
40
|
+
- **Single big commit** — commit per operation, not one giant commit at the end. Each commit should be a coherent unit.
|
|
41
|
+
- **Skipping tests** — code-write without tests means code-review has no safety net. Always include tests.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Document Analysis Workflow (PPT / PDF)
|
|
2
|
+
|
|
3
|
+
When a project task involves analyzing a document (PPTX, PDF, DOCX), follow this pattern to extract content and produce structured docs.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Create a project venv if one doesn't exist:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd <project-root>
|
|
11
|
+
uv venv
|
|
12
|
+
source .venv/bin/activate
|
|
13
|
+
uv pip install python-pptx # for PPTX files
|
|
14
|
+
# or for PDF: uv pip install pymupdf (marker-pdf for complex PDFs)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Step 1 — Write an extraction script
|
|
18
|
+
|
|
19
|
+
Do NOT use inline heredocs for Python scripts — shell quoting issues (nested quotes, `\n`, f-strings) are guaranteed to fail. Write a `.py` file under the task's `scripts/` dir instead.
|
|
20
|
+
|
|
21
|
+
Example (`scripts/extract_ppt.py`):
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
#!/usr/bin/env python3
|
|
25
|
+
"""Extract all text and structure from a PPT."""
|
|
26
|
+
|
|
27
|
+
from pptx import Presentation
|
|
28
|
+
import os
|
|
29
|
+
|
|
30
|
+
# Resolve the PPT path relative to the script
|
|
31
|
+
pptx_path = os.path.join(
|
|
32
|
+
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
|
33
|
+
"S-filename.pptx"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
prs = Presentation(pptx_path)
|
|
37
|
+
print(f"Total slides: {len(prs.slides)}")
|
|
38
|
+
|
|
39
|
+
for i, slide in enumerate(prs.slides, 1):
|
|
40
|
+
print(f"\n{'='*80}")
|
|
41
|
+
print(f"SLIDE {i}")
|
|
42
|
+
print(f"{'='*80}")
|
|
43
|
+
|
|
44
|
+
for shape in slide.shapes:
|
|
45
|
+
text = ""
|
|
46
|
+
has_image = False
|
|
47
|
+
|
|
48
|
+
if shape.has_text_frame:
|
|
49
|
+
for para in shape.text_frame.paragraphs:
|
|
50
|
+
t = para.text.strip()
|
|
51
|
+
if t:
|
|
52
|
+
text += t + "\n"
|
|
53
|
+
|
|
54
|
+
if shape.shape_type == 13: # Picture
|
|
55
|
+
has_image = True
|
|
56
|
+
|
|
57
|
+
if text.strip() or has_image:
|
|
58
|
+
tag = " [IMAGE]" if has_image else ""
|
|
59
|
+
print(f"\n [{shape.name}]{tag}")
|
|
60
|
+
if text.strip():
|
|
61
|
+
for line in text.strip().split("\n"):
|
|
62
|
+
print(f" {line}")
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Step 2 — Save raw output to logs/
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
cd <project-root>
|
|
69
|
+
source .venv/bin/activate
|
|
70
|
+
ts=$(date '+%Y%m%d-%H%M%S')
|
|
71
|
+
python3 tasks/*.<task-name>/scripts/extract_ppt.py \
|
|
72
|
+
> "tasks/*.<task-name>/logs/output.${ts}.log" 2>&1
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Step 3 — Analyze and write structured docs to docs/
|
|
76
|
+
|
|
77
|
+
Organize findings into focused markdown files under `docs/`. Each file covers one domain:
|
|
78
|
+
|
|
79
|
+
| File | Content |
|
|
80
|
+
|------|---------|
|
|
81
|
+
| `docs/01-project-background.md` | Background, policy, market analysis |
|
|
82
|
+
| `docs/02-project-plan.md` | Architecture, technical solution, product design |
|
|
83
|
+
| `docs/03-cost-and-roadmap.md` | Budget, timeline, investment analysis |
|
|
84
|
+
| `docs/04-cooperation-resources.md` | Partners, team, training resources |
|
|
85
|
+
| `docs/05-benefits-and-outlook.md` | Economic/social benefits, forecasts |
|
|
86
|
+
| `docs/06-product-requirements-summary.md` | PRD-style consolidated summary |
|
|
87
|
+
|
|
88
|
+
Number prefix (`01-`, `02-`...) ensures chronological ordering in `ls` and file explorers. Use meaningful topic names, not `slide-notes.md`.
|
|
89
|
+
|
|
90
|
+
## Pitfalls
|
|
91
|
+
|
|
92
|
+
- **Heredoc quoting fails** — Python f-strings with `\n`, nested quotes, and shell variable expansion in heredoc bodies all break. Always write extraction scripts to a `.py` file.
|
|
93
|
+
- **python-pptx cannot extract embedded images' text content** — charts in image-only slides yield `[IMAGE]` with no text. Note these in docs as "diagram — see PPT directly."
|
|
94
|
+
- **Chinese text truncation** — `sed -n '3p'` on README.md with Chinese characters may truncate mid-character if `head -c` cuts at the wrong byte boundary. Use `head -c 60 | head -n 1` to avoid splitting multi-byte chars.
|
|
95
|
+
- **Blank lines after `## Status`** — TASK.md format has `## Status` → blank line → status value. `grep -A1` picks up the blank line; use `grep -A2` + `tail -1` to get the actual status. Both code snippets and pitfall text must use `-A2`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# File Safety Lesson — 50MB PPT Loss (2026-06-02)
|
|
2
|
+
|
|
3
|
+
## What happened
|
|
4
|
+
|
|
5
|
+
A 50MB PPT file (`灵泽——心脑血管主动健康示范(5.18).pptx`) was lost during `task_inbox_accept`. The `mv` command appeared to succeed (no error output, `ls -la` immediately after showed the file at the destination), but the file was later found to be gone — neither at source nor destination.
|
|
6
|
+
|
|
7
|
+
## Root cause
|
|
8
|
+
|
|
9
|
+
`mv` with Chinese filenames across a shell heredoc boundary can silently fail due to encoding/path resolution issues. **No error message was produced** — the `mv` appeared successful but the file never actually arrived.
|
|
10
|
+
|
|
11
|
+
## The fix
|
|
12
|
+
|
|
13
|
+
Never use `mv` for file moves. Always use a two-step approach:
|
|
14
|
+
|
|
15
|
+
1. **Step 1 — Create hard link (or copy)**
|
|
16
|
+
- Same filesystem: `ln <src> <dst>` (instant, no space cost)
|
|
17
|
+
- Cross-filesystem or symlink: `cp <src> <dst>` (slower but safe)
|
|
18
|
+
|
|
19
|
+
2. **Step 2 — Verify then delete**
|
|
20
|
+
```
|
|
21
|
+
ls -la <dst>/ && rm -rf <src>
|
|
22
|
+
```
|
|
23
|
+
The `&&` ensures the delete only runs if verification succeeds.
|
|
24
|
+
|
|
25
|
+
## Verification checklist after ANY file move
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# 1. Confirm destination exists
|
|
29
|
+
ls -la <dst>/ # must show the file
|
|
30
|
+
# 2. Check file size matches
|
|
31
|
+
ls -l <dst>/<file> # compare with expected size
|
|
32
|
+
# 3. Only then remove source
|
|
33
|
+
rm -rf <src>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Why this matters for Hermes agents
|
|
37
|
+
|
|
38
|
+
Terminal commands may produce false positives — an `mv` that prints no error can still fail silently. The agent's shell session, encoding context, and CWD may differ from what the command expects. Two-step ln/cp+rm with explicit ls verification eliminates this class of bug.
|