@mindfoldhq/trellis 0.1.9 → 0.2.1

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 (102) hide show
  1. package/dist/cli/index.js +2 -0
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.js +12 -6
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/update.d.ts +1 -0
  7. package/dist/commands/update.d.ts.map +1 -1
  8. package/dist/commands/update.js +669 -38
  9. package/dist/commands/update.js.map +1 -1
  10. package/dist/configurators/opencode.js +1 -1
  11. package/dist/configurators/opencode.js.map +1 -1
  12. package/dist/configurators/workflow.d.ts +4 -3
  13. package/dist/configurators/workflow.d.ts.map +1 -1
  14. package/dist/configurators/workflow.js +23 -20
  15. package/dist/configurators/workflow.js.map +1 -1
  16. package/dist/constants/paths.d.ts +29 -30
  17. package/dist/constants/paths.d.ts.map +1 -1
  18. package/dist/constants/paths.js +32 -35
  19. package/dist/constants/paths.js.map +1 -1
  20. package/dist/migrations/index.d.ts +35 -0
  21. package/dist/migrations/index.d.ts.map +1 -0
  22. package/dist/migrations/index.js +124 -0
  23. package/dist/migrations/index.js.map +1 -0
  24. package/dist/migrations/manifests/0.1.9.json +30 -0
  25. package/dist/migrations/manifests/0.2.0.json +43 -0
  26. package/dist/templates/claude/agents/check.md +3 -3
  27. package/dist/templates/claude/agents/debug.md +1 -1
  28. package/dist/templates/claude/agents/dispatch.md +12 -12
  29. package/dist/templates/claude/agents/implement.md +6 -6
  30. package/dist/templates/claude/agents/plan.md +37 -37
  31. package/dist/templates/claude/agents/research.md +1 -1
  32. package/dist/templates/claude/commands/before-backend-dev.md +5 -5
  33. package/dist/templates/claude/commands/before-frontend-dev.md +5 -5
  34. package/dist/templates/claude/commands/break-loop.md +2 -2
  35. package/dist/templates/claude/commands/check-backend.md +6 -6
  36. package/dist/templates/claude/commands/check-cross-layer.md +5 -5
  37. package/dist/templates/claude/commands/check-frontend.md +6 -6
  38. package/dist/templates/claude/commands/create-command.md +3 -3
  39. package/dist/templates/claude/commands/finish-work.md +6 -6
  40. package/dist/templates/claude/commands/integrate-skill.md +11 -11
  41. package/dist/templates/claude/commands/{onboard-developer.md → onboard.md} +31 -28
  42. package/dist/templates/claude/commands/parallel.md +17 -17
  43. package/dist/templates/claude/commands/{record-agent-flow.md → record-session.md} +7 -7
  44. package/dist/templates/claude/commands/start.md +36 -36
  45. package/dist/templates/claude/hooks/inject-subagent-context.py +77 -76
  46. package/dist/templates/claude/hooks/ralph-loop.py +18 -18
  47. package/dist/templates/claude/hooks/session-start.py +4 -4
  48. package/dist/templates/cursor/commands/before-backend-dev.md +5 -5
  49. package/dist/templates/cursor/commands/before-frontend-dev.md +5 -5
  50. package/dist/templates/cursor/commands/break-loop.md +2 -2
  51. package/dist/templates/cursor/commands/check-backend.md +6 -6
  52. package/dist/templates/cursor/commands/check-cross-layer.md +5 -5
  53. package/dist/templates/cursor/commands/check-frontend.md +6 -6
  54. package/dist/templates/cursor/commands/create-command.md +3 -3
  55. package/dist/templates/cursor/commands/finish-work.md +6 -6
  56. package/dist/templates/cursor/commands/integrate-skill.md +11 -11
  57. package/dist/templates/cursor/commands/{onboard-developer.md → onboard.md} +31 -28
  58. package/dist/templates/cursor/commands/{record-agent-flow.md → record-session.md} +7 -7
  59. package/dist/templates/cursor/commands/start.md +25 -25
  60. package/dist/templates/extract.d.ts +2 -2
  61. package/dist/templates/extract.js +2 -2
  62. package/dist/templates/markdown/agents.md +2 -2
  63. package/dist/templates/markdown/gitignore.txt +2 -2
  64. package/dist/templates/markdown/index.d.ts +1 -0
  65. package/dist/templates/markdown/index.d.ts.map +1 -1
  66. package/dist/templates/markdown/index.js +4 -2
  67. package/dist/templates/markdown/index.js.map +1 -1
  68. package/dist/templates/markdown/{agent-traces-index.md → workspace-index.md} +14 -14
  69. package/dist/templates/trellis/index.d.ts +7 -1
  70. package/dist/templates/trellis/index.d.ts.map +1 -1
  71. package/dist/templates/trellis/index.js +14 -2
  72. package/dist/templates/trellis/index.js.map +1 -1
  73. package/dist/templates/trellis/scripts/add-session.sh +26 -26
  74. package/dist/templates/trellis/scripts/common/developer.sh +20 -21
  75. package/dist/templates/trellis/scripts/common/git-context.sh +90 -115
  76. package/dist/templates/trellis/scripts/common/paths.sh +53 -63
  77. package/dist/templates/trellis/scripts/common/phase.sh +40 -40
  78. package/dist/templates/trellis/scripts/common/registry.sh +13 -13
  79. package/dist/templates/trellis/scripts/common/task-queue.sh +142 -0
  80. package/dist/templates/trellis/scripts/common/task-utils.sh +151 -0
  81. package/dist/templates/trellis/scripts/common/worktree.sh +3 -3
  82. package/dist/templates/trellis/scripts/create-bootstrap.sh +43 -42
  83. package/dist/templates/trellis/scripts/init-developer.sh +1 -1
  84. package/dist/templates/trellis/scripts/multi-agent/cleanup.sh +33 -33
  85. package/dist/templates/trellis/scripts/multi-agent/create-pr.sh +30 -30
  86. package/dist/templates/trellis/scripts/multi-agent/plan.sh +28 -28
  87. package/dist/templates/trellis/scripts/multi-agent/start.sh +56 -56
  88. package/dist/templates/trellis/scripts/multi-agent/status.sh +59 -59
  89. package/dist/templates/trellis/scripts/{feature.sh → task.sh} +235 -185
  90. package/dist/templates/trellis/workflow.md +71 -74
  91. package/dist/types/migration.d.ts +74 -0
  92. package/dist/types/migration.d.ts.map +1 -0
  93. package/dist/types/migration.js +8 -0
  94. package/dist/types/migration.js.map +1 -0
  95. package/dist/utils/template-hash.d.ts +78 -0
  96. package/dist/utils/template-hash.d.ts.map +1 -0
  97. package/dist/utils/template-hash.js +234 -0
  98. package/dist/utils/template-hash.js.map +1 -0
  99. package/package.json +1 -1
  100. package/dist/templates/trellis/scripts/common/backlog.sh +0 -220
  101. package/dist/templates/trellis/scripts/common/feature-utils.sh +0 -194
  102. /package/dist/templates/trellis/{backlog → tasks}/.gitkeep +0 -0
