diff --git a/README.md b/README.md index cf868b2..616898c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,32 @@ npm install ## Quick start +### Installed as a submodule (recommended) + +The launcher resolves the git root of the current directory, installs +`node_modules` on first use, and picks up `/.kilocode-loop/goal.json` when +no goal is passed: + ```bash +# from anywhere inside the repo (or a submodule — it scopes to that repo) +tools/kilocode-loop/kilo-loop # uses .kilocode-loop/goal.json, 5 iterations +tools/kilocode-loop/kilo-loop -n 3 # override the iteration count +tools/kilocode-loop/kilo-loop --goal plans/another-goal.md +tools/kilocode-loop/kilo-loop --dry-run # offline rehearsal + +# same command from anywhere, once the launcher is on PATH +kilo-loop --goal plans/another-goal.md -n 5 +``` + +Per-repo defaults live in `/.kilocode-loop/config.json` (agent, iterations, +session mode, HITL, port, context threshold). The goal lives in +`/.kilocode-loop/goal.json` — edit it, or point `--goal` somewhere else. + +### Standalone + +```bash +npm install + # Real run: 5 iterations of the code-design agent against ./your-repo node bin/kilocode-loop.mjs \ --goal /path/to/your-repo/.kilocode-loop/goal.json \ diff --git a/kilo-loop b/kilo-loop new file mode 100755 index 0000000..4ed7ab0 --- /dev/null +++ b/kilo-loop @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# kilocode-loop launcher — run from anywhere inside a git repo. +# +# kilo-loop --goal .kilocode-loop/goal.json -n 5 +# kilo-loop # uses /.kilocode-loop/goal.json +# kilo-loop --dry-run -n 3 # offline rehearsal +# +# Installs node_modules on first use, then runs the loop with the repo root as +# --project. Every argument is forwarded to bin/kilocode-loop.mjs. +set -euo pipefail + +APP_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)" + +# Project = git root of the current directory (submodules resolve to themselves). +ROOT="$(git -C "$PWD" rev-parse --show-toplevel 2>/dev/null || printf '%s' "$PWD")" + +if [ ! -d "$APP_DIR/node_modules" ]; then + echo "[kilo-loop] installing dependencies in $APP_DIR ..." >&2 + (cd "$APP_DIR" && npm install --no-audit --no-fund >&2) +fi + +# Use the repo's default goal when the caller did not pass one. +has_goal=0 +for arg in "$@"; do + case "$arg" in + --goal | --goal=* | --goal-text | --goal-text=* | --help | -h) has_goal=1 ;; + esac +done + +# Prefer /.kilocode-loop/goal.json; fall back to the superproject's goal +# so the command also works from inside a submodule (e.g. w4c-workflows-api). +goal_file="" +if [ -f "$ROOT/.kilocode-loop/goal.json" ]; then + goal_file="$ROOT/.kilocode-loop/goal.json" +else + super="$(git -C "$ROOT" rev-parse --show-superproject-working-tree 2>/dev/null || true)" + if [ -n "${super:-}" ] && [ -f "$super/.kilocode-loop/goal.json" ]; then + goal_file="$super/.kilocode-loop/goal.json" + fi +fi + +default_goal=() +if [ "$has_goal" -eq 0 ] && [ -n "$goal_file" ]; then + default_goal=(--goal "$goal_file") +fi + +exec node "$APP_DIR/bin/kilocode-loop.mjs" --project "$ROOT" \ + ${default_goal[@]+"${default_goal[@]}"} "$@" diff --git a/package.json b/package.json index 6a4dbd1..4bdfc44 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "type": "module", "description": "Goal-driven autonomous loop runner for the Kilo CLI, with a live Express dashboard, per-iteration reports and human-in-the-loop control.", "bin": { + "kilo-loop": "./kilo-loop", "kilocode-loop": "./bin/kilocode-loop.mjs" }, "engines": { @@ -12,6 +13,7 @@ }, "scripts": { "start": "node bin/kilocode-loop.mjs", + "loop": "node bin/kilocode-loop.mjs", "dry": "node bin/kilocode-loop.mjs --dry-run --goal examples/goal.example.json --iterations 5 --port 7999", "test": "node --test test/*.test.mjs" },