@jahanxu/trellis 0.4.1 → 0.5.0

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 (65) hide show
  1. package/dist/configurators/workflow.d.ts.map +1 -1
  2. package/dist/configurators/workflow.js +58 -1
  3. package/dist/configurators/workflow.js.map +1 -1
  4. package/dist/constants/paths.d.ts +17 -0
  5. package/dist/constants/paths.d.ts.map +1 -1
  6. package/dist/constants/paths.js +19 -0
  7. package/dist/constants/paths.js.map +1 -1
  8. package/dist/templates/claude/commands/trellis/handoff.md +90 -387
  9. package/dist/templates/claude/commands/trellis/pick-task.md +74 -444
  10. package/dist/templates/claude/hooks/inject-subagent-context.py +17 -101
  11. package/dist/templates/claude/hooks/ralph-loop.py +1 -0
  12. package/dist/templates/claude/hooks/session-start.py +170 -54
  13. package/dist/templates/iflow/commands/trellis/handoff.md +148 -0
  14. package/dist/templates/iflow/commands/trellis/pick-task.md +145 -0
  15. package/dist/templates/iflow/hooks/inject-subagent-context.py +1 -0
  16. package/dist/templates/iflow/hooks/ralph-loop.py +1 -0
  17. package/dist/templates/iflow/hooks/session-start.py +171 -0
  18. package/dist/templates/markdown/index.d.ts +9 -0
  19. package/dist/templates/markdown/index.d.ts.map +1 -1
  20. package/dist/templates/markdown/index.js +10 -0
  21. package/dist/templates/markdown/index.js.map +1 -1
  22. package/dist/templates/markdown/spec/roles/designer/index.md.txt +57 -0
  23. package/dist/templates/markdown/spec/roles/designer/mock-data-standards.md.txt +63 -0
  24. package/dist/templates/markdown/spec/roles/designer/prototype-guidelines.md.txt +49 -0
  25. package/dist/templates/markdown/spec/roles/frontend-impl/api-integration.md.txt +63 -0
  26. package/dist/templates/markdown/spec/roles/frontend-impl/index.md.txt +57 -0
  27. package/dist/templates/markdown/spec/roles/frontend-impl/prototype-to-production.md.txt +57 -0
  28. package/dist/templates/markdown/spec/roles/pm/index.md.txt +45 -0
  29. package/dist/templates/markdown/spec/roles/pm/prd-template.md.txt +64 -0
  30. package/dist/templates/markdown/spec/roles/pm/requirement-checklist.md.txt +43 -0
  31. package/dist/templates/trellis/index.d.ts +1 -0
  32. package/dist/templates/trellis/index.d.ts.map +1 -1
  33. package/dist/templates/trellis/index.js +2 -0
  34. package/dist/templates/trellis/index.js.map +1 -1
  35. package/dist/templates/trellis/scripts/add_session.py +3 -2
  36. package/dist/templates/trellis/scripts/common/cli_adapter.py +4 -3
  37. package/dist/templates/trellis/scripts/common/developer.py +4 -3
  38. package/dist/templates/trellis/scripts/common/git_context.py +7 -7
  39. package/dist/templates/trellis/scripts/common/paths.py +64 -14
  40. package/dist/templates/trellis/scripts/common/phase.py +2 -2
  41. package/dist/templates/trellis/scripts/common/registry.py +16 -15
  42. package/dist/templates/trellis/scripts/common/task_queue.py +10 -10
  43. package/dist/templates/trellis/scripts/common/task_utils.py +5 -4
  44. package/dist/templates/trellis/scripts/common/worktree.py +8 -7
  45. package/dist/templates/trellis/scripts/pool.py +214 -265
  46. package/dist/templates/trellis/scripts/task.py +3 -116
  47. package/package.json +3 -3
  48. package/dist/templates/claude/commands/trellis/before-role-work.md +0 -364
  49. package/dist/templates/trellis/VERSION +0 -1
  50. package/dist/templates/trellis/deliverables/README.md +0 -51
  51. package/dist/templates/trellis/paths.README.md +0 -277
  52. package/dist/templates/trellis/paths.yaml +0 -41
  53. package/dist/templates/trellis/pool/implementations.json +0 -5
  54. package/dist/templates/trellis/pool/prototypes.json +0 -5
  55. package/dist/templates/trellis/pool/requirements.json +0 -5
  56. package/dist/templates/trellis/scripts/common/project_paths.py +0 -189
  57. package/dist/templates/trellis/scripts/handoff_generator.py +0 -380
  58. package/dist/templates/trellis/spec/roles/designer/index.md +0 -243
  59. package/dist/templates/trellis/spec/roles/designer/mock-data-standards.md +0 -481
  60. package/dist/templates/trellis/spec/roles/designer/prototype-guidelines.md +0 -429
  61. package/dist/templates/trellis/spec/roles/frontend-impl/api-integration.md +0 -565
  62. package/dist/templates/trellis/spec/roles/frontend-impl/index.md +0 -321
  63. package/dist/templates/trellis/spec/roles/frontend-impl/state-management.md +0 -599
  64. package/dist/templates/trellis/spec/roles/pm/index.md +0 -112
  65. package/dist/templates/trellis/spec/roles/pm/prd-template.md +0 -124
