aitasks 1.3.2 → 1.3.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.
Files changed (2) hide show
  1. package/dist/index.js +62 -24
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -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.3.2",
1893
+ version: "1.3.3",
1894
1894
  description: "CLI task management tool built for AI agents",
1895
1895
  type: "module",
1896
1896
  bin: {
@@ -29420,17 +29420,22 @@ ${reviewRequired ? `3. Submit for review \u2014 you CANNOT mark done directly:
29420
29420
  \`\`\`bash
29421
29421
  aitasks review TASK-001 --agent $AITASKS_AGENT_ID
29422
29422
  \`\`\`
29423
+ **STOP HERE. Do not run \`aitasks done\` yourself.** The system will block self-approval.
29423
29424
 
29424
- 4. **IMMEDIATELY spawn a review sub-agent** \u2014 do NOT move to other tasks until review resolves.
29425
- The task is still incomplete. The review sub-agent must either:
29426
- - **Approve** (moves task to done):
29427
- \`\`\`bash
29428
- aitasks done TASK-001 --agent <review-agent-id>
29429
- \`\`\`
29430
- - **Reject** (sends task back to in_progress with feedback):
29431
- \`\`\`bash
29432
- aitasks reject TASK-001 --reason "<specific feedback>" --agent <review-agent-id>
29433
- \`\`\`
29425
+ 4. **IMMEDIATELY spawn a review sub-agent with a DIFFERENT agent ID** to inspect the implementation.
29426
+ The review sub-agent must first register itself, then approve or reject:
29427
+ \`\`\`bash
29428
+ # Review sub-agent registers itself
29429
+ aitasks heartbeat --agent <review-agent-id>
29430
+
29431
+ # Approve (moves task to done):
29432
+ aitasks done TASK-001 --agent <review-agent-id>
29433
+
29434
+ # OR reject (sends task back to in_progress with feedback):
29435
+ aitasks reject TASK-001 --reason "<specific feedback>" --agent <review-agent-id>
29436
+ \`\`\`
29437
+ The task is still incomplete until the review agent approves it.
29438
+ **The system will block approval from any agent that has not registered or that submitted the review itself.**
29434
29439
 
29435
29440
  5. If rejected: address the feedback, re-check criteria, and repeat from step 3.
29436
29441
 
@@ -29479,7 +29484,7 @@ aitasks unclaim TASK-001 --agent $AITASKS_AGENT_ID --reason "Blocked on missing
29479
29484
  6. If a task needs splitting, create subtasks BEFORE marking parent done.
29480
29485
  7. Your evidence strings must be concrete and verifiable \u2014 not vague affirmations.
29481
29486
  8. Always provide --desc and at least one --ac when creating a task. Both are required.${reviewRequired ? `
29482
- 9. NEVER move a task to done directly. Always submit for review first with \`aitasks review\`, then IMMEDIATELY spawn a review sub-agent. Do NOT work on other tasks until the review resolves. A task is only complete when its status is \`done\`.` : ""}
29487
+ 9. NEVER move a task to done directly. Always submit for review first with \`aitasks review\`, then IMMEDIATELY spawn a review sub-agent with a DIFFERENT agent ID. Do NOT call \`aitasks done\` yourself after submitting for review \u2014 the system blocks self-approval.` : ""}
29483
29488
 
29484
29489
  ---
29485
29490
 
