phase: 146_search_tool_scope
Phase 146 final verification pass complete — all green, tree untouched by me.
**Verified (final pass — both tasks already in `complete/`):**
- Scoped grep streams `{"type":"tool","name":"grep","argument":<pattern>,"path":<source/path>}`; bare grep/read/ls frames dump byte-identical (unit matrix in `test_sse_events.py` + builder pins in `test_chat_gate.py` L1364–1448)
- Tool line `🔎 Searching for <pattern> in <source/path>` (two `<code>` spans, `.grep-scope` sibling, no new emoji); bare line byte-identical (unit Node test + E2E)
- Status label "… is searching for X in Y" scoped-only; `path` persisted additively on the saved tool record and re-rendered on `/?chat=<id>` restore; pre-phase records restore byte-identically (E2E tests 2 & 3)
**Results (exact commands):**
- `uv run pytest --cov=app --cov-report=term-missing` → **3419 passed**, `app/` coverage **99%** (>90% ✓)
- `uv run pytest tests/e2e/test_search_tool_scope.py -v --no-cov` → **3 passed** in isolation ✓
- `uv run ruff check . && uv run pyright` → clean (0 errors) ✓
**Completion criteria:** all 6 ✓ (wire shape, UI line, status label, save/restore, gates, no completed-phase behavior change — full suite green includes all prior-phase pins).
**Documentation:** README.md (incl. its phase-146 section) and AGENTS.md reviewed in full against the codebase — verified consistent, no changes needed (`.env.example` ⊆ README config tables; no stale vars; phase-100 72rem rule in AGENTS.md §5 matches shipped CSS; no-CDN/smoke-DB/gpgsign claims all confirmed).
**Notable:** none — no defects found, no live-infrastructure touched, nothing committed per harness protocol.
**Next pending phase:** `147_sync_changed_only`.
This commit is contained in:
@@ -62,7 +62,10 @@ def test_tool_branch_is_a_first_class_turn_branch() -> None:
|
||||
assert "uiState === UI_STATE.thinking" in branch, (
|
||||
"label updates only while the state is still thinking"
|
||||
)
|
||||
assert "appendToolLine(wrap, name, argument, frameOffset, frameLimit)" in branch
|
||||
assert (
|
||||
"appendToolLine(wrap, name, argument, frameOffset, frameLimit, framePath)"
|
||||
in branch
|
||||
)
|
||||
# No setUiState in the branch: the state stays "thinking" (never stale).
|
||||
assert "setUiState" not in branch, (
|
||||
"the tool branch must keep uiState=thinking (button stays disabled)"
|
||||
@@ -98,9 +101,15 @@ def test_calling_tool_label_strings() -> None:
|
||||
"the read status requires the name (new or legacy) AND a string argument"
|
||||
)
|
||||
# The search status — new + legacy name, sitting BETWEEN the read
|
||||
# branch and the listing fallback in the ternary.
|
||||
# branch and the listing fallback in the ternary. Phase 146
|
||||
# (task 02): the label gains the additive scope — `` in <path>``
|
||||
# ONLY when the frame carried one (a bare grep renders the exact
|
||||
# pre-phase label — the template's empty-string fallback).
|
||||
assert 'name === "grep" || name === "search_documents") && argument' in branch
|
||||
assert "`${brand()} is searching for ${argument}`" in branch
|
||||
assert (
|
||||
"`${brand()} is searching for ${argument}"
|
||||
"${framePath ? ` in ${framePath}` : \"\"}`" in branch
|
||||
)
|
||||
# Phase 70: the scoped ls status mirrors the scoped tool line; the
|
||||
# unscoped listing stays the final fallback.
|
||||
assert 'name === "ls" && argument' in branch
|
||||
@@ -227,9 +236,11 @@ def test_tool_lines_re_render_on_restore() -> None:
|
||||
end = js.find("function restoreConversation")
|
||||
body = js[fn:end]
|
||||
assert "Array.isArray(m.tools)" in body
|
||||
assert "appendToolLine(wrap, t.name, arg, tOffset, tLimit)" in body, (
|
||||
"phase 139: the stored range rides the SAME helper — a pre-phase"
|
||||
" record (no fields) renders byte-identical"
|
||||
assert (
|
||||
"appendToolLine(wrap, t.name, arg, tOffset, tLimit, tPath)" in body
|
||||
), (
|
||||
"phase 139: the stored range + the phase-146 stored scope ride the "
|
||||
"SAME helper — a pre-phase record (no fields) renders byte-identical"
|
||||
)
|
||||
thinking_restore = body.find("if (m.thinking)")
|
||||
tools_restore = body.find("Array.isArray(m.tools)")
|
||||
|
||||
Reference in New Issue
Block a user