@@ -17,13 +17,13 @@ Provides:
17
17
  is_current_action - Check if at specific action
18
18
  """
19
19
 
20
+ from __future__ import annotations
20
21
 
21
22
  import json
22
23
  from pathlib import Path
23
- from typing import Optional
24
24
 
25
25
 
26
- def _read_json_file(path: Path) -> Optional[dict]:
26
+ def _read_json_file(path: Path) -> dict | None:
27
27
  """Read and parse a JSON file."""
28
28
  try:
29
29
  return json.loads(path.read_text(encoding="utf-8"))
@@ -14,6 +14,7 @@ Provides:
14
14
  registry_list_agents - List all agents
15
15
  """
16
16
 
17
+ from __future__ import annotations
17
18
 
18
19
  import json
19
20
  from datetime import datetime
@@ -23,7 +24,7 @@ from .paths import get_repo_root
23
24
  from .worktree import get_agents_dir
24
25
 
25
26
 
26
- def _read_json_file(path: Path) -> Optional[dict]:
27
+ def _read_json_file(path: Path) -> dict | None:
27
28
  """Read and parse a JSON file."""
28
29
  try:
29
30
  return json.loads(path.read_text(encoding="utf-8"))
@@ -44,7 +45,7 @@ def _write_json_file(path: Path, data: dict) -> bool:
44
45
  # Registry File Access
45
46
  # =============================================================================
46
47
 
47
- def registry_get_file(repo_root: Optional[Path] = None) -> Optional[Path]:
48
+ def registry_get_file(repo_root: Path | None = None) -> Path | None:
48
49
  """Get registry file path.
49
50
 
50
51
  Args:
@@ -62,7 +63,7 @@ def registry_get_file(repo_root: Optional[Path] = None) -> Optional[Path]:
62
63
  return None
63
64
 
64
65
 
65
- def _ensure_registry(repo_root: Optional[Path] = None) -> Optional[Path]:
66
+ def _ensure_registry(repo_root: Path | None = None) -> Path | None:
66
67
  """Ensure registry file exists with valid structure.
67
68
 
68
69
  Args:
@@ -97,8 +98,8 @@ def _ensure_registry(repo_root: Optional[Path] = None) -> Optional[Path]:
97
98
 
98
99
  def registry_get_agent_by_id(
99
100
  agent_id: str,
100
- repo_root: Optional[Path] = None
101
- ) -> Optional[dict]:
101
+ repo_root: Path | None = None
102
+ ) -> dict | None:
102
103
  """Get agent by ID.
103
104
 
104
105
  Args:
@@ -128,8 +129,8 @@ def registry_get_agent_by_id(
128
129
 
129
130
  def registry_get_agent_by_worktree(
130
131
  worktree_path: str,
131
- repo_root: Optional[Path] = None
132
- ) -> Optional[dict]:
132
+ repo_root: Path | None = None
133
+ ) -> dict | None:
133
134
  """Get agent by worktree path.
134
135
 
135
136
  Args:
@@ -159,8 +160,8 @@ def registry_get_agent_by_worktree(
159
160
 
160
161
  def registry_search_agent(
161
162
  search: str,
162
- repo_root: Optional[Path] = None
163
- ) -> Optional[dict]:
163
+ repo_root: Path | None = None
164
+ ) -> dict | None:
164
165
  """Search agent by ID or task_dir containing search term.
165
166
 
166
167
  Args:
@@ -195,8 +196,8 @@ def registry_search_agent(
195
196
 
196
197
  def registry_get_task_dir(
197
198
  worktree_path: str,
198
- repo_root: Optional[Path] = None
199
- ) -> Optional[str]:
199
+ repo_root: Path | None = None
200
+ ) -> str | None:
200
201
  """Get task directory for a worktree.
201
202
 
202
203
  Args:
