|
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
|
``` |