@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.
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +58 -1
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/constants/paths.d.ts +17 -0
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +19 -0
- package/dist/constants/paths.js.map +1 -1
- package/dist/templates/claude/commands/trellis/handoff.md +90 -387
- package/dist/templates/claude/commands/trellis/pick-task.md +74 -444
- package/dist/templates/claude/hooks/inject-subagent-context.py +17 -101
- package/dist/templates/claude/hooks/ralph-loop.py +1 -0
- package/dist/templates/claude/hooks/session-start.py +170 -54
- package/dist/templates/iflow/commands/trellis/handoff.md +148 -0
- package/dist/templates/iflow/commands/trellis/pick-task.md +145 -0
- package/dist/templates/iflow/hooks/inject-subagent-context.py +1 -0
- package/dist/templates/iflow/hooks/ralph-loop.py +1 -0
- package/dist/templates/iflow/hooks/session-start.py +171 -0
- package/dist/templates/markdown/index.d.ts +9 -0
- package/dist/templates/markdown/index.d.ts.map +1 -1
- package/dist/templates/markdown/index.js +10 -0
- package/dist/templates/markdown/index.js.map +1 -1
- package/dist/templates/markdown/spec/roles/designer/index.md.txt +57 -0
- package/dist/templates/markdown/spec/roles/designer/mock-data-standards.md.txt +63 -0
- package/dist/templates/markdown/spec/roles/designer/prototype-guidelines.md.txt +49 -0
- package/dist/templates/markdown/spec/roles/frontend-impl/api-integration.md.txt +63 -0
- package/dist/templates/markdown/spec/roles/frontend-impl/index.md.txt +57 -0
- package/dist/templates/markdown/spec/roles/frontend-impl/prototype-to-production.md.txt +57 -0
- package/dist/templates/markdown/spec/roles/pm/index.md.txt +45 -0
- package/dist/templates/markdown/spec/roles/pm/prd-template.md.txt +64 -0
- package/dist/templates/markdown/spec/roles/pm/requirement-checklist.md.txt +43 -0
- package/dist/templates/trellis/index.d.ts +1 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +2 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/add_session.py +3 -2
- package/dist/templates/trellis/scripts/common/cli_adapter.py +4 -3
- package/dist/templates/trellis/scripts/common/developer.py +4 -3
- package/dist/templates/trellis/scripts/common/git_context.py +7 -7
- package/dist/templates/trellis/scripts/common/paths.py +64 -14
- package/dist/templates/trellis/scripts/common/phase.py +2 -2
- package/dist/templates/trellis/scripts/common/registry.py +16 -15
- package/dist/templates/trellis/scripts/common/task_queue.py +10 -10
- package/dist/templates/trellis/scripts/common/task_utils.py +5 -4
- package/dist/templates/trellis/scripts/common/worktree.py +8 -7
- package/dist/templates/trellis/scripts/pool.py +214 -265
- package/dist/templates/trellis/scripts/task.py +3 -116
- package/package.json +3 -3
- package/dist/templates/claude/commands/trellis/before-role-work.md +0 -364
- package/dist/templates/trellis/VERSION +0 -1
- package/dist/templates/trellis/deliverables/README.md +0 -51
- package/dist/templates/trellis/paths.README.md +0 -277
- package/dist/templates/trellis/paths.yaml +0 -41
- package/dist/templates/trellis/pool/implementations.json +0 -5
- package/dist/templates/trellis/pool/prototypes.json +0 -5
- package/dist/templates/trellis/pool/requirements.json +0 -5
- package/dist/templates/trellis/scripts/common/project_paths.py +0 -189
- package/dist/templates/trellis/scripts/handoff_generator.py +0 -380
- package/dist/templates/trellis/spec/roles/designer/index.md +0 -243
- package/dist/templates/trellis/spec/roles/designer/mock-data-standards.md +0 -481
- package/dist/templates/trellis/spec/roles/designer/prototype-guidelines.md +0 -429
- package/dist/templates/trellis/spec/roles/frontend-impl/api-integration.md +0 -565
- package/dist/templates/trellis/spec/roles/frontend-impl/index.md +0 -321
- package/dist/templates/trellis/spec/roles/frontend-impl/state-management.md +0 -599
- package/dist/templates/trellis/spec/roles/pm/index.md +0 -112
- 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) ->
|
|
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) ->
|
|
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:
|
|
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:
|
|
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:
|
|
101
|
-
) ->
|
|
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:
|
|
132
|
-
) ->
|
|
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:
|
|
163
|
-
) ->
|
|
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:
|
|
199
|
-
) ->
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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) ->
|
|
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:
|
|
40
|
-
repo_root:
|
|
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:
|
|
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:
|
|
109
|
-
repo_root:
|
|
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:
|
|
171
|
-
repo_root:
|
|
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:
|
|
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:
|
|
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) ->
|
|
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:
|
|
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:
|
|
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:
|
|
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) ->
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|