@qelos/aidev 0.5.2 → 0.5.3

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/README.md CHANGED
@@ -1,735 +1,735 @@
1
- # @qelos/aidev
2
-
3
- [![npm version](https://img.shields.io/npm/v/%40qelos%2Faidev.svg?style=flat-square)](https://www.npmjs.com/package/@qelos/aidev)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](./LICENSE)
5
- [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg?style=flat-square)](https://nodejs.org)
6
-
7
- **aidev** turns your tasks into merged code — automatically.
8
-
9
- It polls your task manager (ClickUp, Jira, Linear, Monday.com, Notion, Trello, or local markdown files), checks whether tasks are clear, runs Claude, Cursor, or Windsurf to implement them, pushes a branch, and moves the task to review. All without touching your keyboard.
10
-
11
- ```
12
- Task → AI implements → git push → "in review" → AI resolves code review comments
13
- ```
14
-
15
- ---
16
-
17
- ## Table of Contents
18
-
19
- - [How it works](#how-it-works)
20
- - [Quick start](#quick-start)
21
- - [Commands](#commands)
22
- - [Concurrency lock](#concurrency-lock)
23
- - [Configuration](#configuration)
24
- - [AI agents](#ai-agents)
25
- - [Code review resolution](#code-review-resolution)
26
- - [Auto-merge accepted PRs](#auto-merge-accepted-prs)
27
- - [Dev notes mode](#dev-notes-mode)
28
- - [Local tasks file (`aidev.tasks.json`)](#local-tasks-file-aidevtasksjson)
29
- - [Scheduling](#scheduling)
30
- - [Hooks](#hooks)
31
- - [Logging](#logging)
32
- - [Providers](#providers)
33
- - [Contributing](#contributing)
34
-
35
- ---
36
-
37
- ## How it works
38
-
39
- 1. **Fetch** — pulls all tasks tagged with your configured tag from your task provider
40
- 2. **Filter** — skips done/cancelled tasks and tasks that already have a branch
41
- 3. **Clarify** — in `smart` mode, asks the AI if the task description is clear enough; if not, posts a question as a comment (prefixed with `[aidev]`) and marks the task `pending`
42
- 4. **Wait** — pending tasks are re-checked on the next run; if a human replied or the trigger word is found, implementation proceeds with the conversation as context
43
- 5. **Implement** — checks out a fresh branch (or reuses an existing one), runs your configured AI agent(s), falls back to the next agent if one fails
44
- 6. **Ship** — commits all changes, pushes the branch, posts a comment with the branch name and a PR link, moves the task to your "in review" status
45
- 7. **Review** — checks tasks already in review for unresolved PR code review comments; if found, runs an AI agent to fix code or reply to discussion threads
46
-
47
- ---
48
-
49
- ## Quick start
50
-
51
- ```bash
52
- npm install -g @qelos/aidev
53
- ```
54
-
55
- Navigate to your project and run the interactive setup:
56
-
57
- ```bash
58
- cd my-project
59
- aidev init
60
- ```
61
-
62
- The wizard will ask for your task provider credentials, git settings, and preferred AI agents.
63
-
64
- > **Note:** `aidev init` currently supports **ClickUp, Jira, Linear, Local, and Monday.com**. For **Notion** and **Trello**, create `.env.aidev` manually using `.env.aidev.example` as a template (see [Configuration](#configuration)).
65
- >
66
- > For ClickUp, API keys can be left blank if they are already set as environment variables in your shell. For Jira, Linear, and Monday.com, the wizard requires credentials to be entered directly — to use shell env vars instead, edit `.env.aidev` after init and remove the values you want read from your environment.
67
-
68
- Once configured:
69
-
70
- ```bash
71
- aidev run
72
- ```
73
-
74
- ---
75
-
76
- ## Commands
77
-
78
- | Command | Description |
79
- |---|---|
80
- | `aidev init` | Interactive setup — creates `.env.aidev` |
81
- | `aidev run` | Process open + pending tasks, then check review tasks for unresolved PR comments |
82
- | `aidev run open` | Only open (non-pending) tasks |
83
- | `aidev run pending` | Only pending tasks — check for human replies |
84
- | `aidev run accepted` | Auto-merge PRs for tasks in review with the accepted tag |
85
- | `aidev run tasks` | Publish all entries in `aidev.tasks.json` and exit (no AI run) |
86
- | `aidev tasks add` | Add a new entry to `aidev.tasks.json` (interactive) |
87
- | `aidev tasks ls` | List entries currently queued in `aidev.tasks.json` |
88
- | `aidev tasks update [id]` | Edit a queued entry (interactive if `id` omitted) |
89
- | `aidev tasks remove [id]` | Delete a queued entry (interactive if `id` omitted) |
90
- | `aidev tasks push` | Same as `aidev run tasks` — publish all queued entries and exit |
91
- | `aidev stop` | Stop any running aidev process in the current directory |
92
- | `aidev schedule set` | Interactive cron picker for this directory |
93
- | `aidev schedule set "<expr>"` | Set a specific cron expression |
94
- | `aidev schedule get` | Show the current schedule for this directory |
95
- | `aidev help` | Show command and config reference |
96
-
97
- ### Global flags
98
-
99
- | Flag | Description |
100
- |---|---|
101
- | `-e, --env <path>` | Load config from a custom env file instead of `.env.aidev` |
102
- | `-V, --version` | Print version |
103
-
104
- **Examples**
105
-
106
- ```bash
107
- # Use a shared env file for a staging environment
108
- aidev --env /shared/.env.staging run
109
-
110
- # Only process tasks that are waiting for a reply
111
- aidev run pending
112
-
113
- # Schedule to run every 30 minutes
114
- aidev schedule set "*/30 * * * *"
115
- ```
116
-
117
- ---
118
-
119
- ## Concurrency lock
120
-
121
- `aidev run` writes a PID lock file (`.aidev.lock`) in the current directory when it starts and removes it when it finishes. If a second invocation detects a live process already holding the lock, it logs a warning and exits immediately — preventing two agents from committing to the same branch at the same time.
122
-
123
- ```
124
- $ aidev run
125
- [aidev] aidev is already running in this directory (PID 12345). Use "aidev stop" to terminate it.
126
- ```
127
-
128
- Use `aidev stop` to send `SIGTERM` to the running process and clean up the lock file:
129
-
130
- ```bash
131
- aidev stop
132
- ```
133
-
134
- Stale lock files (left behind by a crash) are detected automatically — the next `aidev run` will overwrite them if the stored PID is no longer alive.
135
-
136
- ---
137
-
138
- ## Configuration
139
-
140
- Run `aidev init` for an interactive setup, or create `.env.aidev` manually using `.env.aidev.example` as a template.
141
-
142
- ### Global env file (`AIDEV_ENV_EXTEND`)
143
-
144
- If you work across multiple projects, you can keep shared settings (API keys, agent list, etc.) in a single global file and reference it from each project's `.env.aidev`:
145
-
146
- ```bash
147
- # ~/.aidev.global
148
- CLICKUP_API_KEY=pk_...
149
- CLICKUP_TEAM_ID=123456
150
- AGENTS=claude,cursor
151
- ```
152
-
153
- ```bash
154
- # my-project/.env.aidev — project-specific values override the global ones
155
- AIDEV_ENV_EXTEND=~/.aidev.global
156
- CLICKUP_TAG=my-project
157
- ```
158
-
159
- **Priority order (highest → lowest):**
160
-
161
- 1. Shell environment variables (e.g. set in `~/.zshrc`) — never overwritten
162
- 2. Local `.env.aidev` values
163
- 3. `AIDEV_ENV_EXTEND` file values (global base)
164
-
165
- `AIDEV_ENV_EXTEND` can be set in two ways:
166
-
167
- - **Per-project** — add `AIDEV_ENV_EXTEND=/path/to/file` inside `.env.aidev`
168
- - **Shell-wide** — `export AIDEV_ENV_EXTEND=~/.aidev.global` in `~/.zshrc` (applies to every project automatically)
169
-
170
- `aidev init` will ask for this path and pre-fill it if the variable is already in your shell environment.
171
-
172
- ### ClickUp
173
-
174
- | Variable | Default | Description |
175
- |---|---|---|
176
- | `CLICKUP_API_KEY` | — | Personal API token — can be set as a shell env var |
177
- | `CLICKUP_TEAM_ID` | — | Workspace / team ID — can be set as a shell env var |
178
- | `CLICKUP_TAG` | — | Tasks with this tag will be picked up (set to `*` to match all tasks) |
179
- | `CLICKUP_PENDING_STATUS` | `pending` | Status name for "waiting for reply" |
180
- | `CLICKUP_IN_REVIEW_STATUS` | `review` | Status set after implementation |
181
- | `ASSIGNEE_TAG` | — | Only process tasks assigned to this user (optional) |
182
- | `THINKING_TAG` | — | Tasks with this tag are analyzed and broken into sub-tasks before execution (optional) |
183
- | `NON_CODE_TAG` | — | Tasks with this tag run without git branching (optional) |
184
- | `NON_CODE_CLICKUP_TEAM_ID` | same as `CLICKUP_TEAM_ID` | Different workspace for non-code tasks (optional) |
185
-
186
- > **Tip:** For ClickUp, API keys and tokens are intentionally omitted from `.env.aidev` if you leave them blank during `aidev init` — they will be read from your shell environment instead. For Jira, Linear, and Monday.com, the wizard requires these values; to use shell env vars, remove the entries from `.env.aidev` after init.
187
-
188
- > **Wildcard tag (`*`):** Set `CLICKUP_TAG=*` (or `JIRA_LABEL=*` / `LINEAR_LABEL=*` / `TRELLO_LABEL=*`) to match **all** tasks regardless of tags/labels. This is useful when the AI dev has its own dedicated user in the task provider and every task assigned to it should be processed.
189
-
190
- ### Jira
191
-
192
- | Variable | Default | Description |
193
- |---|---|---|
194
- | `JIRA_BASE_URL` | — | Jira instance URL (e.g. `https://mycompany.atlassian.net`) |
195
- | `JIRA_EMAIL` | — | Email for Jira authentication |
196
- | `JIRA_API_TOKEN` | — | API token — generate from [Atlassian account settings](https://id.atlassian.com/manage-profile/security/api-tokens) |
197
- | `JIRA_PROJECT` | — | Project key (e.g. `PROJ`) |
198
- | `JIRA_LABEL` | — | Issues with this label will be picked up (set to `*` to match all issues) |
199
- | `JIRA_PENDING_STATUS` | `To Do` | Status name for "waiting for reply" |
200
- | `JIRA_IN_REVIEW_STATUS` | `In Review` | Status set after implementation |
201
- | `NON_CODE_JIRA_PROJECT` | same as `JIRA_PROJECT` | Different project for non-code tasks (optional) |
202
-
203
- ### Linear
204
-
205
- | Variable | Default | Description |
206
- |---|---|---|
207
- | `LINEAR_API_KEY` | — | Personal API key from Linear Settings → API |
208
- | `LINEAR_TEAM_ID` | — | Team UUID from your workspace |
209
- | `LINEAR_LABEL` | — | Issues with this label will be picked up (set to `*` to match all issues) |
210
- | `LINEAR_PENDING_STATUS` | `Backlog` | Status name for "waiting for reply" |
211
- | `LINEAR_IN_REVIEW_STATUS` | `In Review` | Status set after implementation |
212
- | `NON_CODE_LINEAR_TEAM_ID` | same as `LINEAR_TEAM_ID` | Different team for non-code tasks (optional) |
213
-
214
- ### Monday.com
215
-
216
- | Variable | Default | Description |
217
- |---|---|---|
218
- | `MONDAY_API_TOKEN` | — | API token from monday.com Developer settings |
219
- | `MONDAY_BOARD_ID` | — | Board ID (from the board URL) |
220
- | `MONDAY_STATUS_COLUMN_ID` | `status` | Column ID for the status field |
221
- | `MONDAY_GROUP_ID` | — | Group ID to filter items (optional) |
222
-
223
- ### Notion
224
-
225
- | Variable | Default | Description |
226
- |---|---|---|
227
- | `NOTION_API_KEY` | — | Integration token from Notion → Settings → My integrations |
228
- | `NOTION_DATABASE_ID` | — | Database ID from the database URL (32-char hex) |
229
- | `NOTION_STATUS_PROPERTY` | `Status` | Name of the status property in the database |
230
- | `NOTION_PENDING_STATUS` | `pending` | Status value for "waiting for reply" |
231
- | `NOTION_IN_REVIEW_STATUS` | `review` | Status value set after implementation |
232
-
233
- ### Trello
234
-
235
- | Variable | Default | Description |
236
- |---|---|---|
237
- | `TRELLO_API_KEY` | — | Developer API key from [trello.com/power-ups/admin](https://trello.com/power-ups/admin) |
238
- | `TRELLO_TOKEN` | — | Auth token generated via Trello's token flow |
239
- | `TRELLO_BOARD_ID` | — | Board ID from the board URL |
240
- | `TRELLO_LABEL` | — | Label name on cards to pick up (set to `*` to match all cards assigned to the token user) |
241
- | `TRELLO_OPEN_LIST` | `To Do` | List name for open/new cards |
242
- | `TRELLO_PENDING_LIST` | `Blocked` | List name for "waiting for reply" |
243
- | `TRELLO_IN_PROGRESS_LIST` | `Doing` | List name for cards being worked on |
244
- | `TRELLO_IN_REVIEW_LIST` | `In Review` | List name for completed cards awaiting review |
245
- | `TRELLO_OPEN_STATUS` | `open` | Semantic status mapped to the open list |
246
- | `TRELLO_PENDING_STATUS` | `pending` | Semantic status mapped to the pending list |
247
- | `TRELLO_IN_REVIEW_STATUS` | `review` | Semantic status mapped to the review list |
248
-
249
- ### Git & GitHub
250
-
251
- | Variable | Default | Description |
252
- |---|---|---|
253
- | `GIT_REMOTE` | auto-detected | Remote name — detected via `git remote get-url origin` if unset |
254
- | `GITHUB_BASE_BRANCH` | `main` | Base branch; new task branches are cut from here |
255
- | `GITHUB_REPO` | — | `owner/repo` — used to generate PR links in comments |
256
-
257
- ### Behaviour
258
-
259
- | Variable | Default | Description |
260
- |---|---|---|
261
- | `AIDEV_ENV_EXTEND` | — | Path to a global env file loaded as the base for this project (see above) |
262
- | `AGENTS` | `claude,cursor` | Comma-separated list of agents in priority order |
263
- | `DEV_NOTES_MODE` | `smart` | When to ask for clarification (`smart` or `always`) |
264
- | `AIDEV_TRIGGER_WORD` | `aidev-continue` | Comment containing this word re-triggers a skipped task |
265
- | `AIDEV_COMMENT_PREFIX` | `[aidev]` | Custom prefix for all aidev comments posted to task providers |
266
- | `AIDEV_HOOKS_PATH` | — | Path to a `.ts` or `.js` module that exports hook functions (see [Hooks](#hooks)) |
267
- | `ACCEPTED_TAG` | — | Tasks in review with this tag are auto-merged (see [Auto-merge accepted PRs](#auto-merge-accepted-prs)) |
268
- | `DONE_STATUS` | — | Status to set after auto-merging an accepted PR (e.g. `done`) |
269
- | `PR_SIGNATURE` | `Automated PR by aidev.` | Custom signature line appended to the PR body |
270
- | `AIDEV_AUTO_COMPRESS` | `true` | Auto-compress older comments when the prompt grows large. Set to `false` / `0` / `no` to opt out |
271
- | `AIDEV_COMPRESS_THRESHOLD` | `12000` | Char-length threshold that triggers compression |
272
-
273
- ---
274
-
275
- ## Hooks
276
-
277
- Set `AIDEV_HOOKS_PATH` in `.env.aidev` to a path relative to the project directory or an absolute path. `aidev init` writes `.aidev/aidev.hooks.ts` and sets `AIDEV_HOOKS_PATH=.aidev/aidev.hooks.ts` by default.
278
-
279
- The module should export an object (or `export default`) whose properties are optional async functions. Only known hook names are used; anything else is ignored. If a hook throws, the current operation stops (for example the whole run after `beforeRun`, or conflict resolution after `beforeResolveConflicts`). If a hook returns an object, it replaces the context for that step (for example append to `context.prompt` in `beforeEachTask` and return the updated context).
280
-
281
- **Hook names**
282
-
283
- | Hook | When | Context notes |
284
- |---|---|---|
285
- | `beforeRun` / `afterRun` | Start / end of `aidev run` | `afterRun` includes `processed` and `skipped` counts |
286
- | `beforeEachTask` / `afterEachTask` | Around each code task implementation | `prompt`, `branchName`, `task`; `afterEachTask` has `success` |
287
- | `beforeResolveConflicts` / `afterResolveConflicts` | Merge conflict resolution with AI | `conflictFiles`, `prompt`; `afterResolveConflicts` has `resolved` |
288
- | `beforeNonCodeTask` / `afterNonCodeTask` | Non-code tasks | `afterNonCodeTask` includes agent `output` |
289
- | `beforeThinkingTask` / `afterThinkingTask` | Thinking-tag tasks (subtask plan) | `beforeThinkingTask` may adjust `subtasks` before steps run |
290
- | `beforeReviewTask` / `afterReviewTask` | Review tasks with unresolved PR comments | `threads`, `prompt`, `branchName`; `afterReviewTask` has `success`, `resolvedCount` |
291
-
292
- **Second argument: `vm`**
293
-
294
- Each hook receives `(context, vm)`. The `vm` object exposes:
295
-
296
- - `runAI(prompt)` — runs the first available configured AI agent
297
- - `postComment(taskId, text)`, `updateStatus(taskId, status)`, `getComments(taskId)` — same family of operations as the task provider
298
- - `log.info` / `log.warn` / `log.error` — prefixed hook logging
299
-
300
- **TypeScript hooks**
301
-
302
- `.ts` hook files are loaded at runtime via [jiti](https://www.npmjs.com/package/jiti) — no TypeScript compiler or toolchain needed. Just write a plain `.ts` file with the hook functions and aidev handles the rest.
303
-
304
- ---
305
-
306
- ## AI agents
307
-
308
- aidev supports multiple AI agents with automatic fallback. The first available agent in the list is used; if it fails, the next one is tried with the previous agent's output as additional context.
309
-
310
- **Supported agents**
311
-
312
- | Agent | Requires |
313
- |---|---|
314
- | `antigravity` | Google **Antigravity** CLI (`agy` or `antigravity`) in PATH — see [Antigravity](https://antigravity.google/download) |
315
- | `claude` | [Claude CLI](https://github.com/anthropics/claude-code) installed and authenticated |
316
- | `cursor` | Cursor **Agent CLI** (`agent`) in PATH — see [Windows](#windows-cursor-agent-cli) below |
317
- | `windsurf` | [Windsurf](https://windsurf.com) installed with CLI available in PATH |
318
-
319
- ### Windows: Cursor Agent CLI
320
-
321
- On Windows, the Cursor IDE (`cursor.exe`) is separate from the headless Agent CLI. The runner uses the `agent` binary. Install it in PowerShell:
322
-
323
- ```powershell
324
- irm 'https://cursor.com/install?win32=true' | iex
325
- ```
326
-
327
- Then ensure `agent` is on your PATH and run `agent --version` to confirm. Without this, the Cursor runner will report as unavailable.
328
-
329
- **Configure agent order in `.env.aidev`:**
330
-
331
- ```bash
332
- # Claude first, fall back to Cursor
333
- AGENTS=claude,cursor
334
-
335
- # Cursor only
336
- AGENTS=cursor
337
-
338
- # Cursor first (useful when working locally with a monitor)
339
- AGENTS=cursor,claude
340
-
341
- # Claude first, then Windsurf, then Cursor
342
- AGENTS=claude,windsurf,cursor
343
-
344
- # Antigravity first, then Claude
345
- AGENTS=antigravity,claude
346
-
347
- # Windsurf only
348
- AGENTS=windsurf
349
- ```
350
-
351
- ---
352
-
353
- ## Trigger word & re-processing
354
-
355
- aidev prefixes every comment it posts with `[aidev]` (configurable via `AIDEV_COMMENT_PREFIX`). This lets it distinguish its own comments from human replies when deciding whether to re-process a task.
356
-
357
- A task is normally skipped when:
358
- - A remote branch already exists for it, **or**
359
- - It is `pending` and no human has replied yet
360
-
361
- To force aidev to pick the task up again, post a comment containing the **trigger word** (default: `aidev-continue`). aidev will reuse the existing branch and continue implementation from where it left off.
362
-
363
- ```bash
364
- # Customise the trigger word in .env.aidev
365
- AIDEV_TRIGGER_WORD=please-retry
366
- ```
367
-
368
- The trigger word match is case-insensitive, so `aidev-continue`, `AIDEV-CONTINUE`, and `Aidev-Continue` all work.
369
-
370
- For pending tasks, a regular human reply (any comment without the configured prefix) also triggers re-processing — the trigger word is an additional explicit mechanism.
371
-
372
- ```bash
373
- # Customise the comment prefix in .env.aidev
374
- AIDEV_COMMENT_PREFIX=[mybot]
375
- ```
376
-
377
- ---
378
-
379
- ## Auto-compress
380
-
381
- For long-running tasks with many comments, the combined prompt (description + conversation history + review threads) can grow past the AI agent's effective context window. When the assembled context exceeds `AIDEV_COMPRESS_THRESHOLD` characters (default `12000`), aidev summarises the older comments via the configured AI agent and keeps only the **latest comment verbatim** — so the agent always sees the user's most recent intent without ambiguity.
382
-
383
- Compressed summaries are cached under `.aidev/sessions/<taskId>.json` and reused across runs; new comments invalidate the cache and trigger a re-summarisation of the delta. The directory is added to `.gitignore` automatically.
384
-
385
- This is **on by default**. To opt out:
386
-
387
- ```bash
388
- # In .env.aidev
389
- AIDEV_AUTO_COMPRESS=false
390
-
391
- # Or raise the threshold instead of disabling
392
- AIDEV_COMPRESS_THRESHOLD=24000
393
- ```
394
-
395
- ---
396
-
397
- ## Non-code tasks
398
-
399
- Tasks tagged with `NON_CODE_TAG` are executed **without git branching** — no checkout, commit, push, or PR creation. The AI agent runs the task directly in the current working directory.
400
-
401
- This is useful for:
402
- - Research or investigation tasks
403
- - Documentation updates that don't go through PR review
404
- - Running scripts or commands
405
- - Any task where you want the AI to act without creating a branch
406
-
407
- ```bash
408
- # In .env.aidev
409
- NON_CODE_TAG=non-code
410
-
411
- # Optionally use a different ClickUp team for non-code tasks
412
- NON_CODE_CLICKUP_TEAM_ID=987654
413
-
414
- # Or a different Jira project
415
- NON_CODE_JIRA_PROJECT=OPS
416
- ```
417
-
418
- Non-code tasks follow the same lifecycle as regular tasks (clarification → implementation → review), except the implementation step skips all git operations. After completion, the task status is moved to your configured "in review" status.
419
-
420
- If `NON_CODE_TAG` is not configured, non-code task processing is disabled entirely.
421
-
422
- ---
423
-
424
- ## Code review resolution
425
-
426
- When `aidev run` executes, it also checks tasks in **review** status for unresolved PR code review comments. If any actionable threads are found, an AI agent is run to address them — either by fixing the code or replying to discussion comments.
427
-
428
- **How it works:**
429
-
430
- 1. Fetches all tasks in your configured "in review" status
431
- 2. For each task, finds the associated PR by branch name (via `gh` CLI)
432
- 3. Fetches unresolved review threads from the PR
433
- 4. Filters out threads where the last comment is from aidev itself (to avoid re-processing)
434
- 5. Runs an AI agent to address the remaining threads — code fixes are committed and pushed, discussion replies are posted directly on the thread
435
- 6. Resolved threads are marked as resolved on GitHub
436
-
437
- This runs automatically as part of every `aidev run` (after processing open/pending tasks). No additional configuration is needed beyond having `gh` CLI installed and authenticated.
438
-
439
- > **Prerequisites:** The [GitHub CLI](https://cli.github.com/) must be installed and authenticated (`gh auth login`). If `gh` is not available, review task processing is silently skipped.
440
-
441
- ---
442
-
443
- ## Auto-merge accepted PRs
444
-
445
- When a task has been reviewed and is ready to merge, tag it with your configured `ACCEPTED_TAG`. On the next run, aidev will automatically merge the PR via the GitHub CLI (`gh`), update the task status, and sync your local main branch.
446
-
447
- This feature is **optional** — it only activates when both `ACCEPTED_TAG` is configured and the `gh` CLI is installed and authenticated.
448
-
449
- ```bash
450
- # In .env.aidev
451
- ACCEPTED_TAG=accepted
452
- DONE_STATUS=done
453
- ```
454
-
455
- **How it works:**
456
-
457
- 1. Finds all tasks in your "in review" status that have the accepted tag
458
- 2. For each task: merges the PR with squash and deletes the remote branch (`gh pr merge --squash --delete-branch`)
459
- 3. Updates the task status to `DONE_STATUS` (if configured)
460
- 4. Checks out the base branch and pulls the latest changes
461
-
462
- **Run it manually:**
463
-
464
- ```bash
465
- aidev run accepted
466
- ```
467
-
468
- **Automatic mode:** When `ACCEPTED_TAG` is set and `gh` is available, accepted PRs are also auto-merged at the end of every `aidev run`.
469
-
470
- > **Prerequisites:** The [GitHub CLI](https://cli.github.com/) must be installed and authenticated (`gh auth login`). `aidev init` will prompt you for these settings if it detects `gh` on your PATH.
471
-
472
- ---
473
-
474
- ## Dev notes mode
475
-
476
- Controls when aidev asks the task provider for clarification before implementing.
477
-
478
- | Mode | Behaviour |
479
- |---|---|
480
- | `smart` | Asks the AI whether the task description is clear enough. Only posts a clarification question if it's ambiguous. |
481
- | `always` | Always posts "any dev notes?" before implementing every task. |
482
-
483
- When a question is posted, the task is moved to the configured pending status (e.g. `CLICKUP_PENDING_STATUS`, `JIRA_PENDING_STATUS`, etc.). On the next run, aidev checks whether a human has replied and, if so, includes the reply as context for the AI.
484
-
485
- ---
486
-
487
- ## Local tasks file (`aidev.tasks.json`)
488
-
489
- `aidev.tasks.json` is an **outbound queue** — a JSON file that sits at the root of your project and holds task templates that aidev will publish to your configured provider (ClickUp, Jira, Linear, etc.). It is the opposite direction from the [Local provider](#local-provider): the local provider **stores** tasks on disk, while `aidev.tasks.json` **pushes** tasks to a remote provider.
490
-
491
- Typical uses:
492
-
493
- - **Recurring tasks** — with a `cron` expression, an entry publishes a fresh task on every matching tick (daily standup reminders, weekly reviews, monthly housekeeping).
494
- - **Staged work** — queue a batch of tasks in a commit so they appear in the provider together when `aidev` next runs.
495
- - **AI-authored tasks** — another AI agent or script can append entries to the file; `aidev` will pick them up and create real tickets.
496
-
497
- The file is added to `.gitignore` by `aidev init` — each developer or automation environment maintains their own queue.
498
-
499
- ### File format
500
-
501
- `aidev.tasks.json` is a JSON array of task entries. Each entry has the shape:
502
-
503
- ```ts
504
- interface LocalTask {
505
- id: string; // UUID — generated automatically by "aidev tasks add"
506
- title: string; // required — task title on the remote provider
507
- description: string; // task body / description
508
- type: 'code' | 'non-code'; // routes to the non-code provider when set to 'non-code'
509
- priority?: number; // 1=urgent, 2=high, 3=normal, 4=low
510
- assignee?: string; // currently informational (reserved for future use)
511
- dueDate?: string; // ISO date, e.g. "2026-05-01"
512
- tags?: string[]; // extra tags appended to the provider-configured tag
513
- listId?: string; // override provider list / project ID for this task only
514
- cron?: string; // 5-field cron — if set, the task is re-published on every tick
515
- lastPushedAt?: number; // epoch ms of the last successful push (managed by aidev for cron entries)
516
- }
517
- ```
518
-
519
- **Example** (`aidev.tasks.json`):
520
-
521
- ```json
522
- [
523
- {
524
- "id": "7f3a9c2d-5b1e-4a6f-9d8c-1e2f3a4b5c6d",
525
- "title": "Daily standup notes",
526
- "description": "Post yesterday / today / blockers to the team channel.",
527
- "type": "non-code",
528
- "priority": 3,
529
- "tags": ["standup"],
530
- "cron": "0 9 * * 1-5"
531
- },
532
- {
533
- "id": "2b8e1f7a-4c9d-4e5a-8b6c-9f1e2d3c4b5a",
534
- "title": "Upgrade dependencies",
535
- "description": "Run `npm outdated`, bump minor/patch versions, verify tests pass.",
536
- "type": "code",
537
- "priority": 2,
538
- "tags": ["maintenance"]
539
- }
540
- ]
541
- ```
542
-
543
- ### Lifecycle
544
-
545
- 1. **Every `aidev run`** (regardless of filter) begins by reading `aidev.tasks.json` and attempting to publish each entry via the configured provider's `createTask` API.
546
- 2. **One-shot entries** (no `cron` field) are **removed from the file** after a successful push — they become a real ticket and won't be duplicated on the next run.
547
- 3. **Cron entries** remain in the file. `lastPushedAt` is updated on each successful push; on the next run, aidev checks whether the cron has fired at least once since `lastPushedAt` before republishing. A fresh entry with a cron fires on the first run that matches.
548
- 4. **Failures** are logged and the entry is kept — the next run retries.
549
-
550
- ### Routing
551
-
552
- - `type: 'code'` → published with the code tag (`CLICKUP_TAG` / `JIRA_LABEL` / `LINEAR_LABEL`, etc.) to the primary provider.
553
- - `type: 'non-code'` → published with `NON_CODE_TAG` to the non-code provider (a separate team / project if `NON_CODE_CLICKUP_TEAM_ID`, `NON_CODE_JIRA_PROJECT`, or `NON_CODE_LINEAR_TEAM_ID` is configured, otherwise the primary).
554
- - Per-task `tags` are appended to the resolved default tag.
555
- - Per-task `listId` overrides the provider-default list / project for that single task.
556
-
557
- ### Managing entries
558
-
559
- Use the built-in commands rather than hand-editing JSON (although hand-editing is fine — the file is plain JSON):
560
-
561
- ```bash
562
- aidev tasks add # interactive prompt: title, description, type, priority, due date, tags, list, cron
563
- aidev tasks ls # table of queued entries
564
- aidev tasks update [id] # edit an entry by table ID (interactive picker if no id)
565
- aidev tasks remove [id] # delete an entry by table ID (interactive picker if no id)
566
- aidev tasks push # publish everything now (same as "aidev run tasks") — useful for dry-running or in scripts
567
- ```
568
-
569
- `aidev tasks push` and `aidev run tasks` do the same thing: they only process `aidev.tasks.json` and exit without pulling tasks from the provider or invoking the AI. This is useful when you want to decouple queue publishing from the main AI loop — for example, running `aidev tasks push` from a separate cron entry or CI job.
570
-
571
- ---
572
-
573
- ## Scheduling
574
-
575
- aidev can run on a cron schedule, one entry per project directory.
576
-
577
- ```bash
578
- # Interactive picker
579
- aidev schedule set
580
-
581
- # Or pass an expression directly
582
- aidev schedule set "*/15 * * * *"
583
-
584
- # Check what's scheduled for the current directory
585
- aidev schedule get
586
- ```
587
-
588
- **Preset options (interactive picker)**
589
-
590
- | Option | Expression |
591
- |---|---|
592
- | Every 15 minutes | `*/15 * * * *` |
593
- | Every 30 minutes | `*/30 * * * *` |
594
- | Every hour | `0 * * * *` |
595
- | Every 5 hours | `0 */5 * * *` |
596
- | Every day at 8am | `0 8 * * *` |
597
-
598
- Each directory gets its own cron entry identified by a `# aidev-cwd:/path` marker — running `schedule set` again replaces the existing entry rather than adding a duplicate.
599
-
600
- ### macOS: Full Disk Access required
601
-
602
- On macOS (Ventura and later), cron jobs are silently blocked unless `/usr/sbin/cron` has Full Disk Access:
603
-
604
- 1. Open **System Settings → Privacy & Security → Full Disk Access**
605
- 2. Click **+** and add `/usr/sbin/cron`
606
- 3. Re-run `aidev schedule set` to apply your schedule
607
-
608
- Without this, cron will appear to be configured but jobs will never fire.
609
-
610
- ---
611
-
612
- ## Logging
613
-
614
- Every run appends to `aidev.log` in your project directory:
615
-
616
- ```
617
- ────────────────────────────────────────────────────────────
618
- 2026-03-06T08:00:00.000Z [run] started
619
- ────────────────────────────────────────────────────────────
620
- 2026-03-06T08:00:00.120Z [info] Fetching tasks (filter: all)...
621
- 2026-03-06T08:00:01.340Z [task] [abc123] "Fix login flow" (status: open)
622
- 2026-03-06T08:00:12.780Z [info] Running claude...
623
- 2026-03-06T08:00:45.210Z [success] Task implemented: branch abc123/fix-login-flow pushed
624
- 2026-03-06T08:00:45.890Z [success] Done. Processed: 1, Skipped: 3
625
- ```
626
-
627
- ANSI colour codes are stripped so the file stays readable in any editor or `tail -f`. `aidev.log` is added to `.gitignore` automatically by `aidev init`.
628
-
629
- ---
630
-
631
- ## Providers
632
-
633
- | Provider | Status | `aidev init` support |
634
- |---|---|---|
635
- | ClickUp | ✅ Implemented | ✅ Interactive wizard |
636
- | Jira | ✅ Implemented | ✅ Interactive wizard |
637
- | Linear | ✅ Implemented | ✅ Interactive wizard |
638
- | Monday.com | ✅ Implemented | ✅ Interactive wizard |
639
- | Local | ✅ Implemented | ✅ Interactive wizard |
640
- | Notion | ✅ Implemented | Manual `.env.aidev` config |
641
- | Trello | ✅ Implemented | Manual `.env.aidev` config |
642
-
643
- > **Notion & Trello:** These providers are fully functional but not yet included in the `aidev init` wizard. To use them, set `PROVIDER=notion` or `PROVIDER=trello` in `.env.aidev` and fill in the required variables from the [Configuration](#configuration) section above.
644
-
645
- The `TaskProvider` interface makes it straightforward to add new providers. See [CONTRIBUTING.md](./CONTRIBUTING.md).
646
-
647
- ### Local provider
648
-
649
- Set `PROVIDER=local` in `.env.aidev` to manage tasks entirely via local markdown files — no external API needed.
650
-
651
- ```bash
652
- aidev init # choose "local" when prompted for provider
653
- ```
654
-
655
- Tasks live in `.aidev/tasks/` under status folders:
656
-
657
- ```
658
- .aidev/tasks/
659
- open/ # new tasks ready for implementation
660
- pending/ # waiting for human reply
661
- progress/ # currently being implemented
662
- review/ # implementation complete, awaiting review
663
- done/ # finished
664
- ```
665
-
666
- **Task file format** (e.g. `.aidev/tasks/open/a1b2c3d4-fix-login-bug.md`):
667
-
668
- ```markdown
669
- ---
670
- title: Fix login page bug
671
- priority: 2
672
- assignee: david
673
- estimated: 2h
674
- tags: frontend, auth
675
- created: 2026-03-12T10:00:00.000Z
676
- ---
677
-
678
- The login form should redirect users to the dashboard after successful authentication.
679
- ```
680
-
681
- The filename must start with a short ID (hex characters) followed by a dash and a slug. The YAML frontmatter carries task metadata; everything after `---` is the task description.
682
-
683
- #### Code vs non-code tasks
684
-
685
- By default, local tasks are treated as **code tasks** — aidev creates a git branch, runs the AI agent, commits, pushes, and opens a PR.
686
-
687
- To mark a task as **non-code** (research, docs, investigation — no git branching), add `type: non-code` to the frontmatter:
688
-
689
- ```markdown
690
- ---
691
- title: Compare OAuth2 providers
692
- type: non-code
693
- tags: research
694
- ---
695
-
696
- Evaluate Auth0, Clerk, and Supabase Auth. Write a recommendation.
697
- ```
698
-
699
- Non-code tasks follow the same lifecycle but skip all git operations. The AI response is posted as a session comment instead of a PR.
700
-
701
- **Session file** (comments) — `.aidev/tasks/open/a1b2c3d4-fix-login-bug.session.md`:
702
-
703
- ```markdown
704
- <!-- aidev session log — append your comments below using "## your-name" as header -->
705
-
706
- ---
707
-
708
- ## aidev — 2026-03-12T10:05:00.000Z
709
-
710
- [aidev] Starting implementation on branch `a1b2c3d4/fix-login-bug`
711
-
712
- ---
713
-
714
- ## david — 2026-03-12T10:10:00.000Z
715
-
716
- Please use the new auth API endpoint for this.
717
- ```
718
-
719
- To add a comment, append a `---` separator followed by a `## your-name` header and your message. aidev parses these entries automatically and uses them as conversation context, just like ClickUp/Jira comments.
720
-
721
- Downloaded task attachments are stored in `.aidev/assets/<task-id>/`, and `aidev init` adds `.aidev/assets/` to `.gitignore` automatically.
722
-
723
- ---
724
-
725
- ## Contributing
726
-
727
- Contributions are welcome — new providers, new AI runners, bug fixes, and docs improvements.
728
-
729
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full guide.
730
-
731
- ---
732
-
733
- ## License
734
-
735
- [MIT](./LICENSE)
1
+ # @qelos/aidev
2
+
3
+ [![npm version](https://img.shields.io/npm/v/%40qelos%2Faidev.svg?style=flat-square)](https://www.npmjs.com/package/@qelos/aidev)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](./LICENSE)
5
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg?style=flat-square)](https://nodejs.org)
6
+
7
+ **aidev** turns your tasks into merged code — automatically.
8
+
9
+ It polls your task manager (ClickUp, Jira, Linear, Monday.com, Notion, Trello, or local markdown files), checks whether tasks are clear, runs Claude, Cursor, or Windsurf to implement them, pushes a branch, and moves the task to review. All without touching your keyboard.
10
+
11
+ ```
12
+ Task → AI implements → git push → "in review" → AI resolves code review comments
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Table of Contents
18
+
19
+ - [How it works](#how-it-works)
20
+ - [Quick start](#quick-start)
21
+ - [Commands](#commands)
22
+ - [Concurrency lock](#concurrency-lock)
23
+ - [Configuration](#configuration)
24
+ - [AI agents](#ai-agents)
25
+ - [Code review resolution](#code-review-resolution)
26
+ - [Auto-merge accepted PRs](#auto-merge-accepted-prs)
27
+ - [Dev notes mode](#dev-notes-mode)
28
+ - [Local tasks file (`aidev.tasks.json`)](#local-tasks-file-aidevtasksjson)
29
+ - [Scheduling](#scheduling)
30
+ - [Hooks](#hooks)
31
+ - [Logging](#logging)
32
+ - [Providers](#providers)
33
+ - [Contributing](#contributing)
34
+
35
+ ---
36
+
37
+ ## How it works
38
+
39
+ 1. **Fetch** — pulls all tasks tagged with your configured tag from your task provider
40
+ 2. **Filter** — skips done/cancelled tasks and tasks that already have a branch
41
+ 3. **Clarify** — in `smart` mode, asks the AI if the task description is clear enough; if not, posts a question as a comment (prefixed with `[aidev]`) and marks the task `pending`
42
+ 4. **Wait** — pending tasks are re-checked on the next run; if a human replied or the trigger word is found, implementation proceeds with the conversation as context
43
+ 5. **Implement** — checks out a fresh branch (or reuses an existing one), runs your configured AI agent(s), falls back to the next agent if one fails
44
+ 6. **Ship** — commits all changes, pushes the branch, posts a comment with the branch name and a PR link, moves the task to your "in review" status
45
+ 7. **Review** — checks tasks already in review for unresolved PR code review comments; if found, runs an AI agent to fix code or reply to discussion threads
46
+
47
+ ---
48
+
49
+ ## Quick start
50
+
51
+ ```bash
52
+ npm install -g @qelos/aidev
53
+ ```
54
+
55
+ Navigate to your project and run the interactive setup:
56
+
57
+ ```bash
58
+ cd my-project
59
+ aidev init
60
+ ```
61
+
62
+ The wizard will ask for your task provider credentials, git settings, and preferred AI agents.
63
+
64
+ > **Note:** `aidev init` currently supports **ClickUp, Jira, Linear, Local, and Monday.com**. For **Notion** and **Trello**, create `.env.aidev` manually using `.env.aidev.example` as a template (see [Configuration](#configuration)).
65
+ >
66
+ > For ClickUp, API keys can be left blank if they are already set as environment variables in your shell. For Jira, Linear, and Monday.com, the wizard requires credentials to be entered directly — to use shell env vars instead, edit `.env.aidev` after init and remove the values you want read from your environment.
67
+
68
+ Once configured:
69
+
70
+ ```bash
71
+ aidev run
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Commands
77
+
78
+ | Command | Description |
79
+ |---|---|
80
+ | `aidev init` | Interactive setup — creates `.env.aidev` |
81
+ | `aidev run` | Process open + pending tasks, then check review tasks for unresolved PR comments |
82
+ | `aidev run open` | Only open (non-pending) tasks |
83
+ | `aidev run pending` | Only pending tasks — check for human replies |
84
+ | `aidev run accepted` | Auto-merge PRs for tasks in review with the accepted tag |
85
+ | `aidev run tasks` | Publish all entries in `aidev.tasks.json` and exit (no AI run) |
86
+ | `aidev tasks add` | Add a new entry to `aidev.tasks.json` (interactive) |
87
+ | `aidev tasks ls` | List entries currently queued in `aidev.tasks.json` |
88
+ | `aidev tasks update [id]` | Edit a queued entry (interactive if `id` omitted) |
89
+ | `aidev tasks remove [id]` | Delete a queued entry (interactive if `id` omitted) |
90
+ | `aidev tasks push` | Same as `aidev run tasks` — publish all queued entries and exit |
91
+ | `aidev stop` | Stop any running aidev process in the current directory |
92
+ | `aidev schedule set` | Interactive cron picker for this directory |
93
+ | `aidev schedule set "<expr>"` | Set a specific cron expression |
94
+ | `aidev schedule get` | Show the current schedule for this directory |
95
+ | `aidev help` | Show command and config reference |
96
+
97
+ ### Global flags
98
+
99
+ | Flag | Description |
100
+ |---|---|
101
+ | `-e, --env <path>` | Load config from a custom env file instead of `.env.aidev` |
102
+ | `-V, --version` | Print version |
103
+
104
+ **Examples**
105
+
106
+ ```bash
107
+ # Use a shared env file for a staging environment
108
+ aidev --env /shared/.env.staging run
109
+
110
+ # Only process tasks that are waiting for a reply
111
+ aidev run pending
112
+
113
+ # Schedule to run every 30 minutes
114
+ aidev schedule set "*/30 * * * *"
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Concurrency lock
120
+
121
+ `aidev run` writes a PID lock file (`.aidev.lock`) in the current directory when it starts and removes it when it finishes. If a second invocation detects a live process already holding the lock, it logs a warning and exits immediately — preventing two agents from committing to the same branch at the same time.
122
+
123
+ ```
124
+ $ aidev run
125
+ [aidev] aidev is already running in this directory (PID 12345). Use "aidev stop" to terminate it.
126
+ ```
127
+
128
+ Use `aidev stop` to send `SIGTERM` to the running process and clean up the lock file:
129
+
130
+ ```bash
131
+ aidev stop
132
+ ```
133
+
134
+ Stale lock files (left behind by a crash) are detected automatically — the next `aidev run` will overwrite them if the stored PID is no longer alive.
135
+
136
+ ---
137
+
138
+ ## Configuration
139
+
140
+ Run `aidev init` for an interactive setup, or create `.env.aidev` manually using `.env.aidev.example` as a template.
141
+
142
+ ### Global env file (`AIDEV_ENV_EXTEND`)
143
+
144
+ If you work across multiple projects, you can keep shared settings (API keys, agent list, etc.) in a single global file and reference it from each project's `.env.aidev`:
145
+
146
+ ```bash
147
+ # ~/.aidev.global
148
+ CLICKUP_API_KEY=pk_...
149
+ CLICKUP_TEAM_ID=123456
150
+ AGENTS=claude,cursor
151
+ ```
152
+
153
+ ```bash
154
+ # my-project/.env.aidev — project-specific values override the global ones
155
+ AIDEV_ENV_EXTEND=~/.aidev.global
156
+ CLICKUP_TAG=my-project
157
+ ```
158
+
159
+ **Priority order (highest → lowest):**
160
+
161
+ 1. Shell environment variables (e.g. set in `~/.zshrc`) — never overwritten
162
+ 2. Local `.env.aidev` values
163
+ 3. `AIDEV_ENV_EXTEND` file values (global base)
164
+
165
+ `AIDEV_ENV_EXTEND` can be set in two ways:
166
+
167
+ - **Per-project** — add `AIDEV_ENV_EXTEND=/path/to/file` inside `.env.aidev`
168
+ - **Shell-wide** — `export AIDEV_ENV_EXTEND=~/.aidev.global` in `~/.zshrc` (applies to every project automatically)
169
+
170
+ `aidev init` will ask for this path and pre-fill it if the variable is already in your shell environment.
171
+
172
+ ### ClickUp
173
+
174
+ | Variable | Default | Description |
175
+ |---|---|---|
176
+ | `CLICKUP_API_KEY` | — | Personal API token — can be set as a shell env var |
177
+ | `CLICKUP_TEAM_ID` | — | Workspace / team ID — can be set as a shell env var |
178
+ | `CLICKUP_TAG` | — | Tasks with this tag will be picked up (set to `*` to match all tasks) |
179
+ | `CLICKUP_PENDING_STATUS` | `pending` | Status name for "waiting for reply" |
180
+ | `CLICKUP_IN_REVIEW_STATUS` | `review` | Status set after implementation |
181
+ | `ASSIGNEE_TAG` | — | Only process tasks assigned to this user (optional) |
182
+ | `THINKING_TAG` | — | Tasks with this tag are analyzed and broken into sub-tasks before execution (optional) |
183
+ | `NON_CODE_TAG` | — | Tasks with this tag run without git branching (optional) |
184
+ | `NON_CODE_CLICKUP_TEAM_ID` | same as `CLICKUP_TEAM_ID` | Different workspace for non-code tasks (optional) |
185
+
186
+ > **Tip:** For ClickUp, API keys and tokens are intentionally omitted from `.env.aidev` if you leave them blank during `aidev init` — they will be read from your shell environment instead. For Jira, Linear, and Monday.com, the wizard requires these values; to use shell env vars, remove the entries from `.env.aidev` after init.
187
+
188
+ > **Wildcard tag (`*`):** Set `CLICKUP_TAG=*` (or `JIRA_LABEL=*` / `LINEAR_LABEL=*` / `TRELLO_LABEL=*`) to match **all** tasks regardless of tags/labels. This is useful when the AI dev has its own dedicated user in the task provider and every task assigned to it should be processed.
189
+
190
+ ### Jira
191
+
192
+ | Variable | Default | Description |
193
+ |---|---|---|
194
+ | `JIRA_BASE_URL` | — | Jira instance URL (e.g. `https://mycompany.atlassian.net`) |
195
+ | `JIRA_EMAIL` | — | Email for Jira authentication |
196
+ | `JIRA_API_TOKEN` | — | API token — generate from [Atlassian account settings](https://id.atlassian.com/manage-profile/security/api-tokens) |
197
+ | `JIRA_PROJECT` | — | Project key (e.g. `PROJ`) |
198
+ | `JIRA_LABEL` | — | Issues with this label will be picked up (set to `*` to match all issues) |
199
+ | `JIRA_PENDING_STATUS` | `To Do` | Status name for "waiting for reply" |
200
+ | `JIRA_IN_REVIEW_STATUS` | `In Review` | Status set after implementation |
201
+ | `NON_CODE_JIRA_PROJECT` | same as `JIRA_PROJECT` | Different project for non-code tasks (optional) |
202
+
203
+ ### Linear
204
+
205
+ | Variable | Default | Description |
206
+ |---|---|---|
207
+ | `LINEAR_API_KEY` | — | Personal API key from Linear Settings → API |
208
+ | `LINEAR_TEAM_ID` | — | Team UUID from your workspace |
209
+ | `LINEAR_LABEL` | — | Issues with this label will be picked up (set to `*` to match all issues) |
210
+ | `LINEAR_PENDING_STATUS` | `Backlog` | Status name for "waiting for reply" |
211
+ | `LINEAR_IN_REVIEW_STATUS` | `In Review` | Status set after implementation |
212
+ | `NON_CODE_LINEAR_TEAM_ID` | same as `LINEAR_TEAM_ID` | Different team for non-code tasks (optional) |
213
+
214
+ ### Monday.com
215
+
216
+ | Variable | Default | Description |
217
+ |---|---|---|
218
+ | `MONDAY_API_TOKEN` | — | API token from monday.com Developer settings |
219
+ | `MONDAY_BOARD_ID` | — | Board ID (from the board URL) |
220
+ | `MONDAY_STATUS_COLUMN_ID` | `status` | Column ID for the status field |
221
+ | `MONDAY_GROUP_ID` | — | Group ID to filter items (optional) |
222
+
223
+ ### Notion
224
+
225
+ | Variable | Default | Description |
226
+ |---|---|---|
227
+ | `NOTION_API_KEY` | — | Integration token from Notion → Settings → My integrations |
228
+ | `NOTION_DATABASE_ID` | — | Database ID from the database URL (32-char hex) |
229
+ | `NOTION_STATUS_PROPERTY` | `Status` | Name of the status property in the database |
230
+ | `NOTION_PENDING_STATUS` | `pending` | Status value for "waiting for reply" |
231
+ | `NOTION_IN_REVIEW_STATUS` | `review` | Status value set after implementation |
232
+
233
+ ### Trello
234
+
235
+ | Variable | Default | Description |
236
+ |---|---|---|
237
+ | `TRELLO_API_KEY` | — | Developer API key from [trello.com/power-ups/admin](https://trello.com/power-ups/admin) |
238
+ | `TRELLO_TOKEN` | — | Auth token generated via Trello's token flow |
239
+ | `TRELLO_BOARD_ID` | — | Board ID from the board URL |
240
+ | `TRELLO_LABEL` | — | Label name on cards to pick up (set to `*` to match all cards assigned to the token user) |
241
+ | `TRELLO_OPEN_LIST` | `To Do` | List name for open/new cards |
242
+ | `TRELLO_PENDING_LIST` | `Blocked` | List name for "waiting for reply" |
243
+ | `TRELLO_IN_PROGRESS_LIST` | `Doing` | List name for cards being worked on |
244
+ | `TRELLO_IN_REVIEW_LIST` | `In Review` | List name for completed cards awaiting review |
245
+ | `TRELLO_OPEN_STATUS` | `open` | Semantic status mapped to the open list |
246
+ | `TRELLO_PENDING_STATUS` | `pending` | Semantic status mapped to the pending list |
247
+ | `TRELLO_IN_REVIEW_STATUS` | `review` | Semantic status mapped to the review list |
248
+
249
+ ### Git & GitHub
250
+
251
+ | Variable | Default | Description |
252
+ |---|---|---|
253
+ | `GIT_REMOTE` | auto-detected | Remote name — detected via `git remote get-url origin` if unset |
254
+ | `GITHUB_BASE_BRANCH` | `main` | Base branch; new task branches are cut from here |
255
+ | `GITHUB_REPO` | — | `owner/repo` — used to generate PR links in comments |
256
+
257
+ ### Behaviour
258
+
259
+ | Variable | Default | Description |
260
+ |---|---|---|
261
+ | `AIDEV_ENV_EXTEND` | — | Path to a global env file loaded as the base for this project (see above) |
262
+ | `AGENTS` | `claude,cursor` | Comma-separated list of agents in priority order |
263
+ | `DEV_NOTES_MODE` | `smart` | When to ask for clarification (`smart` or `always`) |
264
+ | `AIDEV_TRIGGER_WORD` | `aidev-continue` | Comment containing this word re-triggers a skipped task |
265
+ | `AIDEV_COMMENT_PREFIX` | `[aidev]` | Custom prefix for all aidev comments posted to task providers |
266
+ | `AIDEV_HOOKS_PATH` | — | Path to a `.ts` or `.js` module that exports hook functions (see [Hooks](#hooks)) |
267
+ | `ACCEPTED_TAG` | — | Tasks in review with this tag are auto-merged (see [Auto-merge accepted PRs](#auto-merge-accepted-prs)) |
268
+ | `DONE_STATUS` | — | Status to set after auto-merging an accepted PR (e.g. `done`) |
269
+ | `PR_SIGNATURE` | `Automated PR by aidev.` | Custom signature line appended to the PR body |
270
+ | `AIDEV_AUTO_COMPRESS` | `true` | Auto-compress older comments when the prompt grows large. Set to `false` / `0` / `no` to opt out |
271
+ | `AIDEV_COMPRESS_THRESHOLD` | `12000` | Char-length threshold that triggers compression |
272
+
273
+ ---
274
+
275
+ ## Hooks
276
+
277
+ Set `AIDEV_HOOKS_PATH` in `.env.aidev` to a path relative to the project directory or an absolute path. `aidev init` writes `.aidev/aidev.hooks.ts` and sets `AIDEV_HOOKS_PATH=.aidev/aidev.hooks.ts` by default.
278
+
279
+ The module should export an object (or `export default`) whose properties are optional async functions. Only known hook names are used; anything else is ignored. If a hook throws, the current operation stops (for example the whole run after `beforeRun`, or conflict resolution after `beforeResolveConflicts`). If a hook returns an object, it replaces the context for that step (for example append to `context.prompt` in `beforeEachTask` and return the updated context).
280
+
281
+ **Hook names**
282
+
283
+ | Hook | When | Context notes |
284
+ |---|---|---|
285
+ | `beforeRun` / `afterRun` | Start / end of `aidev run` | `afterRun` includes `processed` and `skipped` counts |
286
+ | `beforeEachTask` / `afterEachTask` | Around each code task implementation | `prompt`, `branchName`, `task`; `afterEachTask` has `success` |
287
+ | `beforeResolveConflicts` / `afterResolveConflicts` | Merge conflict resolution with AI | `conflictFiles`, `prompt`; `afterResolveConflicts` has `resolved` |
288
+ | `beforeNonCodeTask` / `afterNonCodeTask` | Non-code tasks | `afterNonCodeTask` includes agent `output` |
289
+ | `beforeThinkingTask` / `afterThinkingTask` | Thinking-tag tasks (subtask plan) | `beforeThinkingTask` may adjust `subtasks` before steps run |
290
+ | `beforeReviewTask` / `afterReviewTask` | Review tasks with unresolved PR comments | `threads`, `prompt`, `branchName`; `afterReviewTask` has `success`, `resolvedCount` |
291
+
292
+ **Second argument: `vm`**
293
+
294
+ Each hook receives `(context, vm)`. The `vm` object exposes:
295
+
296
+ - `runAI(prompt)` — runs the first available configured AI agent
297
+ - `postComment(taskId, text)`, `updateStatus(taskId, status)`, `getComments(taskId)` — same family of operations as the task provider
298
+ - `log.info` / `log.warn` / `log.error` — prefixed hook logging
299
+
300
+ **TypeScript hooks**
301
+
302
+ `.ts` hook files are loaded at runtime via [jiti](https://www.npmjs.com/package/jiti) — no TypeScript compiler or toolchain needed. Just write a plain `.ts` file with the hook functions and aidev handles the rest.
303
+
304
+ ---
305
+
306
+ ## AI agents
307
+
308
+ aidev supports multiple AI agents with automatic fallback. The first available agent in the list is used; if it fails, the next one is tried with the previous agent's output as additional context.
309
+
310
+ **Supported agents**
311
+
312
+ | Agent | Requires |
313
+ |---|---|
314
+ | `antigravity` | Google **Antigravity** CLI (`agy` or `antigravity`) in PATH — see [Antigravity](https://antigravity.google/download) |
315
+ | `claude` | [Claude CLI](https://github.com/anthropics/claude-code) installed and authenticated |
316
+ | `cursor` | Cursor **Agent CLI** (`agent`) in PATH — see [Windows](#windows-cursor-agent-cli) below |
317
+ | `windsurf` | [Windsurf](https://windsurf.com) installed with CLI available in PATH |
318
+
319
+ ### Windows: Cursor Agent CLI
320
+
321
+ On Windows, the Cursor IDE (`cursor.exe`) is separate from the headless Agent CLI. The runner uses the `agent` binary. Install it in PowerShell:
322
+
323
+ ```powershell
324
+ irm 'https://cursor.com/install?win32=true' | iex
325
+ ```
326
+
327
+ Then ensure `agent` is on your PATH and run `agent --version` to confirm. Without this, the Cursor runner will report as unavailable.
328
+
329
+ **Configure agent order in `.env.aidev`:**
330
+
331
+ ```bash
332
+ # Claude first, fall back to Cursor
333
+ AGENTS=claude,cursor
334
+
335
+ # Cursor only
336
+ AGENTS=cursor
337
+
338
+ # Cursor first (useful when working locally with a monitor)
339
+ AGENTS=cursor,claude
340
+
341
+ # Claude first, then Windsurf, then Cursor
342
+ AGENTS=claude,windsurf,cursor
343
+
344
+ # Antigravity first, then Claude
345
+ AGENTS=antigravity,claude
346
+
347
+ # Windsurf only
348
+ AGENTS=windsurf
349
+ ```
350
+
351
+ ---
352
+
353
+ ## Trigger word & re-processing
354
+
355
+ aidev prefixes every comment it posts with `[aidev]` (configurable via `AIDEV_COMMENT_PREFIX`). This lets it distinguish its own comments from human replies when deciding whether to re-process a task.
356
+
357
+ A task is normally skipped when:
358
+ - A remote branch already exists for it, **or**
359
+ - It is `pending` and no human has replied yet
360
+
361
+ To force aidev to pick the task up again, post a comment containing the **trigger word** (default: `aidev-continue`). aidev will reuse the existing branch and continue implementation from where it left off.
362
+
363
+ ```bash
364
+ # Customise the trigger word in .env.aidev
365
+ AIDEV_TRIGGER_WORD=please-retry
366
+ ```
367
+
368
+ The trigger word match is case-insensitive, so `aidev-continue`, `AIDEV-CONTINUE`, and `Aidev-Continue` all work.
369
+
370
+ For pending tasks, a regular human reply (any comment without the configured prefix) also triggers re-processing — the trigger word is an additional explicit mechanism.
371
+
372
+ ```bash
373
+ # Customise the comment prefix in .env.aidev
374
+ AIDEV_COMMENT_PREFIX=[mybot]
375
+ ```
376
+
377
+ ---
378
+
379
+ ## Auto-compress
380
+
381
+ For long-running tasks with many comments, the combined prompt (description + conversation history + review threads) can grow past the AI agent's effective context window. When the assembled context exceeds `AIDEV_COMPRESS_THRESHOLD` characters (default `12000`), aidev summarises the older comments via the configured AI agent and keeps only the **latest comment verbatim** — so the agent always sees the user's most recent intent without ambiguity.
382
+
383
+ Compressed summaries are cached under `.aidev/sessions/<taskId>.json` and reused across runs; new comments invalidate the cache and trigger a re-summarisation of the delta. The directory is added to `.gitignore` automatically.
384
+
385
+ This is **on by default**. To opt out:
386
+
387
+ ```bash
388
+ # In .env.aidev
389
+ AIDEV_AUTO_COMPRESS=false
390
+
391
+ # Or raise the threshold instead of disabling
392
+ AIDEV_COMPRESS_THRESHOLD=24000
393
+ ```
394
+
395
+ ---
396
+
397
+ ## Non-code tasks
398
+
399
+ Tasks tagged with `NON_CODE_TAG` are executed **without git branching** — no checkout, commit, push, or PR creation. The AI agent runs the task directly in the current working directory.
400
+
401
+ This is useful for:
402
+ - Research or investigation tasks
403
+ - Documentation updates that don't go through PR review
404
+ - Running scripts or commands
405
+ - Any task where you want the AI to act without creating a branch
406
+
407
+ ```bash
408
+ # In .env.aidev
409
+ NON_CODE_TAG=non-code
410
+
411
+ # Optionally use a different ClickUp team for non-code tasks
412
+ NON_CODE_CLICKUP_TEAM_ID=987654
413
+
414
+ # Or a different Jira project
415
+ NON_CODE_JIRA_PROJECT=OPS
416
+ ```
417
+
418
+ Non-code tasks follow the same lifecycle as regular tasks (clarification → implementation → review), except the implementation step skips all git operations. After completion, the task status is moved to your configured "in review" status.
419
+
420
+ If `NON_CODE_TAG` is not configured, non-code task processing is disabled entirely.
421
+
422
+ ---
423
+
424
+ ## Code review resolution
425
+
426
+ When `aidev run` executes, it also checks tasks in **review** status for unresolved PR code review comments. If any actionable threads are found, an AI agent is run to address them — either by fixing the code or replying to discussion comments.
427
+
428
+ **How it works:**
429
+
430
+ 1. Fetches all tasks in your configured "in review" status
431
+ 2. For each task, finds the associated PR by branch name (via `gh` CLI)
432
+ 3. Fetches unresolved review threads from the PR
433
+ 4. Filters out threads where the last comment is from aidev itself (to avoid re-processing)
434
+ 5. Runs an AI agent to address the remaining threads — code fixes are committed and pushed, discussion replies are posted directly on the thread
435
+ 6. Resolved threads are marked as resolved on GitHub
436
+
437
+ This runs automatically as part of every `aidev run` (after processing open/pending tasks). No additional configuration is needed beyond having `gh` CLI installed and authenticated.
438
+
439
+ > **Prerequisites:** The [GitHub CLI](https://cli.github.com/) must be installed and authenticated (`gh auth login`). If `gh` is not available, review task processing is silently skipped.
440
+
441
+ ---
442
+
443
+ ## Auto-merge accepted PRs
444
+
445
+ When a task has been reviewed and is ready to merge, tag it with your configured `ACCEPTED_TAG`. On the next run, aidev will automatically merge the PR via the GitHub CLI (`gh`), update the task status, and sync your local main branch.
446
+
447
+ This feature is **optional** — it only activates when both `ACCEPTED_TAG` is configured and the `gh` CLI is installed and authenticated.
448
+
449
+ ```bash
450
+ # In .env.aidev
451
+ ACCEPTED_TAG=accepted
452
+ DONE_STATUS=done
453
+ ```
454
+
455
+ **How it works:**
456
+
457
+ 1. Finds all tasks in your "in review" status that have the accepted tag
458
+ 2. For each task: merges the PR with squash and deletes the remote branch (`gh pr merge --squash --delete-branch`)
459
+ 3. Updates the task status to `DONE_STATUS` (if configured)
460
+ 4. Checks out the base branch and pulls the latest changes
461
+
462
+ **Run it manually:**
463
+
464
+ ```bash
465
+ aidev run accepted
466
+ ```
467
+
468
+ **Automatic mode:** When `ACCEPTED_TAG` is set and `gh` is available, accepted PRs are also auto-merged at the end of every `aidev run`.
469
+
470
+ > **Prerequisites:** The [GitHub CLI](https://cli.github.com/) must be installed and authenticated (`gh auth login`). `aidev init` will prompt you for these settings if it detects `gh` on your PATH.
471
+
472
+ ---
473
+
474
+ ## Dev notes mode
475
+
476
+ Controls when aidev asks the task provider for clarification before implementing.
477
+
478
+ | Mode | Behaviour |
479
+ |---|---|
480
+ | `smart` | Asks the AI whether the task description is clear enough. Only posts a clarification question if it's ambiguous. |
481
+ | `always` | Always posts "any dev notes?" before implementing every task. |
482
+
483
+ When a question is posted, the task is moved to the configured pending status (e.g. `CLICKUP_PENDING_STATUS`, `JIRA_PENDING_STATUS`, etc.). On the next run, aidev checks whether a human has replied and, if so, includes the reply as context for the AI.
484
+
485
+ ---
486
+
487
+ ## Local tasks file (`aidev.tasks.json`)
488
+
489
+ `aidev.tasks.json` is an **outbound queue** — a JSON file that sits at the root of your project and holds task templates that aidev will publish to your configured provider (ClickUp, Jira, Linear, etc.). It is the opposite direction from the [Local provider](#local-provider): the local provider **stores** tasks on disk, while `aidev.tasks.json` **pushes** tasks to a remote provider.
490
+
491
+ Typical uses:
492
+
493
+ - **Recurring tasks** — with a `cron` expression, an entry publishes a fresh task on every matching tick (daily standup reminders, weekly reviews, monthly housekeeping).
494
+ - **Staged work** — queue a batch of tasks in a commit so they appear in the provider together when `aidev` next runs.
495
+ - **AI-authored tasks** — another AI agent or script can append entries to the file; `aidev` will pick them up and create real tickets.
496
+
497
+ The file is added to `.gitignore` by `aidev init` — each developer or automation environment maintains their own queue.
498
+
499
+ ### File format
500
+
501
+ `aidev.tasks.json` is a JSON array of task entries. Each entry has the shape:
502
+
503
+ ```ts
504
+ interface LocalTask {
505
+ id: string; // UUID — generated automatically by "aidev tasks add"
506
+ title: string; // required — task title on the remote provider
507
+ description: string; // task body / description
508
+ type: 'code' | 'non-code'; // routes to the non-code provider when set to 'non-code'
509
+ priority?: number; // 1=urgent, 2=high, 3=normal, 4=low
510
+ assignee?: string; // currently informational (reserved for future use)
511
+ dueDate?: string; // ISO date, e.g. "2026-05-01"
512
+ tags?: string[]; // extra tags appended to the provider-configured tag
513
+ listId?: string; // override provider list / project ID for this task only
514
+ cron?: string; // 5-field cron — if set, the task is re-published on every tick
515
+ lastPushedAt?: number; // epoch ms of the last successful push (managed by aidev for cron entries)
516
+ }
517
+ ```
518
+
519
+ **Example** (`aidev.tasks.json`):
520
+
521
+ ```json
522
+ [
523
+ {
524
+ "id": "7f3a9c2d-5b1e-4a6f-9d8c-1e2f3a4b5c6d",
525
+ "title": "Daily standup notes",
526
+ "description": "Post yesterday / today / blockers to the team channel.",
527
+ "type": "non-code",
528
+ "priority": 3,
529
+ "tags": ["standup"],
530
+ "cron": "0 9 * * 1-5"
531
+ },
532
+ {
533
+ "id": "2b8e1f7a-4c9d-4e5a-8b6c-9f1e2d3c4b5a",
534
+ "title": "Upgrade dependencies",
535
+ "description": "Run `npm outdated`, bump minor/patch versions, verify tests pass.",
536
+ "type": "code",
537
+ "priority": 2,
538
+ "tags": ["maintenance"]
539
+ }
540
+ ]
541
+ ```
542
+
543
+ ### Lifecycle
544
+
545
+ 1. **Every `aidev run`** (regardless of filter) begins by reading `aidev.tasks.json` and attempting to publish each entry via the configured provider's `createTask` API.
546
+ 2. **One-shot entries** (no `cron` field) are **removed from the file** after a successful push — they become a real ticket and won't be duplicated on the next run.
547
+ 3. **Cron entries** remain in the file. `lastPushedAt` is updated on each successful push; on the next run, aidev checks whether the cron has fired at least once since `lastPushedAt` before republishing. A fresh entry with a cron fires on the first run that matches.
548
+ 4. **Failures** are logged and the entry is kept — the next run retries.
549
+
550
+ ### Routing
551
+
552
+ - `type: 'code'` → published with the code tag (`CLICKUP_TAG` / `JIRA_LABEL` / `LINEAR_LABEL`, etc.) to the primary provider.
553
+ - `type: 'non-code'` → published with `NON_CODE_TAG` to the non-code provider (a separate team / project if `NON_CODE_CLICKUP_TEAM_ID`, `NON_CODE_JIRA_PROJECT`, or `NON_CODE_LINEAR_TEAM_ID` is configured, otherwise the primary).
554
+ - Per-task `tags` are appended to the resolved default tag.
555
+ - Per-task `listId` overrides the provider-default list / project for that single task.
556
+
557
+ ### Managing entries
558
+
559
+ Use the built-in commands rather than hand-editing JSON (although hand-editing is fine — the file is plain JSON):
560
+
561
+ ```bash
562
+ aidev tasks add # interactive prompt: title, description, type, priority, due date, tags, list, cron
563
+ aidev tasks ls # table of queued entries
564
+ aidev tasks update [id] # edit an entry by table ID (interactive picker if no id)
565
+ aidev tasks remove [id] # delete an entry by table ID (interactive picker if no id)
566
+ aidev tasks push # publish everything now (same as "aidev run tasks") — useful for dry-running or in scripts
567
+ ```
568
+
569
+ `aidev tasks push` and `aidev run tasks` do the same thing: they only process `aidev.tasks.json` and exit without pulling tasks from the provider or invoking the AI. This is useful when you want to decouple queue publishing from the main AI loop — for example, running `aidev tasks push` from a separate cron entry or CI job.
570
+
571
+ ---
572
+
573
+ ## Scheduling
574
+
575
+ aidev can run on a cron schedule, one entry per project directory.
576
+
577
+ ```bash
578
+ # Interactive picker
579
+ aidev schedule set
580
+
581
+ # Or pass an expression directly
582
+ aidev schedule set "*/15 * * * *"
583
+
584
+ # Check what's scheduled for the current directory
585
+ aidev schedule get
586
+ ```
587
+
588
+ **Preset options (interactive picker)**
589
+
590
+ | Option | Expression |
591
+ |---|---|
592
+ | Every 15 minutes | `*/15 * * * *` |
593
+ | Every 30 minutes | `*/30 * * * *` |
594
+ | Every hour | `0 * * * *` |
595
+ | Every 5 hours | `0 */5 * * *` |
596
+ | Every day at 8am | `0 8 * * *` |
597
+
598
+ Each directory gets its own cron entry identified by a `# aidev-cwd:/path` marker — running `schedule set` again replaces the existing entry rather than adding a duplicate.
599
+
600
+ ### macOS: Full Disk Access required
601
+
602
+ On macOS (Ventura and later), cron jobs are silently blocked unless `/usr/sbin/cron` has Full Disk Access:
603
+
604
+ 1. Open **System Settings → Privacy & Security → Full Disk Access**
605
+ 2. Click **+** and add `/usr/sbin/cron`
606
+ 3. Re-run `aidev schedule set` to apply your schedule
607
+
608
+ Without this, cron will appear to be configured but jobs will never fire.
609
+
610
+ ---
611
+
612
+ ## Logging
613
+
614
+ Every run appends to `aidev.log` in your project directory:
615
+
616
+ ```
617
+ ────────────────────────────────────────────────────────────
618
+ 2026-03-06T08:00:00.000Z [run] started
619
+ ────────────────────────────────────────────────────────────
620
+ 2026-03-06T08:00:00.120Z [info] Fetching tasks (filter: all)...
621
+ 2026-03-06T08:00:01.340Z [task] [abc123] "Fix login flow" (status: open)
622
+ 2026-03-06T08:00:12.780Z [info] Running claude...
623
+ 2026-03-06T08:00:45.210Z [success] Task implemented: branch abc123/fix-login-flow pushed
624
+ 2026-03-06T08:00:45.890Z [success] Done. Processed: 1, Skipped: 3
625
+ ```
626
+
627
+ ANSI colour codes are stripped so the file stays readable in any editor or `tail -f`. `aidev.log` is added to `.gitignore` automatically by `aidev init`.
628
+
629
+ ---
630
+
631
+ ## Providers
632
+
633
+ | Provider | Status | `aidev init` support |
634
+ |---|---|---|
635
+ | ClickUp | ✅ Implemented | ✅ Interactive wizard |
636
+ | Jira | ✅ Implemented | ✅ Interactive wizard |
637
+ | Linear | ✅ Implemented | ✅ Interactive wizard |
638
+ | Monday.com | ✅ Implemented | ✅ Interactive wizard |
639
+ | Local | ✅ Implemented | ✅ Interactive wizard |
640
+ | Notion | ✅ Implemented | Manual `.env.aidev` config |
641
+ | Trello | ✅ Implemented | Manual `.env.aidev` config |
642
+
643
+ > **Notion & Trello:** These providers are fully functional but not yet included in the `aidev init` wizard. To use them, set `PROVIDER=notion` or `PROVIDER=trello` in `.env.aidev` and fill in the required variables from the [Configuration](#configuration) section above.
644
+
645
+ The `TaskProvider` interface makes it straightforward to add new providers. See [CONTRIBUTING.md](./CONTRIBUTING.md).
646
+
647
+ ### Local provider
648
+
649
+ Set `PROVIDER=local` in `.env.aidev` to manage tasks entirely via local markdown files — no external API needed.
650
+
651
+ ```bash
652
+ aidev init # choose "local" when prompted for provider
653
+ ```
654
+
655
+ Tasks live in `.aidev/tasks/` under status folders:
656
+
657
+ ```
658
+ .aidev/tasks/
659
+ open/ # new tasks ready for implementation
660
+ pending/ # waiting for human reply
661
+ progress/ # currently being implemented
662
+ review/ # implementation complete, awaiting review
663
+ done/ # finished
664
+ ```
665
+
666
+ **Task file format** (e.g. `.aidev/tasks/open/a1b2c3d4-fix-login-bug.md`):
667
+
668
+ ```markdown
669
+ ---
670
+ title: Fix login page bug
671
+ priority: 2
672
+ assignee: david
673
+ estimated: 2h
674
+ tags: frontend, auth
675
+ created: 2026-03-12T10:00:00.000Z
676
+ ---
677
+
678
+ The login form should redirect users to the dashboard after successful authentication.
679
+ ```
680
+
681
+ The filename must start with a short ID (hex characters) followed by a dash and a slug. The YAML frontmatter carries task metadata; everything after `---` is the task description.
682
+
683
+ #### Code vs non-code tasks
684
+
685
+ By default, local tasks are treated as **code tasks** — aidev creates a git branch, runs the AI agent, commits, pushes, and opens a PR.
686
+
687
+ To mark a task as **non-code** (research, docs, investigation — no git branching), add `type: non-code` to the frontmatter:
688
+
689
+ ```markdown
690
+ ---
691
+ title: Compare OAuth2 providers
692
+ type: non-code
693
+ tags: research
694
+ ---
695
+
696
+ Evaluate Auth0, Clerk, and Supabase Auth. Write a recommendation.
697
+ ```
698
+
699
+ Non-code tasks follow the same lifecycle but skip all git operations. The AI response is posted as a session comment instead of a PR.
700
+
701
+ **Session file** (comments) — `.aidev/tasks/open/a1b2c3d4-fix-login-bug.session.md`:
702
+
703
+ ```markdown
704
+ <!-- aidev session log — append your comments below using "## your-name" as header -->
705
+
706
+ ---
707
+
708
+ ## aidev — 2026-03-12T10:05:00.000Z
709
+
710
+ [aidev] Starting implementation on branch `a1b2c3d4/fix-login-bug`
711
+
712
+ ---
713
+
714
+ ## david — 2026-03-12T10:10:00.000Z
715
+
716
+ Please use the new auth API endpoint for this.
717
+ ```
718
+
719
+ To add a comment, append a `---` separator followed by a `## your-name` header and your message. aidev parses these entries automatically and uses them as conversation context, just like ClickUp/Jira comments.
720
+
721
+ Downloaded task attachments are stored in `.aidev/assets/<task-id>/`, and `aidev init` adds `.aidev/assets/` to `.gitignore` automatically.
722
+
723
+ ---
724
+
725
+ ## Contributing
726
+
727
+ Contributions are welcome — new providers, new AI runners, bug fixes, and docs improvements.
728
+
729
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full guide.
730
+
731
+ ---
732
+
733
+ ## License
734
+
735
+ [MIT](./LICENSE)