aitasks 1.4.2 → 1.4.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 +215 -213
- package/dist/index.js +107 -97
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,213 +1,215 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
|
75
|
-
|
|
76
|
-
| `aitasks
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
|
83
|
-
|
|
84
|
-
| `aitasks
|
|
85
|
-
| `aitasks
|
|
86
|
-
| `aitasks
|
|
87
|
-
| `aitasks
|
|
88
|
-
| `aitasks
|
|
89
|
-
| `aitasks
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
|
96
|
-
|
|
97
|
-
| `aitasks
|
|
98
|
-
| `aitasks
|
|
99
|
-
| `aitasks
|
|
100
|
-
| `aitasks
|
|
101
|
-
| `aitasks
|
|
102
|
-
| `aitasks
|
|
103
|
-
| `aitasks
|
|
104
|
-
| `aitasks
|
|
105
|
-
| `aitasks
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
|
121
|
-
|
|
122
|
-
| `aitasks
|
|
123
|
-
| `aitasks
|
|
124
|
-
| `aitasks
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
--
|
|
141
|
-
--
|
|
142
|
-
--
|
|
143
|
-
--
|
|
144
|
-
--
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
aitasks onboard
|
|
159
|
-
aitasks onboard --
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
**
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
- **
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
**
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
1
|
+
[](https://www.npmjs.com/package/aitasks)
|
|
2
|
+
|
|
3
|
+
# aitasks
|
|
4
|
+
|
|
5
|
+
> CLI task management built for AI agents.
|
|
6
|
+
|
|
7
|
+
`aitasks` gives AI agents (Claude, Gemini, GPT, etc.) a structured task queue to work from. Agents can claim tasks, log progress notes, verify acceptance criteria with evidence, and hand off work — all via simple shell commands.
|
|
8
|
+
|
|
9
|
+
**Requires [Bun](https://bun.sh) ≥ 1.0.0.**
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
bun install -g aitasks
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
# 1. Initialize in your project
|
|
23
|
+
aitasks init
|
|
24
|
+
|
|
25
|
+
# 2. Create a task
|
|
26
|
+
aitasks create --title "Add JWT auth" --desc "Implement user authentication" --priority high --ac "POST /login returns token" --ac "Token expires in 1h"
|
|
27
|
+
|
|
28
|
+
# 3. Agent picks up work (one-liner with auto-claim)
|
|
29
|
+
aitasks next --claim --agent claude-sonnet
|
|
30
|
+
|
|
31
|
+
# 4. Or claim and start separately
|
|
32
|
+
aitasks claim TASK-001 --agent claude-sonnet
|
|
33
|
+
aitasks start TASK-001 --agent claude-sonnet
|
|
34
|
+
|
|
35
|
+
# 5. Log notes along the way
|
|
36
|
+
aitasks note TASK-001 "Using bcrypt for hashing — src/auth.ts:L22" --agent claude-sonnet
|
|
37
|
+
|
|
38
|
+
# 6. Verify acceptance criteria
|
|
39
|
+
aitasks check TASK-001 0 --evidence "POST /login returns 200 with token field" --agent claude-sonnet
|
|
40
|
+
aitasks check TASK-001 1 --evidence "token exp claim set to now+3600, confirmed in jwt.test.ts:L14"
|
|
41
|
+
|
|
42
|
+
# 7. Mark done
|
|
43
|
+
aitasks done TASK-001 --agent claude-sonnet
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Pro tips:**
|
|
47
|
+
- Use `aitasks next --claim --agent <id>` to find, claim, and start in one command
|
|
48
|
+
- Bulk operations: `aitasks done TASK-001 TASK-002 TASK-003 --agent <id>`
|
|
49
|
+
- Pattern matching: `aitasks claim TASK-0* --agent <id>` claims all TASK-00x tasks
|
|
50
|
+
- Search: `aitasks search "auth"` finds tasks mentioning authentication
|
|
51
|
+
- Undo mistakes: `aitasks undo TASK-001`
|
|
52
|
+
- Delete tasks: `aitasks delete TASK-001` (no need to claim first)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Environment Variables
|
|
57
|
+
|
|
58
|
+
| Variable | Description |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `AITASKS_AGENT_ID` | Default agent ID — avoids passing `--agent` on every command |
|
|
61
|
+
| `AITASKS_JSON` | Set to `true` to force JSON output globally (useful for scripting) |
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
export AITASKS_AGENT_ID=claude-sonnet
|
|
65
|
+
export AITASKS_JSON=true
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Commands
|
|
71
|
+
|
|
72
|
+
### Setup
|
|
73
|
+
|
|
74
|
+
| Command | Description |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `aitasks init` | Initialize a task database in the current project |
|
|
77
|
+
| `aitasks init --with-review` | Initialize with review enforcement (agents cannot mark done without a passing review) |
|
|
78
|
+
| `aitasks onboard` | Print or inject agent protocol instructions into CLAUDE.md / AGENTS.md |
|
|
79
|
+
|
|
80
|
+
### Task Discovery
|
|
81
|
+
|
|
82
|
+
| Command | Description |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `aitasks list` | List all tasks, sorted by priority |
|
|
85
|
+
| `aitasks list --status ready` | Filter by status (`ready`, `in_progress`, `blocked`, `review`, `done`) |
|
|
86
|
+
| `aitasks next` | Show the highest-priority unblocked ready task |
|
|
87
|
+
| `aitasks next --claim --agent <id>` | Auto-claim and start the best task |
|
|
88
|
+
| `aitasks show <id>` | Full detail on a specific task (includes time tracking) |
|
|
89
|
+
| `aitasks search <query>` | Full-text search across titles, descriptions, and notes |
|
|
90
|
+
| `aitasks deps <id>` | Show dependency tree (what blocks what) |
|
|
91
|
+
| `aitasks board` | Kanban-style board view |
|
|
92
|
+
|
|
93
|
+
### Task Lifecycle
|
|
94
|
+
|
|
95
|
+
| Command | Description |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `aitasks create` | Create a task (interactive if no flags given) |
|
|
98
|
+
| `aitasks claim <id...> --agent <id>` | Claim task(s) - supports patterns like `TASK-0*` |
|
|
99
|
+
| `aitasks start <id...> --agent <id>` | Begin active work on task(s) |
|
|
100
|
+
| `aitasks note <id> <text>` | Add an implementation note |
|
|
101
|
+
| `aitasks check <id> <n> --evidence <text>` | Verify acceptance criterion n |
|
|
102
|
+
| `aitasks done <id...> --agent <id>` | Mark task(s) complete (all criteria must be verified; must be in `review` status if enforcement is on) |
|
|
103
|
+
| `aitasks review <id...> --agent <id>` | Submit task(s) for review (moves to `review` status) |
|
|
104
|
+
| `aitasks reject <id> --reason <text>` | Reject a task in review, send it back to `in_progress` with feedback |
|
|
105
|
+
| `aitasks unclaim <id> --agent <id>` | Release a task back to the pool |
|
|
106
|
+
| `aitasks undo <id>` | Undo the last action on a task |
|
|
107
|
+
| `aitasks delete <id...>` | Delete task(s) - does not require claiming first |
|
|
108
|
+
|
|
109
|
+
**Note:** Commands marked with `<id...>` support multiple task IDs and pattern matching (e.g., `TASK-0*`).
|
|
110
|
+
|
|
111
|
+
### Blocking
|
|
112
|
+
|
|
113
|
+
| Command | Description |
|
|
114
|
+
|---|---|
|
|
115
|
+
| `aitasks block <id> --on <id,...>` | Mark a task as blocked by others |
|
|
116
|
+
| `aitasks unblock <id> --from <id>` | Manually remove a blocker |
|
|
117
|
+
|
|
118
|
+
### Agents & History
|
|
119
|
+
|
|
120
|
+
| Command | Description |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `aitasks agents` | List active agents and their current tasks |
|
|
123
|
+
| `aitasks heartbeat [taskId]` | Update agent last-seen timestamp |
|
|
124
|
+
| `aitasks log <id>` | Full event history for a task |
|
|
125
|
+
| `aitasks export --format json` | Export all tasks as JSON |
|
|
126
|
+
| `aitasks export --format csv` | Export all tasks as CSV |
|
|
127
|
+
|
|
128
|
+
### Database
|
|
129
|
+
|
|
130
|
+
| Command | Description |
|
|
131
|
+
|---|---|
|
|
132
|
+
| `aitasks db status` | Show database health and stats |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## `create` Flags
|
|
137
|
+
|
|
138
|
+
```sh
|
|
139
|
+
aitasks create \
|
|
140
|
+
--title "My task" \
|
|
141
|
+
--desc "Longer description" \
|
|
142
|
+
--ac "Returns 200" \ # Acceptance criterion (repeatable, at least one required)
|
|
143
|
+
--priority high \ # critical | high | medium | low
|
|
144
|
+
--type feature \ # feature | bug | chore | spike
|
|
145
|
+
--parent TASK-001 \ # Parent task ID (optional)
|
|
146
|
+
--agent $AITASKS_AGENT_ID # Agent creating the task (logged in event history)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Agent Protocol
|
|
152
|
+
|
|
153
|
+
When you run `aitasks init`, it automatically injects a full agent protocol into `CLAUDE.md`, `AGENTS.md`, or `GEMINI.md` (whichever exists, or creates `AGENTS.md`). This tells the AI agent exactly how to use `aitasks`.
|
|
154
|
+
|
|
155
|
+
You can also inject/view it manually:
|
|
156
|
+
|
|
157
|
+
```sh
|
|
158
|
+
aitasks onboard # print to stdout (reflects current review_required setting)
|
|
159
|
+
aitasks onboard --append # append to detected agent file
|
|
160
|
+
aitasks onboard --file MY.md # append to a specific file
|
|
161
|
+
aitasks onboard --json # output as JSON string
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The injected instructions automatically adapt to the project's review enforcement setting — if `--with-review` is enabled, agents receive the full review workflow (with `aitasks review`, sub-agent approval, and `aitasks reject`) instead of the standard completion flow.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Review Enforcement
|
|
169
|
+
|
|
170
|
+
Enable a mandatory review gate so agents cannot mark tasks done without an explicit approval step:
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
# Enable at init time
|
|
174
|
+
aitasks init --with-review
|
|
175
|
+
|
|
176
|
+
# Enable on an existing project (also replaces the agent instructions file with review-aware version)
|
|
177
|
+
aitasks init --with-review # safe to re-run; updates DB setting and rewrites agent file
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**A task is only complete when its status is `done`.** No other status — verified criteria, `review`, `in_progress` — counts as complete. Agents must reach `done` to consider a task finished.
|
|
181
|
+
|
|
182
|
+
**How it works:**
|
|
183
|
+
|
|
184
|
+
1. Agent completes work and verifies all acceptance criteria with evidence
|
|
185
|
+
2. Agent submits for review — task moves to `review` status:
|
|
186
|
+
```sh
|
|
187
|
+
aitasks review TASK-001 --agent $AITASKS_AGENT_ID
|
|
188
|
+
```
|
|
189
|
+
The command output explicitly instructs the agent to immediately spawn a review sub-agent. The task is **not complete** at this point.
|
|
190
|
+
3. The agent **immediately spawns a review sub-agent** to inspect the implementation:
|
|
191
|
+
- **Approves** — moves task to done:
|
|
192
|
+
```sh
|
|
193
|
+
aitasks done TASK-001 --agent review-agent
|
|
194
|
+
```
|
|
195
|
+
- **Rejects** — sends it back to `in_progress` with feedback:
|
|
196
|
+
```sh
|
|
197
|
+
aitasks reject TASK-001 --reason "Missing error handling for 404 case" --agent review-agent
|
|
198
|
+
```
|
|
199
|
+
4. If rejected, the original agent addresses the feedback, re-verifies criteria, and repeats from step 2.
|
|
200
|
+
|
|
201
|
+
**Enforcement:** `aitasks done` and `aitasks update --status done` both block if the task isn't already in `review` status. The gate cannot be bypassed.
|
|
202
|
+
|
|
203
|
+
**Board:** Tasks in `review` status appear in the **IN PROGRESS** section with a `◈` magenta indicator so they're visually distinct from actively-worked tasks.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Data Storage
|
|
208
|
+
|
|
209
|
+
`aitasks init` creates a `.aitasks/` directory in your project root containing a SQLite database. Add `.aitasks/` to your `.gitignore` if you don't want to commit task data, or commit it to share tasks across your team.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -861,7 +861,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
861
861
|
this._exitCallback = (err) => {
|
|
862
862
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
863
863
|
throw err;
|
|
864
|
-
}
|
|
864
|
+
}
|
|
865
865
|
};
|
|
866
866
|
}
|
|
867
867
|
return this;
|
|
@@ -1890,7 +1890,7 @@ var require_commander = __commonJS((exports) => {
|
|
|
1890
1890
|
var require_package = __commonJS((exports, module) => {
|
|
1891
1891
|
module.exports = {
|
|
1892
1892
|
name: "aitasks",
|
|
1893
|
-
version: "1.4.
|
|
1893
|
+
version: "1.4.3",
|
|
1894
1894
|
description: "CLI task management tool built for AI agents",
|
|
1895
1895
|
type: "module",
|
|
1896
1896
|
bin: {
|
|
@@ -9868,7 +9868,7 @@ Learn more about data fetching with Hooks: https://react.dev/link/hooks-data-fet
|
|
|
9868
9868
|
offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
|
|
9869
9869
|
wasHidden && !hoistableRoot && !prevOffscreenSubtreeIsHidden && !prevOffscreenSubtreeWasHidden && (finishedWork.mode & 2) !== NoMode && 0 <= componentEffectStartTime && 0 <= componentEffectEndTime && 0.05 < componentEffectEndTime - componentEffectStartTime && logComponentReappeared(finishedWork, componentEffectStartTime, componentEffectEndTime);
|
|
9870
9870
|
commitReconciliationEffects(finishedWork);
|
|
9871
|
-
if (flags & 8192 && (root = finishedWork.stateNode, root._visibility = hoistableRoot ? root._visibility & ~OffscreenVisible : root._visibility | OffscreenVisible, !hoistableRoot || current2 === null || wasHidden || offscreenSubtreeIsHidden || offscreenSubtreeWasHidden || (recursivelyTraverseDisappearLayoutEffects(finishedWork), (finishedWork.mode & 2) !== NoMode && 0 <= componentEffectStartTime && 0 <= componentEffectEndTime && 0.05 < componentEffectEndTime - componentEffectStartTime && logComponentTrigger(finishedWork, componentEffectStartTime, componentEffectEndTime, "Disconnect")), supportsMutation))
|
|
9871
|
+
if (flags & 8192 && (root = finishedWork.stateNode, root._visibility = hoistableRoot ? root._visibility & ~OffscreenVisible : root._visibility | OffscreenVisible, !hoistableRoot || current2 === null || wasHidden || offscreenSubtreeIsHidden || offscreenSubtreeWasHidden || (recursivelyTraverseDisappearLayoutEffects(finishedWork), (finishedWork.mode & 2) !== NoMode && 0 <= componentEffectStartTime && 0 <= componentEffectEndTime && 0.05 < componentEffectEndTime - componentEffectStartTime && logComponentTrigger(finishedWork, componentEffectStartTime, componentEffectEndTime, "Disconnect")), supportsMutation)) {
|
|
9872
9872
|
a:
|
|
9873
9873
|
if (current2 = null, supportsMutation)
|
|
9874
9874
|
for (root = finishedWork;; ) {
|
|
@@ -9918,6 +9918,7 @@ Learn more about data fetching with Hooks: https://react.dev/link/hooks-data-fet
|
|
|
9918
9918
|
root.sibling.return = root.return;
|
|
9919
9919
|
root = root.sibling;
|
|
9920
9920
|
}
|
|
9921
|
+
}
|
|
9921
9922
|
flags & 4 && (flags = finishedWork.updateQueue, flags !== null && (current2 = flags.retryQueue, current2 !== null && (flags.retryQueue = null, attachSuspenseRetryListeners(finishedWork, current2))));
|
|
9922
9923
|
break;
|
|
9923
9924
|
case 19:
|
|
@@ -14590,7 +14591,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
14590
14591
|
987: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
14591
14592
|
if (true) {
|
|
14592
14593
|
module2.exports = __webpack_require__2(786);
|
|
14593
|
-
}
|
|
14594
|
+
}
|
|
14594
14595
|
},
|
|
14595
14596
|
126: (__unused_webpack_module, exports2, __webpack_require__2) => {
|
|
14596
14597
|
var process6 = __webpack_require__2(169);
|
|
@@ -15050,7 +15051,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
15050
15051
|
189: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
15051
15052
|
if (true) {
|
|
15052
15053
|
module2.exports = __webpack_require__2(126);
|
|
15053
|
-
}
|
|
15054
|
+
}
|
|
15054
15055
|
},
|
|
15055
15056
|
206: function(module2, exports2, __webpack_require__2) {
|
|
15056
15057
|
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
|
|
@@ -15070,7 +15071,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
15070
15071
|
(function(root, factory) {
|
|
15071
15072
|
if (true) {
|
|
15072
15073
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__2(430)], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
15073
|
-
}
|
|
15074
|
+
}
|
|
15074
15075
|
})(this, function ErrorStackParser(StackFrame) {
|
|
15075
15076
|
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
|
|
15076
15077
|
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
|
|
@@ -15746,7 +15747,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
15746
15747
|
(function(root, factory) {
|
|
15747
15748
|
if (true) {
|
|
15748
15749
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
15749
|
-
}
|
|
15750
|
+
}
|
|
15750
15751
|
})(this, function() {
|
|
15751
15752
|
function _isNumber(n) {
|
|
15752
15753
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
@@ -20528,7 +20529,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
20528
20529
|
var suffix = "";
|
|
20529
20530
|
if (true) {
|
|
20530
20531
|
suffix = " (<anonymous>)";
|
|
20531
|
-
}
|
|
20532
|
+
}
|
|
20532
20533
|
return `
|
|
20533
20534
|
` + prefix + name + suffix;
|
|
20534
20535
|
}
|
|
@@ -22857,7 +22858,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
22857
22858
|
hasChanges = true;
|
|
22858
22859
|
updateMostRecentlyInspectedElementIfNecessary(devtoolsInstance.id);
|
|
22859
22860
|
}
|
|
22860
|
-
}
|
|
22861
|
+
}
|
|
22861
22862
|
}
|
|
22862
22863
|
} catch (err) {
|
|
22863
22864
|
_iterator2.e(err);
|
|
@@ -26729,7 +26730,7 @@ The error thrown in the component is:
|
|
|
26729
26730
|
rendererInterface = renderer_attach(hook, id, renderer, global2, shouldStartProfilingNow, profilingSettings);
|
|
26730
26731
|
} else if (renderer.ComponentTree) {
|
|
26731
26732
|
rendererInterface = legacy_renderer_attach(hook, id, renderer, global2);
|
|
26732
|
-
}
|
|
26733
|
+
}
|
|
26733
26734
|
}
|
|
26734
26735
|
return rendererInterface;
|
|
26735
26736
|
}
|
|
@@ -29409,8 +29410,14 @@ aitasks block TASK-001 --on TASK-002,TASK-003
|
|
|
29409
29410
|
View dependencies:
|
|
29410
29411
|
\`\`\`bash
|
|
29411
29412
|
aitasks deps TASK-001 # Shows what this task is blocked by and what it blocks
|
|
29413
|
+
aitasks show TASK-001 # Also lists "Blocked by" / "Blocks" for a single task
|
|
29412
29414
|
\`\`\`
|
|
29413
29415
|
|
|
29416
|
+
When a prerequisite is marked \`done\`, its dependents are **auto-unblocked**: any task
|
|
29417
|
+
whose last blocker just completed moves to \`ready\` automatically (no manual promotion
|
|
29418
|
+
needed). You can then \`aitasks claim\` it directly. To override a status by hand, use
|
|
29419
|
+
\`aitasks update <id> --status ready\`.
|
|
29420
|
+
|
|
29414
29421
|
---
|
|
29415
29422
|
|
|
29416
29423
|
### Completing a Task${reviewRequired ? " \u26A0\uFE0F REVIEW REQUIRED" : ""}
|
|
@@ -29528,10 +29535,12 @@ must be spawned and must approve the task in this same session.
|
|
|
29528
29535
|
\`\`\`
|
|
29529
29536
|
aitasks next [--claim] [--agent <id>] Find best task (optionally auto-claim/start)
|
|
29530
29537
|
aitasks list [--status <s>] [--json] List tasks
|
|
29538
|
+
aitasks board Live kanban board (visual TUI)
|
|
29531
29539
|
aitasks show <id> Full task detail (includes time tracking)
|
|
29532
29540
|
aitasks search <query> Search titles, descriptions, notes
|
|
29533
29541
|
aitasks deps <id> Show dependency tree
|
|
29534
29542
|
aitasks create --title <t> --desc <d> --ac <c> [--ac <c> ...] --agent <id> Create a task
|
|
29543
|
+
aitasks update <id> [--status|--priority|--title|--desc|--ac|--type] Update task fields
|
|
29535
29544
|
aitasks claim <id...> --agent <id> Claim task(s) - supports patterns like TASK-0*
|
|
29536
29545
|
aitasks start <id...> --agent <id> Begin work on task(s)
|
|
29537
29546
|
aitasks note <id> <text> --agent <id> Add implementation note
|
|
@@ -29546,6 +29555,7 @@ aitasks undo <id> Undo last action on task
|
|
|
29546
29555
|
aitasks delete <id...> Delete task(s) - no claim required
|
|
29547
29556
|
aitasks log <id> Full event history
|
|
29548
29557
|
aitasks agents List active agents
|
|
29558
|
+
aitasks heartbeat [<id>] --agent <id> Keep-alive: refresh agent last-seen
|
|
29549
29559
|
aitasks export --format json Export all tasks
|
|
29550
29560
|
\`\`\`
|
|
29551
29561
|
|
|
@@ -29631,6 +29641,42 @@ function appendToSpecificFile(filePath, version, reviewRequired = false) {
|
|
|
29631
29641
|
return { filePath, action: "appended" };
|
|
29632
29642
|
}
|
|
29633
29643
|
|
|
29644
|
+
// src/commands/shared.ts
|
|
29645
|
+
function jsonOut(success, data, errorMsg) {
|
|
29646
|
+
console.log(JSON.stringify(success ? { success: true, data } : { success: false, error: errorMsg }, null, 2));
|
|
29647
|
+
}
|
|
29648
|
+
function agentId(flagValue) {
|
|
29649
|
+
return flagValue ?? process.env["AITASKS_AGENT_ID"] ?? null;
|
|
29650
|
+
}
|
|
29651
|
+
function requireAgentId(flagValue, command = "this command") {
|
|
29652
|
+
const id = agentId(flagValue);
|
|
29653
|
+
if (!id) {
|
|
29654
|
+
console.error(` Agent ID required for ${command}.
|
|
29655
|
+
` + ` Use --agent <id> or set AITASKS_AGENT_ID environment variable.`);
|
|
29656
|
+
process.exit(1);
|
|
29657
|
+
}
|
|
29658
|
+
return id;
|
|
29659
|
+
}
|
|
29660
|
+
function isJsonMode(flag) {
|
|
29661
|
+
return flag === true || process.env["AITASKS_JSON"] === "true";
|
|
29662
|
+
}
|
|
29663
|
+
function exitError(msg, json) {
|
|
29664
|
+
if (json) {
|
|
29665
|
+
console.log(JSON.stringify({ success: false, error: msg }, null, 2));
|
|
29666
|
+
} else {
|
|
29667
|
+
console.error(` Error: ${msg}`);
|
|
29668
|
+
}
|
|
29669
|
+
process.exit(1);
|
|
29670
|
+
}
|
|
29671
|
+
function getVersion() {
|
|
29672
|
+
try {
|
|
29673
|
+
const pkg = require_package();
|
|
29674
|
+
return pkg.version;
|
|
29675
|
+
} catch {
|
|
29676
|
+
return "0.0.0";
|
|
29677
|
+
}
|
|
29678
|
+
}
|
|
29679
|
+
|
|
29634
29680
|
// src/commands/init.ts
|
|
29635
29681
|
var initCommand = new Command("init").description("Initialize AITasks in the current project").option("--skip-agent-file", "Skip injecting agent instructions into CLAUDE.md/AGENTS.md/GEMINI.md").option("--with-review", "Enforce review gate: agents cannot mark tasks done without a passing review").addHelpText("after", `
|
|
29636
29682
|
Examples:
|
|
@@ -29697,14 +29743,6 @@ function printAgentFileResult(result) {
|
|
|
29697
29743
|
}
|
|
29698
29744
|
console.log("");
|
|
29699
29745
|
}
|
|
29700
|
-
function getVersion() {
|
|
29701
|
-
try {
|
|
29702
|
-
const pkg = require_package();
|
|
29703
|
-
return pkg.version;
|
|
29704
|
-
} catch {
|
|
29705
|
-
return "1.0.0";
|
|
29706
|
-
}
|
|
29707
|
-
}
|
|
29708
29746
|
|
|
29709
29747
|
// node_modules/@clack/core/dist/index.mjs
|
|
29710
29748
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
@@ -30456,22 +30494,22 @@ function updateTask(id, updates) {
|
|
|
30456
30494
|
const row = db.query(`UPDATE tasks SET ${fields.join(", ")} WHERE id = ? RETURNING *`).get(...params);
|
|
30457
30495
|
return row ? parseTask(row) : null;
|
|
30458
30496
|
}
|
|
30459
|
-
function addImplementationNote(taskId, note,
|
|
30497
|
+
function addImplementationNote(taskId, note, agentId2) {
|
|
30460
30498
|
const task = getTask(taskId);
|
|
30461
30499
|
if (!task)
|
|
30462
30500
|
return null;
|
|
30463
30501
|
const entry = {
|
|
30464
30502
|
timestamp: Date.now(),
|
|
30465
|
-
agent:
|
|
30503
|
+
agent: agentId2,
|
|
30466
30504
|
note
|
|
30467
30505
|
};
|
|
30468
30506
|
const updated = updateTask(taskId, {
|
|
30469
30507
|
implementation_notes: [...task.implementation_notes, entry]
|
|
30470
30508
|
});
|
|
30471
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30509
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "note_added", payload: { note } });
|
|
30472
30510
|
return updated;
|
|
30473
30511
|
}
|
|
30474
|
-
function checkCriterion(taskId, index, evidence,
|
|
30512
|
+
function checkCriterion(taskId, index, evidence, agentId2) {
|
|
30475
30513
|
const task = getTask(taskId);
|
|
30476
30514
|
if (!task)
|
|
30477
30515
|
return { task: null, error: "Task not found" };
|
|
@@ -30488,20 +30526,20 @@ function checkCriterion(taskId, index, evidence, agentId) {
|
|
|
30488
30526
|
passed: true,
|
|
30489
30527
|
evidence,
|
|
30490
30528
|
checked_at: Date.now(),
|
|
30491
|
-
agent:
|
|
30529
|
+
agent: agentId2
|
|
30492
30530
|
};
|
|
30493
30531
|
const results = task.test_results.filter((r2) => r2.index !== index);
|
|
30494
30532
|
results.push(result);
|
|
30495
30533
|
const updated = updateTask(taskId, { test_results: results });
|
|
30496
30534
|
logEvent({
|
|
30497
30535
|
task_id: taskId,
|
|
30498
|
-
agent_id:
|
|
30536
|
+
agent_id: agentId2,
|
|
30499
30537
|
event_type: "criterion_checked",
|
|
30500
30538
|
payload: { index, criterion, evidence }
|
|
30501
30539
|
});
|
|
30502
30540
|
return { task: updated };
|
|
30503
30541
|
}
|
|
30504
|
-
function claimTask(taskId,
|
|
30542
|
+
function claimTask(taskId, agentId2) {
|
|
30505
30543
|
const s = stmts2();
|
|
30506
30544
|
const task = getTask(taskId);
|
|
30507
30545
|
if (!task)
|
|
@@ -30518,34 +30556,34 @@ function claimTask(taskId, agentId) {
|
|
|
30518
30556
|
};
|
|
30519
30557
|
}
|
|
30520
30558
|
const now = Date.now();
|
|
30521
|
-
s.upsertAgent.run(
|
|
30522
|
-
const updated = updateTask(taskId, { assigned_to:
|
|
30523
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30559
|
+
s.upsertAgent.run(agentId2, now, now, taskId);
|
|
30560
|
+
const updated = updateTask(taskId, { assigned_to: agentId2, status: "ready" });
|
|
30561
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "claimed", payload: {} });
|
|
30524
30562
|
return { task: updated };
|
|
30525
30563
|
}
|
|
30526
|
-
function startTask(taskId,
|
|
30564
|
+
function startTask(taskId, agentId2) {
|
|
30527
30565
|
const s = stmts2();
|
|
30528
30566
|
const task = getTask(taskId);
|
|
30529
30567
|
if (!task)
|
|
30530
30568
|
return { task: null, error: "Task not found" };
|
|
30531
30569
|
if (task.status === "in_progress")
|
|
30532
30570
|
return { task: null, error: "Task is already in progress" };
|
|
30533
|
-
if (task.assigned_to && task.assigned_to !==
|
|
30534
|
-
return { task: null, error: `Task is assigned to ${task.assigned_to}, not ${
|
|
30571
|
+
if (task.assigned_to && task.assigned_to !== agentId2) {
|
|
30572
|
+
return { task: null, error: `Task is assigned to ${task.assigned_to}, not ${agentId2}` };
|
|
30535
30573
|
}
|
|
30536
30574
|
if (!task.assigned_to) {
|
|
30537
30575
|
const now = Date.now();
|
|
30538
|
-
s.upsertAgent.run(
|
|
30576
|
+
s.upsertAgent.run(agentId2, now, now, taskId);
|
|
30539
30577
|
}
|
|
30540
30578
|
const updated = updateTask(taskId, {
|
|
30541
|
-
assigned_to:
|
|
30579
|
+
assigned_to: agentId2,
|
|
30542
30580
|
status: "in_progress",
|
|
30543
30581
|
started_at: Date.now()
|
|
30544
30582
|
});
|
|
30545
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30583
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "started", payload: {} });
|
|
30546
30584
|
return { task: updated };
|
|
30547
30585
|
}
|
|
30548
|
-
function completeTask(taskId,
|
|
30586
|
+
function completeTask(taskId, agentId2) {
|
|
30549
30587
|
const s = stmts2();
|
|
30550
30588
|
const task = getTask(taskId);
|
|
30551
30589
|
if (!task)
|
|
@@ -30571,18 +30609,18 @@ function completeTask(taskId, agentId) {
|
|
|
30571
30609
|
` + " Tasks cannot be moved to Done without a passing review."
|
|
30572
30610
|
};
|
|
30573
30611
|
}
|
|
30574
|
-
if (task.assigned_to && task.assigned_to ===
|
|
30612
|
+
if (task.assigned_to && task.assigned_to === agentId2) {
|
|
30575
30613
|
return {
|
|
30576
30614
|
task: null,
|
|
30577
|
-
error: `Self-approval blocked: ${
|
|
30615
|
+
error: `Self-approval blocked: ${agentId2} is the implementing agent and cannot approve their own review.
|
|
30578
30616
|
` + ` A separate review sub-agent must run: aitasks done ${taskId} --agent <review-agent-id>`
|
|
30579
30617
|
};
|
|
30580
30618
|
}
|
|
30581
30619
|
const reviewEvent = getLastReviewEvent(taskId);
|
|
30582
|
-
if (reviewEvent?.agent_id && reviewEvent.agent_id ===
|
|
30620
|
+
if (reviewEvent?.agent_id && reviewEvent.agent_id === agentId2) {
|
|
30583
30621
|
return {
|
|
30584
30622
|
task: null,
|
|
30585
|
-
error: `Self-approval blocked: ${
|
|
30623
|
+
error: `Self-approval blocked: ${agentId2} submitted this task for review and cannot also approve it.
|
|
30586
30624
|
` + ` A separate review sub-agent must run: aitasks done ${taskId} --agent <review-agent-id>`
|
|
30587
30625
|
};
|
|
30588
30626
|
}
|
|
@@ -30590,7 +30628,7 @@ function completeTask(taskId, agentId) {
|
|
|
30590
30628
|
const db = s.db;
|
|
30591
30629
|
const doComplete = db.transaction(() => {
|
|
30592
30630
|
const updated2 = updateTask(taskId, { status: "done", completed_at: Date.now() });
|
|
30593
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30631
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "completed", payload: {} });
|
|
30594
30632
|
const pendingRows = db.query(`SELECT id, blocked_by FROM tasks
|
|
30595
30633
|
WHERE status != 'done' AND blocked_by LIKE '%' || ? || '%'`).all(taskId);
|
|
30596
30634
|
for (const row of pendingRows) {
|
|
@@ -30608,14 +30646,14 @@ function completeTask(taskId, agentId) {
|
|
|
30608
30646
|
});
|
|
30609
30647
|
}
|
|
30610
30648
|
}
|
|
30611
|
-
if (
|
|
30612
|
-
s.releaseAgent.run(
|
|
30649
|
+
if (agentId2)
|
|
30650
|
+
s.releaseAgent.run(agentId2);
|
|
30613
30651
|
return updated2;
|
|
30614
30652
|
});
|
|
30615
30653
|
const updated = doComplete();
|
|
30616
30654
|
return { task: updated };
|
|
30617
30655
|
}
|
|
30618
|
-
function blockTask(taskId, blockerIds,
|
|
30656
|
+
function blockTask(taskId, blockerIds, agentId2) {
|
|
30619
30657
|
const s = stmts2();
|
|
30620
30658
|
const db = s.db;
|
|
30621
30659
|
const task = getTask(taskId);
|
|
@@ -30647,7 +30685,7 @@ function blockTask(taskId, blockerIds, agentId) {
|
|
|
30647
30685
|
const updated = updateTask(taskId, { blocked_by: newBlockedBy, status: "blocked" });
|
|
30648
30686
|
logEvent({
|
|
30649
30687
|
task_id: taskId,
|
|
30650
|
-
agent_id:
|
|
30688
|
+
agent_id: agentId2,
|
|
30651
30689
|
event_type: "blocked",
|
|
30652
30690
|
payload: { blocked_by: blockerIds }
|
|
30653
30691
|
});
|
|
@@ -30666,7 +30704,7 @@ function detectCycleFromMap(taskId, candidateBlocker, taskMap, visited = new Set
|
|
|
30666
30704
|
return false;
|
|
30667
30705
|
return blocker.blocked_by.some((id) => detectCycleFromMap(taskId, id, taskMap, visited));
|
|
30668
30706
|
}
|
|
30669
|
-
function unblockTask(taskId, fromId,
|
|
30707
|
+
function unblockTask(taskId, fromId, agentId2) {
|
|
30670
30708
|
const db = stmts2().db;
|
|
30671
30709
|
const task = getTask(taskId);
|
|
30672
30710
|
if (!task)
|
|
@@ -30682,10 +30720,10 @@ function unblockTask(taskId, fromId, agentId) {
|
|
|
30682
30720
|
}
|
|
30683
30721
|
const newStatus = remaining.length === 0 ? "ready" : "blocked";
|
|
30684
30722
|
const updated = updateTask(taskId, { blocked_by: remaining, status: newStatus });
|
|
30685
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30723
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "unblocked", payload: { from: fromId } });
|
|
30686
30724
|
return { task: updated };
|
|
30687
30725
|
}
|
|
30688
|
-
function reviewTask(taskId,
|
|
30726
|
+
function reviewTask(taskId, agentId2) {
|
|
30689
30727
|
const task = getTask(taskId);
|
|
30690
30728
|
if (!task)
|
|
30691
30729
|
return { task: null, error: "Task not found" };
|
|
@@ -30693,17 +30731,17 @@ function reviewTask(taskId, agentId) {
|
|
|
30693
30731
|
return { task: null, error: "Task must be in_progress to request review" };
|
|
30694
30732
|
}
|
|
30695
30733
|
const updated = updateTask(taskId, { status: "review" });
|
|
30696
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30734
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "review_requested", payload: {} });
|
|
30697
30735
|
return { task: updated };
|
|
30698
30736
|
}
|
|
30699
|
-
function rejectTask(taskId, reason,
|
|
30737
|
+
function rejectTask(taskId, reason, agentId2) {
|
|
30700
30738
|
const task = getTask(taskId);
|
|
30701
30739
|
if (!task)
|
|
30702
30740
|
return { task: null, error: "Task not found" };
|
|
30703
30741
|
if (task.status !== "review") {
|
|
30704
30742
|
return { task: null, error: "Task must be in review status to reject" };
|
|
30705
30743
|
}
|
|
30706
|
-
const agent =
|
|
30744
|
+
const agent = agentId2 ?? "human";
|
|
30707
30745
|
const entry = {
|
|
30708
30746
|
timestamp: Date.now(),
|
|
30709
30747
|
agent,
|
|
@@ -30713,30 +30751,30 @@ function rejectTask(taskId, reason, agentId) {
|
|
|
30713
30751
|
status: "in_progress",
|
|
30714
30752
|
implementation_notes: [...task.implementation_notes, entry]
|
|
30715
30753
|
});
|
|
30716
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30754
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "note_added", payload: { note: entry.note } });
|
|
30717
30755
|
logEvent({
|
|
30718
30756
|
task_id: taskId,
|
|
30719
|
-
agent_id:
|
|
30757
|
+
agent_id: agentId2,
|
|
30720
30758
|
event_type: "rejected",
|
|
30721
30759
|
payload: { reason }
|
|
30722
30760
|
});
|
|
30723
30761
|
return { task: updated };
|
|
30724
30762
|
}
|
|
30725
|
-
function unclaimTask(taskId,
|
|
30763
|
+
function unclaimTask(taskId, agentId2, reason) {
|
|
30726
30764
|
const s = stmts2();
|
|
30727
30765
|
const task = getTask(taskId);
|
|
30728
30766
|
if (!task)
|
|
30729
30767
|
return { task: null, error: "Task not found" };
|
|
30730
|
-
if (task.assigned_to !==
|
|
30731
|
-
return { task: null, error: `Task is not assigned to ${
|
|
30768
|
+
if (task.assigned_to !== agentId2) {
|
|
30769
|
+
return { task: null, error: `Task is not assigned to ${agentId2}` };
|
|
30732
30770
|
}
|
|
30733
30771
|
const backStatus = task.blocked_by.length > 0 ? "blocked" : "ready";
|
|
30734
30772
|
let updated;
|
|
30735
30773
|
if (reason) {
|
|
30736
30774
|
const entry = {
|
|
30737
30775
|
timestamp: Date.now(),
|
|
30738
|
-
agent:
|
|
30739
|
-
note: `UNCLAIMED by ${
|
|
30776
|
+
agent: agentId2,
|
|
30777
|
+
note: `UNCLAIMED by ${agentId2}: ${reason}`
|
|
30740
30778
|
};
|
|
30741
30779
|
updated = updateTask(taskId, {
|
|
30742
30780
|
assigned_to: null,
|
|
@@ -30744,32 +30782,32 @@ function unclaimTask(taskId, agentId, reason) {
|
|
|
30744
30782
|
started_at: null,
|
|
30745
30783
|
implementation_notes: [...task.implementation_notes, entry]
|
|
30746
30784
|
});
|
|
30747
|
-
logEvent({ task_id: taskId, agent_id:
|
|
30785
|
+
logEvent({ task_id: taskId, agent_id: agentId2, event_type: "note_added", payload: { note: entry.note } });
|
|
30748
30786
|
} else {
|
|
30749
30787
|
updated = updateTask(taskId, { assigned_to: null, status: backStatus, started_at: null });
|
|
30750
30788
|
}
|
|
30751
|
-
s.releaseAgent.run(
|
|
30789
|
+
s.releaseAgent.run(agentId2);
|
|
30752
30790
|
logEvent({
|
|
30753
30791
|
task_id: taskId,
|
|
30754
|
-
agent_id:
|
|
30792
|
+
agent_id: agentId2,
|
|
30755
30793
|
event_type: "unclaimed",
|
|
30756
30794
|
payload: { reason: reason ?? "" }
|
|
30757
30795
|
});
|
|
30758
30796
|
return { task: updated };
|
|
30759
30797
|
}
|
|
30760
|
-
function heartbeat(
|
|
30798
|
+
function heartbeat(agentId2, taskId) {
|
|
30761
30799
|
const now = Date.now();
|
|
30762
|
-
stmts2().heartbeat.run(
|
|
30800
|
+
stmts2().heartbeat.run(agentId2, now, now, taskId ?? null);
|
|
30763
30801
|
}
|
|
30764
30802
|
function listAgents() {
|
|
30765
30803
|
const db = stmts2().db;
|
|
30766
30804
|
return db.query("SELECT * FROM agents ORDER BY last_seen DESC").all();
|
|
30767
30805
|
}
|
|
30768
|
-
function getNextTask(
|
|
30806
|
+
function getNextTask(agentId2) {
|
|
30769
30807
|
const db = stmts2().db;
|
|
30770
|
-
if (
|
|
30808
|
+
if (agentId2) {
|
|
30771
30809
|
const mine = db.query(`SELECT * FROM tasks WHERE status = 'ready' AND assigned_to = ?
|
|
30772
|
-
ORDER BY ${PRIORITY_ORDER}, created_at ASC LIMIT 1`).get(
|
|
30810
|
+
ORDER BY ${PRIORITY_ORDER}, created_at ASC LIMIT 1`).get(agentId2);
|
|
30773
30811
|
if (mine)
|
|
30774
30812
|
return parseTask(mine);
|
|
30775
30813
|
}
|
|
@@ -30796,7 +30834,7 @@ function getStats() {
|
|
|
30796
30834
|
}
|
|
30797
30835
|
return { by_status, by_priority, by_type, total };
|
|
30798
30836
|
}
|
|
30799
|
-
function deleteTask(taskId,
|
|
30837
|
+
function deleteTask(taskId, agentId2) {
|
|
30800
30838
|
const s = stmts2();
|
|
30801
30839
|
const db = s.db;
|
|
30802
30840
|
const task = getTask(taskId);
|
|
@@ -30813,7 +30851,7 @@ function deleteTask(taskId, agentId) {
|
|
|
30813
30851
|
const doDelete = db.transaction(() => {
|
|
30814
30852
|
logEvent({
|
|
30815
30853
|
task_id: taskId,
|
|
30816
|
-
agent_id:
|
|
30854
|
+
agent_id: agentId2,
|
|
30817
30855
|
event_type: "deleted",
|
|
30818
30856
|
payload: {}
|
|
30819
30857
|
});
|
|
@@ -30837,34 +30875,6 @@ function deleteTask(taskId, agentId) {
|
|
|
30837
30875
|
return { success: true };
|
|
30838
30876
|
}
|
|
30839
30877
|
|
|
30840
|
-
// src/commands/shared.ts
|
|
30841
|
-
function jsonOut(success, data, errorMsg) {
|
|
30842
|
-
console.log(JSON.stringify(success ? { success: true, data } : { success: false, error: errorMsg }, null, 2));
|
|
30843
|
-
}
|
|
30844
|
-
function agentId(flagValue) {
|
|
30845
|
-
return flagValue ?? process.env["AITASKS_AGENT_ID"] ?? null;
|
|
30846
|
-
}
|
|
30847
|
-
function requireAgentId(flagValue, command = "this command") {
|
|
30848
|
-
const id = agentId(flagValue);
|
|
30849
|
-
if (!id) {
|
|
30850
|
-
console.error(` Agent ID required for ${command}.
|
|
30851
|
-
` + ` Use --agent <id> or set AITASKS_AGENT_ID environment variable.`);
|
|
30852
|
-
process.exit(1);
|
|
30853
|
-
}
|
|
30854
|
-
return id;
|
|
30855
|
-
}
|
|
30856
|
-
function isJsonMode(flag) {
|
|
30857
|
-
return flag === true || process.env["AITASKS_JSON"] === "true";
|
|
30858
|
-
}
|
|
30859
|
-
function exitError(msg, json) {
|
|
30860
|
-
if (json) {
|
|
30861
|
-
console.log(JSON.stringify({ success: false, error: msg }, null, 2));
|
|
30862
|
-
} else {
|
|
30863
|
-
console.error(` Error: ${msg}`);
|
|
30864
|
-
}
|
|
30865
|
-
process.exit(1);
|
|
30866
|
-
}
|
|
30867
|
-
|
|
30868
30878
|
// src/commands/create.ts
|
|
30869
30879
|
var createCommand2 = new Command("create").description("Create a new task").option("-t, --title <title>", "Task title").option("-d, --desc <description>", "Task description").option("-a, --ac <criterion>", "Acceptance criterion (repeatable)", collect, []).option("-p, --priority <priority>", "Priority: critical|high|medium|low", "medium").option("--type <type>", "Type: feature|bug|chore|spike", "feature").option("--parent <taskId>", "Parent task ID for subtasks").option("--agent <agentId>", "Agent ID creating this task (or set AITASKS_AGENT_ID)").option("--json", "Output as JSON").action(async (opts) => {
|
|
30870
30880
|
requireInitialized();
|
|
@@ -42919,7 +42929,7 @@ var exportCommand = new Command("export").description("Export all task data").op
|
|
|
42919
42929
|
});
|
|
42920
42930
|
|
|
42921
42931
|
// src/commands/onboard.ts
|
|
42922
|
-
var VERSION =
|
|
42932
|
+
var VERSION = getVersion();
|
|
42923
42933
|
var onboardCommand = new Command("onboard").description("Print or inject agent protocol instructions").option("--append", "Auto-detect and append to CLAUDE.md/AGENTS.md/GEMINI.md").option("--file <path>", "Append to a specific file").option("--json", "Output the instructions as a JSON string").action((opts) => {
|
|
42924
42934
|
const reviewRequired = isInitialized() ? getReviewRequired() : false;
|
|
42925
42935
|
const instructions = getAgentInstructions(VERSION, { reviewRequired });
|
|
@@ -43514,4 +43524,4 @@ program2.parseAsync(process.argv).catch((err) => {
|
|
|
43514
43524
|
process.exit(1);
|
|
43515
43525
|
});
|
|
43516
43526
|
|
|
43517
|
-
//# debugId=
|
|
43527
|
+
//# debugId=624747270A6DB83264756E2164756E21
|