diff --git a/README.md b/README.md index f10a4d0..dd5b375 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,8 @@ imi goal "name" --why "why now" # Create a goal imi task "title" --why "..." # Add a task imi log "direction note" # Log strategic direction imi decide "what" "why" # Log a decision -imi orchestrate --workers 8 -- # Parallel worker loop +imi orchestrate --workers 8 -- # Parallel worker loop (hankweave) +imi orchestrate --workers 4 --cli auto # Auto-detect agent CLI from environment ``` ## The Loop @@ -151,4 +152,21 @@ imi next --agent engineer-b --toon # Agent B claims task 2 (different task) imi next --agent engineer-c --toon # Agent C claims task 3 ``` +Or spin up a parallel worker pool that auto-selects the right CLI for the current environment: + +```bash +imi orchestrate --workers 4 --cli auto +``` + +`--cli auto` detects the running agent environment and routes accordingly: + +| Environment variable | Detected agent | +|---|---| +| `CLAUDE_CODE_SSE_PORT` or `CLAUDE_CODE_ENTRYPOINT` | Claude Code | +| `OPENCODE_SESSION` | OpenCode | +| `GH_COPILOT_SESSION_ID` or `COPILOT_AGENT_SESSION` | GitHub Copilot | +| _(none)_ | hankweave (default) | + +You can also specify the CLI explicitly: `--cli claude`, `--cli opencode`, `--cli codex`, or `--cli hankweave`. + If a task is abandoned, IMI auto-releases it after 30 minutes. The next agent picks it up with full failure context. diff --git a/skills/imi/SKILL.md b/skills/imi/SKILL.md new file mode 100644 index 0000000..1fe9a95 --- /dev/null +++ b/skills/imi/SKILL.md @@ -0,0 +1,87 @@ +--- +name: imi +description: > + Activate when: the project has a .imi/ directory, or the user asks about + what to build, what's next, tasks, goals, decisions, progress, or where we + left off. Always run `imi context` before responding. Install if missing: bunx imi-agent +license: MIT +metadata: + author: ProjectAI00 + version: "3.0" +compatibility: Requires imi CLI. Install: bunx imi-agent +allowed-tools: Bash(imi:*) +--- + +# IMI — Agent Instruction Manual + +IMI is the PM thinking layer between humans and agents. It keeps human intent, direction, and decisions persistent so every session stays aligned without re-briefing. Goals, tasks, decisions, and direction notes live in `.imi/state.db`. + +**The 3 questions IMI must always answer:** +1. What are we building? +2. How is it going? +3. Are we still aligned with intent? + +**Authority order:** Direction notes + decisions → goals → tasks → execution. If work cannot trace to a direction or decision, flag it before doing anything. + +--- + +## ⛔ HARD STOP — before you do anything + +DO NOT: +- `cat`, `grep`, `ls`, or `sqlite3` any file inside `.imi/` +- Use session memory, built-in todos, or conversation history as project state +- Answer any question about project status without first running `imi context` +- Create a goal or task without filling in `why` and `success_signal` +- Execute work that cannot be traced to a goal in the DB + +--- + +## Every session — no exceptions + +```bash +imi context +``` + +Run this before your first response. Every session. No exceptions. Then ask: does the user's request map to a goal in the DB? If you can't point to one, say so before doing anything. + +--- + +## Mode routing + +Detect which mode applies and load the full instructions: + +| Situation | Mode | Load | +|---|---|---| +| User is checking status, making decisions, thinking out loud | **Ops** | `cat ~/.copilot/skills/imi/ops-mode.md` | +| User wants to plan goals, decompose work, write task specs | **Plan** | `cat ~/.copilot/skills/imi/plan-mode.md` | +| User wants to execute a task, do the work | **Execute** | `cat ~/.copilot/skills/imi/execute-mode.md` | +| Writing `imi complete`, `imi fail`, or memory entries | **Voice** | `cat ~/.copilot/skills/imi/ai-voice.md` | + +Load the relevant mode file before proceeding. It contains the full behavioral contract for that mode. + +--- + +## Quick command reference + +```bash +imi context # start every session here +imi think # is this still the right thing to build? +imi plan # full goal + task list +imi decide "what" "why" # log a firm decision +imi log "note" # log a direction, instinct, or observation +imi goal "" "" "" "" "" +imi task "" --why "<reason>" --acceptance-criteria "<done looks like>" --relevant-files "<files>" +imi complete <task_id> "summary" # mark done — never skip this +imi mlesson "what went wrong" # store a lesson after a corrected mistake +imi check # verification state +``` + +--- + +## If imi is not installed + +```bash +bunx imi-agent +``` + +Then re-run `imi context`. diff --git a/tests/integration.sh b/tests/integration.sh index 74ff09a..4504e3b 100755 --- a/tests/integration.sh +++ b/tests/integration.sh @@ -375,6 +375,71 @@ else fail "orchestrate: completion summaries missing" "DB said: $DB_OUT" fi +# ───────────────────────────────────────────────────────────── +# 9D. ORCHESTRATE --cli auto (auto-selection) +# ───────────────────────────────────────────────────────────── +echo "" +echo "── 9D. Orchestrate --cli auto ──────────────────────────" + +run add-goal "Auto-select goal" "Verify --cli auto selects correct agent CLI" +AUTO_GOAL_ID=$(echo "$CMD_OUT" | grep -oE '[a-z0-9]{14,}' | head -1) +if [[ -z "$AUTO_GOAL_ID" ]]; then + db_query "SELECT id FROM goals ORDER BY rowid DESC LIMIT 1;" + AUTO_GOAL_ID="$DB_OUT" +fi + +run add-task "$AUTO_GOAL_ID" "auto-select task 1" "auto worker one" +run add-task "$AUTO_GOAL_ID" "auto-select task 2" "auto worker two" + +# Create a fake 'claude' binary that simply exits 0 (simulates a real agent run). +# $FAKE_BIN_DIR lives inside $TEST_DIR which is removed by the EXIT trap above. +FAKE_BIN_DIR="$TEST_DIR/fake-bin" +mkdir -p "$FAKE_BIN_DIR" +cat > "$FAKE_BIN_DIR/claude" <<'EOF' +#!/usr/bin/env bash +exit 0 +EOF +chmod +x "$FAKE_BIN_DIR/claude" + +# With CLAUDE_CODE_ENTRYPOINT set, --cli auto should select the 'claude' path. +# The resolved command becomes: sh -c 'claude -p "$(cat "$IMI_TASK_CONTEXT_FILE")" ...' +# Our fake claude ignores arguments and exits 0, so wrap auto-completes the task. +CLAUDE_CODE_ENTRYPOINT=1 PATH="$FAKE_BIN_DIR:$PATH" \ + "$IMI_BIN" orchestrate "$AUTO_GOAL_ID" \ + --workers 2 --max-tasks 2 --cli auto --agent-prefix auto-bench --ping-secs 1 --checkpoint-secs 1 \ + 2>&1 && CMD_EXIT=0 || CMD_EXIT=$? +if [[ "$CMD_EXIT" -eq 0 ]]; then + pass "orchestrate --cli auto (CLAUDE_CODE_ENTRYPOINT) exits 0" +else + fail "orchestrate --cli auto (CLAUDE_CODE_ENTRYPOINT) exited $CMD_EXIT" +fi + +db_query "SELECT COUNT(*) FROM tasks WHERE goal_id='$AUTO_GOAL_ID' AND status='done';" +if [[ "$DB_OUT" == "2" ]]; then + pass "orchestrate --cli auto: all tasks completed" +else + fail "orchestrate --cli auto: expected 2 done tasks" "DB said: $DB_OUT" +fi + +# With no agent env vars, --cli auto should fall back to hankweave (imi run). +# Use --max-tasks 0 so no workers are launched — just verifies the flag is accepted. +run add-goal "Auto-select fallback" "Verify --cli auto with no env vars" +AUTO_FB_GOAL_ID=$(echo "$CMD_OUT" | grep -oE '[a-z0-9]{14,}' | head -1) +if [[ -z "$AUTO_FB_GOAL_ID" ]]; then + db_query "SELECT id FROM goals ORDER BY rowid DESC LIMIT 1;" + AUTO_FB_GOAL_ID="$DB_OUT" +fi +( + # Unset all env vars documented in README's auto-detection table. + unset CLAUDE_CODE_SSE_PORT CLAUDE_CODE_ENTRYPOINT OPENCODE_SESSION GH_COPILOT_SESSION_ID COPILOT_AGENT_SESSION + "$IMI_BIN" orchestrate "$AUTO_FB_GOAL_ID" --workers 1 --max-tasks 0 --cli auto +) && CMD_EXIT=0 || CMD_EXIT=$? +if [[ "$CMD_EXIT" -eq 0 ]]; then + pass "orchestrate --cli auto (no env vars fallback) exits 0" +else + fail "orchestrate --cli auto (no env vars fallback) exited $CMD_EXIT" +fi + # ═════════════════════════════════════════════════════════════ # 10. MEMORY ADD + LIST # ═════════════════════════════════════════════════════════════