Add follow-up task generation on approve
When approving a task, PM agent analyzes pipeline output and creates
follow-up tasks automatically (e.g. security audit → 8 fix tasks).
core/followup.py:
generate_followups() — collects pipeline output, runs followup agent,
parses JSON task list, creates tasks with parent_task_id linkage.
Handles: bare arrays, {tasks:[...]} wrappers, invalid JSON, empty.
agents/prompts/followup.md — PM prompt for analyzing results and
creating actionable follow-up tasks with priority from severity.
CLI: kin approve <task_id> [--followup] [--decision "text"]
API: POST /api/tasks/{id}/approve {create_followups: true}
Returns {status, decision, followup_tasks: [...]}
Frontend (TaskDetail approve modal):
- Checkbox "Create follow-up tasks" (default ON)
- Loading state during generation
- Results view: list of created tasks with links to /task/:id
ProjectView: tasks show "from VDOL-001" for follow-ups.
13 new tests (followup), 125 total, all passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f7830d484c
commit
9264415776
8 changed files with 426 additions and 17 deletions
40
cli/main.py
40
cli/main.py
|
|
@ -410,6 +410,46 @@ def cost(ctx, period):
|
|||
click.echo(f"\nTotal: ${total:.4f}")
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# approve
|
||||
# ===========================================================================
|
||||
|
||||
@cli.command("approve")
|
||||
@click.argument("task_id")
|
||||
@click.option("--followup", is_flag=True, help="Generate follow-up tasks from pipeline results")
|
||||
@click.option("--decision", "decision_text", default=None, help="Record a decision with this text")
|
||||
@click.pass_context
|
||||
def approve_task(ctx, task_id, followup, decision_text):
|
||||
"""Approve a task (set status=done). Optionally generate follow-ups."""
|
||||
from core.followup import generate_followups
|
||||
|
||||
conn = ctx.obj["conn"]
|
||||
task = models.get_task(conn, task_id)
|
||||
if not task:
|
||||
click.echo(f"Task '{task_id}' not found.", err=True)
|
||||
raise SystemExit(1)
|
||||
|
||||
models.update_task(conn, task_id, status="done")
|
||||
click.echo(f"Approved: {task_id} → done")
|
||||
|
||||
if decision_text:
|
||||
models.add_decision(
|
||||
conn, task["project_id"], "decision", decision_text, decision_text,
|
||||
task_id=task_id,
|
||||
)
|
||||
click.echo(f"Decision recorded.")
|
||||
|
||||
if followup:
|
||||
click.echo("Generating follow-up tasks...")
|
||||
created = generate_followups(conn, task_id)
|
||||
if created:
|
||||
click.echo(f"Created {len(created)} follow-up tasks:")
|
||||
for t in created:
|
||||
click.echo(f" {t['id']}: {t['title']} (pri {t['priority']})")
|
||||
else:
|
||||
click.echo("No follow-up tasks generated.")
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# run
|
||||
# ===========================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue