hermes-task-framework 1.1.0__tar.gz → 1.2.1__tar.gz

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 (57) hide show
  1. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/PKG-INFO +1 -1
  2. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-external-repos-pattern/SKILL.md +7 -11
  3. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/SKILL.md +37 -37
  4. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/docs/product-requirements.md +3 -3
  5. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/auto-runner.md +1 -1
  6. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/composites/software-dev.md +1 -1
  7. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/generating-output-documents.md +1 -1
  8. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/operations/document-write.md +4 -4
  9. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/research-workflow.md +2 -2
  10. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/task-hash-naming.md +2 -2
  11. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/task-lifecycle-example.md +5 -5
  12. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/task-types/analysis.md +1 -1
  13. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/task-types/external-audit.md +1 -1
  14. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/task-types/video-production-pipeline.md +5 -5
  15. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/scripts/manage_task.py +38 -20
  16. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/scripts/task_ref.py +18 -10
  17. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/scripts/update-index.py +2 -2
  18. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/templates/CHANGELOG.md +2 -2
  19. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/templates/TASK.md +5 -5
  20. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/templates/run.py +2 -2
  21. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-edge-cases/SKILL.md +4 -4
  22. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-edge-cases/references/task-5d5a1a-recovery-example.md +6 -6
  23. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-portability/SKILL.md +8 -8
  24. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-portability/references/design-session-20260611.md +2 -2
  25. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-portability/references/pipeline-output-transition.md +2 -2
  26. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-portability/references/task-recovery-5d5a1a-example.md +5 -5
  27. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-portability/references/task-recovery-procedure.md +1 -1
  28. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-timestamp-convention/SKILL.md +2 -2
  29. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-tracker/SKILL.md +7 -8
  30. hermes_task_framework-1.2.1/hermes_task_framework/tests/test_task_root_resolution.py +122 -0
  31. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework.egg-info/PKG-INFO +1 -1
  32. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework.egg-info/SOURCES.txt +2 -1
  33. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/pyproject.toml +1 -1
  34. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/LICENSE +0 -0
  35. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/README.md +0 -0
  36. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/__init__.py +0 -0
  37. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/CHANGELOG.md +0 -0
  38. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/docs/TASKS.md +0 -0
  39. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/docs/architecture.dot +0 -0
  40. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/docs/architecture.svg +0 -0
  41. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/composites/code-review-session.md +0 -0
  42. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/composites/research.md +0 -0
  43. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/document-analysis-workflow.md +0 -0
  44. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/file-safety-lesson.md +0 -0
  45. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/operations/code-write.md +0 -0
  46. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/operations/info-search.md +0 -0
  47. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/operations/web-research.md +0 -0
  48. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/policy-time-metadata.md +0 -0
  49. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/task-format-validation.md +0 -0
  50. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/references/task-overview-discovery.md +0 -0
  51. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/scripts/__init__.py +0 -0
  52. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/scripts/convert_md_to_pdf.py +0 -0
  53. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-framework/scripts/task-runner.sh +0 -0
  54. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework/skills/task-lifecycle-portability/references/output-model-design.md +0 -0
  55. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework.egg-info/dependency_links.txt +0 -0
  56. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/hermes_task_framework.egg-info/top_level.txt +0 -0
  57. {hermes_task_framework-1.1.0 → hermes_task_framework-1.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hermes-task-framework
3
- Version: 1.1.0
3
+ Version: 1.2.1
4
4
  Summary: Structured task management skills for Hermes Agent — task creation, decomposition, stage gates
5
5
  Project-URL: Source, https://github.com/nuffin/hermes-task-framework-pip
6
6
  Requires-Python: >=3.11
@@ -130,23 +130,19 @@ This pattern extends the `task-framework` skill's directory structure. The `task
130
130
 
131
131
  For `task_reset --hard` semantics: `repos/` is never deleted by cleanup operations (same as `input/`). Custom `clean.sh` scripts can further refine which directories to protect.
132
132
 
133
- ## Kanban Escalation: Multi-Repo Tasks → Kanban
133
+ ## Optional: Escalate to External Task Manager
134
134
 
135
- When a task involves **multiple independent external repos** (e.g. cloning 5+ repos from an awesome-list for study), the work typically decomposes into parallel workstreams. The user's convention is **one kanban card per task-framework task** (not one card per sub-operation):
136
-
137
- User signal: *"一个 clone 任务创建一个 card"* / *"这是多个任务了,放到 default 看板里"*
135
+ When a task involves **multiple independent external repos** (e.g. cloning 5+ repos from an awesome-list for study), the work typically decomposes into parallel workstreams. The recommended convention is **one tracking card per task-framework task** (not one card per sub-operation):
138
136
 
139
137
  **Right approach:**
140
138
  1. Create a single task-framework task with its own `repos/` directory
141
- 2. Create one kanban card for that task, `--workspace dir:<task-path>`
142
- 3. Update the bridge db.yaml to map task hash ↔ card id
139
+ 2. If using an external task manager (kanban board, issue tracker, etc.), create one card/issue for that task and link it via the task hash
140
+ 3. Map the external card ID back to `.hermes-task.json` if your workflow requires bidirectional linking
143
141
 
144
142
  **Wrong approach:**
145
- - Creating one kanban card per individual sub-repo
143
+ - Creating one tracking card per individual sub-repo
146
144
  - Mixing unrelated work into one card
147
145
 
148
- See also: `kanban-orchestrator` skill for decomposition playbook, `kanban-bridge` for task ↔ card mapping.
149
-
150
146
  ## Custom Clean Methods (Implemented)
151
147
 
152
148
  Each task can protect sensitive directories from cleanup via a `scripts/clean.sh` script:
@@ -178,9 +174,9 @@ echo "[clean] output/ cleaned"
178
174
  - 没有 clean.sh 时回退到默认行为,不破坏现有任务
179
175
 
180
176
  **本 task 的 clean.sh 示例路径:**
181
- `tasks/20260615-213922.awesome-obsidian-vaults-cc6b3b/scripts/clean.sh`
177
+ `tasks/<ts>.<task-name>-<hash6>/scripts/clean.sh`
182
178
  该脚本保护 `repos/`、`input/`,只清理 `output/`。
183
179
 
184
180
  **Framework 集成状态:**
185
- - `task-framework` SKILL.md 已更新,记录了 clean.sh 查找顺序和模板(`~/hermes/skills/software-development/task-framework/SKILL.md` 的 Task Directory Structure 章节)
181
+ - `task-framework` SKILL.md 已更新,记录了 clean.sh 查找顺序和模板
186
182
  - `analysis` task-type 生命周期文档也加了自定义清理的提示
@@ -1,5 +1,5 @@
1
1
  ---
2
- author: Hauzer S. Lee
2
+ author: Hermes Agent
3
3
  category: software-development
4
4
  description: 'Three-layer task system: (1) methodology — decompose complex work into
5
5
  composable operations (info-search, code-write, paper-reproduce…) and composite
@@ -33,7 +33,7 @@ tags:
33
33
  - operations
34
34
  - logging
35
35
  - pdf
36
- version: 1.1.0
36
+ version: 1.2.1
37
37
  ---
38
38
 
39
39
  ---
@@ -121,28 +121,28 @@ When you receive a task request:
121
121
 
122
122
  ## Environment Variables
123
123
 
124
- This skill uses environment variables for portability across machines. After Personal Suite installation, these are set in `~/.hermes/personal/env.sh`:
124
+ This skill uses environment variables for portability across machines. After installation, these are set in `~/.hermes/env.sh`:
125
125
 
126
126
  | Variable | Default | Purpose |
127
127
  |----------|---------|---------|
128
- | `HERMES_TASKS_ROOT` | `~/studio/hermes/tasks` | Task container root (`tasks/2*/`, `tasks/inbox/`) |
129
- | `HERMES_PROJECTS_ROOT` | `~/studio/hermes/projects` | Project repos root |
128
+ | `HERMES_TASKS_ROOT` | `$HERMES_TASKS_ROOT` | Task container root (`tasks/2*/`, `tasks/inbox/`) |
129
+ | `HERMES_PROJECTS_ROOT` | `$HERMES_PROJECTS_ROOT` | Project repos root |
130
130
 
131
131
  **Usage rule:** All inline shell commands in this SKILL.md use `$HERMES_TASKS_ROOT` instead of bare `tasks/` paths. When running commands from a Hermes session, source the env file first:
132
132
 
133
133
  ```bash
134
- source ~/.hermes/personal/env.sh
134
+ source ~/.hermes/env.sh
135
135
  ```
136
136
 
137
- If the variable is unset, fall back to `~/studio/hermes/tasks` (the historical default).
137
+ Root resolution order is: `HERMES_TASKS_ROOT`, `HERMES_TASKS_DIR` compatibility alias, active-profile `tasks.data_dir`, global `tasks.data_dir`, then `~/studio/hermes/tasks`. The historical `~/.hermes/tasks` directory is compatibility-only: never create, mirror, populate, or symlink task directories there. When a custom `tasks.data_dir` is configured, it is the only task root used.
138
138
 
139
139
  ## Task Directory Structure
140
140
 
141
- The canonical tasks root is defined by `$HERMES_TASKS_ROOT` (default: `~/studio/hermes/tasks/`). All relative paths (e.g. `tasks/YYYYMMDD-*`) in documentation are relative to this root. When the user says "tasks" without qualification, this directory is the default reference — not the abstract concept of "任务". "创建一个任务" means creating a `YYYYMMDD-HHMMSS.<name>-<hash6>/` structure here using this skill.
141
+ The canonical tasks root is defined by `$HERMES_TASKS_ROOT` or configuration (default: `~/studio/hermes/tasks/`). All relative paths (e.g. `tasks/YYYYMMDD-*`) in documentation are relative to this root. When the user says "tasks" without qualification, this directory is the default reference — not the abstract concept of "任务". "创建一个任务" means creating a `YYYYMMDD-HHMMSS.<name>-<hash6>/` structure here using this skill. Task directories must be real directories; do not create task-root or task-directory symlinks.
142
142
 
143
143
  🔴 **Semantic disambiguation (important):** When the user says "任务" or "task", first determine whether they mean (a) a task-framework managed task (in `tasks/YY.../` directories) or (b) a generic concept. Clues: specific name/timestamp, operating on a task directory → (a); abstract discussion → (b). For (a), always use task-framework tools (task_create, task_set_status, etc.) — never raw `mv`/`cp`/`rm` on task directories. For (b), handle as normal conversation.
144
144
 
145
- ```\ntasks/\n├── README.md ← summary index (directory façade)\n├── TASKS.md ← aggregated checklist view (done/total per task)\n├── YYYYMMDD-HHMMSS.<task-name>-<hash6>/\n│ ├── README.md ← goal, scope, key findings\n│ ├── TASK.md ← checklist with status + checkboxes\n│ ├── CHANGELOG.md ← per-task changelog: auto-appended log of decisions, state, findings\n│ ├── MEMORY.md ← compact §-delimited durable facts (ports, rules, constraints). REQUIRED to maintain — see compact-directory-memory skill for format and trigger rules.
145
+ ```\ntasks/\n├── README.md ← summary index (directory façade)\n├── TASKS.md ← aggregated checklist view (done/total per task)\n├── YYYYMMDD-HHMMSS.<task-name>-<hash6>/\n│ ├── README.md ← goal, scope, key findings\n│ ├── TASK.md ← checklist with status + checkboxes\n│ ├── CHANGELOG.md ← per-task changelog: auto-appended log of decisions, state, findings\n│ ├── MEMORY.md ← compact §-delimited durable facts (ports, rules, constraints). REQUIRED to maintain — see your memory management skill (if available) for format and trigger rules.
146
146
  │ ├── input/ ← **source files** — NEVER deleted by cleanup operations\n│ │ (PDF, DOCX, images, REQUIREMENTS.md copied from inbox)\n│ ├── output/ ← **generated files** — CAN be safely deleted entirely\n│ │ ├── docs/ ← analysis documents, reports (for analysis tasks)\n│ │ ├── logs/ ← execution logs\n│ │ ├── tts-<hash6>/ ← pipeline phase dirs (for pipeline tasks)\n│ │ ├── RECORDING.md ← pipeline generated specs\n│ │ ├── COMPOSITING.md\n│ │ └── ...\n│ ├── inbox/ ← proposal inbox (one file/dir per idea)\n│ └── declined/ ← rejected proposals (with DECLINED.md)\n```
147
147
 
148
148
  **`input/` 目录** — 存放从 inbox 复制来的源文件(PDF、DOCX、图片、REQUIREMENTS.md 等)。**核心规则:所有删除操作不得触及 `input/`。**
@@ -283,7 +283,7 @@ tasks/<ts>.<name>-<hash6>/
283
283
  ├── recording-bd71ef/ ← browser-video-recording 的工作目录
284
284
  │ ├── video.mp4
285
285
  │ └── timeline.txt
286
- ├── compositing-c9f3a2/ ← video-audio-compositing 的工作目录
286
+ ├── compositing-c9f3a2/ ← <domain-skill> 的工作目录
287
287
  │ └── output.mp4
288
288
  ├── docs/ ← 共享文档(timestamps.json、多 phase 共用文件等)
289
289
  └── logs/
@@ -328,7 +328,7 @@ When a task has a `run.py` at its root, use it as the single entry point. The au
328
328
  |------|------|------|
329
329
  | (无标注) | 按顺序串行,在前一阶段之后执行 | `Phase 2 — 录制视频` |
330
330
  | `和 Phase X 同步进行` | 和 Phase X 并行执行 | `Phase 2 (browser-video-recording) — 和 Phase 1 同步进行, 录制视频` |
331
- | `等待 Phase X 完成` | Phase X 完成后才执行,不关心其他阶段 | `Phase 3 (video-audio-compositing) — 等待 Phase 1 完成, 等待 Phase 2 完成, 合成` |
331
+ | `等待 Phase X 完成` | Phase X 完成后才执行,不关心其他阶段 | `Phase 3 (<domain-skill>) — 等待 Phase 1 完成, 等待 Phase 2 完成, 合成` |
332
332
 
333
333
  **Implementation:** 并行阶段通过 `delegate_task()` 启动子代理执行。等待阶段通过 `process(action='wait')` 或检查输出产物来判断完成。
334
334
 
@@ -343,7 +343,7 @@ When a task has a `run.py` at its root, use it as the single entry point. The au
343
343
 
344
344
  - `text-to-speech` — 生成语音音频
345
345
  - `browser-video-recording` — 录制浏览器操作视频
346
- - `video-audio-compositing` — 合成音视频
346
+ - `<domain-skill>` — 合成音视频
347
347
 
348
348
  ## 环境要求
349
349
 
@@ -357,7 +357,7 @@ When a task has a `run.py` at its root, use it as the single entry point. The au
357
357
 
358
358
  - [ ] Phase 1 (text-to-speech) — 根据解说脚本生成 N 段音频
359
359
  - [ ] Phase 2 (browser-video-recording) — 和 Phase 1 同步进行, 录制浏览器操作视频
360
- - [ ] Phase 3 (video-audio-compositing) — 等待 Phase 1 完成, 等待 Phase 2 完成, 将音频合成到视频的正确时间点
360
+ - [ ] Phase 3 (<domain-skill>) — 等待 Phase 1 完成, 等待 Phase 2 完成, 将音频合成到视频的正确时间点
361
361
  - [ ] BREAK: 检查最终视频效果
362
362
  ```
363
363
 
@@ -417,7 +417,7 @@ Unimplemented phases (5-7 in the template) return True (skip, don't fail).
417
417
 
418
418
  用一个文件描述完整流水线,`generate_all()` 自动拆解生成各子 spec。
419
419
 
420
- 参考 `standards/video-production-spec.md`,工具入口 `video-audio-compositing/scripts/utils/production_spec.py`:
420
+ 参考 `standards/video-production-spec.md`,工具入口 `<domain-skill>/scripts/utils/production_spec.py`:
421
421
 
422
422
  ```python
423
423
  from utils.production_spec import generate_all
@@ -570,7 +570,7 @@ The agent reads TASK.md from top to bottom:
570
570
  **BREAK 行** → 执行到此时暂停,输出内容给用户。用户确认后将 `[ ] BREAK:` 改成 `[x] DONE:`,下次自动跳过。
571
571
 
572
572
 
573
- **🔴 执行纪律:非 BREAK 不停** — 完成一个 `[ ]` 项后,立即找到下一个未完成的 `[ ]` 项。如果中间没有 `[ ] BREAK:`,直接执行,绝不询问"要不要继续"。用户对停顿询问非常反感。
573
+ **🔴 执行纪律:非 BREAK 不停** — 完成一个 `[ ]` 项后,立即找到下一个未完成的 `[ ]` 项。如果中间没有 `[ ] BREAK:`,直接执行,绝不询问"要不要继续"。Frequent confirmation prompts disrupt workflow.
574
574
 
575
575
  ---
576
576
 
@@ -663,7 +663,7 @@ The script handles: directory creation (`<ts>.<name>-<hash6>/`), subdirs (`input
663
663
  执行: `uv run python <script>`
664
664
  ```
665
665
 
666
- 5. **Kanban 卡片**(如有 kanban 集成):在 `default` 看板创建卡片,卡片标题 `<task-name> [task:<目录名>]`,assignee `default`,卡片 ID 写入 `.hermes-task.json`。
666
+ 5. **(Optional) External task manager card** — if using an external task manager (kanban board, issue tracker, etc.), create a card/issue with title `<task-name> [task:<目录名>]` and store its ID in `.hermes-task.json`.
667
667
 
668
668
  Skill 的 `scripts/create_task.py` 接口约定:
669
669
 
@@ -683,7 +683,7 @@ task_hash = sys.argv[3]
683
683
  # ... skill 自己的逻辑
684
684
  ```
685
685
 
686
- **示例:** 创建带 browser-screen-record-task 模板的任务:
686
+ **示例:** 创建带 `<custom-skill>` 模板的任务:
687
687
 
688
688
  ```bash
689
689
  # Step 1: script creates base structure
@@ -825,8 +825,8 @@ python3 scripts/update-index.py # from the skill directory
825
825
  Output:
826
826
  ```
827
827
  Updated:
828
- /home/hauzer/studio/hermes/tasks/README.md (1464B)
829
- /home/hauzer/studio/hermes/tasks/TASKS.md (6912B)
828
+ $HERMES_TASKS_ROOT/README.md (1464B)
829
+ $HERMES_TASKS_ROOT/TASKS.md (6912B)
830
830
  Found 9 active tasks
831
831
  ```
832
832
 
@@ -921,17 +921,17 @@ python3 scripts/manage_task.py reset <hash_or_dir> [--no-hard]
921
921
 
922
922
  # ── 底层操作 ──
923
923
  # 初始化一个任务(创建目录 + TASK.md + CHANGELOG.md + .hermes-task.json)
924
- python3 scripts/manage_task.py init 5d5a1a
925
- python3 scripts/manage_task.py init tasks/20260605-233355.health-sales-demo-5d5a1a/
924
+ python3 scripts/manage_task.py init <hash6>
925
+ python3 scripts/manage_task.py init tasks/<ts>.<task-name>-<hash6>/
926
926
 
927
927
  # 导出任务(tar.gz)
928
- python3 scripts/manage_task.py export 5d5a1a
928
+ python3 scripts/manage_task.py export <hash6>
929
929
 
930
930
  # 导入任务
931
- python3 scripts/manage_task.py import tasks/20260605-233355.health-sales-demo-5d5a1a.tar.gz
931
+ python3 scripts/manage_task.py import tasks/<ts>.<task-name>-<hash6>.tar.gz
932
932
 
933
933
  # 按 hash 重建(查找最近 tar.gz)
934
- python3 scripts/manage_task.py rebuild 5d5a1a
934
+ python3 scripts/manage_task.py rebuild <hash6>
935
935
 
936
936
  # 一次性迁移:将旧个人存储目录下的文件迁移到统一目录
937
937
  python3 scripts/manage_task.py migrate
@@ -957,15 +957,15 @@ python3 scripts/manage_task.py list
957
957
 
958
958
  ```bash
959
959
  # 源机器:导出
960
- cd ~/studio/hermes
961
- python3 scripts/manage_task.py # from the skill directory export 5d5a1a
962
- git add tasks/*5d5a1a*.tar.gz
963
- git commit -m "export 5d5a1a"
960
+ cd "$HERMES_TASKS_ROOT"
961
+ python3 scripts/manage_task.py # from the skill directory export <hash6>
962
+ git add tasks/*<hash6>*.tar.gz
963
+ git commit -m "export <hash6>"
964
964
  git push
965
965
 
966
966
  # 目标机器:拉取 + 导入
967
967
  git pull
968
- python3 scripts/manage_task.py # from the skill directory rebuild 5d5a1a
968
+ python3 scripts/manage_task.py # from the skill directory rebuild <hash6>
969
969
  ```
970
970
 
971
971
  ### 旧任务(无 hash)的管理
@@ -993,7 +993,7 @@ After modifying any TASK.md, README.md, or log file inside a task directory, run
993
993
 
994
994
  ## Task Tracking (automatic phase completion log)
995
995
 
996
- When TASK.md includes a `## Tracking` section, orchestrators (stratis/corvan/valros)
996
+ When TASK.md includes a `## Tracking` section, orchestrators
997
997
  inject tracking instructions into each dispatched card. The executor loads
998
998
  `task-tracker` skill after each phase to:
999
999
  - Mark the phase checkbox `[x]` in TASK.md
@@ -1170,7 +1170,7 @@ check_cycles(meta) # raises ValueError on cycle
1170
1170
  |------|------|------|---------|
1171
1171
  | `TASK.md` | checklist、状态、要求 | 创建时填充 | 手动维护 |
1172
1172
  | `CHANGELOG.md` | 操作记录、决策、发现、阻塞原因 | 自动追加 | 按时间追加,永不删除 |
1173
- | `MEMORY.md` | 跨阶段的硬事实(端口、规则、公约) | 手动维护 | §-delimited, compact format; MUST use `compact-directory-memory` skill for format and trigger rules. Review after every phase completion or session that changes task state. |
1173
+ | `MEMORY.md` | 跨阶段的硬事实(端口、规则、公约) | 手动维护 | §-delimited, compact format; MUST use your memory management skill (if available) for format and trigger rules. Review after every phase completion or session that changes task state. |
1174
1174
  | `logs/` | 命令输出 | 自动生成 | 可清理 |
1175
1175
  | `.hermes-task.json` | hash、outputs、依赖 | 自动维护 | 随任务更新 |
1176
1176
 
@@ -1191,7 +1191,7 @@ check_cycles(meta) # raises ValueError on cycle
1191
1191
  ```
1192
1192
  ## 2026-06-06 13:00
1193
1193
 
1194
- **操作:** 重命名 task 目录 demo-video-production-v2 → health-sales-demo-5d5a1a
1194
+ **操作:** 重命名 task 目录 <old-name> → <task-name>-<hash6>
1195
1195
  **原因:** 遵循新命名规则,目录名需包含 hash
1196
1196
  **改动:**
1197
1197
  - 目录改名
@@ -1285,7 +1285,7 @@ python3 scripts/manage_task.py create <task-name> # from the skill directory
1285
1285
  post-flight 的 Integrity Check 会检查"本轮的复杂程度是否达到了触发条件",
1286
1286
  Pending Action Scan 会处理"达到了但没有 task 目录 → 立即补建"。
1287
1287
  CHANGELOG.md 的创建和维护是 post-flight 后置链的固定组成部分。
1288
- 同样,**当 `compact-directory-memory` skill 可用时,post-flight 应触发 MEMORY.md
1288
+ 同样,**当 your memory management skill 可用时,post-flight 应触发 MEMORY.md
1289
1289
  的审查**:检查现有事实是否过时、本 session 是否产生了需要记录的新事实。
1290
1290
 
1291
1291
  - **`.hermes-task.json` 必须在任务根目录** — 和 TASK.md 同级
@@ -1300,16 +1300,16 @@ CHANGELOG.md 的创建和维护是 post-flight 后置链的固定组成部分。
1300
1300
  | Operation catalog out of date | Add new operations as they're discovered. |
1301
1301
  | **🔴 Never fill task placeholders from conversation history** | When user says \"create a task named X\", create an empty template with all `{placeholder}` intact. Do NOT infer URL, steps, or operations from earlier chat context unless user explicitly says \"根据上面的对话\" or similar. Corrected multiple times — the user will delete and re-create if you guess. |\n| **🔴 File moves must be ln/cp + verify + rm** | Never `mv`. Use `ln <src> <dst>`, verify with `ls -la`, then `rm <src>`. |
1302
1302
  | **🔴 Missing `## 环境要求` in TASK.md** | Executor pre-flight forces this check. Always include it. |
1303
- | **🔴 Confirm CWD before creating tasks** | Project root must have `tasks/` dir. If not, confirm user expects `~/studio/hermes/tasks/` as base. |
1304
- | **🔴 "tasks" naming ambiguity + no manual management** | When user says "tasks" or "task", first disambiguate: (a) task-framework managed → use task_create/task_set_status/etc., never raw `mv`/`cp`/`rm` on task dirs; (b) generic concept → normal conversation. See `PROJECT_STRUCTURE.md` for the full convention. Corrected: manual `mv` on a task dir instead of using framework. |
1303
+ | **🔴 Confirm CWD before creating tasks** | Project root must have `tasks/` dir. If not, confirm user expects `$HERMES_TASKS_ROOT/` as base. |
1304
+ | **🔴 "tasks" naming ambiguity + no manual management** | When user says "tasks" or "task", first disambiguate: (a) task-framework managed → use task_create/task_set_status/etc., never raw `mv`/`cp`/`rm` on task dirs; (b) generic concept → normal conversation. Corrected: manual `mv` on a task dir instead of using framework. |
1305
1305
  | 🔴 Log accumulation | Clean old logs with `rm tasks/*.<name>/logs/*.YYYYMMDD-*.log`. |
1306
1306
  | 🔴 Root index files stale | After creating/updating/deleting any task, run `python3 scripts/update-index.py # from the skill directory` to regenerate both `tasks/README.md` and `tasks/TASKS.md`. Users rely on these indexes for overview. |
1307
1307
  | **🔴 Data Flow table not consulted** | In cross-skill composite tasks, a phase that produces a file (e.g. TTS → `audio_manifest.json`) must write it in the format expected by the consumer phase. The `## Data Flow` table's `格式说明` column tells you where to find that format spec. Don't guess the schema — load the referenced skill/reference file and read it. Corrected in discussion about how compositing finds audio manifest format. |
1308
1308
  | **`tasks/2*/` glob matches active tasks only** | Inbox/declined don't start with `2` — natural filtering. |
1309
1309
  | **`## Status` empty line matters** | `grep -A2` not `-A1` to skip blank line after header. |
1310
1310
  | LLM reasoning where a script would do | If you've repeated the same manual sequence twice, write a script. The LLM should handle judgment, not memorized mechanical steps. |
1311
- | **🔴 Don't stop & ask between checklist items unless there's a BREAK** | Execution Logic says: `[ ] BREAK:` → pause; `[ ]` → execute immediately. After completing one item, scan for the next unchecked `[ ]`. If there's no BREAK between them, execute it right away — do NOT ask 'do you want to continue?'. User corrected: '继续呀!!!你为什么要听下呢?这里有说要break吗?' Parallel dependencies (e.g. 'and Phase 1 同步进行') don't imply you should wait for instructions — check if the dependency is already resolved and act. |
1311
+ | **🔴 Don't stop & ask between checklist items unless there's a BREAK** | Execution Logic says: `[ ] BREAK:` → pause; `[ ]` → execute immediately. After completing one item, scan for the next unchecked `[ ]`. If there's no BREAK between them, execute it right away — do NOT ask 'do you want to continue?'. Parallel dependencies (e.g. 'and Phase 1 同步进行') don't imply you should wait for instructions — check if the dependency is already resolved and act. |
1312
1312
  | **🔴 Never modify REQUIREMENTS.md** | REQUIREMENTS.md is user-owned. If changes are needed, tell the user what to change and let them do it themselves. Do NOT edit it directly — the user won't know what changed. Corrected twice in one session. |
1313
1313
  | **🔴 Input source files go in input/, output/ is for generated files** | `task_reset --hard` does `rm -rf output/`. Any source file (PDF, DOCX, images, REQUIREMENTS.md) placed in `output/` will be lost. Always put source material in `input/`. |
1314
1314
  | **🔴 Inbox source files must be copied to task** | When creating a task from an inbox file (PDF/DOCX/etc.), copy the file into the task's `input/` directory. A Data Flow reference to `tasks/inbox/...` is fragile — the inbox item could be moved or deleted independently of the task. The task must be self-contained. |
1315
- | **🔴 Design discussion ≠ execution signal** | When the user makes observations, suggestions, or asks how a system/skill/process should work (e.g. "在从 REQUIREMENTS.md 生成 RECORDING.md 的时候,xxx 应该 yyy"), they are in **design/discussion mode**. Do NOT start executing pipeline steps or making code changes based on a design opinion. Wait for explicit go-ahead ("可以了" / "继续" / "跑吧"). Corrected with extreme frustration — user hadn't finished their thought. |
1315
+ | **🔴 Design discussion ≠ execution signal** | When the user makes observations, suggestions, or asks how a system/skill/process should work (e.g. "在从 REQUIREMENTS.md 生成 RECORDING.md 的时候,xxx 应该 yyy"), they are in **design/discussion mode**. Do NOT start executing pipeline steps or making code changes based on a design opinion. Wait for explicit go-ahead. This pattern has caused confusion in practice. |
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## 一、概述
8
8
 
9
- Task Framework 是 Hermes Personal Suite 的核心技能之一,提供从任务创建、执行到归档的完整工作流。它覆盖三层能力:
9
+ Task Framework 是 Hermes 的核心技能之一,提供从任务创建、执行到归档的完整工作流。它覆盖三层能力:
10
10
 
11
11
  - **方法论** — 如何把一句话需求拆成可执行的操作
12
12
  - **容器** — 如何在文件系统中有序组织任务产物
@@ -61,5 +61,5 @@ Task Framework 是 Hermes Personal Suite 的核心技能之一,提供从任务
61
61
  | 组件 | 关系 |
62
62
  |------|------|
63
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 管系统状态 |
64
+ | Git workflow rules | git 操作前置同步(Pre-Change Sync)和后置清理(Post-Change Workflow)(if available) |
65
+ | Memory/state backup skill (if available) | 任务的记忆备份不冲突 — task-framework 管任务内容,backup skill 管系统状态 |
@@ -29,4 +29,4 @@ Phases without an implementation should return `True` (skip, don't fail) so the
29
29
 
30
30
  ## Venv
31
31
 
32
- Use `~/.venvs/playwright/bin/python` if available (has playwright, edge-tts, matplotlib, Pillow).
32
+ Use the task's `.venv` if available (e.g. playwright, edge-tts, matplotlib, Pillow).
@@ -12,7 +12,7 @@ Standard round-trip for implementing a feature from scratch.
12
12
  5. project-tasks → 更新 TASK.md,标记完成
13
13
  ```
14
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.
15
+ > **Note on docs:** The recommended pattern is 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
16
 
17
17
  ## Loop Patterns
18
18
 
@@ -139,7 +139,7 @@ Add a `> **发文:** ... | **文号:** ... | **目标节点:** ...` li
139
139
  ```
140
140
  This script has its own markdown→HTML renderer that handles Chinese headings, pipe tables, blockquotes, lists, code blocks, and `---` horizontal rules without pandoc's YAML issue.
141
141
 
142
- 3. **Font Requirements:** This system has `WenQuanYi Zen Hei` at `/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc`. The CSS font-family MUST list this font first. Do NOT use:
142
+ 3. **Font Requirements:** Ensure a CJK font is installed (e.g., WenQuanYi Zen Hei, Noto Sans CJK). The CSS font-family MUST list an installed CJK font first. Do NOT use:
143
143
  - `Noto Sans CJK SC` (not installed)
144
144
  - `Source Han Sans SC` (not installed)
145
145
  - `SimSun` (not installed)
@@ -159,14 +159,14 @@ When writing or updating any of the four docs:
159
159
 
160
160
  ## Cross-Referencing with Session History
161
161
 
162
- When writing "as-built" docs for work already implemented, use the `conversation-message-list` skill to review the actual conversation and extract the precise set of changes:
162
+ When writing "as-built" docs for work already implemented, use the `conversation-message-list` skill (if available) to review the actual conversation and extract the precise set of changes:
163
163
 
164
164
  ```bash
165
165
  # Get the session ID for the relevant conversation
166
166
  hermes sessions list
167
167
 
168
168
  # Show compact Q&A history (no tool calls)
169
- python3 ~/.hermes/skills/hermes/conversation-message-list/scripts/list-messages.py <session_id>
169
+ python3 scripts/list-messages.py <session_id>
170
170
  ```
171
171
 
172
172
  This gives a tool-call-free list of every user question and final answer, which maps directly to feature requirements and design decisions.
@@ -177,9 +177,9 @@ This gives a tool-call-free list of every user question and final answer, which
177
177
  |---------|------------|
178
178
  | Writing only PRD without design/tech docs | Split into all four to cover product + implementation perspectives |
179
179
  | ASCII diagrams with ambiguous proportion | Mark flex ratios explicitly (`flex: 2` / `flex: 1`) in the diagram caption |
180
- | Ignoring user feedback-coupling | Use feedback-station skill to cross-reference doc sections with user feedback IDs |
180
+ | Ignoring user feedback-coupling | Use feedback-station skill (if available) to cross-reference doc sections with user feedback IDs |
181
181
  | Doc status unchanged after implementation | Update status from "需求讨论中" to actual development phase |
182
182
  | No known-issues section in tech design | Always include a backlog/Known Issues table to track gaps |
183
183
  | Overwriting existing PRD structure | Read existing doc first, then append/update sections — don't rewrite from scratch |
184
- | Writing docs from memory instead of session replay | Use `conversation-message-list` skill to re-read the actual conversation for accurate change scope |
184
+ | Writing docs from memory instead of session replay | Use `conversation-message-list` skill (if available) to re-read the actual conversation for accurate change scope |
185
185
  | Forgetting to update sibling docs | When any one doc changes, check and update all four — they form a coherent set |
@@ -109,7 +109,7 @@ Each subagent's prompt must include:
109
109
  Example task spec:
110
110
 
111
111
  ```
112
- "context": "输出文件:~/studio/project/tasks/*.research/docs/competitor-qinjia.md
112
+ "context": "输出文件:$HERMES_TASKS_ROOT/<ts>.<name>/docs/competitor-<name>.md
113
113
  格式规范:
114
114
  # 亲家科技
115
115
  ## 产品体系
@@ -132,7 +132,7 @@ delegate_task(
132
132
  )
133
133
  ```
134
134
 
135
- Max concurrent tasks for this user: 3. Time budget: ~5-10 min each.
135
+ Max concurrent tasks: 3 (adjust per environment). Time budget: ~5-10 min each.
136
136
 
137
137
  ## Compile results
138
138
 
@@ -23,8 +23,8 @@ The hash suffix at the end of the directory name ensures:
23
23
 
24
24
  Example:
25
25
  ```
26
- tasks/20260605-233355.health-sales-demo-5d5a1a/
27
- ├── .hermes-task.json ← hash: "5d5a1a", name: "health-sales-demo-5d5a1a"
26
+ tasks/<ts>.<task-name>-<hash6>/
27
+ ├── .hermes-task.json ← hash: "<hash6>", name: "<task-name>-<hash6>"
28
28
  ├── TASK.md
29
29
  └── ...
30
30
  ```
@@ -15,12 +15,12 @@ For research/documentation tasks, also create docs/:
15
15
 
16
16
  ```
17
17
  ts=$(date '+%Y%m%d-%H%M%S')
18
- mkdir -p "tasks/${ts}.kangyang-center-research/logs/"
19
- mkdir -p "tasks/${ts}.kangyang-center-research/docs/"
18
+ mkdir -p "tasks/${ts}.<task-name>/logs/"
19
+ mkdir -p "tasks/${ts}.<task-name>/docs/"
20
20
  ```
21
21
 
22
22
  Result: `tasks/20260601-164001.paper-reproduction/` (code) or
23
- `tasks/20260602-041236.kangyang-center-research/` (research)
23
+ `tasks/20260602-041236.<task-name>/` (research)
24
24
 
25
25
  ## 2. Status — active
26
26
 
@@ -106,11 +106,11 @@ tasks/
106
106
  └── error.20260601-171200.log
107
107
  ```
108
108
 
109
- For a **research/documentation task** (康养中心调研):
109
+ For a **research/documentation task** (<task-name>):
110
110
 
111
111
  ```
112
112
  tasks/
113
- └── 20260602-041236.kangyang-center-research/
113
+ └── 20260602-041236.<task-name>/
114
114
  ├── README.md ← overview + key findings summary
115
115
  ├── TASK.md ← checklist (Phase 1-5)
116
116
  ├── docs/ ← organized markdown research materials
@@ -57,4 +57,4 @@ rm -rf output/ # 删除所有生成文档和日志
57
57
 
58
58
  1. 确认所有交付物在 `output/docs/` 中
59
59
  2. 更新 TASK.md 状态为 `completed`
60
- 3. 运行 `python3 ~/.hermes/skills/software-development/task-framework/scripts/update-index.py` 更新索引
60
+ 3. 运行 `python3 scripts/update-index.py` 更新索引
@@ -53,4 +53,4 @@ rm -rf output/ # 删除所有分析文档和日志
53
53
 
54
54
  1. 确认所有交付物在 `output/docs/` 中
55
55
  2. 更新 TASK.md 状态为 `completed`
56
- 3. 运行 `python3 ~/.hermes/skills/software-development/task-framework/scripts/update-index.py` 更新索引
56
+ 3. 运行 `python3 scripts/update-index.py` 更新索引
@@ -2,10 +2,10 @@
2
2
 
3
3
  ## 创建
4
4
 
5
- 1. 通过 `task_create --skill browser-screen-record-task` 创建
5
+ 1. 通过 `task_create --skill <video-skill>` 创建
6
6
  2. 创建 `tasks/<ts>.<name>-<hash6>/` 目录,含 `input/` `output/` `scripts/`
7
7
  3. 用户填写的 `REQUIREMENTS.md` 和 `images/`(封面图片)放在 `input/`
8
- 4. `browser-screen-record-task` 的 `scripts/create_task.py` 生成初始 `TASK.md`
8
+ 4. `<video-skill>` 的 `scripts/create_task.py` 生成初始 `TASK.md`
9
9
  5. 写入 `.hermes-task.json`
10
10
 
11
11
  ## 执行
@@ -50,7 +50,7 @@ tasks/<ts>.<name>-<hash6>/
50
50
  └── .hermes-task.json
51
51
  ```
52
52
 
53
- > **迁移说明:** 现有 pipeline 任务(如 `health-sales-demo-5d5a1a`)可能还把 REQUIREMENTS.md 和 images/ 放在根目录。后续对此任务操作时,应迁移到 `input/` + `output/` 模型。
53
+ > **迁移说明:** 现有 pipeline 任务(如 `<task-name>-<hash6>`)可能还把 REQUIREMENTS.md 和 images/ 放在根目录。后续对此任务操作时,应迁移到 `input/` + `output/` 模型。
54
54
 
55
55
  ## 修改
56
56
 
@@ -62,7 +62,7 @@ tasks/<ts>.<name>-<hash6>/
62
62
  ```bash
63
63
  # 方式 A(推荐):通过 pipeline.py
64
64
  cd tasks/<ts>.<name>-<hash6>/
65
- python3 ~/.hermes/skills/media/video-production-pipeline/scripts/pipeline.py --clean
65
+ python3 <skill-path>/scripts/pipeline.py --clean
66
66
 
67
67
  # 方式 B:通用清理(input/ 安全)
68
68
  rm -rf output/
@@ -74,4 +74,4 @@ rm -rf output/
74
74
 
75
75
  1. 确认 `output/compositing-<hash6>/output.mp4` 存在且可播放(ffprobe 验证)
76
76
  2. 更新 TASK.md 状态为 `completed`
77
- 3. 运行 `python3 ~/.hermes/skills/software-development/task-framework/scripts/update-index.py` 更新索引
77
+ 3. 运行 `python3 scripts/update-index.py # from the skill directory` 更新索引
@@ -2,14 +2,14 @@
2
2
  """
3
3
  task-framework 任务生命周期管理工具
4
4
 
5
- 管理 ~/studio/hermes/tasks/ 下的任务文件(默认,可通过 config.yaml 配置)。
5
+ 管理 $HERMES_TASKS_ROOT 下的任务文件(默认,可通过 config.yaml 配置)。
6
6
  不再使用镜像目录——所有文件直接存放在任务目录下。
7
7
 
8
- 配置优先级(同 token-consumption-tracker 模式):
8
+ 配置优先级:
9
9
  1. HERMES_TASKS_ROOT 或 HERMES_TASKS_DIR 环境变量
10
10
  2. 当前 profile config.yaml: tasks.data_dir
11
11
  3. 全局 ~/.hermes/config.yaml: tasks.data_dir
12
- 4. Fallback: ~/studio/hermes/tasks
12
+ 4. Fallback: ~/studio/hermes/tasks (legacy ~/.hermes/tasks is never populated)
13
13
 
14
14
  Commands:
15
15
  create 创建新任务(目录 + hash + 元数据 + 模板 + 可选 inbox 移入)
@@ -22,17 +22,17 @@ Commands:
22
22
  reindex 重建索引文件(README.md + TASKS.md)
23
23
  init 为任务创建目录 + TASK.md + CHANGELOG.md + .hermes-task.json
24
24
  export 将任务打包为可移植 tar.gz
25
- import 从 tar.gz 恢复任务
26
- rebuild 按 hash 查找最近 tar.gz 并导入
25
+ import 从 tar.gz 或 zip 恢复任务
26
+ rebuild 按 hash 查找最近 tar.gz 或 zip 并导入
27
27
  migrate 一次性迁移:将旧存储目录下的文件迁移到统一目录
28
28
  ensure-all 全量注册所有现有任务
29
29
  """
30
- import os, sys, glob, json, shutil, re, tarfile, tempfile, hashlib, random, argparse, secrets
30
+ import os, sys, glob, json, shutil, re, tarfile, zipfile, tempfile, hashlib, random, argparse, secrets
31
31
  from datetime import datetime
32
32
  from pathlib import Path
33
33
 
34
34
 
35
- # ── config resolution (mirrors token-consumption-tracker pattern) ──
35
+ # ── config resolution ──
36
36
 
37
37
  def _read_config_yaml(config_path):
38
38
  if not config_path or not os.path.exists(str(config_path)):
@@ -46,9 +46,11 @@ def _read_config_yaml(config_path):
46
46
 
47
47
 
48
48
  def _resolve_tasks_root() -> str:
49
- """Priority chain: env → profile config → global config → fallback."""
50
- # 1. Env var
51
- env = os.environ.get("HERMES_TASKS_DIR", "").strip()
49
+ """Resolve the task root with ROOT as canonical and DIR as legacy fallback."""
50
+ # 1. Canonical env var, then the legacy pip-package compatibility alias.
51
+ env = os.environ.get("HERMES_TASKS_ROOT", "").strip()
52
+ if not env:
53
+ env = os.environ.get("HERMES_TASKS_DIR", "").strip()
52
54
  if env:
53
55
  return os.path.expanduser(env)
54
56
 
@@ -76,7 +78,7 @@ def _resolve_tasks_root() -> str:
76
78
  if val and isinstance(val, str):
77
79
  return os.path.expanduser(val)
78
80
 
79
- # 4. Fallback
81
+ # 4. Canonical fallback. Never populate the legacy ~/.hermes/tasks root.
80
82
  return os.path.expanduser("~/studio/hermes/tasks")
81
83
 
82
84
 
@@ -360,8 +362,15 @@ def cmd_import(archive_path):
360
362
  print(f"Archive not found: {archive_path}")
361
363
  return False
362
364
  with tempfile.TemporaryDirectory(prefix="task-import-") as tmp:
363
- with tarfile.open(archive_path, 'r:gz') as tar:
364
- tar.extractall(path=tmp)
365
+ if tarfile.is_tarfile(archive_path):
366
+ with tarfile.open(archive_path, 'r:gz') as tar:
367
+ tar.extractall(path=tmp)
368
+ elif zipfile.is_zipfile(archive_path):
369
+ with zipfile.ZipFile(archive_path) as archive:
370
+ archive.extractall(path=tmp)
371
+ else:
372
+ print(f"Unsupported archive format: {archive_path}")
373
+ return False
365
374
  extracted = os.listdir(tmp)
366
375
  print(f"Extracted: {extracted}")
367
376
 
@@ -415,16 +424,25 @@ def cmd_import(archive_path):
415
424
 
416
425
 
417
426
  def cmd_rebuild(hash_or_archive):
418
- if tarfile.is_tarfile(hash_or_archive):
427
+ if os.path.isfile(hash_or_archive) and (
428
+ tarfile.is_tarfile(hash_or_archive) or zipfile.is_zipfile(hash_or_archive)
429
+ ):
419
430
  return cmd_import(hash_or_archive)
420
431
  h = hash_or_archive
421
432
  if not re.match(r'^[a-z0-9]{6}$', h):
422
433
  print(f"Invalid hash: {h}")
423
434
  return False
424
- pattern = os.path.join(TASKS_ROOT, f"*{h}*.tar.gz")
425
- matches = sorted(glob.glob(pattern), key=os.path.getmtime, reverse=True)
435
+ patterns = [
436
+ os.path.join(TASKS_ROOT, f"*{h}*.tar.gz"),
437
+ os.path.join(TASKS_ROOT, f"*{h}*.zip"),
438
+ ]
439
+ matches = sorted(
440
+ [match for pattern in patterns for match in glob.glob(pattern)],
441
+ key=os.path.getmtime,
442
+ reverse=True,
443
+ )
426
444
  if not matches:
427
- print(f"No tar.gz found for hash {h} in {TASKS_ROOT}")
445
+ print(f"No tar.gz or zip found for hash {h} in {TASKS_ROOT}")
428
446
  return False
429
447
  archive = matches[0]
430
448
  print(f"Found: {archive}")
@@ -489,7 +507,7 @@ def cmd_list():
489
507
 
490
508
  def cmd_migrate():
491
509
  """One-shot migration: copy files from old personal storage to task dir."""
492
- old_root = os.path.expanduser("~/.hermes/personal/tasks")
510
+ old_root = os.path.expanduser("~/.hermes/tasks")
493
511
  if not os.path.isdir(old_root):
494
512
  print("No old personal/tasks directory to migrate from.")
495
513
  return True
@@ -592,8 +610,8 @@ def cmd_create(name, from_inbox=None, description=None):
592
610
  cl_tmpl = _load_template('CHANGELOG.md')
593
611
  if cl_tmpl:
594
612
  cl_content = cl_tmpl.replace(
595
- '## 2026-06-06 HH:MM',
596
- f"## {datetime.now().strftime('%Y-%m-%d %H:%M')}")
613
+ '## 2026-06-06 HH:MM:SS',
614
+ f"## {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
597
615
  else:
598
616
  cl_content = f"# CHANGELOG.md -- {h}\n"
599
617
  with open(os.path.join(task_dir, 'CHANGELOG.md'), 'w') as f: