1 ---
2 name: project_tasks
3 description: Create and manage persistent project tasks visible to the user.
4 ---
5
6 # Project Tasks
7
8 Manage persistent, user-visible project tasks that the main agent or a task agent can execute. Only task agents run in isolated environments. Use these to track high-level deliverables and milestones that the user cares about.
9
10 ## Project Tasks vs Internal Task List
11
12 | Aspect | Project Tasks | Internal Task List |
13 |--------|--------------|-------------------|
14 | Purpose | User-visible deliverables | Agent's own work breakdown |
15 | Persistence | Persistent across sessions (PID2) | Current session only |
16 | Visibility | Shown to the user | Internal to the agent |
17 | Granularity | High-level milestones | Detailed implementation steps |
18
19 ## When to Use
20
21 - Tracking user-requested features or deliverables
22 - Breaking a project into visible milestones
23 - Communicating progress to the user
24 - Managing tasks that persist across sessions
25
26 ## When NOT to Use
27
28 - Internal agent work breakdown (use the internal task list)
29 - Temporary implementation steps
30 - Sub-tasks that only matter to the agent
31
32 ## Task Identifiers
33
34 Tasks are identified by `taskRef` — a short string like `"#1"`, `"#2"`, `"#3"`. Use it in all API calls and when referring to tasks in conversation: "Task #1 (Add authentication)".
35
36 ## Available Functions
37
38 ### getProjectTask(taskRef)
39
40 Get a project task by task ref.
41
42 **Parameters:**
43
44 | Parameter | Type | Required | Description |
45 |-----------|------|----------|-------------|
46 | `taskRef` | str | Yes | Task ref to retrieve |
47
48 **Returns:** Dict with `taskRef`, `title`, `description`, `state`, `createdAt`, `updatedAt`
49
50 **Example:**
51
52 ```javascript
53 const task = await getProjectTask({ taskRef: "#1" });
54 // "Task #1 (Add authentication)"
55 ```
56
57 ### updateProjectTask(taskRef, title=None, description=None, filePath=None, dependsOn=None, artifactKinds=None)
58
59 Update an existing project task's content. Only provided fields are updated. Editing a plan file alone does NOT update the task — you must call `updateProjectTask` to persist changes.
60
61 **Parameters:**
62
63 | Parameter | Type | Required | Description |
64 |-----------|------|----------|-------------|
65 | `taskRef` | str | Yes | Task ref to update |
66 | `title` | str | No | New title |
67 | `description` | str | No | New description as an inline string. Use this when there is no plan file. Mutually exclusive with `filePath`. |
68 | `filePath` | str | No | Path to a plan file under `.local/tasks/`. If you've created/edited a plan file, pass its path here and its content becomes the new description. Mutually exclusive with `description`. |
69 | `dependsOn` | array of str | No | Full list of dependency task refs (replaces existing) |
70 | `artifactKinds` | array | No | Updated artifact kind tags. Pass `[]` to clear stale tags when the task is no longer artifact-producing. |
71
72 **Returns:** Dict with `taskRef`, `title`, `description`, `state`, `createdAt`, `updatedAt`
73
74 **Examples:**
75
76 ```javascript
77 // Edited plan file → push its content as the new description.
78 await updateProjectTask({
79 taskRef: "#1",
80 title: "Agentic canvas prototype (tldraw)",
81 filePath: ".local/tasks/agentic-canvas-prototype.md",
82 });
83
84 // No plan file → pass the new description inline.
85 await updateProjectTask({
86 taskRef: "#1",
87 description: "Add a Canvas toggle button to the preview pane.",
88 });
89 ```
90
91 ### markTaskInProgress(taskRef)
92
93 Resume work on an IMPLEMENTED task. Call this before making further changes to a task that was already marked complete.
94
95 **Parameters:**
96
97 | Parameter | Type | Required | Description |
98 |-----------|------|----------|-------------|
99 | `taskRef` | str | Yes | Task ref to resume |
100
101 **Returns:** Dict with `taskRef`, `title`, `description`, `state`, `createdAt`, `updatedAt`
102
103 **Example:**
104
105 ```javascript
106 await markTaskInProgress({ taskRef: "#1" });
107 ```
108
109 ### searchProjectTasks(query, locale=None, limit=None)
110
111 Search project tasks by text query, ordered by relevance.
112
113 **Parameters:**
114
115 | Parameter | Type | Required | Description |
116 |-----------|------|----------|-------------|
117 | `query` | str | Yes | Search query. Supports boolean syntax: `"exact phrase"`, `foo bar` (both words), `foo OR bar`, `-foo` (exclude) |
118 | `locale` | str | No | BCP 47 locale of the query (e.g. `"en"`, `"es"`, `"fr"`). Pass for non-English queries for better stemming. |
119 | `limit` | int | No | Maximum number of results (default: 20) |
120
121 **Returns:** List of dicts, each with `taskRef`, `title`, `description`, `state`, `score`, `matchType`, `createdAt`, `updatedAt`
122
123 **Example:**
124
125 ```javascript
126 // Simple keyword search
127 const results = await searchProjectTasks({ query: "authentication" });
128
129 // Boolean syntax: find auth tasks that aren't about login
130 const results = await searchProjectTasks({ query: "authentication -login", limit: 5 });
131
132 // Exact phrase
133 const results = await searchProjectTasks({ query: '"payment integration"' });
134
135 // Non-English query — pass locale for better stemming
136 const results = await searchProjectTasks({ query: "autenticación", locale: "es" });
137
138 for (const r of results) {
139 console.log(`${r.taskRef} (${r.title}) — score: ${r.score}`);
140 }
141 ```
142
143 ### listProjectTasks(state=None, taskRefs=None, includeDescription=False)
144
145 List project tasks, optionally filtered by state or specific task refs.
146
147 **Parameters:**
148
149 | Parameter | Type | Required | Description |
150 |-----------|------|----------|-------------|
151 | `state` | str | No | Filter by state (e.g., "IN_PROGRESS") |
152 | `taskRefs` | array of str | No | List of specific task refs to retrieve |
153 | `includeDescription` | bool | No | Whether to include the task description (default: false) |
154
155 **Returns:** List of dicts, each with `taskRef`, `title`, `state`, `dependsOn`, `createdAt`, `updatedAt` (plus `description` if `includeDescription` is true). `dependsOn` lists dependency task refs also in the result set; dependencies pointing outside the `taskRefs` filter are omitted.
156
157 **Example:**
158
159 ```javascript
160 const allTasks = await listProjectTasks();
161 for (const task of allTasks) {
162 console.log(` - Task ${task.taskRef} (${task.title})`);
163 }
164 ```
165
166 ### bulkCreateProjectTasks(tasks)
167
168 Create multiple tasks at once with dependency relationships. Each task is created in PROPOSED state. The plan file content becomes the task description.
169
170 **Parameters:**
171
172 | Parameter | Type | Required | Description |
173 |-----------|------|----------|-------------|
174 | `tasks` | array | Yes | List of task objects (see below) |
175
176 Each task object:
177
178 | Field | Type | Required | Description |
179 |-------|------|----------|-------------|
180 | `id` | str | No | Alias within the batch, referenced by other tasks' `dependsOn`. Auto-generated if omitted. |
181 | `title` | str | Yes | Short title for the task |
182 | `filePath` | str | Yes | Path to the plan file (e.g. `.local/tasks/payment-integration.md`). The file content becomes the task description. |
183 | `dependsOn` | array | No | List of `id` values from other tasks in this batch, or task refs (`"#1"`, `"#2"`) of already-accepted tasks. Never depend on PROPOSED — only PENDING or later. Tasks within the same batch may depend on each other freely. |
184 | `artifactKinds` | array | No | Artifact kinds for tasks creating new artifacts. Values: `web`, `mobile`, `video`, `slides`, `automation`, `data-app`, `design`. Omit for code-only or non-artifact work. |
185
186 **Returns:** List of created task dicts with `taskRef`, `title`, `description`, `state`, `dependsOn`, `createdAt`, `updatedAt`
187
188 **Examples:**
189
190 ```javascript
191 // Single task (no dependencies)
192 const created = await bulkCreateProjectTasks({
193 tasks: [
194 {
195 title: "Launch microsite",
196 filePath: ".local/tasks/launch-microsite.md",
197 artifactKinds: ["web"],
198 },
199 ]
200 });
201
202 // Multiple tasks with dependencies using id aliases
203 const created = await bulkCreateProjectTasks({
204 tasks: [
205 {
206 id: "auth",
207 title: "Add authentication",
208 filePath: ".local/tasks/auth.md",
209 },
210 {
211 id: "payments",
212 title: "Payment integration",
213 filePath: ".local/tasks/payments.md",
214 dependsOn: ["auth"],
215 },
216 ]
217 });
218 ```
219
220 ## Plan File Format
221
222 Write each project-task plan as a plain markdown document in `.local/tasks/`. The file content becomes the task description. Do not run `mkdir`; the write tool creates parent dirs.
223
224 By default, create one project task per user request. Combine related work into a single plan rather than splitting into many tasks. Only create multiple tasks if the user explicitly asks for them or the request contains clearly independent, unrelated goals.
225
226 Dependencies and artifact tags are not declared in the plan file — pass them via `dependsOn` and `artifactKinds` when creating or updating tasks.
227
228 ### Plan body
229
230 First line: a short, descriptive title (3-6 words) prefixed with `#`. Then include these sections:
231
232 - **What & Why** — Brief description of the feature/change and its purpose.
233 - **Done looks like** — Observable outcomes when complete (what the user sees, not code-level details).
234 - **Out of scope** — What is explicitly NOT included.
235 - **Steps** — Numbered implementation steps for the executor agent, not separate project tasks.
236 - **Relevant files** — Existing files discovered during investigation that the executor should start from. Use backtick-wrapped paths only, no trailing descriptions. Only list files you verified exist.
237 - Whole file: `src/api/billing.ts`
238 - Specific lines: `src/api/billing.ts:12-85`
239 - Multiple ranges: `src/api/billing.ts:12-85,200-250`
240 - WRONG: `src/api/billing.ts` — Billing API handlers (lines 12-85)
241
242 Assume features build on each other. If a new task depends on another task, declare that dependency via `dependsOn` rather than in the plan body. You may depend on existing tasks that are PENDING or later — never on existing PROPOSED tasks. Tasks within the same batch may depend on each other freely.
243
244 Rules for the `## Steps` section:
245
246 - Each step should be describable in 1-2 sentences.
247 - Focus on what to build, not how to build it.
248 - Do not include file paths, code snippets, CSS classes, or line-level edits in step bullets. Put file references in `## Relevant files` instead.
249 - Draw clean boundaries so parallel executors won't conflict. Combine same-area steps into one project task.
250 - Add a short note for critical architectural constraints.
251
252 ### Example
253
254 ```markdown
255 # Payment Integration
256
257 ## What & Why
258 Add Stripe payment processing so users can upgrade to paid plans.
259
260 ## Done looks like
261 - Users can enter payment info and subscribe to a plan
262 - Successful payments activate the paid tier immediately
263 - Failed payments show a clear error message
264
265 ## Out of scope
266 - Invoicing and receipts (future work)
267 - Multiple payment methods (Stripe only for now)
268
269 ## Steps
270 1. **Stripe backend integration** — Set up Stripe SDK, create endpoints for creating checkout sessions and handling webhooks
271 2. **Payment UI** — Build the checkout page with plan selection and Stripe Elements for card input
272 3. **Tier activation** — On successful payment, upgrade the user's account to the paid tier and reflect it in the UI
273
274 ## Relevant files
275 - `src/api/billing.ts:12-85`
276 - `src/config/stripe.ts`
277 ```
278
279 ### proposeProjectTasks(taskRefs)
280
281 Propose existing tasks for user review. Pauses the agent until the user approves.
282
283 **Parameters:**
284
285 | Parameter | Type | Required | Description |
286 |-----------|------|----------|-------------|
287 | `taskRefs` | array of str | Yes | Task refs to propose |
288
289 **Returns:** Dict with `proposed` list of `{ taskRef, title }` summaries
290
291 **Example:**
292
293 ```javascript
294 await proposeProjectTasks({ taskRefs: created.map(t => t.taskRef) });
295 ```
296
297 ## Task States
298
299 | State | Description |
300 |-------|-------------|
301 | `PROPOSED` | Suggested but not yet accepted by the user. No implementation exists. |
302 | `PENDING` | Accepted, waiting to start. No implementation exists. |
303 | `IN_PROGRESS` | Being worked on by a task agent in a separate Repl. Changes are not visible in this Repl. |
304 | `IMPLEMENTED` | Work is done in a separate Repl, ready for merge. Changes are not visible in this Repl — do not search the codebase for them. |
305 | `MERGING` | Currently being merged. Do not duplicate. |
306 | `MERGED` | Finished and merged. Changes are now visible in this Repl. |
307 | `BLOCKED_BY_DRIFT` | Blocked because an upstream task diverged from its plan; needs replanning. |
308 | `CANCELLED` | Abandoned. |
309
310 ## User Communication Rules
311
312 Follow these rules strictly when discussing tasks with the user:
313
314 1. **Always describe tasks by ref and title**: e.g. "Task #1 (Add authentication button)"
315 2. **Never use internal state names**: use these display names instead:
316 - PROPOSED → "Drafts"
317 - PENDING → "Active"
318 - IN_PROGRESS → "Active"
319 - IMPLEMENTED → "Ready"
320 - MERGING → "Merging"
321 - MERGED → "Merged"
322 - CANCELLED → "Archived"
323 - BLOCKED_BY_DRIFT → "Affected by another task that changed"
324 3. **Never expose implementation details**: Do not reveal function names (`bulkCreateProjectTasks`, `updateProjectTask`, etc.), API surface, or internal task system mechanics to the user
325
326 ## Best Practices
327
328 1. **Prefer fewer tasks**: Default to one task per request unless the user explicitly asks for more
329 2. **Create tasks early**: Create the project task when you understand the user's goals
330 3. **Keep titles short**: Titles should be concise and descriptive
331 4. **Use descriptions for detail**: Put implementation details in the description field
332
333 ## Example Workflow
334
335 ```javascript
336 // 1. Write the plan file directly with the write tool — it creates `.local/tasks/` for you.
337
338 // 2. Create the task — file content becomes the description
339 const created = await bulkCreateProjectTasks({
340 tasks: [
341 {
342 title: "Launch microsite",
343 filePath: ".local/tasks/launch-microsite.md",
344 artifactKinds: ["web"],
345 },
346 ]
347 });
348
349 // 3. Propose for user approval (pauses agent loop)
350 await proposeProjectTasks({
351 taskRefs: created.map(t => t.taskRef),
352 });
353
354 // --- After user approves, the system handles scheduling ---
355
356 // 4. Check progress
357 const tasks = await listProjectTasks();
358 for (const task of tasks) {
359 console.log(`Task ${task.taskRef} (${task.title}): ${task.state}`);
360 }
361 ```