cowork-flow 0.0.37 → 0.0.39

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 (111) hide show
  1. package/README.md +27 -14
  2. package/package.json +1 -1
  3. package/src/commands/init.js +39 -28
  4. package/src/commands/sync.js +2 -2
  5. package/src/lib/asset-plan.js +127 -0
  6. package/src/lib/copy-template.js +101 -141
  7. package/src/lib/host-assets.js +231 -0
  8. package/src/lib/plan-applier.js +329 -0
  9. package/src/lib/platforms.js +15 -76
  10. package/src/lib/skill-registry.js +503 -0
  11. package/template/.claude/agents/cowork-check.md +10 -1
  12. package/template/.claude/agents/cowork-implement.md +11 -2
  13. package/template/.claude/hooks/inject-workflow-state.py +51 -254
  14. package/template/.codex/agents/cowork-check.toml +12 -3
  15. package/template/.codex/agents/cowork-implement.toml +11 -2
  16. package/template/.codex/agents/default.toml +3 -2
  17. package/template/.codex/agents/explorer.toml +3 -2
  18. package/template/.codex/agents/worker.toml +2 -1
  19. package/template/.codex/hooks/inject-workflow-state.py +46 -265
  20. package/template/.cowork-flow/.version +1 -1
  21. package/template/.cowork-flow/scripts/application/__init__.py +1 -0
  22. package/template/.cowork-flow/scripts/application/batch_execution.py +743 -0
  23. package/template/.cowork-flow/scripts/application/runtime_context_service.py +365 -0
  24. package/template/.cowork-flow/scripts/application/task_archive.py +220 -0
  25. package/template/.cowork-flow/scripts/application/task_context.py +765 -0
  26. package/template/.cowork-flow/scripts/application/task_creation.py +201 -0
  27. package/template/.cowork-flow/scripts/application/task_lifecycle.py +532 -0
  28. package/template/.cowork-flow/scripts/application/task_tree.py +179 -0
  29. package/template/.cowork-flow/scripts/commands/doctor.py +78 -57
  30. package/template/.cowork-flow/scripts/commands/party_mode_v2.py +671 -425
  31. package/template/.cowork-flow/scripts/commands/subagent.py +38 -26
  32. package/template/.cowork-flow/scripts/commands/task.py +535 -1953
  33. package/template/.cowork-flow/scripts/commands/task_archive_commands.py +195 -0
  34. package/template/.cowork-flow/scripts/commands/task_context_commands.py +240 -0
  35. package/template/.cowork-flow/scripts/commands/task_create_command.py +164 -0
  36. package/template/.cowork-flow/scripts/commands/task_navigation.py +407 -0
  37. package/template/.cowork-flow/scripts/commands/task_parser.py +364 -0
  38. package/template/.cowork-flow/scripts/commands/task_support.py +76 -0
  39. package/template/.cowork-flow/scripts/commands/task_tree_commands.py +160 -0
  40. package/template/.cowork-flow/scripts/common/core/execution_context.py +161 -85
  41. package/template/.cowork-flow/scripts/common/core/host_manifest.py +393 -0
  42. package/template/.cowork-flow/scripts/common/core/skill_registry.py +568 -0
  43. package/template/.cowork-flow/scripts/common/gates/coding_standards.py +58 -7
  44. package/template/.cowork-flow/scripts/common/gates/gates.py +323 -46
  45. package/template/.cowork-flow/scripts/common/gates/models.py +196 -0
  46. package/template/.cowork-flow/scripts/common/gates/registry.py +79 -0
  47. package/template/.cowork-flow/scripts/common/gates/tdd_evidence.py +13 -13
  48. package/template/.cowork-flow/scripts/common/gates/validate_coding_standards.py +104 -62
  49. package/template/.cowork-flow/scripts/common/gates/validate_implementation.py +39 -22
  50. package/template/.cowork-flow/scripts/common/gates/validate_rules.py +223 -40
  51. package/template/.cowork-flow/scripts/common/git/git_context.py +216 -182
  52. package/template/.cowork-flow/scripts/common/host/__init__.py +1 -0
  53. package/template/.cowork-flow/scripts/common/host/workflow_state_hook.py +303 -0
  54. package/template/.cowork-flow/scripts/common/storage/__init__.py +1 -0
  55. package/template/.cowork-flow/scripts/common/storage/operation_log.py +72 -0
  56. package/template/.cowork-flow/scripts/common/storage/state_store.py +279 -0
  57. package/template/.cowork-flow/scripts/common/storage/unit_of_work.py +214 -0
  58. package/template/.cowork-flow/scripts/common/task/active_task.py +93 -135
  59. package/template/.cowork-flow/scripts/common/task/batch_mode.py +33 -120
  60. package/template/.cowork-flow/scripts/common/task/decision_review.py +85 -0
  61. package/template/.cowork-flow/scripts/common/task/readiness.py +9 -15
  62. package/template/.cowork-flow/scripts/common/task/task_repository.py +156 -0
  63. package/template/.cowork-flow/scripts/run.py +24 -0
  64. package/template/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
  65. package/template/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
  66. package/template/.cowork-flow/spec/contracts/workflow-state-templates.md +1 -1
  67. package/template/.cowork-flow/spec/protocols/decision-review.md +28 -0
  68. package/template/.cowork-flow/spec/protocols/review.md +34 -0
  69. package/template/.cowork-flow/spec/protocols/spec-maintenance.md +16 -0
  70. package/template/.cowork-flow/spec/protocols/tdd.md +30 -0
  71. package/template/.cowork-flow/spec/references/definition-of-done.md +4 -4
  72. package/template/.cowork-flow/spec/references/orchestration-patterns.md +1 -1
  73. package/template/.cowork-flow/spec/runtime/contract-registry.json +25 -0
  74. package/template/.cowork-flow/spec/runtime/host-assets.json +214 -0
  75. package/template/.cowork-flow/spec/runtime/index.md +8 -0
  76. package/template/.cowork-flow/spec/runtime/rules.json +61 -10
  77. package/template/.cowork-flow/spec/runtime/skill-registry.json +397 -0
  78. package/template/.cowork-flow/spec/schemas/host-assets.schema.json +173 -0
  79. package/template/.cowork-flow/spec/schemas/rules.schema.json +10 -1
  80. package/template/.cowork-flow/spec/schemas/skill-registry.schema.json +202 -0
  81. package/template/.cowork-flow/workflow.md +18 -13
  82. package/template/.opencode/agents/cowork-check.md +11 -0
  83. package/template/.opencode/agents/cowork-implement.md +16 -1
  84. package/template/.zcode/.zcode-plugin/plugin.json +1 -1
  85. package/template/.zcode/hooks/inject-context.js +3 -85
  86. package/template/.zcode/hooks/inject-context.selfcheck.mjs +6 -6
  87. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/decision-anchor.md +8 -2
  88. package/template/.zcode/scaffold/.cowork-flow/spec/contracts/subagent-dispatch.md +2 -4
  89. package/template/.zcode/scaffold/.cowork-flow/spec/runtime/rules.json +61 -10
  90. package/template/.zcode/scaffold/.cowork-flow/spec/schemas/rules.schema.json +10 -1
  91. package/template/.zcode/scaffold/.cowork-flow/workflow.md +18 -13
  92. package/template/.zcode/scaffold/AGENTS.md +18 -8
  93. package/template/AGENTS.md +1 -1
  94. package/template/skills/batch-mode/SKILL.md +140 -76
  95. package/template/skills/brainstorming/SKILL.md +2 -2
  96. package/template/skills/cowork-flow/SKILL.md +42 -0
  97. package/template/skills/party-mode/SHARED-BOUNDARIES.md +1 -1
  98. package/template/skills/party-mode/SKILL.md +48 -119
  99. package/template/.cowork-flow/scripts/common/gates/spec_validator.py +0 -53
  100. package/template/.cowork-flow/scripts/common/gates/validate_jsonl.py +0 -32
  101. package/template/skills/before-dev/SKILL.md +0 -41
  102. package/template/skills/check/SKILL.md +0 -53
  103. package/template/skills/check/simplification-guide.md +0 -47
  104. package/template/skills/continue/SKILL.md +0 -29
  105. package/template/skills/doubt-review/SKILL.md +0 -118
  106. package/template/skills/finish-work/SKILL.md +0 -32
  107. package/template/skills/party-mode-v2/SKILL.md +0 -75
  108. package/template/skills/start/SKILL.md +0 -78
  109. package/template/skills/tdd/SKILL.md +0 -74
  110. package/template/skills/update-spec/SKILL.md +0 -39
  111. package/template/skills/using-cowork-flow/SKILL.md +0 -80
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env python3
2
+ """Task creation application service."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import re
7
+ from dataclasses import dataclass
8
+ from datetime import datetime
9
+ from pathlib import Path
10
+
11
+ from application.task_tree import TaskTreeError, TaskTreeService
12
+ from common.core.paths import (
13
+ FILE_TASK_JSON,
14
+ ensure_task_date_prefix,
15
+ get_tasks_dir,
16
+ )
17
+ from common.task.task_repository import TaskRepository, TaskRepositoryError
18
+
19
+
20
+ class TaskCreationError(RuntimeError):
21
+ """Raised when task creation cannot be completed."""
22
+
23
+ def __init__(self, code: str, path: Path, detail: str) -> None:
24
+ self.code = code
25
+ self.path = path
26
+ self.detail = detail
27
+ super().__init__(f"{code}: {detail}: {path}")
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class TaskCreationRequest:
32
+ title: str
33
+ slug: str
34
+ assignee: str
35
+ priority: str
36
+ description: str | None = None
37
+ creator: str | None = None
38
+ parent: str | Path | None = None
39
+ from_plan: str | Path | None = None
40
+ created_at: str | None = None
41
+ date_prefix: str | None = None
42
+
43
+
44
+ @dataclass(frozen=True)
45
+ class TaskCreationResult:
46
+ task_dir: Path
47
+ directory_existed: bool
48
+ linked_parent: str | None
49
+ missing_parent: str | None
50
+ generated_anchor: bool
51
+
52
+
53
+ def ensure_tasks_dir(repo_root: Path) -> Path:
54
+ """Ensure active and archived task directories exist."""
55
+ tasks_dir = get_tasks_dir(repo_root)
56
+ tasks_dir.mkdir(parents=True, exist_ok=True)
57
+ (tasks_dir / "archive").mkdir(parents=True, exist_ok=True)
58
+ return tasks_dir
59
+
60
+
61
+ class TaskCreationService:
62
+ """Create task metadata and optional parent/plan relationships."""
63
+
64
+ def __init__(
65
+ self,
66
+ repo_root: Path,
67
+ *,
68
+ repository: TaskRepository | None = None,
69
+ tree_service: TaskTreeService | None = None,
70
+ ) -> None:
71
+ self.repo_root = Path(repo_root)
72
+ self.repository = repository or TaskRepository(self.repo_root)
73
+ self.tree_service = tree_service or TaskTreeService(
74
+ self.repo_root,
75
+ repository=self.repository,
76
+ )
77
+
78
+ def create(
79
+ self,
80
+ request: TaskCreationRequest,
81
+ ) -> TaskCreationResult:
82
+ tasks_dir = ensure_tasks_dir(self.repo_root)
83
+ task_name = self._task_name(request)
84
+ task_dir = tasks_dir / task_name
85
+ directory_existed = task_dir.exists()
86
+ task_dir.mkdir(parents=True, exist_ok=True)
87
+
88
+ created_at = request.created_at or datetime.now().strftime(
89
+ "%Y-%m-%d"
90
+ )
91
+ task_data = {
92
+ "id": request.slug,
93
+ "name": request.slug,
94
+ "title": request.title,
95
+ "description": request.description or "",
96
+ "status": "planning",
97
+ "dev_type": None,
98
+ "scope": None,
99
+ "priority": request.priority,
100
+ "creator": request.creator or request.assignee,
101
+ "assignee": request.assignee,
102
+ "createdAt": created_at,
103
+ "completedAt": None,
104
+ "commit": None,
105
+ "subtasks": [],
106
+ "children": [],
107
+ "parent": None,
108
+ "relatedFiles": [],
109
+ "notes": "",
110
+ "meta": {},
111
+ }
112
+ try:
113
+ self.repository.replace(task_dir, task_data)
114
+ except TaskRepositoryError as error:
115
+ raise TaskCreationError(
116
+ "TASK-CREATE-SAVE-001",
117
+ error.path,
118
+ error.detail,
119
+ ) from error
120
+
121
+ linked_parent = None
122
+ missing_parent = None
123
+ if request.parent:
124
+ parent_dir = self.repository.resolve(request.parent)
125
+ if not (parent_dir / FILE_TASK_JSON).is_file():
126
+ missing_parent = str(request.parent)
127
+ else:
128
+ try:
129
+ self.tree_service.link(parent_dir, task_dir)
130
+ except TaskTreeError as error:
131
+ raise TaskCreationError(
132
+ "TASK-CREATE-LINK-001",
133
+ error.path,
134
+ error.detail,
135
+ ) from error
136
+ linked_parent = parent_dir.name
137
+
138
+ generated_anchor = self._generate_anchor(
139
+ task_dir,
140
+ request.from_plan,
141
+ )
142
+ return TaskCreationResult(
143
+ task_dir=task_dir,
144
+ directory_existed=directory_existed,
145
+ linked_parent=linked_parent,
146
+ missing_parent=missing_parent,
147
+ generated_anchor=generated_anchor,
148
+ )
149
+
150
+ @staticmethod
151
+ def _task_name(request: TaskCreationRequest) -> str:
152
+ if re.match(r"^\d{2}-\d{2}-", request.slug):
153
+ return request.slug
154
+ if request.date_prefix:
155
+ return f"{request.date_prefix}-{request.slug}"
156
+ return ensure_task_date_prefix(request.slug)
157
+
158
+ @staticmethod
159
+ def _generate_anchor(
160
+ task_dir: Path,
161
+ from_plan: str | Path | None,
162
+ ) -> bool:
163
+ if not from_plan:
164
+ return False
165
+ plan_path = Path(from_plan)
166
+ if not plan_path.is_file():
167
+ return False
168
+
169
+ try:
170
+ plan_text = plan_path.read_text(encoding="utf-8")
171
+ except (OSError, UnicodeDecodeError) as error:
172
+ raise TaskCreationError(
173
+ "TASK-CREATE-PLAN-001",
174
+ plan_path,
175
+ "plan cannot be read as UTF-8",
176
+ ) from error
177
+
178
+ goal = next(
179
+ (
180
+ line.split(":", 1)[1].strip()
181
+ for line in plan_text.splitlines()
182
+ if line.startswith("**Goal:**")
183
+ or line.startswith("**目标:**")
184
+ ),
185
+ None,
186
+ )
187
+ anchor_file = task_dir / "decision-anchor.md"
188
+ if not goal or anchor_file.exists():
189
+ return False
190
+ try:
191
+ anchor_file.write_text(
192
+ f"## 目标\n\n{goal}\n\n## 验收标准\n- [ ] \n",
193
+ encoding="utf-8",
194
+ )
195
+ except OSError as error:
196
+ raise TaskCreationError(
197
+ "TASK-CREATE-PLAN-002",
198
+ anchor_file,
199
+ "decision anchor could not be written",
200
+ ) from error
201
+ return True