From e9432f7af7b60db03056438eb60410ee25570678 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 20 May 2026 16:09:41 +0200 Subject: [PATCH 1/2] chore(core): remove leftover auto-continue references The auto-continue feature and clue-collector were removed in ef44374, but stale references survived in docs, config help text, the E2E test script, and TODO. - docs/getting-started.md: drop auto-continue from feature list, steps, table - docs/architecture.md: remove Clue Collection section and tree/test entries - scripts/config.ts: fix stale `autoContinue.mode` example -> validateCommit.mode - scripts/test-hooks.sh: delete 6 tests shelling out to the deleted auto-continue.ts (kept the deny-list sub-agent test) - TODO.md: remove obsolete auto-continue note Backward-compat tests asserting legacy autoContinue keys are ignored are intentionally retained. Co-Authored-By: Claude Opus 4.7 (1M context) --- TODO.md | 1 - dist/bundle/scripts/config.js | 2 +- docs/architecture.md | 42 +----- docs/getting-started.md | 4 +- scripts/config.ts | 2 +- scripts/test-hooks.sh | 265 ---------------------------------- 6 files changed, 4 insertions(+), 312 deletions(-) diff --git a/TODO.md b/TODO.md index 35df3a5..8df759b 100644 --- a/TODO.md +++ b/TODO.md @@ -6,4 +6,3 @@ cjs for auto-engineer <<< look into this http server do not give reminders to validator subagents -do not run auto continue for validator subagents (also otehr lifecycle hooks) diff --git a/dist/bundle/scripts/config.js b/dist/bundle/scripts/config.js index 3bd68eb..a8279d8 100755 --- a/dist/bundle/scripts/config.js +++ b/dist/bundle/scripts/config.js @@ -3845,7 +3845,7 @@ function usage() { Subcommands: show Show all current configuration - set Set a config value (e.g., autoContinue.mode off) + set Set a config value (e.g., validateCommit.mode off) validators List all validators with status validators enable Enable a validator validators disable Disable a validator diff --git a/docs/architecture.md b/docs/architecture.md index a1ebbfa..fb496ff 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -280,44 +280,6 @@ if (subagentType === 'work' && state.validateCommitOnWork) { --- -## Clue Collection - -The clue collector analyzes Claude transcripts for continuation signals. - -``` -transcript.jsonl - │ - ▼ -┌─────────────────────────┐ -│ Parse JSONL lines │ -│ Extract entries │ -└──────────┬──────────────┘ - │ - ├─────────────────────────────────────────┐ - │ │ - ▼ ▼ -┌─────────────────────────┐ ┌─────────────────────────┐ -│ Pattern Detection │ │ Metadata Extraction │ -│ ├─► CONTINUE_PATTERNS │ │ ├─► ketchup-plan paths │ -│ ├─► ketchup mentions │ │ ├─► working directories │ -│ └─► plan mentions │ │ └─► current cwd │ -└──────────┬──────────────┘ └──────────┬──────────────┘ - │ │ - └─────────────┬───────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ ClueCollectorResult │ -│ ├─► clues: Array Detected patterns │ -│ ├─► lastChats: Array Last 5 exchanges │ -│ ├─► ketchupPlanPaths Found plan files │ -│ ├─► workingDirs Detected directories │ -│ └─► summary: string Human-readable summary │ -└─────────────────────────────────────────────────────────────┘ -``` - ---- - ## Directory Structure ### Plugin Structure @@ -335,7 +297,6 @@ ketchup/ │ ├── debug-logger.ts Debug output (internal) │ ├── clean-logs.ts Log cleanup (internal) │ ├── subagent-classifier.ts Task classification (internal) -│ ├── clue-collector.ts Transcript analysis (internal) │ │ │ └── hooks/ │ ├── session-start.ts SessionStart handler @@ -439,8 +400,7 @@ Unit Tests (vitest) ├── Deny-list (load patterns, match files) ├── Hook state (read, write, update) ├── Subagent classifier (patterns, extraction) -├── Path resolver (environment-based resolution) -└── Clue collector (transcript analysis) +└── Path resolver (environment-based resolution) E2E Tests (scripts/test-hooks.sh) ├── Deny-list blocking diff --git a/docs/getting-started.md b/docs/getting-started.md index 0b004b4..12eb842 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -50,7 +50,7 @@ This creates `.ketchup/` with default configuration. Then verify: /ketchup:config show ``` -Ketchup is now active with commit validation, reminders, deny-lists, and auto-continue. +Ketchup is now active with commit validation, reminders, and deny-lists. --- @@ -101,7 +101,6 @@ Start a Claude Code session. The supervisor will: 1. **Inject** your guidelines at session start 2. **Validate** every commit against your rules 3. **ACK** clean commits, **NACK** rule violations -4. **Auto-continue** until the plan is complete --- @@ -148,7 +147,6 @@ You installed Ketchup: | Validators | ACK/NACK every commit via LLM | PreToolUse hooks | | Reminders | Your rules, every session + prompt | SessionStart + prompt | | Deny-list | Structural file protection | PreToolUse deny-list | -| Auto-Continue | Agent keeps working while plan has work | Stop hooks | | TCR gate | `test && commit revert` enforced | TCR Workflow validator | --- diff --git a/scripts/config.ts b/scripts/config.ts index f6210b3..db06501 100644 --- a/scripts/config.ts +++ b/scripts/config.ts @@ -28,7 +28,7 @@ function usage(): string { Subcommands: show Show all current configuration - set Set a config value (e.g., autoContinue.mode off) + set Set a config value (e.g., validateCommit.mode off) validators List all validators with status validators enable Enable a validator validators disable Disable a validator diff --git a/scripts/test-hooks.sh b/scripts/test-hooks.sh index 19a57d4..5f94008 100755 --- a/scripts/test-hooks.sh +++ b/scripts/test-hooks.sh @@ -18,147 +18,6 @@ pass() { echo -e "${GREEN}✓${NC} $1"; ((PASSED++)) || true; } fail() { echo -e "${RED}✗${NC} $1: $2"; ((FAILED++)) || true; } skip() { echo -e "${YELLOW}○${NC} $1 (skipped)"; } -#----------------------------------------------------------- -# Test: auto-continue respects mode=off (no transcript needed) -#----------------------------------------------------------- -test_autocontinue_mode_off() { - local name="auto-continue respects mode=off" - - # Backup current state - local state_file="$PROJECT_ROOT/.claude.hooks.json" - local backup="" - if [[ -f "$state_file" ]]; then - backup=$(cat "$state_file") - fi - - # Set mode to off - echo '{"autoContinue":{"mode":"off"}}' > "$state_file" - - local input='{"session_id":"test-off","permission_mode":"code"}' - - cd "$PROJECT_ROOT" - local output - output=$(echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null) || true - - # Restore state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - - if echo "$output" | grep -q '"decision":"block"'; then - fail "$name" "should not block when mode=off" - else - pass "$name" - fi -} - -#----------------------------------------------------------- -# Test: auto-continue skips plan permission mode -#----------------------------------------------------------- -test_autocontinue_skips_plan_mode() { - local name="auto-continue skips plan permission mode" - - # Backup current state - local state_file="$PROJECT_ROOT/.claude.hooks.json" - local backup="" - if [[ -f "$state_file" ]]; then - backup=$(cat "$state_file") - fi - - # Set mode to smart (but plan mode should be skipped) - echo '{"autoContinue":{"mode":"smart"}}' > "$state_file" - - # permission_mode="plan" should be skipped by default - local input='{"session_id":"test-plan","permission_mode":"plan"}' - - cd "$PROJECT_ROOT" - local output - output=$(echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null) || true - - # Restore state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - - if echo "$output" | grep -q '"decision":"block"'; then - fail "$name" "should skip plan mode" - else - pass "$name" - fi -} - -#----------------------------------------------------------- -# Test: non-stop mode blocks and counts iterations -#----------------------------------------------------------- -test_autocontinue_nonstop_iterations() { - local name="auto-continue non-stop mode counts iterations" - - # Backup current state - local state_file="$PROJECT_ROOT/.claude.hooks.json" - local backup="" - if [[ -f "$state_file" ]]; then - backup=$(cat "$state_file") - fi - - # Set non-stop mode with limit of 2 - echo '{"autoContinue":{"mode":"non-stop","maxIterations":2,"iteration":0}}' > "$state_file" - - local input='{"session_id":"test-nonstop","permission_mode":"code"}' - - cd "$PROJECT_ROOT" - - # First call: should block and increment - local output1 - output1=$(echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null) - - if ! echo "$output1" | grep -q '"decision":"block"'; then - # Restore state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - fail "$name" "iteration 1 should block" - return - fi - - # Second call: should block again - local output2 - output2=$(echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null) - - if ! echo "$output2" | grep -q '"decision":"block"'; then - # Restore state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - fail "$name" "iteration 2 should block" - return - fi - - # Third call: should allow (maxIterations reached) - local output3 - output3=$(echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null) || true - - # Restore state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - - if echo "$output3" | grep -q '"decision":"block"'; then - fail "$name" "iteration 3 should allow (limit reached)" - else - pass "$name" - fi -} - #----------------------------------------------------------- # Test: deny-list denies paths on deny list #----------------------------------------------------------- @@ -329,124 +188,6 @@ test_subagent_inherits_denylist() { fi } -#----------------------------------------------------------- -# Test: sub-agent state modifications persist -#----------------------------------------------------------- -test_subagent_state_persists() { - local name="sub-agent state modifications persist" - - # Backup current state - local state_file="$PROJECT_ROOT/.claude.hooks.json" - local backup="" - if [[ -f "$state_file" ]]; then - backup=$(cat "$state_file") - fi - - # Set initial state with iteration=5 - echo '{"autoContinue":{"mode":"non-stop","maxIterations":10,"iteration":5}}' > "$state_file" - - # Simulate a sub-agent call that would increment iteration - # (non-stop mode increments on each block) - local input='{"session_id":"subagent-test","permission_mode":"code"}' - - cd "$PROJECT_ROOT" - echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null || true - - # Read back the state - iteration should now be 6 - local new_state - new_state=$(cat "$state_file") - - # Restore original state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - - if echo "$new_state" | grep -q '"iteration": 6'; then - pass "$name" - else - fail "$name" "state should persist iteration increment, got: $new_state" - fi -} - -#----------------------------------------------------------- -# Test: sub-agent respects skipModes configuration -#----------------------------------------------------------- -test_subagent_respects_skipmodes() { - local name="sub-agent respects custom skipModes" - - # Backup current state - local state_file="$PROJECT_ROOT/.claude.hooks.json" - local backup="" - if [[ -f "$state_file" ]]; then - backup=$(cat "$state_file") - fi - - # Set mode to non-stop but add "explore" to skipModes - # This simulates skipping auto-continue for explore sub-agents - echo '{"autoContinue":{"mode":"non-stop","skipModes":["plan","explore"]}}' > "$state_file" - - # Simulate a sub-agent with permission_mode="explore" - local input='{"session_id":"explore-agent","permission_mode":"explore"}' - - cd "$PROJECT_ROOT" - local output - output=$(echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null) || true - - # Restore state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - - # Should NOT block because "explore" is in skipModes - if echo "$output" | grep -q '"decision":"block"'; then - fail "$name" "should skip auto-continue for explore permission_mode" - else - pass "$name" - fi -} - -#----------------------------------------------------------- -# Test: sub-agent non-skipped mode still blocks -#----------------------------------------------------------- -test_subagent_nonskipped_blocks() { - local name="sub-agent non-skipped mode blocks correctly" - - # Backup current state - local state_file="$PROJECT_ROOT/.claude.hooks.json" - local backup="" - if [[ -f "$state_file" ]]; then - backup=$(cat "$state_file") - fi - - # Set mode to non-stop with only "plan" in skipModes - echo '{"autoContinue":{"mode":"non-stop","maxIterations":10,"skipModes":["plan"]}}' > "$state_file" - - # Simulate a sub-agent with permission_mode="code" (NOT in skipModes) - local input='{"session_id":"code-agent","permission_mode":"code"}' - - cd "$PROJECT_ROOT" - local output - output=$(echo "$input" | npx tsx "$PROJECT_ROOT/.claude/scripts/auto-continue.ts" 2>/dev/null) || true - - # Restore state - if [[ -n "$backup" ]]; then - echo "$backup" > "$state_file" - else - rm -f "$state_file" - fi - - # SHOULD block because "code" is not in skipModes - if echo "$output" | grep -q '"decision":"block"'; then - pass "$name" - else - fail "$name" "should block for non-skipped permission_mode" - fi -} - #----------------------------------------------------------- # Test: subagent-classifier classifies explore tasks #----------------------------------------------------------- @@ -872,9 +613,6 @@ echo "Running hook E2E tests..." echo "" echo "=== Basic Hook Tests ===" -test_autocontinue_mode_off -test_autocontinue_skips_plan_mode -test_autocontinue_nonstop_iterations test_denylist_denies test_denylist_allows_normal test_prompt_reminder_returns_context @@ -882,9 +620,6 @@ test_prompt_reminder_returns_context echo "" echo "=== Sub-Agent Hook Tests ===" test_subagent_inherits_denylist -test_subagent_state_persists -test_subagent_respects_skipmodes -test_subagent_nonskipped_blocks echo "" echo "=== Sub-Agent Classification Tests ===" From a32bc6558c4e282fe82c1ee8639ce6149a117b43 Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 20 May 2026 16:09:41 +0200 Subject: [PATCH 2/2] chore(global): add changeset --- .changeset/auto-b2febcaa83c70990.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/auto-b2febcaa83c70990.md diff --git a/.changeset/auto-b2febcaa83c70990.md b/.changeset/auto-b2febcaa83c70990.md new file mode 100644 index 0000000..12dd8ec --- /dev/null +++ b/.changeset/auto-b2febcaa83c70990.md @@ -0,0 +1,9 @@ +--- +"ketchup": minor +--- + +- Rebranded the project to Ketchup, renaming the package, plugin, slash commands, data directory (.ketchup), and all documentation +- Switched to plugin-only installation via the marketplace, removing the legacy npx CLI, install/doctor/repair commands, and symlink setup +- Added automatic migration so existing setups upgrade in place, moving the data directory, state file, and deny-list to their new .ketchup locations +- Removed the auto-continue feature in favor of parallel sub-agent planning, with config and docs updated to match +- Added runtime configuration for validators and reminders, plus a config skill and first-setup guidance