Add Auto/Review mode toggle and non-interactive runner

- GUI: Auto/Review toggle on TaskDetail and ProjectView
  persisted per-project in localStorage
- Runner: noninteractive param (stdin=DEVNULL, 300s timeout)
  activated by KIN_NONINTERACTIVE=1 env or param
- CLI: --allow-write flag for kin run command
- API: POST /run accepts {allow_write: bool}, sets
  KIN_NONINTERACTIVE=1 and stdin=DEVNULL for subprocess
- Fixes pipeline hanging on interactive claude input (VDOL-002)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gros Frumos 2026-03-15 17:35:08 +02:00
parent 03961500e6
commit e755a19633
8 changed files with 174 additions and 18 deletions

View file

@ -276,8 +276,12 @@ def is_task_running(task_id: str):
return {"running": False}
class TaskRun(BaseModel):
allow_write: bool = False
@app.post("/api/tasks/{task_id}/run")
def run_task(task_id: str):
def run_task(task_id: str, body: TaskRun | None = None):
"""Launch pipeline for a task in background. Returns 202."""
conn = get_conn()
t = models.get_task(conn, task_id)
@ -289,12 +293,22 @@ def run_task(task_id: str):
conn.close()
# Launch kin run in background subprocess
kin_root = Path(__file__).parent.parent
cmd = [sys.executable, "-m", "cli.main", "--db", str(DB_PATH),
"run", task_id]
if body and body.allow_write:
cmd.append("--allow-write")
import os
env = os.environ.copy()
env["KIN_NONINTERACTIVE"] = "1"
try:
proc = subprocess.Popen(
[sys.executable, "-m", "cli.main", "--db", str(DB_PATH),
"run", task_id],
cmd,
cwd=str(kin_root),
stdout=subprocess.DEVNULL,
stdin=subprocess.DEVNULL,
env=env,
)
import logging
logging.getLogger("kin").info(f"Pipeline started for {task_id}, pid={proc.pid}")