@@ -35,14 +35,14 @@ cat .trellis/workflow.md
35
35
  ./.trellis/scripts/get-context.sh
36
36
  ```
37
37
 
38
- This shows: developer identity, git status, current feature (if any), backlog items.
38
+ This shows: developer identity, git status, current task (if any), active tasks.
39
39
 
40
40
  ### Step 3: Read Guidelines Index
41
41
 
42
42
  ```bash
43
- cat .trellis/structure/frontend/index.md # Frontend guidelines
44
- cat .trellis/structure/backend/index.md # Backend guidelines
45
- cat .trellis/structure/guides/index.md # Thinking guides
43
+ cat .trellis/spec/frontend/index.md # Frontend guidelines
44
+ cat .trellis/spec/backend/index.md # Backend guidelines
45
+ cat .trellis/spec/guides/index.md # Thinking guides
46
46
  ```
47
47
 
48
48
  ### Step 4: Report and Ask
@@ -59,13 +59,13 @@ When user describes a task, classify it:
59
59
  |------|----------|----------|
60
60
  | **Question** | User asks about code, architecture, or how something works | Answer directly |
61
61
  | **Trivial Fix** | Typo fix, comment update, single-line change, < 5 minutes | Direct Edit |
62
- | **Development Task** | Any code change that: modifies logic, adds features, fixes bugs, touches multiple files | **Feature Workflow** |
62
+ | **Development Task** | Any code change that: modifies logic, adds features, fixes bugs, touches multiple files | **Task Workflow** |
63
63
 
64
64
  ### Decision Rule
65
65
 
66
- > **If in doubt, use Feature Workflow.**
66
+ > **If in doubt, use Task Workflow.**
67
67
  >
68
- > Feature Workflow ensures specs are injected to agents, resulting in higher quality code.
68
+ > Task Workflow ensures specs are injected to agents, resulting in higher quality code.
69
69
  > The overhead is minimal, but the benefit is significant.
70
70
 
71
71
  ---
@@ -79,7 +79,7 @@ For questions or trivial fixes, work directly:
79
79
 
80
80
  ---
81
81
 
82
- ## Feature Workflow (Development Tasks)
82
+ ## Task Workflow (Development Tasks)
83
83
 
84
84
  **Why this workflow?**
85
85
  - Research Agent analyzes what specs are needed
@@ -110,7 +110,7 @@ Task(
110
110
  Type: <frontend/backend/fullstack>
111
111
 
112
112
  Please find:
113
- 1. Relevant spec files in .trellis/structure/
113
+ 1. Relevant spec files in .trellis/spec/
114
114
  2. Existing code patterns to follow (find 2-3 examples)
115
115
  3. Files that will likely need modification
116
116
 
@@ -124,18 +124,18 @@ Task(
124
124
  ## Files to Modify
125
125
  - <path>: <what change>
126
126
 
127
- ## Suggested Feature Name
127
+ ## Suggested Task Name
128
128
  - <short-slug-name>",
129
129
  model: "opus"
130
130
  )
131
131
  ```