@@ -30448,16 +30453,43 @@ function completeTask(taskId, agentId) {
30448
30453
  if (unchecked.length > 0) {
30449
30454
  return { task: null, error: "Not all acceptance criteria are verified", unchecked };
30450
30455
  }
30451
- if (getReviewRequired() && task.status !== "review") {
30452
- return {
30453
- task: null,
30454
- error: `Review required: submit this task for review first.
30456
+ if (getReviewRequired()) {
30457
+ if (task.status !== "review") {
30458
+ return {
30459
+ task: null,
30460
+ error: `Review required: submit this task for review first.
30455
30461
  ` + ` 1. aitasks review <taskId> --agent $AITASKS_AGENT_ID
30456
30462
  ` + ` 2. Spawn a review sub-agent to inspect the work
30457
30463
  ` + ` 3. Review agent approves: aitasks done <taskId> --agent <review-agent-id>
30458
30464
  ` + ` Review agent rejects: aitasks reject <taskId> --reason "<feedback>"
30459
30465
  ` + " Tasks cannot be moved to Done without a passing review."
30460
- };
30466
+ };
30467
+ }
30468
+ if (task.assigned_to && task.assigned_to === agentId) {
30469
+ return {
30470
+ task: null,
30471
+ error: `Self-approval blocked: ${agentId} is the implementing agent and cannot approve their own review.
30472
+ ` + ` A separate review sub-agent must run: aitasks done ${taskId} --agent <review-agent-id>`
30473
+ };
30474
+ }
30475
+ const events = getTaskEvents(taskId);
30476
+ const reviewEvent = [...events].reverse().find((e2) => e2.event_type === "review_requested");
30477
+ if (reviewEvent?.agent_id && reviewEvent.agent_id === agentId) {
30478
+ return {
30479
+ task: null,
30480
+ error: `Self-approval blocked: ${agentId} submitted this task for review and cannot also approve it.
30481
+ ` + ` A separate review sub-agent must run: aitasks done ${taskId} --agent <review-agent-id>`
30482
+ };
30483
+ }
30484
+ const knownAgent = db.query(`SELECT id FROM agents WHERE id = ?`).get(agentId);
30485
+ if (!knownAgent) {
30486
+ return {
30487
+ task: null,
30488
+ error: `Unknown review agent: '${agentId}' has not registered with the system.
30489
+ ` + ` A real review sub-agent must register first by running any aitasks command
30490
+ ` + ` (e.g. aitasks heartbeat --agent ${agentId}) before it can approve a review.`
30491
+ };
30492
+ }
30461
30493
  }
30462
30494
  const updated = updateTask(taskId, { status: "done", completed_at: Date.now() });
30463
30495
  logEvent({ task_id: taskId, agent_id: agentId, event_type: "completed", payload: {} });
@@ -41322,10 +41354,10 @@ var reviewCommand = new Command("review").description("Request human review for
41322
41354
  id: taskId,
41323
41355
  success: true,
41324
41356
  status: "review",
41325
- next_action: "REQUIRED: Spawn a review sub-agent immediately. This task is NOT complete until the review agent approves it.",
41357
+ next_action: `REQUIRED: Spawn a review sub-agent immediately with a DIFFERENT agent ID (e.g. review-${taskId.toLowerCase()}). Do NOT call aitasks done yourself \u2014 the system will block self-approval.`,
41326
41358
  review_commands: {
41327
- approve: `aitasks done ${taskId} --agent <review-agent-id>`,
41328
- reject: `aitasks reject ${taskId} --reason "<specific feedback>" --agent <review-agent-id>`
41359
+ approve: `aitasks done ${taskId} --agent review-${taskId.toLowerCase()}`,
41360
+ reject: `aitasks reject ${taskId} --reason "<specific feedback>" --agent review-${taskId.toLowerCase()}`
41329
41361
  }
41330
41362
  });
41331
41363
  } else {
@@ -41340,10 +41372,16 @@ var reviewCommand = new Command("review").description("Request human review for
41340
41372
  console.log(` You MUST ${source_default.bold("immediately spawn a review sub-agent")} to inspect the implementation.`);
41341
41373
  console.log(source_default.dim(" The task remains incomplete until the review agent moves it to done."));
41342
41374
  console.log("");
41375
+ console.log(source_default.yellow(" \u2716 ") + source_default.bold("STOP \u2014 do NOT run `aitasks done` yourself."));
41376
+ console.log(source_default.dim(" The system will block self-approval. A separate agent must do the review."));
41377
+ console.log("");
41343
41378
  console.log(source_default.dim(" Review sub-agent steps:"));
41344
- console.log(source_default.dim(` 1. Examine implementation and verify all acceptance criteria`));
41345
- console.log(source_default.dim(` 2. Approve: aitasks done ${task.id} --agent <review-agent-id>`));
41346
- console.log(source_default.dim(` Reject: aitasks reject ${task.id} --reason "<feedback>" --agent <review-agent-id>`));
41379
+ console.log(source_default.dim(` 1. Spawn a sub-agent with a unique agent ID, e.g. review-${task.id.toLowerCase()}`));
41380
+ console.log(source_default.dim(` 2. Sub-agent registers: aitasks heartbeat --agent review-${task.id.toLowerCase()}`));
41381
+ console.log(source_default.dim(` 3. Sub-agent examines implementation and verifies all acceptance criteria`));
41382
+ console.log(source_default.dim(` 4. Approve: aitasks done ${task.id} --agent review-${task.id.toLowerCase()}`));
41383
+ console.log(source_default.dim(` Reject: aitasks reject ${task.id} --reason "<feedback>" --agent review-${task.id.toLowerCase()}`));
41384
+ console.log(source_default.dim(` The system will reject approval from unregistered or self-approving agents.`));
41347
41385
  } else {
41348
41386
  console.log(source_default.dim(` Approve: aitasks done ${task.id} --agent <review-agent-id>`));
41349
41387
  console.log(source_default.dim(` Reject: aitasks reject ${task.id} --reason "<feedback>"`));
@@ -43280,4 +43318,4 @@ program2.parseAsync(process.argv).catch((err) => {
43280
43318
  process.exit(1);
43281
43319
  });
43282
43320
 
43283
- //# debugId=3AB57D11F115EBBB64756E2164756E21
43321
+ //# debugId=62CCA2B3357C2C9A64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aitasks",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "CLI task management tool built for AI agents",
5
5
  "type": "module",
6
6
  "bin": {