@@ -216,7 +217,7 @@ def registry_get_task_dir(
216
217
  # Agent Modification
217
218
  # =============================================================================
218
219
 
219
- def registry_remove_by_id(agent_id: str, repo_root: Optional[Path] = None) -> bool:
220
+ def registry_remove_by_id(agent_id: str, repo_root: Path | None = None) -> bool:
220
221
  """Remove agent by ID.
221
222
 
222
223
  Args:
@@ -245,7 +246,7 @@ def registry_remove_by_id(agent_id: str, repo_root: Optional[Path] = None) -> bo
245
246
 
246
247
  def registry_remove_by_worktree(
247
248
  worktree_path: str,
248
- repo_root: Optional[Path] = None
249
+ repo_root: Path | None = None
249
250
  ) -> bool:
250
251
  """Remove agent by worktree path.
251
252
 
@@ -278,7 +279,7 @@ def registry_add_agent(
278
279
  worktree_path: str,
279
280
  pid: int,
280
281
  task_dir: str,
281
- repo_root: Optional[Path] = None,
282
+ repo_root: Path | None = None,
282
283
  platform: str = "claude",
283
284
  ) -> bool:
284
285
  """Add agent to registry (replaces if same ID exists).
@@ -326,7 +327,7 @@ def registry_add_agent(
326
327
  return _write_json_file(registry_file, data)
327
328
 
328
329
 
329
- def registry_list_agents(repo_root: Optional[Path] = None) -> list[dict]:
330
+ def registry_list_agents(repo_root: Path | None = None) -> list[dict]:
330
331
  """List all agents.
331
332
 
332
333
  Args:
@@ -10,10 +10,10 @@ Provides:
10
10
  get_task_stats - Get P0/P1/P2/P3 counts
11
11
  """
12
12
 
13
+ from __future__ import annotations
13
14
 
14
15
  import json
15
16
  from pathlib import Path
16
- from typing import Optional, List
17
17
 
18
18
  from .paths import (
19
19
  FILE_TASK_JSON,
@@ -23,7 +23,7 @@ from .paths import (
23
23
  )
24
24
 
25
25
 
26
- def _read_json_file(path: Path) -> Optional[dict]:
26
+ def _read_json_file(path: Path) -> dict | None:
27
27
  """Read and parse a JSON file."""
28
28
  try:
29
29
  return json.loads(path.read_text(encoding="utf-8"))
@@ -36,8 +36,8 @@ def _read_json_file(path: Path) -> Optional[dict]:
36
36
  # =============================================================================
37
37
 
38
38
  def list_tasks_by_status(
39
- filter_status: Optional[str] = None,
40
- repo_root: Optional[Path] = None
39
+ filter_status: str | None = None,
40
+ repo_root: Path | None = None
41
41
  ) -> list[dict]:
42
42
  """List tasks by status.
43
43
 
@@ -91,7 +91,7 @@ def list_tasks_by_status(
91
91
  return results
92
92
 
93
93
 
94
- def list_pending_tasks(repo_root: Optional[Path] = None) -> list[dict]:
94
+ def list_pending_tasks(repo_root: Path | None = None) -> list[dict]:
95
95
  """List pending tasks.
96
96
 
97
97
  Args:
@@ -105,8 +105,8 @@ def list_pending_tasks(repo_root: Optional[Path] = None) -> list[dict]:
105
105
 
106
106
  def list_tasks_by_assignee(
107
107
  assignee: str,
108
- filter_status: Optional[str] = None,
109
- repo_root: Optional[Path] = None
108
+ filter_status: str | None = None,
109
+ repo_root: Path | None = None
110
110
  ) -> list[dict]:
111
111
  """List tasks assigned to a specific developer.
112
112
 
@@ -167,8 +167,8 @@ def list_tasks_by_assignee(
167
167
 
168
168
 
169
169
  def list_my_tasks(
170
- filter_status: Optional[str] = None,
171
- repo_root: Optional[Path] = None
170
+ filter_status: str | None = None,
171
+ repo_root: Path | None = None
172
172
  ) -> list[dict]:
173
173
  """List tasks assigned to current developer.
174
174
 
@@ -192,7 +192,7 @@ def list_my_tasks(
192
192
  return list_tasks_by_assignee(developer, filter_status, repo_root)
193
193
 
194
194
 
195
- def get_task_stats(repo_root: Optional[Path] = None) -> dict[str, int]:
195
+ def get_task_stats(repo_root: Path | None = None) -> dict[str, int]:
196
196
  """Get task statistics.
197
197
 
198
198
  Args:
@@ -8,6 +8,7 @@ Provides:
8
8
  archive_task_dir - Archive task to monthly directory
9
9
  """
10
10
 
11
+ from __future__ import annotations
11
12
 
12
13
  import shutil
13
14
  import sys
@@ -21,7 +22,7 @@ from .paths import get_repo_root
21
22
  # Path Safety
22
23
  # =============================================================================
23
24
 
24
- def is_safe_task_path(task_path: str, repo_root: Optional[Path] = None) -> bool:
25
+ def is_safe_task_path(task_path: str, repo_root: Path | None = None) -> bool:
25
26
  """Check if a relative task path is safe to operate on.
26
27
 
27
28
  Args:
@@ -68,7 +69,7 @@ def is_safe_task_path(task_path: str, repo_root: Optional[Path] = None) -> bool:
68
69
  # Task Lookup
69
70
  # =============================================================================
70
71
 
71
- def find_task_by_name(task_name: str, tasks_dir: Path) -> Optional[Path]:
72
+ def find_task_by_name(task_name: str, tasks_dir: Path) -> Path | None:
72
73
  """Find task directory by name (exact or suffix match).
73
74
 
74
75
  Args:
@@ -98,7 +99,7 @@ def find_task_by_name(task_name: str, tasks_dir: Path) -> Optional[Path]:
98
99
  # Archive Operations
99
100
  # =============================================================================
100
101
 
101
- def archive_task_dir(task_dir_abs: Path, repo_root: Optional[Path] = None) -> Optional[Path]:
102
+ def archive_task_dir(task_dir_abs: Path, repo_root: Path | None = None) -> Path | None:
102
103
  """Archive a task directory to archive/{YYYY-MM}/.
103
104
 
104
105
  Args:
@@ -140,7 +141,7 @@ def archive_task_dir(task_dir_abs: Path, repo_root: Optional[Path] = None) -> Op
140
141
 
141
142
  def archive_task_complete(
142
143
  task_dir_abs: Path,
143
- repo_root: Optional[Path] = None
144
+ repo_root: Path | None = None
144
145
  ) -> dict[str, str]:
145
146
  """Complete archive workflow: archive directory.
146
147
 
@@ -10,6 +10,7 @@ Provides:
10
10
  get_agents_dir - Get agents registry directory
11
11
  """
12
12
 
13
+ from __future__ import annotations
13
14
 
14
15
  from pathlib import Path
15
16
 
@@ -34,7 +35,7 @@ def parse_simple_yaml(content: str) -> dict:
34
35
  Parsed dict.
35
36
  """
36
37
  result: dict = {}
37
- current_list: Optional[list] = None
38
+ current_list: list | None = None
38
39
 
39
40
  for line in content.splitlines():
40
41
  stripped = line.strip()
@@ -60,7 +61,7 @@ def parse_simple_yaml(content: str) -> dict:
60
61
  return result
61
62
 
62
63
 
63
- def _yaml_get_value(config_file: Path, key: str) -> Optional[str]:
64
+ def _yaml_get_value(config_file: Path, key: str) -> str | None:
64
65
  """Read simple value from worktree.yaml.
65
66
 
66
67
  Args:
@@ -110,7 +111,7 @@ def _yaml_get_list(config_file: Path, section: str) -> list[str]:
110
111
  WORKTREE_CONFIG_PATH = f"{DIR_WORKFLOW}/worktree.yaml"
111
112
 
112
113
 
113
- def get_worktree_config(repo_root: Optional[Path] = None) -> Path:
114
+ def get_worktree_config(repo_root: Path | None = None) -> Path:
114
115
  """Get worktree.yaml config file path.
115
116
 
116
117
  Args:
@@ -124,7 +125,7 @@ def get_worktree_config(repo_root: Optional[Path] = None) -> Path:
124
125
  return repo_root / WORKTREE_CONFIG_PATH
125
126
 
126
127
 
127
- def get_worktree_base_dir(repo_root: Optional[Path] = None) -> Path:
128
+ def get_worktree_base_dir(repo_root: Path | None = None) -> Path:
128
129
  """Get worktree base directory.
129
130
 
130
131
  Args:
@@ -152,7 +153,7 @@ def get_worktree_base_dir(repo_root: Optional[Path] = None) -> Path:
152
153
  return Path(worktree_dir)
153
154
 
154
155
 
155
- def get_worktree_copy_files(repo_root: Optional[Path] = None) -> list[str]:
156
+ def get_worktree_copy_files(repo_root: Path | None = None) -> list[str]:
156
157
  """Get files to copy list.
157
158
 
158
159
  Args:
@@ -167,7 +168,7 @@ def get_worktree_copy_files(repo_root: Optional[Path] = None) -> list[str]:
167
168
  return _yaml_get_list(config, "copy")
168
169
 
169
170
 
170
- def get_worktree_post_create_hooks(repo_root: Optional[Path] = None) -> list[str]:
171
+ def get_worktree_post_create_hooks(repo_root: Path | None = None) -> list[str]:
171
172
  """Get post_create hooks.
172
173
 
173
174
  Args:
@@ -186,7 +187,7 @@ def get_worktree_post_create_hooks(repo_root: Optional[Path] = None) -> list[str
186
187
  # Agents Registry
187
188
  # =============================================================================
188
189
 
189
- def get_agents_dir(repo_root: Optional[Path] = None) -> Optional[Path]:
190
+ def get_agents_dir(repo_root: Path | None = None) -> Path | None:
190
191
  """Get agents directory for current developer.
191
192
 
192
193
  Args: