cowork-flow 0.0.3 → 0.0.5

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 (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -10
  3. package/package.json +6 -4
  4. package/src/lib/copy-template.js +15 -11
  5. package/src/lib/package-info.js +8 -2
  6. package/template/.agent/skills/agent-team-execution/SKILL.md +26 -0
  7. package/template/{.superpowers → .agent/skills}/brainstorming/SKILL.md +1 -1
  8. package/template/{.superpowers → .agent/skills}/brainstorming/scripts/start-server.sh +0 -0
  9. package/template/{.superpowers → .agent/skills}/brainstorming/scripts/stop-server.sh +0 -0
  10. package/template/.agent/skills/record-session/SKILL.md +8 -8
  11. package/template/.agent/skills/start/SKILL.md +29 -24
  12. package/template/.cowork-flow/.version +1 -1
  13. package/template/.cowork-flow/agent-team/adapters.yaml +15 -0
  14. package/template/.cowork-flow/agent-team/agents.yaml +68 -0
  15. package/template/.cowork-flow/agent-team/policy.yaml +23 -0
  16. package/template/.cowork-flow/config.yaml +9 -0
  17. package/template/.cowork-flow/run +166 -0
  18. package/template/.cowork-flow/run.cmd +198 -0
  19. package/template/.cowork-flow/scripts/add_session.py +2 -2
  20. package/template/.cowork-flow/scripts/agent_team.py +508 -0
  21. package/template/.cowork-flow/scripts/change.py +5 -11
  22. package/template/.cowork-flow/scripts/common/agent_team.py +241 -0
  23. package/template/.cowork-flow/scripts/common/config.py +18 -0
  24. package/template/.cowork-flow/scripts/common/developer.py +1 -1
  25. package/template/.cowork-flow/scripts/common/git_context.py +21 -4
  26. package/template/.cowork-flow/scripts/get_context.py +2 -2
  27. package/template/.cowork-flow/scripts/init_developer.py +1 -1
  28. package/template/.cowork-flow/scripts/task.py +45 -45
  29. package/template/.cowork-flow/workflow.md +61 -175
  30. package/template/.cowork-flow/workspace/index.md +3 -3
  31. package/template/.superpowers/executing-plans/SKILL.md +2 -0
  32. package/template/AGENTS.md +6 -3
  33. /package/template/{.superpowers → .agent/skills}/brainstorming/scripts/frame-template.html +0 -0
  34. /package/template/{.superpowers → .agent/skills}/brainstorming/scripts/helper.js +0 -0
  35. /package/template/{.superpowers → .agent/skills}/brainstorming/scripts/server.cjs +0 -0
  36. /package/template/{.superpowers → .agent/skills}/brainstorming/spec-document-reviewer-prompt.md +0 -0
  37. /package/template/{.superpowers → .agent/skills}/brainstorming/visual-companion.md +0 -0
  38. /package/template/{.superpowers → .agent/skills}/requesting-code-review/SKILL.md +0 -0
  39. /package/template/{.superpowers → .agent/skills}/requesting-code-review/code-reviewer.md +0 -0
  40. /package/template/{.superpowers → .agent/skills}/subagent-driven-development/SKILL.md +0 -0
  41. /package/template/{.superpowers → .agent/skills}/subagent-driven-development/code-quality-reviewer-prompt.md +0 -0
  42. /package/template/{.superpowers → .agent/skills}/subagent-driven-development/implementer-prompt.md +0 -0
  43. /package/template/{.superpowers → .agent/skills}/subagent-driven-development/spec-reviewer-prompt.md +0 -0
  44. /package/template/{.superpowers → .agent/skills}/writing-plans/SKILL.md +0 -0
  45. /package/template/{.superpowers → .agent/skills}/writing-plans/plan-document-reviewer-prompt.md +0 -0
@@ -0,0 +1,241 @@
1
+ """Helpers for the cowork-flow agent team runtime."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import re
7
+ from pathlib import Path
8
+
9
+
10
+ TASK_RE = re.compile(r"^### Task\s+(\d+):\s*(.+?)\s*$")
11
+ FILE_RE = re.compile(r"^-\s+(Create|Modify|Test):\s+`([^`]+)`")
12
+ DEP_RE = re.compile(r"depends on Task\s+(\d+)", re.IGNORECASE)
13
+
14
+
15
+ def parse_plan(text: str) -> list[dict[str, object]]:
16
+ tasks: list[dict[str, object]] = []
17
+ current: dict[str, object] | None = None
18
+
19
+ for raw_line in text.splitlines():
20
+ line = raw_line.rstrip()
21
+ task_match = TASK_RE.match(line)
22
+ if task_match:
23
+ current = {
24
+ "number": int(task_match.group(1)),
25
+ "id": f"T{int(task_match.group(1)):03d}",
26
+ "title": task_match.group(2),
27
+ "files": [],
28
+ "steps": [],
29
+ "commands": [],
30
+ "explicit_dependencies": [],
31
+ }
32
+ tasks.append(current)
33
+ continue
34
+
35
+ if current is None:
36
+ continue
37
+
38
+ file_match = FILE_RE.match(line.strip())
39
+ if file_match:
40
+ current["files"].append(
41
+ {
42
+ "kind": file_match.group(1).lower(),
43
+ "path": file_match.group(2),
44
+ }
45
+ )
46
+ continue
47
+
48
+ stripped = line.strip()
49
+ if stripped.startswith("- [ ]"):
50
+ current["steps"].append(stripped)
51
+ continue
52
+
53
+ if stripped.startswith("Run:"):
54
+ current["commands"].append(stripped.removeprefix("Run:").strip())
55
+
56
+ dep_match = DEP_RE.search(stripped)
57
+ if dep_match:
58
+ current["explicit_dependencies"].append(f"T{int(dep_match.group(1)):03d}")
59
+
60
+ return tasks
61
+
62
+
63
+ def _task_files(task: dict[str, object]) -> set[str]:
64
+ files = task.get("files", [])
65
+ if not isinstance(files, list):
66
+ return set()
67
+ paths = set()
68
+ for item in files:
69
+ if isinstance(item, dict) and isinstance(item.get("path"), str):
70
+ paths.add(item["path"])
71
+ return paths
72
+
73
+
74
+ def _task_dependencies(tasks: list[dict[str, object]]) -> list[dict[str, str]]:
75
+ dependencies: list[dict[str, str]] = []
76
+ for index, task in enumerate(tasks):
77
+ task_id = str(task["id"])
78
+ task_files = _task_files(task)
79
+
80
+ explicit = task.get("explicit_dependencies", [])
81
+ if isinstance(explicit, list):
82
+ for dependency in explicit:
83
+ dependencies.append(
84
+ {
85
+ "task": task_id,
86
+ "depends_on_task": str(dependency),
87
+ "reason": "explicit",
88
+ }
89
+ )
90
+
91
+ for previous in tasks[:index]:
92
+ previous_files = _task_files(previous)
93
+ if task_files.intersection(previous_files):
94
+ dependencies.append(
95
+ {
96
+ "task": task_id,
97
+ "depends_on_task": str(previous["id"]),
98
+ "reason": "file-overlap",
99
+ }
100
+ )
101
+
102
+ return dependencies
103
+
104
+
105
+ def _role_agent(role: str) -> tuple[str, str]:
106
+ if role == "implementer":
107
+ return ("implementer", "worker")
108
+ if role == "spec-reviewer":
109
+ return ("spec-reviewer", "default")
110
+ return ("quality-reviewer", "default")
111
+
112
+
113
+ def build_dispatch_plan(tasks: list[dict[str, object]]) -> dict[str, object]:
114
+ assignments: list[dict[str, object]] = []
115
+ task_dependencies = _task_dependencies(tasks)
116
+ dependency_lookup: dict[str, list[str]] = {}
117
+ for dependency in task_dependencies:
118
+ dependency_lookup.setdefault(dependency["task"], []).append(dependency["depends_on_task"])
119
+
120
+ for task in tasks:
121
+ task_id = str(task["id"])
122
+ task_dependency_assignments = [
123
+ f"{dependency}-quality-reviewer"
124
+ for dependency in dependency_lookup.get(task_id, [])
125
+ ]
126
+ chain = [
127
+ ("implementer", task_dependency_assignments),
128
+ ("spec-reviewer", [f"{task_id}-implementer"]),
129
+ ("quality-reviewer", [f"{task_id}-spec-reviewer"]),
130
+ ]
131
+ for role, depends_on in chain:
132
+ agent, codex_type = _role_agent(role)
133
+ assignments.append(
134
+ {
135
+ "id": f"{task_id}-{role}",
136
+ "task": task_id,
137
+ "title": task["title"],
138
+ "role": role,
139
+ "recommended_agent": agent,
140
+ "codex_type": codex_type,
141
+ "depends_on": depends_on,
142
+ "files": task.get("files", []),
143
+ "steps": task.get("steps", []),
144
+ "commands": task.get("commands", []),
145
+ }
146
+ )
147
+
148
+ return {
149
+ "version": 1,
150
+ "adapter": "codex",
151
+ "tasks": tasks,
152
+ "task_dependencies": task_dependencies,
153
+ "assignments": assignments,
154
+ }
155
+
156
+
157
+ def render_dispatch_plan(dispatch_plan: dict[str, object]) -> str:
158
+ lines = [
159
+ "version: 1",
160
+ f"adapter: {dispatch_plan['adapter']}",
161
+ "task_dependencies:",
162
+ ]
163
+ for dependency in dispatch_plan["task_dependencies"]:
164
+ lines.extend(
165
+ [
166
+ f" - task: {dependency['task']}",
167
+ f" depends_on_task: {dependency['depends_on_task']}",
168
+ f" reason: {dependency['reason']}",
169
+ ]
170
+ )
171
+ lines.append("assignments:")
172
+ for assignment in dispatch_plan["assignments"]:
173
+ lines.extend(
174
+ [
175
+ f" - id: {assignment['id']}",
176
+ f" task: {assignment['task']}",
177
+ f" role: {assignment['role']}",
178
+ f" recommended_agent: {assignment['recommended_agent']}",
179
+ f" codex_type: {assignment['codex_type']}",
180
+ " depends_on:",
181
+ ]
182
+ )
183
+ depends_on = assignment.get("depends_on", [])
184
+ if depends_on:
185
+ for dependency in depends_on:
186
+ lines.append(f" - {dependency}")
187
+ else:
188
+ lines.append(" - none")
189
+ lines.append("")
190
+ return "\n".join(lines)
191
+
192
+
193
+ def write_json(path: Path, data: dict[str, object]) -> None:
194
+ path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
195
+
196
+
197
+ def build_initial_status(dispatch_plan: dict[str, object]) -> dict[str, object]:
198
+ assignments: dict[str, dict[str, object]] = {}
199
+ for assignment in dispatch_plan["assignments"]:
200
+ depends_on = [
201
+ dependency
202
+ for dependency in assignment.get("depends_on", [])
203
+ if dependency != "none"
204
+ ]
205
+ assignments[assignment["id"]] = {
206
+ "status": "ready" if not depends_on else "pending",
207
+ "attempts": 0,
208
+ "depends_on": depends_on,
209
+ "role": assignment["role"],
210
+ "task": assignment["task"],
211
+ "recommended_agent": assignment["recommended_agent"],
212
+ "codex_type": assignment["codex_type"],
213
+ }
214
+
215
+ return {"version": 1, "current_batch": 1, "assignments": assignments}
216
+
217
+
218
+ def build_initial_metrics(dispatch_plan: dict[str, object]) -> dict[str, object]:
219
+ return {
220
+ "assignments": len(dispatch_plan["assignments"]),
221
+ "attempts": 0,
222
+ "successfulAssignments": 0,
223
+ "failedAssignments": 0,
224
+ "reviewReworks": 0,
225
+ "agents": {},
226
+ }
227
+
228
+
229
+ def render_assignment_prompt(assignment: dict[str, object]) -> str:
230
+ return "\n".join(
231
+ [
232
+ f"# {assignment['id']}",
233
+ "",
234
+ f"Role: {assignment['role']}",
235
+ f"Recommended agent: {assignment['recommended_agent']}",
236
+ f"Codex type: {assignment['codex_type']}",
237
+ "",
238
+ "You are not alone in this codebase. Respect the write boundary, do not revert other agents' edits, and report changed files.",
239
+ "",
240
+ ]
241
+ )
@@ -15,6 +15,7 @@ from .paths import DIR_WORKFLOW, get_repo_root
15
15
  # Defaults
16
16
  DEFAULT_SESSION_COMMIT_MESSAGE = "chore: record journal"
17
17
  DEFAULT_MAX_JOURNAL_LINES = 2000
18
+ DEFAULT_AGENT_TEAM_ENABLED = False
18
19
 
19
20
  CONFIG_FILE = "config.yaml"
20
21
 
@@ -108,6 +109,23 @@ def get_max_journal_lines(repo_root: Path | None = None) -> int:
108
109
  return DEFAULT_MAX_JOURNAL_LINES
109
110
 
110
111
 
112
+ def _is_true(value: object) -> bool:
113
+ if value is True:
114
+ return True
115
+ if isinstance(value, str):
116
+ return value.strip().lower() == "true"
117
+ return False
118
+
119
+
120
+ def get_agent_team_enabled(repo_root: Path | None = None) -> bool:
121
+ """Return whether agent-team runtime commands are enabled."""
122
+ config = _load_config(repo_root)
123
+ agent_team = config.get("agent_team")
124
+ if not isinstance(agent_team, dict):
125
+ return DEFAULT_AGENT_TEAM_ENABLED
126
+ return _is_true(agent_team.get("enabled"))
127
+
128
+
111
129
  def get_hooks(event: str, repo_root: Path | None = None) -> list[str]:
112
130
  """Get hook commands for a lifecycle event.
113
131
 
@@ -174,7 +174,7 @@ def ensure_developer(repo_root: Path | None = None) -> None:
174
174
 
175
175
  if not check_developer(repo_root):
176
176
  print("Error: developer identity has not been initialized.", file=sys.stderr)
177
- print(f"Run: python3 ./{DIR_WORKFLOW}/scripts/init_developer.py <your-name>", file=sys.stderr)
177
+ print(f"Run: ./{DIR_WORKFLOW}/run init-developer <your-name>", file=sys.stderr)
178
178
  sys.exit(1)
179
179
 
180
180
 
@@ -253,12 +253,19 @@ def _task_plan_references(repo_root: Path, snapshot: CurrentTaskSnapshot) -> lis
253
253
  return plan_refs
254
254
 
255
255
 
256
+ def _task_has_agent_team_status(repo_root: Path, snapshot: CurrentTaskSnapshot) -> bool:
257
+ """Return whether the current task has persisted agent-team runtime state."""
258
+ if not snapshot.path:
259
+ return False
260
+ return (repo_root / snapshot.path / "agent-team" / "status.json").is_file()
261
+
262
+
256
263
  def _build_resume_checklist(
257
264
  repo_root: Path,
258
265
  snapshot: CurrentTaskSnapshot,
259
266
  ) -> dict[str, list[str]]:
260
267
  """构建最小恢复清单,只返回路径和命令,不展开文件内容。"""
261
- commands = [f"python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/resume.py"]
268
+ commands = [f"./{DIR_WORKFLOW}/run resume"]
262
269
  read_files: list[str] = []
263
270
  notes: list[str] = []
264
271
 
@@ -268,7 +275,10 @@ def _build_resume_checklist(
268
275
  return {"commands": commands, "readFiles": read_files, "notes": notes}
269
276
 
270
277
  current_task = snapshot.path
271
- commands.append(f"python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/task.py list-context {current_task}")
278
+ commands.append(f"./{DIR_WORKFLOW}/run task list-context {current_task}")
279
+ if _task_has_agent_team_status(repo_root, snapshot):
280
+ commands.append(f"./{DIR_WORKFLOW}/run agent-team status {current_task}")
281
+ commands.append(f"./{DIR_WORKFLOW}/run agent-team next {current_task}")
272
282
 
273
283
  if snapshot.has_prd:
274
284
  read_files.append(f"{current_task}/prd.md")
@@ -329,6 +339,13 @@ def _append_resume_checklist(
329
339
  else:
330
340
  lines.append("- No plan reference found in task context; do not search all plans unless needed.")
331
341
 
342
+ agent_team_commands = [
343
+ command for command in commands if f"./{DIR_WORKFLOW}/run agent-team " in command
344
+ ]
345
+ if agent_team_commands:
346
+ lines.append(f"- Check agent-team status: {agent_team_commands[0]}")
347
+ lines.append(f"- Continue agent-team dispatch: {agent_team_commands[1]}")
348
+
332
349
  lines.append("- Do not bulk-read .cowork-flow/spec/ or workspace journals; follow JSONL references on demand.")
333
350
  lines.append("")
334
351
 
@@ -503,7 +520,7 @@ def get_context_text(repo_root: Path | None = None) -> str:
503
520
  lines.append("## DEVELOPER")
504
521
  if not developer:
505
522
  lines.append(
506
- f"ERROR: Not initialized. Run: python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>"
523
+ f"ERROR: Not initialized. Run: ./{DIR_WORKFLOW}/run init-developer <name>"
507
524
  )
508
525
  return "\n".join(lines)
509
526
 
@@ -670,7 +687,7 @@ def get_context_text_record(repo_root: Path | None = None) -> str:
670
687
  developer = get_developer(repo_root)
671
688
  if not developer:
672
689
  lines.append(
673
- f"ERROR: Not initialized. Run: python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>"
690
+ f"ERROR: Not initialized. Run: ./{DIR_WORKFLOW}/run init-developer <name>"
674
691
  )
675
692
  return "\n".join(lines)
676
693
 
@@ -3,8 +3,8 @@
3
3
  Get Session Context for AI Agent.
4
4
 
5
5
  Usage:
6
- python3 get_context.py Output context in text format
7
- python3 get_context.py --json Output context in JSON format
6
+ ./.cowork-flow/run get-context Output context in text format
7
+ ./.cowork-flow/run get-context --json Output context in JSON format
8
8
  """
9
9
 
10
10
  from __future__ import annotations
@@ -3,7 +3,7 @@
3
3
  Initialize developer for workflow.
4
4
 
5
5
  Usage:
6
- python3 init_developer.py <developer-name>
6
+ ./.cowork-flow/run init-developer <developer-name>
7
7
 
8
8
  This creates:
9
9
  - .cowork-flow/.developer file with developer info
@@ -4,18 +4,18 @@
4
4
  Task Management Script for cowork-flow workflow.
5
5
 
6
6
  Usage:
7
- python3 task.py create "<title>" [--slug <name>] [--assignee <dev>] [--priority P0|P1|P2|P3] [--parent <dir>]
8
- python3 task.py init-context <dir> <type> # Initialize jsonl files
9
- python3 task.py add-context <dir> <file> <path> [reason] # Add jsonl entry
10
- python3 task.py validate <dir> # Validate jsonl files
11
- python3 task.py list-context <dir> # List jsonl entries
12
- python3 task.py start <dir> # Set as current task
13
- python3 task.py finish # Clear current task
14
- python3 task.py archive <task-name> # Archive completed task
15
- python3 task.py list # List active tasks
16
- python3 task.py list-archive [month] # List archived tasks
17
- python3 task.py add-subtask <parent-dir> <child-dir> # Link child to parent
18
- python3 task.py remove-subtask <parent-dir> <child-dir> # Unlink child from parent
7
+ ./.cowork-flow/run task create "<title>" [--slug <name>] [--assignee <dev>] [--priority P0|P1|P2|P3] [--parent <dir>]
8
+ ./.cowork-flow/run task init-context <dir> <type> # Initialize jsonl files
9
+ ./.cowork-flow/run task add-context <dir> <file> <path> [reason] # Add jsonl entry
10
+ ./.cowork-flow/run task validate <dir> # Validate jsonl files
11
+ ./.cowork-flow/run task list-context <dir> # List jsonl entries
12
+ ./.cowork-flow/run task start <dir> # Set as current task
13
+ ./.cowork-flow/run task finish # Clear current task
14
+ ./.cowork-flow/run task archive <task-name> # Archive completed task
15
+ ./.cowork-flow/run task list # List active tasks
16
+ ./.cowork-flow/run task list-archive [month] # List archived tasks
17
+ ./.cowork-flow/run task add-subtask <parent-dir> <child-dir> # Link child to parent
18
+ ./.cowork-flow/run task remove-subtask <parent-dir> <child-dir> # Unlink child from parent
19
19
  """
20
20
 
21
21
  from __future__ import annotations
@@ -630,8 +630,8 @@ def cmd_create(args: argparse.Namespace) -> int:
630
630
  print("", file=sys.stderr)
631
631
  print(colored("Next steps:", Colors.BLUE), file=sys.stderr)
632
632
  print(" 1. Create prd.md with requirements", file=sys.stderr)
633
- print(" 2. Run: python3 task.py init-context <dir> <dev_type>", file=sys.stderr)
634
- print(" 3. Run: python3 task.py start <dir>", file=sys.stderr)
633
+ print(" 2. Run: ./.cowork-flow/run task init-context <dir> <dev_type>", file=sys.stderr)
634
+ print(" 3. Run: ./.cowork-flow/run task start <dir>", file=sys.stderr)
635
635
  print("", file=sys.stderr)
636
636
 
637
637
  # Output relative path for script chaining
@@ -653,7 +653,7 @@ def cmd_init_context(args: argparse.Namespace) -> int:
653
653
 
654
654
  if not dev_type:
655
655
  print(colored("Error: Missing arguments", Colors.RED))
656
- print("Usage: python3 task.py init-context <task-dir> <dev_type>")
656
+ print("Usage: ./.cowork-flow/run task init-context <task-dir> <dev_type>")
657
657
  print(" dev_type: backend | frontend | fullstack | test | docs")
658
658
  return 1
659
659
 
@@ -699,8 +699,8 @@ def cmd_init_context(args: argparse.Namespace) -> int:
699
699
  print(colored("[OK] All context files created", Colors.GREEN))
700
700
  print()
701
701
  print(colored("Next steps:", Colors.BLUE))
702
- print(" 1. Add task-specific specs: python3 task.py add-context <dir> <jsonl> <path>")
703
- print(" 2. Set as current: python3 task.py start <dir>")
702
+ print(" 1. Add task-specific specs: ./.cowork-flow/run task add-context <dir> <jsonl> <path>")
703
+ print(" 2. Set as current: ./.cowork-flow/run task start <dir>")
704
704
 
705
705
  return 0
706
706
 
@@ -914,7 +914,7 @@ def cmd_start(args: argparse.Namespace) -> int:
914
914
  for blocker in blockers:
915
915
  print(f" - {blocker}", file=sys.stderr)
916
916
  print(
917
- "Hint: write prd.md, run python3 ./.cowork-flow/scripts/task.py init-context <dir> <dev_type>, then retry",
917
+ "Hint: write prd.md, run ./.cowork-flow/run task init-context <dir> <dev_type>, then retry",
918
918
  file=sys.stderr,
919
919
  )
920
920
  return 1
@@ -925,14 +925,14 @@ def cmd_start(args: argparse.Namespace) -> int:
925
925
  for issue in validation_issues:
926
926
  print(f" - {issue}", file=sys.stderr)
927
927
  print(
928
- "Hint: run python3 ./.cowork-flow/scripts/task.py validate <dir> and fix the reported issues",
928
+ "Hint: run ./.cowork-flow/run task validate <dir> and fix the reported issues",
929
929
  file=sys.stderr,
930
930
  )
931
931
  return 1
932
932
 
933
933
  # Convert to relative path for storage
934
934
  try:
935
- task_dir = str(full_path.relative_to(repo_root))
935
+ task_dir = full_path.relative_to(repo_root).as_posix()
936
936
  except ValueError:
937
937
  task_dir = str(full_path)
938
938
 
@@ -1311,19 +1311,19 @@ def show_usage() -> None:
1311
1311
  print("""Task Management Script for cowork-flow workflow
1312
1312
 
1313
1313
  Usage:
1314
- python3 task.py create <title> Create new task directory
1315
- python3 task.py create <title> --parent <dir> Create task as child of parent
1316
- python3 task.py init-context <dir> <dev_type> Initialize jsonl files
1317
- python3 task.py add-context <dir> <jsonl> <path> [reason] Add entry to jsonl
1318
- python3 task.py validate <dir> Validate jsonl files
1319
- python3 task.py list-context <dir> List jsonl entries
1320
- python3 task.py start <dir> Set as current task
1321
- python3 task.py finish Clear current task
1322
- python3 task.py archive <task-name> Archive completed task
1323
- python3 task.py add-subtask <parent> <child> Link child task to parent
1324
- python3 task.py remove-subtask <parent> <child> Unlink child from parent
1325
- python3 task.py list [--mine] [--status <status>] List tasks
1326
- python3 task.py list-archive [YYYY-MM] List archived tasks
1314
+ ./.cowork-flow/run task create <title> Create new task directory
1315
+ ./.cowork-flow/run task create <title> --parent <dir> Create task as child of parent
1316
+ ./.cowork-flow/run task init-context <dir> <dev_type> Initialize jsonl files
1317
+ ./.cowork-flow/run task add-context <dir> <jsonl> <path> [reason] Add entry to jsonl
1318
+ ./.cowork-flow/run task validate <dir> Validate jsonl files
1319
+ ./.cowork-flow/run task list-context <dir> List jsonl entries
1320
+ ./.cowork-flow/run task start <dir> Set as current task
1321
+ ./.cowork-flow/run task finish Clear current task
1322
+ ./.cowork-flow/run task archive <task-name> Archive completed task
1323
+ ./.cowork-flow/run task add-subtask <parent> <child> Link child task to parent
1324
+ ./.cowork-flow/run task remove-subtask <parent> <child> Unlink child from parent
1325
+ ./.cowork-flow/run task list [--mine] [--status <status>] List tasks
1326
+ ./.cowork-flow/run task list-archive [YYYY-MM] List archived tasks
1327
1327
 
1328
1328
  Arguments:
1329
1329
  dev_type: backend | frontend | fullstack | test | docs
@@ -1333,18 +1333,18 @@ List options:
1333
1333
  --status, -s <s> Filter by status (planning, in_progress, review, completed)
1334
1334
 
1335
1335
  Examples:
1336
- python3 task.py create "Add login feature" --slug add-login
1337
- python3 task.py create "Child task" --slug child --parent .cowork-flow/tasks/01-21-parent
1338
- python3 task.py init-context .cowork-flow/tasks/01-21-add-login backend
1339
- python3 task.py add-context <dir> implement .cowork-flow/spec/backend/auth.md "Auth guidelines"
1340
- python3 task.py start .cowork-flow/tasks/01-21-add-login
1341
- python3 task.py finish
1342
- python3 task.py archive add-login
1343
- python3 task.py add-subtask parent-task child-task # Link existing tasks
1344
- python3 task.py remove-subtask parent-task child-task
1345
- python3 task.py list # List all active tasks
1346
- python3 task.py list --mine # List my tasks only
1347
- python3 task.py list --mine --status in_progress # List my in-progress tasks
1336
+ ./.cowork-flow/run task create "Add login feature" --slug add-login
1337
+ ./.cowork-flow/run task create "Child task" --slug child --parent .cowork-flow/tasks/01-21-parent
1338
+ ./.cowork-flow/run task init-context .cowork-flow/tasks/01-21-add-login backend
1339
+ ./.cowork-flow/run task add-context <dir> implement .cowork-flow/spec/backend/auth.md "Auth guidelines"
1340
+ ./.cowork-flow/run task start .cowork-flow/tasks/01-21-add-login
1341
+ ./.cowork-flow/run task finish
1342
+ ./.cowork-flow/run task archive add-login
1343
+ ./.cowork-flow/run task add-subtask parent-task child-task # Link existing tasks
1344
+ ./.cowork-flow/run task remove-subtask parent-task child-task
1345
+ ./.cowork-flow/run task list # List all active tasks
1346
+ ./.cowork-flow/run task list --mine # List my tasks only
1347
+ ./.cowork-flow/run task list --mine --status in_progress # List my in-progress tasks
1348
1348
  """)
1349
1349
 
1350
1350