132
132
 
133
- ### Step 3: Create Feature Directory `[AI]`
133
+ ### Step 3: Create Task Directory `[AI]`
134
134
 
135
135
  Based on research results:
136
136
 
137
137
  ```bash
138
- FEATURE_DIR=$(./.trellis/scripts/feature.sh create "<title from research>" --slug <suggested-slug>)
138
+ TASK_DIR=$(./.trellis/scripts/task.sh create "<title from research>" --slug <suggested-slug>)
139
139
  ```
140
140
 
141
141
  ### Step 4: Configure Context `[AI]`
@@ -143,7 +143,7 @@ FEATURE_DIR=$(./.trellis/scripts/feature.sh create "<title from research>" --slu
143
143
  Initialize default context:
144
144
 
145
145
  ```bash
146
- ./.trellis/scripts/feature.sh init-context "$FEATURE_DIR" <type>
146
+ ./.trellis/scripts/task.sh init-context "$TASK_DIR" <type>
147
147
  # type: backend | frontend | fullstack
148
148
  ```
149
149
 
@@ -151,16 +151,16 @@ Add specs found by Research Agent:
151
151
 
152
152
  ```bash
153
153
  # For each relevant spec and code pattern:
154
- ./.trellis/scripts/feature.sh add-context "$FEATURE_DIR" implement "<path>" "<reason>"
155
- ./.trellis/scripts/feature.sh add-context "$FEATURE_DIR" check "<path>" "<reason>"
154
+ ./.trellis/scripts/task.sh add-context "$TASK_DIR" implement "<path>" "<reason>"
155
+ ./.trellis/scripts/task.sh add-context "$TASK_DIR" check "<path>" "<reason>"
156
156
  ```
157
157
 
158
158
  ### Step 5: Write Requirements `[AI]`
159
159
 
160
- Create `prd.md` in the feature directory with:
160
+ Create `prd.md` in the task directory with:
161
161
 
162
162
  ```markdown
163
- # <Feature Title>
163
+ # <Task Title>
164
164
 
165
165
  ## Goal
166
166
  <What we're trying to achieve>
@@ -177,13 +177,13 @@ Create `prd.md` in the feature directory with:
177
177
  <Any technical decisions or constraints>
178
178
  ```
179
179
 
180
- ### Step 6: Activate Feature `[AI]`
180
+ ### Step 6: Activate Task `[AI]`
181
181
 
182
182
  ```bash
183
- ./.trellis/scripts/feature.sh start "$FEATURE_DIR"
183
+ ./.trellis/scripts/task.sh start "$TASK_DIR"
184
184
  ```
185
185
 
186
- This sets `.current-feature` so hooks can inject context.
186
+ This sets `.current-task` so hooks can inject context.
187
187
 
188
188
  ### Step 7: Implement `[AI]`
189
189
 
@@ -192,7 +192,7 @@ Call Implement Agent (specs are auto-injected by hook):
192
192
  ```
193
193
  Task(
194
194
  subagent_type: "implement",
195
- prompt: "Implement the feature described in prd.md.
195
+ prompt: "Implement the task described in prd.md.
196
196
 
197
197
  Follow all specs that have been injected into your context.
198
198
  Run lint and typecheck before finishing.",
@@ -222,17 +222,17 @@ Task(
222
222
  3. Remind user to:
223
223
  - Test the changes
224
224
  - Commit when ready
225
- - Run `/record-agent-flow` to record this session
225
+ - Run `/record-session` to record this session
226
226
 
227
227
  ---
228
228
 
229
- ## Continuing Existing Feature
229
+ ## Continuing Existing Task
230
230
 
231
- If `get-context.sh` shows a current feature:
231
+ If `get-context.sh` shows a current task:
232
232
 
233
- 1. Read the feature's `prd.md` to understand the goal
234
- 2. Check `feature.json` for current status and phase
235
- 3. Ask user: "Continue working on <feature-name>?"
233
+ 1. Read the task's `prd.md` to understand the goal
234
+ 2. Check `task.json` for current status and phase
235
+ 3. Ask user: "Continue working on <task-name>?"
236
236
 
237
237
  If yes, resume from the appropriate step (usually Step 7 or 8).
238
238
 
@@ -245,21 +245,21 @@ If yes, resume from the appropriate step (usually Step 7 or 8).
245
245
  | Command | When to Use |
246
246
  |---------|-------------|
247
247
  | `/start` | Begin a session (this command) |
248
- | `/parallel` | Complex features needing isolated worktree |
248
+ | `/parallel` | Complex tasks needing isolated worktree |
249
249
  | `/finish-work` | Before committing changes |
250
- | `/record-agent-flow` | After completing a task |
250
+ | `/record-session` | After completing a task |
251
251
 
252
252
  ### AI Scripts `[AI]`
253
253
 
254
254
  | Script | Purpose |
255
255
  |--------|---------|
256
256
  | `get-context.sh` | Get session context |
257
- | `feature.sh create` | Create feature directory |
258
- | `feature.sh init-context` | Initialize jsonl files |
259
- | `feature.sh add-context` | Add spec to jsonl |
260
- | `feature.sh start` | Set current feature |
261
- | `feature.sh finish` | Clear current feature |
262
- | `feature.sh archive` | Archive completed feature |
257
+ | `task.sh create` | Create task directory |
258
+ | `task.sh init-context` | Initialize jsonl files |
259
+ | `task.sh add-context` | Add spec to jsonl |
260
+ | `task.sh start` | Set current task |
261
+ | `task.sh finish` | Clear current task |
262
+ | `task.sh archive` | Archive completed task |
263
263
 
264
264
  ### Sub Agents `[AI]`
265
265
 
@@ -276,5 +276,5 @@ If yes, resume from the appropriate step (usually Step 7 or 8).
276
276
 
277
277
  > **Specs are injected, not remembered.**
278
278
  >
279
- > The Feature Workflow ensures agents receive relevant specs automatically.
279
+ > The Task Workflow ensures agents receive relevant specs automatically.
280
280
  > This is more reliable than hoping the AI "remembers" conventions.
@@ -10,7 +10,7 @@ Core Design Philosophy:
10
10
 
11
11
  Trigger: PreToolUse (before Task tool call)
12
12
 
13
- Context Source: .trellis/.current-feature points to feature directory
13
+ Context Source: .trellis/.current-task points to task directory
14
14
  - implement.jsonl - Implement agent dedicated context
15
15
  - check.jsonl - Check agent dedicated context
16
16
  - debug.jsonl - Debug agent dedicated context
@@ -31,10 +31,11 @@ from pathlib import Path
31
31
  # =============================================================================
32
32
 
33
33
  DIR_WORKFLOW = ".trellis"
34
- DIR_PROGRESS = "agent-traces"
35
- DIR_FEATURES = "features"
36
- DIR_STRUCTURE = "structure"
37
- FILE_CURRENT_FEATURE = ".current-feature"
34
+ DIR_WORKSPACE = "workspace"
35
+ DIR_TASKS = "tasks"
36
+ DIR_SPEC = "spec"
37
+ FILE_CURRENT_TASK = ".current-task"
38
+ FILE_TASK_JSON = "task.json"
38
39
 
39
40
  # Agents that don't update phase (can be called at any time)
40
41
  AGENTS_NO_PHASE_UPDATE = {"debug", "research"}
@@ -48,8 +49,8 @@ AGENT_CHECK = "check"
48
49
  AGENT_DEBUG = "debug"
49
50
  AGENT_RESEARCH = "research"
50
51
 
51
- # Agents that require a feature directory
52
- AGENTS_REQUIRE_FEATURE = (AGENT_IMPLEMENT, AGENT_CHECK, AGENT_DEBUG)
52
+ # Agents that require a task directory
53
+ AGENTS_REQUIRE_TASK = (AGENT_IMPLEMENT, AGENT_CHECK, AGENT_DEBUG)
53
54
  # All supported agents
54
55
  AGENTS_ALL = (AGENT_IMPLEMENT, AGENT_CHECK, AGENT_DEBUG, AGENT_RESEARCH)
55
56
 
@@ -69,35 +70,35 @@ def find_repo_root(start_path: str) -> str | None:
69
70
  return None
70
71
 
71
72
 
72
- def get_current_feature(repo_root: str) -> str | None:
73
+ def get_current_task(repo_root: str) -> str | None:
73
74
  """
74
- Read current feature directory path from .trellis/.current-feature
75
+ Read current task directory path from .trellis/.current-task
75
76
 
76
77
  Returns:
77
- Feature directory relative path (relative to repo_root)
78
+ Task directory relative path (relative to repo_root)
78
79
  None if not set
79
80
  """
80
- current_feature_file = os.path.join(repo_root, DIR_WORKFLOW, FILE_CURRENT_FEATURE)
81
- if not os.path.exists(current_feature_file):
81
+ current_task_file = os.path.join(repo_root, DIR_WORKFLOW, FILE_CURRENT_TASK)
82
+ if not os.path.exists(current_task_file):
82
83
  return None
83
84
 
84
85
  try:
85
- with open(current_feature_file, "r", encoding="utf-8") as f:
86
+ with open(current_task_file, "r", encoding="utf-8") as f:
86
87
  content = f.read().strip()
87
88
  return content if content else None
88
89
  except Exception:
89
90
  return None
90
91
 
91
92
 
92
- def update_current_phase(repo_root: str, feature_dir: str, subagent_type: str) -> None:
93
+ def update_current_phase(repo_root: str, task_dir: str, subagent_type: str) -> None:
93
94
  """
94
- Update current_phase in feature.json based on subagent_type.
95
+ Update current_phase in task.json based on subagent_type.
95
96
 
96
97
  This ensures phase tracking is always accurate, regardless of whether
97
98
  dispatch agent remembers to update it.
98
99
 
99
100
  Logic:
100
- - Read next_action array from feature.json
101
+ - Read next_action array from task.json
101
102
  - Find the next phase whose action matches subagent_type
102
103
  - Only move forward, never backward
103
104
  - Some agents (debug, research) don't update phase
@@ -105,16 +106,16 @@ def update_current_phase(repo_root: str, feature_dir: str, subagent_type: str) -
105
106
  if subagent_type in AGENTS_NO_PHASE_UPDATE:
106
107
  return
107
108
 
108
- feature_json_path = os.path.join(repo_root, feature_dir, "feature.json")
109
- if not os.path.exists(feature_json_path):
109
+ task_json_path = os.path.join(repo_root, task_dir, FILE_TASK_JSON)
110
+ if not os.path.exists(task_json_path):
110
111
  return
111
112
 
112
113
  try:
113
- with open(feature_json_path, "r", encoding="utf-8") as f:
114
- feature_data = json.load(f)
114
+ with open(task_json_path, "r", encoding="utf-8") as f:
115
+ task_data = json.load(f)
115
116
 
116
- current_phase = feature_data.get("current_phase", 0)
117
- next_actions = feature_data.get("next_action", [])
117
+ current_phase = task_data.get("current_phase", 0)
118
+ next_actions = task_data.get("next_action", [])
118
119
 
119
120
  # Map action names to subagent types
120
121
  # "implement" -> "implement", "check" -> "check", "finish" -> "check"
@@ -137,10 +138,10 @@ def update_current_phase(repo_root: str, feature_dir: str, subagent_type: str) -
137
138
  break
138
139
 
139
140
  if new_phase is not None:
140
- feature_data["current_phase"] = new_phase
141
+ task_data["current_phase"] = new_phase
141
142
 
142
- with open(feature_json_path, "w", encoding="utf-8") as f:
143
- json.dump(feature_data, f, indent=2, ensure_ascii=False)
143
+ with open(task_json_path, "w", encoding="utf-8") as f:
144
+ json.dump(task_data, f, indent=2, ensure_ascii=False)
144
145
  except Exception:
145
146
  # Don't fail the hook if phase update fails
146
147
  pass
@@ -249,7 +250,7 @@ def read_jsonl_entries(base_path: str, jsonl_path: str) -> list[tuple[str, str]]
249
250
  return results
250
251
 
251
252
 
252
- def get_agent_context(repo_root: str, feature_dir: str, agent_type: str) -> str:
253
+ def get_agent_context(repo_root: str, task_dir: str, agent_type: str) -> str:
253
254
  """
254
255
  Get complete context for specified agent
255
256
 
@@ -258,12 +259,12 @@ def get_agent_context(repo_root: str, feature_dir: str, agent_type: str) -> str:
258
259
  context_parts = []
259
260
 
260
261
  # 1. Try agent-specific jsonl
261
- agent_jsonl = f"{feature_dir}/{agent_type}.jsonl"
262
+ agent_jsonl = f"{task_dir}/{agent_type}.jsonl"
262
263
  agent_entries = read_jsonl_entries(repo_root, agent_jsonl)
263
264
 
264
265
  # 2. If agent-specific jsonl doesn't exist or empty, fallback to spec.jsonl
265
266
  if not agent_entries:
266
- agent_entries = read_jsonl_entries(repo_root, f"{feature_dir}/spec.jsonl")
267
+ agent_entries = read_jsonl_entries(repo_root, f"{task_dir}/spec.jsonl")
267
268
 
268
269
  # 3. Add all files from jsonl
269
270
  for file_path, content in agent_entries:
@@ -272,7 +273,7 @@ def get_agent_context(repo_root: str, feature_dir: str, agent_type: str) -> str:
272
273
  return "\n\n".join(context_parts)
273
274
 
274
275
 
275
- def get_implement_context(repo_root: str, feature_dir: str) -> str:
276
+ def get_implement_context(repo_root: str, task_dir: str) -> str:
276
277
  """
277
278
  Complete context for Implement Agent
278
279
 
@@ -284,39 +285,39 @@ def get_implement_context(repo_root: str, feature_dir: str) -> str:
284
285
  context_parts = []
285
286
 
286
287
  # 1. Read implement.jsonl (or fallback to spec.jsonl)
287
- base_context = get_agent_context(repo_root, feature_dir, "implement")
288
+ base_context = get_agent_context(repo_root, task_dir, "implement")
288
289
  if base_context:
289
290
  context_parts.append(base_context)
290
291
 
291
292
  # 2. Requirements document
292
- prd_content = read_file_content(repo_root, f"{feature_dir}/prd.md")
293
+ prd_content = read_file_content(repo_root, f"{task_dir}/prd.md")
293
294
  if prd_content:
294
295
  context_parts.append(
295
- f"=== {feature_dir}/prd.md (Requirements) ===\n{prd_content}"
296
+ f"=== {task_dir}/prd.md (Requirements) ===\n{prd_content}"
296
297
  )
297
298
 
298
299
  # 3. Technical design
299
- info_content = read_file_content(repo_root, f"{feature_dir}/info.md")
300
+ info_content = read_file_content(repo_root, f"{task_dir}/info.md")
300
301
  if info_content:
301
302
  context_parts.append(
302
- f"=== {feature_dir}/info.md (Technical Design) ===\n{info_content}"
303
+ f"=== {task_dir}/info.md (Technical Design) ===\n{info_content}"
303
304
  )
304
305
 
305
306
  return "\n\n".join(context_parts)
306
307
 
307
308
 
308
- def get_check_context(repo_root: str, feature_dir: str) -> str:
309
+ def get_check_context(repo_root: str, task_dir: str) -> str:
309
310
  """
310
311
  Complete context for Check Agent
311
312
 
312
313
  Read order:
313
314
  1. All files in check.jsonl (check specs + dev specs)
314
- 2. prd.md (for understanding feature intent)
315
+ 2. prd.md (for understanding task intent)
315
316
  """
316
317
  context_parts = []
317
318
 
318
319
  # 1. Read check.jsonl (or fallback to spec.jsonl + hardcoded check files)
319
- check_entries = read_jsonl_entries(repo_root, f"{feature_dir}/check.jsonl")
320
+ check_entries = read_jsonl_entries(repo_root, f"{task_dir}/check.jsonl")
320
321
 
321
322
  if check_entries:
322
323
  for file_path, content in check_entries:
@@ -335,21 +336,21 @@ def get_check_context(repo_root: str, feature_dir: str) -> str:
335
336
  context_parts.append(f"=== {file_path} ({description}) ===\n{content}")
336
337
 
337
338
  # Add spec.jsonl
338
- spec_entries = read_jsonl_entries(repo_root, f"{feature_dir}/spec.jsonl")
339
+ spec_entries = read_jsonl_entries(repo_root, f"{task_dir}/spec.jsonl")
339
340
  for file_path, content in spec_entries:
340
341
  context_parts.append(f"=== {file_path} (Dev spec) ===\n{content}")
341
342
 
342
- # 2. Requirements document (for understanding feature intent)
343
- prd_content = read_file_content(repo_root, f"{feature_dir}/prd.md")
343
+ # 2. Requirements document (for understanding task intent)
344
+ prd_content = read_file_content(repo_root, f"{task_dir}/prd.md")
344
345
  if prd_content:
345
346
  context_parts.append(
346
- f"=== {feature_dir}/prd.md (Requirements - for understanding intent) ===\n{prd_content}"
347
+ f"=== {task_dir}/prd.md (Requirements - for understanding intent) ===\n{prd_content}"
347
348
  )
348
349
 
349
350
  return "\n\n".join(context_parts)
350
351
 
351
352
 
352
- def get_finish_context(repo_root: str, feature_dir: str) -> str:
353
+ def get_finish_context(repo_root: str, task_dir: str) -> str:
353
354
  """
354
355
  Complete context for Finish phase (final check before PR)
355
356
 
@@ -361,7 +362,7 @@ def get_finish_context(repo_root: str, feature_dir: str) -> str:
361
362
  context_parts = []
362
363
 
363
364
  # 1. Try finish.jsonl first
364
- finish_entries = read_jsonl_entries(repo_root, f"{feature_dir}/finish.jsonl")
365
+ finish_entries = read_jsonl_entries(repo_root, f"{task_dir}/finish.jsonl")
365
366
 
366
367
  if finish_entries:
367
368
  for file_path, content in finish_entries:
@@ -375,16 +376,16 @@ def get_finish_context(repo_root: str, feature_dir: str) -> str:
375
376
  )
376
377
 
377
378
  # 2. Requirements document (for verifying requirements are met)
378
- prd_content = read_file_content(repo_root, f"{feature_dir}/prd.md")
379
+ prd_content = read_file_content(repo_root, f"{task_dir}/prd.md")
379
380
  if prd_content:
380
381
  context_parts.append(
381
- f"=== {feature_dir}/prd.md (Requirements - verify all met) ===\n{prd_content}"
382
+ f"=== {task_dir}/prd.md (Requirements - verify all met) ===\n{prd_content}"
382
383
  )
383
384
 
384
385
  return "\n\n".join(context_parts)
385
386
 
386
387
 
387
- def get_debug_context(repo_root: str, feature_dir: str) -> str:
388
+ def get_debug_context(repo_root: str, task_dir: str) -> str:
388
389
  """
389
390
  Complete context for Debug Agent
390
391
 
@@ -395,14 +396,14 @@ def get_debug_context(repo_root: str, feature_dir: str) -> str:
395
396
  context_parts = []
396
397
 
397
398
  # 1. Read debug.jsonl (or fallback to spec.jsonl + hardcoded check files)
398
- debug_entries = read_jsonl_entries(repo_root, f"{feature_dir}/debug.jsonl")
399
+ debug_entries = read_jsonl_entries(repo_root, f"{task_dir}/debug.jsonl")
399
400
 
400
401
  if debug_entries:
401
402
  for file_path, content in debug_entries:
402
403
  context_parts.append(f"=== {file_path} ===\n{content}")
403
404
  else:
404
405
  # Fallback: use spec.jsonl + hardcoded check files
405
- spec_entries = read_jsonl_entries(repo_root, f"{feature_dir}/spec.jsonl")
406
+ spec_entries = read_jsonl_entries(repo_root, f"{task_dir}/spec.jsonl")
406
407
  for file_path, content in spec_entries:
407
408
  context_parts.append(f"=== {file_path} (Dev spec) ===\n{content}")
408
409
 
@@ -418,11 +419,11 @@ def get_debug_context(repo_root: str, feature_dir: str) -> str:
418
419
 
419
420
  # 2. Codex review output (if exists)
420
421
  codex_output = read_file_content(
421
- repo_root, f"{feature_dir}/codex-review-output.txt"
422
+ repo_root, f"{task_dir}/codex-review-output.txt"
422
423
  )
423
424
  if codex_output:
424
425
  context_parts.append(
425
- f"=== {feature_dir}/codex-review-output.txt (Codex Review Results) ===\n{codex_output}"
426
+ f"=== {task_dir}/codex-review-output.txt (Codex Review Results) ===\n{codex_output}"
426
427
  )
427
428
 
428
429
  return "\n\n".join(context_parts)
@@ -564,7 +565,7 @@ Dev specs and Codex Review results:
564
565
  - Report which issues were fixed and which files were modified"""
565
566
 
566
567
 
567
- def get_research_context(repo_root: str, feature_dir: str | None) -> str:
568
+ def get_research_context(repo_root: str, task_dir: str | None) -> str:
568
569
  """
569
570
  Context for Research Agent
570
571
 
@@ -575,11 +576,11 @@ def get_research_context(repo_root: str, feature_dir: str | None) -> str:
575
576
  context_parts = []
576
577
 
577
578
  # 1. Project structure overview (uses constants for paths)
578
- structure_path = f"{DIR_WORKFLOW}/{DIR_STRUCTURE}"
579
+ spec_path = f"{DIR_WORKFLOW}/{DIR_SPEC}"
579
580
  project_structure = f"""## Project Spec Directory Structure
580
581
 
581
582
  ```
582
- {structure_path}/
583
+ {spec_path}/
583
584
  ├── shared/ # Cross-project common specs (TypeScript, code quality, git)
584
585
  ├── frontend/ # Frontend standards
585
586
  ├── backend/ # Backend standards
@@ -590,17 +591,17 @@ def get_research_context(repo_root: str, feature_dir: str | None) -> str:
590
591
 
591
592
  ## Search Tips
592
593
 
593
- - Spec files: `{structure_path}/**/*.md`
594
+ - Spec files: `{spec_path}/**/*.md`
594
595
  - Known issues: `{DIR_WORKFLOW}/big-question/`
595
596
  - Code search: Use Glob and Grep tools
596
597
  - Tech solutions: Use mcp__exa__web_search_exa or mcp__exa__get_code_context_exa"""
597
598
 
598
599
  context_parts.append(project_structure)
599
600
 
600
- # 2. If feature directory exists, try reading research.jsonl (optional)
601
- if feature_dir:
601
+ # 2. If task directory exists, try reading research.jsonl (optional)
602
+ if task_dir:
602
603
  research_entries = read_jsonl_entries(
603
- repo_root, f"{feature_dir}/research.jsonl"
604
+ repo_root, f"{task_dir}/research.jsonl"
604
605
  )
605
606
  if research_entries:
606
607
  context_parts.append(
@@ -697,46 +698,46 @@ def main():
697
698
  if not repo_root:
698
699
  sys.exit(0)
699
700
 
700
- # Get current feature directory (research doesn't require it)
701
- feature_dir = get_current_feature(repo_root)
701
+ # Get current task directory (research doesn't require it)
702
+ task_dir = get_current_task(repo_root)
702
703
 
703
- # implement/check/debug need feature directory
704
- if subagent_type in AGENTS_REQUIRE_FEATURE:
705
- if not feature_dir:
704
+ # implement/check/debug need task directory
705
+ if subagent_type in AGENTS_REQUIRE_TASK:
706
+ if not task_dir:
706
707
  sys.exit(0)
707
- # Check if feature directory exists
708
- feature_dir_full = os.path.join(repo_root, feature_dir)
709
- if not os.path.exists(feature_dir_full):
708
+ # Check if task directory exists
709
+ task_dir_full = os.path.join(repo_root, task_dir)
710
+ if not os.path.exists(task_dir_full):
710
711
  sys.exit(0)
711
712
 
712
- # Update current_phase in feature.json (system-level enforcement)
713
- update_current_phase(repo_root, feature_dir, subagent_type)
713
+ # Update current_phase in task.json (system-level enforcement)
714
+ update_current_phase(repo_root, task_dir, subagent_type)
714
715
 
715
716
  # Check for [finish] marker in prompt (check agent with finish context)
716
717
  is_finish_phase = "[finish]" in original_prompt.lower()
717
718
 
718
719
  # Get context and build prompt based on subagent type
719
720
  if subagent_type == AGENT_IMPLEMENT:
720
- assert feature_dir is not None # validated above
721
- context = get_implement_context(repo_root, feature_dir)
721
+ assert task_dir is not None # validated above
722
+ context = get_implement_context(repo_root, task_dir)
722
723
  new_prompt = build_implement_prompt(original_prompt, context)
723
724
  elif subagent_type == AGENT_CHECK:
724
- assert feature_dir is not None # validated above
725
+ assert task_dir is not None # validated above
725
726
  if is_finish_phase:
726
727
  # Finish phase: use finish context (lighter, focused on final verification)
727
- context = get_finish_context(repo_root, feature_dir)
728
+ context = get_finish_context(repo_root, task_dir)
728
729
  new_prompt = build_finish_prompt(original_prompt, context)
729
730
  else:
730
731
  # Regular check phase: use check context (full specs for self-fix loop)
731
- context = get_check_context(repo_root, feature_dir)
732
+ context = get_check_context(repo_root, task_dir)
732
733
  new_prompt = build_check_prompt(original_prompt, context)
733
734
  elif subagent_type == AGENT_DEBUG:
734
- assert feature_dir is not None # validated above
735
- context = get_debug_context(repo_root, feature_dir)
735
+ assert task_dir is not None # validated above
736
+ context = get_debug_context(repo_root, task_dir)
736
737
  new_prompt = build_debug_prompt(original_prompt, context)
737
738
  elif subagent_type == AGENT_RESEARCH:
738
- # Research can work without feature directory
739
- context = get_research_context(repo_root, feature_dir)
739
+ # Research can work without task directory
740
+ context = get_research_context(repo_root, task_dir)
740
741
  new_prompt = build_research_prompt(original_prompt, context)
741
742
  else:
742
743
  sys.exit(0)