From dae34a497e53579f37fdacce7faf68b85d304785 Mon Sep 17 00:00:00 2001 From: senna-lang Date: Sat, 13 Jun 2026 12:39:08 +0900 Subject: [PATCH 1/2] feat(prime): add IDE-selection trigger for loci context recall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Teach the agent to treat an active IDE editor selection as a deictic anchor ("this / これ") for memory recall. The selection resolves *which* symbol to look up; it does not by itself request a recall. Recall fires only on the conjunction: a selection is active AND either the user asks about the past or the agent's next action on the selected code needs prior decisions. Guards against over-firing on edit-only selections. Selection -> query mapping: named symbol -> `loci context --symbol`; mid-function fragment -> resolve enclosing symbol (LSP/read) first; multi-symbol / non-symbol / empty result -> fall back to `loci search`. Adds PRIME_TEXT contract tests for the new section. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/codeatrium/cli/prime_cmd.py | 31 ++++++++++++++++++++++++++++++ tests/test_prime_cmd.py | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/codeatrium/cli/prime_cmd.py b/src/codeatrium/cli/prime_cmd.py index 52837c6..139d5b3 100644 --- a/src/codeatrium/cli/prime_cmd.py +++ b/src/codeatrium/cli/prime_cmd.py @@ -41,6 +41,37 @@ # Retrieve past conversations from work on a specific branch loci context --branch "feature/foo" --json +``` + +### IDE selection as a deictic anchor + +When the IDE injects an active editor selection (shown as `⧉ Selected N lines from `), treat that selection as the referent of "this / これ / この〜" in the user's prompt. The selection resolves *which* symbol the memory lookup is about — it is NOT by itself a request to recall. + +Recall from a selection ONLY when BOTH hold: + +1. a selection is active, AND +2. either (a) the user asks about the past — recall / why / history / decisions ("この実装の時の会話を思い出して", "これ前にどう決めた?"), or (b) your own next action on the selected code (edit / refactor / debug) needs prior decisions or constraints. + +Do NOT recall when the selection is present only because the user is about to edit it and asks nothing past-oriented. + +Map the selection to a query: + +- Selection IS a named function/class → look it up directly: + +```bash +loci context --symbol "" --json +``` + +- Selection is a fragment INSIDE one function/class — the `def`/`class` line is usually not in the selection, so resolve the enclosing symbol first (LSP `workspaceSymbol`/`hover`, or read `` around the selection), then: + +```bash +loci context --symbol "" --json +``` + +- Selection spans multiple symbols or belongs to none (module-level code, config, comments), OR the lookups above return no results → fall back to semantic search over your question: + +```bash +loci search "" --json ```\ """ diff --git a/tests/test_prime_cmd.py b/tests/test_prime_cmd.py index 3722bb9..b8456f2 100644 --- a/tests/test_prime_cmd.py +++ b/tests/test_prime_cmd.py @@ -44,6 +44,40 @@ def test_prime_text_context_section_explains_bidirectional_recall(): ) +# ---- IDE selection trigger contract ---- + + +def test_prime_text_has_ide_selection_section(): + """PRIME_TEXT must explain IDE selection as a deictic anchor for context recall""" + assert "IDE selection as a deictic anchor" in PRIME_TEXT + + +def test_prime_text_ide_selection_requires_conjunction(): + """A selection alone must NOT trigger recall — requires selection AND a recall need""" + text_lower = PRIME_TEXT.lower() + assert "only when both" in text_lower + # both branches of the recall need must be present + assert "asks about the past" in text_lower + assert "your own next action" in text_lower + + +def test_prime_text_ide_selection_guards_against_over_fire(): + """PRIME_TEXT must tell the agent NOT to recall on edit-only selections""" + assert "Do NOT recall" in PRIME_TEXT + + +def test_prime_text_ide_selection_resolves_enclosing_symbol_for_fragments(): + """A fragment selection must resolve its enclosing symbol before context lookup""" + assert "enclosing symbol" in PRIME_TEXT + + +def test_prime_text_ide_selection_has_search_fallback(): + """When no single symbol applies or context is empty, fall back to loci search""" + text_lower = PRIME_TEXT.lower() + assert "spans multiple symbols" in text_lower + assert "return no results" in text_lower + + # ---- inject_claude_md idempotency ---- From 3c4050651aded582d063441db387897ee41c1d64 Mon Sep 17 00:00:00 2001 From: senna-lang Date: Sat, 13 Jun 2026 12:40:12 +0900 Subject: [PATCH 2/2] build: fall back to uvx ruff in lint/fmt when no venv present The pre-commit hook (make check -> lint) hard-coded .venv/bin/ruff and failed in worktrees without a provisioned venv. Resolve ruff to the venv binary when present, otherwise `uvx ruff`, so lint/fmt work everywhere. Co-Authored-By: Claude Opus 4.8 (1M context) --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d9e7f1e..0100f9d 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,18 @@ VENV := .venv/bin +# ruff: prefer the project venv, fall back to `uvx ruff` when no venv is present +RUFF := $(shell [ -x .venv/bin/ruff ] && echo .venv/bin/ruff || echo "uvx ruff") + .PHONY: test lint fmt typecheck check hooks test: $(VENV)/pytest tests/ -v lint: - $(VENV)/ruff check src/ tests/ + $(RUFF) check src/ tests/ fmt: - $(VENV)/ruff format src/ tests/ + $(RUFF) format src/ tests/ typecheck: $(VENV)/pyright src/