Skip to content

feat(spec): project steering UI + cecli scan/scaffold (dev-integration)#6

Open
JessicaMulein wants to merge 64 commits into
mainfrom
dev-integration
Open

feat(spec): project steering UI + cecli scan/scaffold (dev-integration)#6
JessicaMulein wants to merge 64 commits into
mainfrom
dev-integration

Conversation

@JessicaMulein

Copy link
Copy Markdown
Member

Summary

  • Project steering discoverability (Kiro parity): Tasks + Spec tabs show SteeringFilesHint — Active/Missing status, Open STEERING.md, Create template (desktop editor).
  • Engine (cecli pr/spec-development @ efe29d0ed): scan_steering_files / scaffold_steering_files + bright-vision-tasks steering scan|scaffold.
  • Vision HTTP: GET/POST …/workspaces/steering-files (+ scaffold); vision-client helpers; tests/core/test_http_steering_files.py.
  • Test gates: steering HTTP in yarn verify:ears + yarn test:bright-core; yarn test:lab in yarn dogfood:check; mocked e2e e2e/tasks-steering.spec.ts.

Latest commit: f3972c6. This branch also carries the E7 cecli spec lift (d7b49fa / #55) and related dogfood/e2e fixes already on dev-integration.

Test plan

  • yarn verify:ears (155 passed)
  • yarn test:lab (36 passed)
  • yarn test:fast (351 passed)
  • yarn test:e2e e2e/tasks-steering.spec.ts (2 passed)
  • yarn verify:cecli-spec (143 passed)
  • yarn test:everything or Test Lab full suite (optional; needs Ollama)

Made with Cursor

JessicaMulein and others added 30 commits June 3, 2026 11:57
Submodule at 91540f39d (cherry-picked from pr/multi-repo-context):
path: projects, .cecli.workspaces.yml walk-up, tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…e split

- Open-project gate (#50): vision-current-project, ProjectBar, e2e helpers
- Multi-repo (#48 partial): .cecli.workspaces.yml, Vision API, Settings UI
- Tasks aligned with open project (#49); workspace path utils
- brightdate-python submodule; turn metrics; test-lab timing updates

Co-authored-by: Cursor <cursoragent@cursor.com>
Submodule includes multi-repo workspaces (91540f39d) and
UpdateTodoList normalize_json_array (5c79f96b5).

Co-authored-by: Cursor <cursoragent@cursor.com>
Submodule at 6974c2e58: rebased local multi-repo workspaces and
UpdateTodoList JSON hardening for integration testing.

Co-authored-by: Cursor <cursoragent@cursor.com>
Route POST /sessions through Tauri/reqwest so WebKit fetch no longer fails
with "Load failed", and harden engine spawn: wait for health, kill stale
:8741 listeners, resolve install root from the binary, and align Settings
paths when the repo lives under both /Users and /Volumes.

Co-authored-by: Cursor <cursoragent@cursor.com>
… routing

Repair /agent when Tasks prepends checklist context: rebuild slash preproc input,
apply unlimited agent timeout (not VISION_SLASH_PREPROC_TIMEOUT_S), finalize with
prose-shell recovery, auto-confirm, and empty-turn warnings. Route desktop
WebKit POST/SSE through Tauri reqwest; free :8741 on Quit; add agent guard UI,
workspace path filters, and troubleshooting notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Import parse_tool_arguments from cecli.helpers.responses (not helpers.py).
Pin cecli @ 383b6fd8b — Grep format_output hardening for local-model searches.

Co-authored-by: Cursor <cursoragent@cursor.com>
Persist run options, stable ETC anchors, live test progress chips, and copy
step logs once a step leaves pending. Add GPU stall abort, historical GPU
warnings, short-circuit fail-fast, and transcript reveal in Finder. Harden
LLM SSE parsing, block browser opens during suite/LLM runs, and fix e2e
helpers plus Ollama warmup for llm:core.

Co-authored-by: Cursor <cursoragent@cursor.com>
Show a lightning bolt for steps aborted by short-circuit, document Jun 2026
Test Lab ship notes in ROADMAP #46, and target spec-layer tabs in the wizard
e2e so Tasks nav no longer steals Playwright clicks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a two-row progress header with live step elapsed time and start stamp,
step-type chip icons, and Run ETC ordering fix. Speed up activate.sh for
lab/vision launchers, fix agent done on continuation turns, and resolve
E2E_PYTHON absolutely in suite steps and e2e helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: cecli (ollama_chat/qwen3.6:27b-q4_K_M)
Co-authored-by: cecli (ollama_chat/qwen2.5-coder:7b)
…d fix.

Test Lab gains suite resume, Playwright line-reporter sub-step tracking (without
pytest START noise), and orchestrator/runner reliability. Chat improves user
message rendering, Cmd+F find, and applied-edit chips when turn timing is absent.
E2E LLM specs tolerate long slash-command turns; SSE client guards null events.
Venv launchers use ensure-venv + pytest import probe so verify:ears and Lab steps
self-heal. Pin cecli @39085bc (gitignore path resolve for superproject /add).

Co-authored-by: Cursor <cursoragent@cursor.com>
Add explore-and-deepen spec generation (#53), spec job debug endpoints/chips,
token-limit auto-continue, spec wizard UX fixes, chat activity overlay and slash
completion, and PEP 440 git-describe for pip install -e . (v0.2.1-bright5).

Co-authored-by: Cursor <cursoragent@cursor.com>
Expose configurable spec-generation wall/turn timeouts in Settings and Tasks.
Lean spec-focus inject on implement turns (/agent, truncated design) to avoid
re-sending full specs every message. Auto-continue /agent after stalled
exploration (empty Ollama, repetition on read tools) and block spurious local
token-limit auto-continue. Pin cecli dev-integration (EditText LIST_PARAMS +
ReadRange empty-file hint); document upstream PR workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
…v0.100.5

Pin cecli at f2ad1c75c (validation pipeline + ReadRange hint, add.py staging,
repomap path resolve). Chat groups tool call/args/range/result into cards with
error highlighting. Document fork rebuild in CECLI_UPSTREAM_PR.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Cecli v0.100.5 FileSystemService calls these on the repo facade; superproject
workspaces (e.g. brightdate-rust) use bright_vision_core.RepoSet and failed
POST /sessions with 400 until these methods were implemented.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Document `brew trust --cask digital-defiance/tap/brightvision` for Homebrew
4.6+. Drop stray `>>>>>>> Stashed changes` line from the architecture table.

Co-authored-by: Cursor <cursoragent@cursor.com>
Ground implement/resume turns with lib/test snapshots and flutter test
verification; abort ls/repetition/read-range dead ends; default heavy
keep_alive to -1 so router models stay loaded between agent LLM calls.
Pin cecli dev-integration (ReadRange int marker coerce).

Co-authored-by: Cursor <cursoragent@cursor.com>
Add fast/code/think routing with per-hopper think toggles and LiteLLM extra_params, env-driven tier defaults, and SSE model_route snapshots. Replace the system router chip with a colored left edge on assistant replies (with inherited route across tool breaks), fix post-tool stream deduplication, and align Settings hopper UI and tests/docs for release.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ntract

Pin cecli submodule to a653ce9f0 (dev-integration), which carries the
Kiro-style agent prompt rewrite + explicit edit contract and the
{final_reminders}/sub-agent-inheritance fixes (upstream PR cecli-dev/cecli#566).

Adds the BrightVision-side prompt-quality eval harness:
- bright_vision_core/agent_eval.py: objective behavioral scorer reusing the
  agent_turn.py signal parsers (edit failures, ReadRange-before-edit, ls-spam,
  token limit, rounds) + tests/core/test_agent_eval.py.
- bright_vision_core/agent_judge.py: opt-in LLM-as-judge rubric (scope,
  directness, investigation, summary quality) with robust JSON parsing +
  tests/core/test_agent_judge.py.
- tests/core/test_agent_prompt_eval.py + 'eval:prompts' script: real-Ollama
  behavioral eval scoring one scoped edit turn (E2E_LLM, BV_PROMPT_JUDGE).
- docs: ROADMAP #54, TESTING 'Measuring prompt quality' section; .gitignore for
  the regenerated eval workspace.
… prioritizing thinking models and ensures that thinking configurations are not overridden by stale `localStorage` values. It also includes improvements to specification documentation and E2E test reliability.

**1. Model Router Enhancements (`bright_vision_core/model_router.py`)**

- **Think Model Preference:** Added `prefer_think` configuration to `ModelRouterConfig` and logic to determine this preference based on pool configuration (`pool_prefers_think`).
- **Env Var Overrides:** Added functions (`_parse_env_bool`, `_read_local_llm_env_bool`, `_apply_env_think_to_pool`) to force `CODE_THINK` and `FAST_THINK` settings from local environment files, bypassing potentially stale frontend settings.
- **Classification Logic:** Updated `classify_prompt` to prioritize "think" models for non-tool turns when `prefer_think` is active, while continuing to enforce the use of "code" models for tool-use turns (agent commands, `/agent` slash command).

**2. Specification Documentation (`bright_vision_core/spec_layers.py`, `bright_vision_core/todo_spec_generate.py`)**

- **Improved Guidance:** Updated `todo_spec_generate.py` with more rigorous, professional guidelines for requirements, design, and task generation. It now emphasizes completeness, concrete examples, and adherence to specific section structures.
- **Assessment Rigor:** Increased the threshold in `assess_spec_richness` for requiring more detailed requirements and acceptance criteria.

**3. E2E Testing Improvements**

- **Ollama Warmup:** Added a new global setup script (`e2e/global-llm-setup.ts`) to pre-warm Ollama models before test suites, preventing cold-start stalls that caused test failures.
- **Resilient Assertions:** Updated E2E helpers (`e2e/helpers/llmChat.ts`, `e2e/agent-llm.spec.ts`) to use a more flexible `expectLatestAssistantSettled` approach, allowing for minor variations in model responses (like paraphrasing) rather than enforcing exact string matches.
- **Environment Cleanup:** Added `clearLlmE2eWorkspaceTodos` to ensure tests start with a clean workspace, preventing auto-injected task specs from interfering with router tier assertions.
JessicaMulein and others added 8 commits June 12, 2026 16:08
…ve session

lifecycleActive includes isRunning, so the mismatch banner disabled Stop & Start whenever a session was running. Use isSessionRestartInFlight for the banner and reset process state when Start fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
Cherry-pick 3a84e9f37 (upstream PR cecli-dev/cecli#573). Tool cards show
collapsible output for all tools with multiple result chunks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wire cecli steering scan/scaffold through Vision HTTP, vision-client, and a
SteeringFilesHint panel on Tasks + Spec (status, open, create template).
Add mocked e2e, verify:ears/bright-core gates, and yarn test:lab in dogfood-check.
Pin cecli pr/spec-development at efe29d0ed.

Co-authored-by: Cursor <cursoragent@cursor.com>
@typo-app

typo-app Bot commented Jun 15, 2026

Copy link
Copy Markdown

Your Typo free trial has ended. To continue receiving code reviews, please ask your admin to upgrade to a paid plan.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 293 files, which is 143 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6fe92dc3-7d24-4578-8fff-42ab8af6ece8

📥 Commits

Reviewing files that changed from the base of the PR and between 378b904 and 2e32668.

⛔ Files ignored due to path filters (7)
  • .yarn/install-state.gz is excluded by !**/.yarn/**, !**/*.gz
  • apps/test-lab/src-tauri/Cargo.lock is excluded by !**/*.lock
  • apps/test-lab/src/assets/chip-ai.svg is excluded by !**/*.svg
  • apps/test-lab/src/assets/chip-cpu.svg is excluded by !**/*.svg
  • apps/test-lab/src/assets/vision-api.svg is excluded by !**/*.svg
  • docs/bv-lab-remote-screenshot.jpg is excluded by !**/*.jpg
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (293)
  • .github/workflows/core-compat-audit.yml
  • .gitignore
  • .gitmodules
  • .kiro/specs/model-priority-hopper/.config.kiro
  • .kiro/specs/model-priority-hopper/design.md
  • .kiro/specs/model-priority-hopper/requirements.md
  • .kiro/specs/model-priority-hopper/tasks.md
  • .kiro/specs/multiple-llm-manager-support/README.md
  • .kiro/specs/multiple-llm-manager-support/design.md
  • .kiro/specs/multiple-llm-manager-support/requirements.md
  • .kiro/specs/multiple-llm-manager-support/tasks.md
  • .kiro/specs/multiple-llm-managers/README.md
  • .kiro/specs/multiple-llm-managers/design.md
  • .kiro/specs/multiple-llm-managers/requirements.md
  • .kiro/specs/multiple-llm-managers/tasks.md
  • .kiro/theme.ts
  • .pnp.cjs
  • .pnp.loader.mjs
  • .yarnrc.yml
  • AGENTS.md
  • README.md
  • activate.sh
  • apps/lab-remote/.expo/README.md
  • apps/lab-remote/.expo/devices.json
  • apps/lab-remote/App.tsx
  • apps/lab-remote/PairingQrScanButton.tsx
  • apps/lab-remote/README.md
  • apps/lab-remote/app.json
  • apps/lab-remote/babel.config.js
  • apps/lab-remote/index.ts
  • apps/lab-remote/metro.config.js
  • apps/lab-remote/package.json
  • apps/lab-remote/tsconfig.json
  • apps/lab-remote/useLabRunProgress.ts
  • apps/remote/App.tsx
  • apps/remote/README.md
  • apps/remote/RemoteChatPanel.tsx
  • apps/remote/app.json
  • apps/remote/babel.config.js
  • apps/remote/metro.config.js
  • apps/remote/package.json
  • apps/remote/useRemoteSession.ts
  • apps/test-lab/README.md
  • apps/test-lab/package.json
  • apps/test-lab/src-tauri/Cargo.toml
  • apps/test-lab/src-tauri/src/lan_lab_remote.rs
  • apps/test-lab/src-tauri/src/main.rs
  • apps/test-lab/src/App.tsx
  • apps/test-lab/src/LabRemoteSettings.tsx
  • apps/test-lab/src/StepLogPanel.tsx
  • apps/test-lab/src/StepMetaChips.tsx
  • apps/test-lab/src/SubstepStatusLines.tsx
  • apps/test-lab/src/SuiteProgressTable.tsx
  • apps/test-lab/src/brightdateTiming.ts
  • apps/test-lab/src/labRemotePrefs.ts
  • apps/test-lab/src/pytestSubstepTracker.ts
  • apps/test-lab/src/stepChipIcons.tsx
  • apps/test-lab/src/stepTiming.test.ts
  • apps/test-lab/src/stepTiming.ts
  • apps/test-lab/src/substepDisplay.ts
  • apps/test-lab/src/suiteResume.test.ts
  • apps/test-lab/src/suiteResume.ts
  • apps/test-lab/src/testLabPrefs.ts
  • apps/test-lab/src/testProgressParser.ts
  • apps/test-lab/src/testSuiteClient.ts
  • apps/test-lab/src/vite-env.d.ts
  • bright_vision_core/agent_eval.py
  • bright_vision_core/agent_judge.py
  • bright_vision_core/agent_todos.py
  • bright_vision_core/agent_turn.py
  • bright_vision_core/brightdate.py
  • bright_vision_core/cli_tasks.py
  • bright_vision_core/ears/__init__.py
  • bright_vision_core/ears/index.py
  • bright_vision_core/ears/lint.py
  • bright_vision_core/ears/model.py
  • bright_vision_core/ears/parse.py
  • bright_vision_core/ears/patterns.py
  • bright_vision_core/ears/prompt.py
  • bright_vision_core/ears/repair.py
  • bright_vision_core/ears/report.py
  • bright_vision_core/ears/trace.py
  • bright_vision_core/event_io.py
  • bright_vision_core/git_workspace.py
  • bright_vision_core/headless_args.py
  • bright_vision_core/hot_reload.py
  • bright_vision_core/http_api.py
  • bright_vision_core/implement_progress.py
  • bright_vision_core/implement_verify.py
  • bright_vision_core/implement_workspace.py
  • bright_vision_core/litellm_extra_params.py
  • bright_vision_core/litellm_ollama_patch.py
  • bright_vision_core/llm_backends/__init__.py
  • bright_vision_core/llm_backends/base.py
  • bright_vision_core/llm_backends/config.py
  • bright_vision_core/llm_backends/llamacpp_client.py
  • bright_vision_core/llm_backends/lmstudio_client.py
  • bright_vision_core/llm_backends/metadata.json
  • bright_vision_core/llm_backends/metadata_resolver.py
  • bright_vision_core/llm_backends/ollama_client.py
  • bright_vision_core/llm_backends/registry.py
  • bright_vision_core/llm_backends/vllm_client.py
  • bright_vision_core/model_router.py
  • bright_vision_core/model_router_apply.py
  • bright_vision_core/session.py
  • bright_vision_core/session_debug.py
  • bright_vision_core/slash_helpers.py
  • bright_vision_core/spec_focus.py
  • bright_vision_core/spec_gen_agent.py
  • bright_vision_core/spec_job_debug.py
  • bright_vision_core/spec_layers.py
  • bright_vision_core/spec_progress.py
  • bright_vision_core/spec_steering.py
  • bright_vision_core/test_suite/brightdate_timing.py
  • bright_vision_core/test_suite/cli.py
  • bright_vision_core/test_suite/gpucap_metrics.py
  • bright_vision_core/test_suite/http.py
  • bright_vision_core/test_suite/jobs.py
  • bright_vision_core/test_suite/local_llm.py
  • bright_vision_core/test_suite/manifest.py
  • bright_vision_core/test_suite/pytest_catalog.py
  • bright_vision_core/test_suite/router_preflight.py
  • bright_vision_core/test_suite/runner.py
  • bright_vision_core/test_suite/timing.py
  • bright_vision_core/test_suite/transcript.py
  • bright_vision_core/test_suite/vision_spawn.py
  • bright_vision_core/todo_markdown.py
  • bright_vision_core/todo_spec_generate.py
  • bright_vision_core/todo_spec_jobs.py
  • bright_vision_core/turn_metrics.py
  • bright_vision_core/vision_runtime.py
  • bright_vision_core/vision_serve.py
  • bright_vision_core/workspace_config.py
  • bright_vision_core/workspace_files.py
  • bright_vision_core/workspace_paths.py
  • bright_vision_core/workspace_todos.py
  • brightdate-python
  • cecli
  • cloud-llm.env.example
  • docs/.cecli.workspaces.example.yml
  • docs/ARCHITECTURE.md
  • docs/BRIGHTDATE_PYTHON.md
  • docs/BUILD_MACOS.md
  • docs/CECLI_PIN.md
  • docs/CECLI_UPSTREAM_PR.md
  • docs/DEVELOPMENT.md
  • docs/DOGFOOD.md
  • docs/EARS_MODULE.md
  • docs/FUNCTIONALITY_CHECKLIST.md
  • docs/IPC.md
  • docs/LOCAL_LLM.md
  • docs/MULTI_REPO.md
  • docs/RELEASE.md
  • docs/ROADMAP.md
  • docs/SPEC_DRIVEN_DEV.md
  • docs/TESTING.md
  • docs/TROUBLESHOOTING.md
  • docs/UPSTREAM_CECLI.md
  • docs/USER_WORKFLOW.md
  • docs/design/OUT_OF_REPO_CONTEXT.md
  • docs/index.html
  • e2e/ROADMAP_COVERAGE.md
  • e2e/SHIPPED_FEATURES.md
  • e2e/agent-llm.spec.ts
  • e2e/chat-ux.spec.ts
  • e2e/fixture-pack
  • e2e/fixtures/README.md
  • e2e/fixtures/hello-workspace/hello-workspace/main.py
  • e2e/fixtures/hello-workspace/hello-world.py
  • e2e/fixtures/hello-workspace/hello.py
  • e2e/fixtures/hello-workspace/src/patchme.ts
  • e2e/fixtures/implement-workspace/README.md
  • e2e/fixtures/implement-workspace/lib/.gitkeep
  • e2e/fixtures/implement-workspace/package.json
  • e2e/fixtures/implement-workspace/src/api/handler.ts
  • e2e/fixtures/implement-workspace/src/auth/service.ts
  • e2e/global-integration-setup.ts
  • e2e/global-llm-setup.ts
  • e2e/hello-llm.spec.ts
  • e2e/helpers/fixtureWorkspaces.ts
  • e2e/helpers/implementBlockPreview.ts
  • e2e/helpers/implementFixture.ts
  • e2e/helpers/implementLlmShared.ts
  • e2e/helpers/implementMessagePreview.ts
  • e2e/helpers/integrationEnv.ts
  • e2e/helpers/integrationSession.ts
  • e2e/helpers/llmChat.ts
  • e2e/helpers/llmEnv.ts
  • e2e/helpers/llmSession.ts
  • e2e/helpers/mockCoreApi.ts
  • e2e/helpers/mockTauri.ts
  • e2e/helpers/openProject.ts
  • e2e/helpers/primeScenarioConfig.ts
  • e2e/helpers/realCoreServer.ts
  • e2e/helpers/scenarios.ts
  • e2e/helpers/session.ts
  • e2e/helpers/specGenerate.ts
  • e2e/helpers/specProgressFixture.ts
  • e2e/helpers/testConfig.ts
  • e2e/helpers/todoAgentFile.ts
  • e2e/implement-auto-advance-llm.spec.ts
  • e2e/implement-llm.spec.ts
  • e2e/implement-progress.spec.ts
  • e2e/implement-resume-llm.spec.ts
  • e2e/implement-workspace.spec.ts
  • e2e/integration/implement-progress.spec.ts
  • e2e/integration/implement-workspace-http.spec.ts
  • e2e/integration/implement-workspace.spec.ts
  • e2e/llm-suite-order.ts
  • e2e/local-llm-backend.spec.ts
  • e2e/model-hopper.spec.ts
  • e2e/model-router-roles.spec.ts
  • e2e/model-router.spec.ts
  • e2e/navigation.spec.ts
  • e2e/ntfy-alerts.spec.ts
  • e2e/open-project.spec.ts
  • e2e/proposed-edits-apply.spec.ts
  • e2e/roadmap-gaps.spec.ts
  • e2e/router-llm.spec.ts
  • e2e/session-lifecycle.spec.ts
  • e2e/settings-config.spec.ts
  • e2e/shipped-scenarios.spec.ts
  • e2e/spec-agent.spec.ts
  • e2e/spec-focus-gating.spec.ts
  • e2e/tasks-generate-spec.spec.ts
  • e2e/tasks-spec-wizard.spec.ts
  • e2e/tasks-steering.spec.ts
  • e2e/tasks-workspace.spec.ts
  • e2e/todo-list-llm.spec.ts
  • local-llm.env.example
  • package.json
  • packages/test-suite-client/package.json
  • packages/test-suite-client/src/client.ts
  • packages/test-suite-client/src/duration.ts
  • packages/test-suite-client/src/index.ts
  • packages/test-suite-client/src/labLanPairing.test.ts
  • packages/test-suite-client/src/labLanPairing.ts
  • packages/test-suite-client/src/pytestSubstepTracker.test.ts
  • packages/test-suite-client/src/pytestSubstepTracker.ts
  • packages/test-suite-client/src/runProgress.test.ts
  • packages/test-suite-client/src/runProgress.ts
  • packages/test-suite-client/src/stepTiming.test.ts
  • packages/test-suite-client/src/stepTiming.ts
  • packages/test-suite-client/src/substepDisplay.test.ts
  • packages/test-suite-client/src/substepDisplay.ts
  • packages/test-suite-client/src/substepManifest.test.ts
  • packages/test-suite-client/src/substepManifest.ts
  • packages/test-suite-client/src/testProgressParser.test.ts
  • packages/test-suite-client/src/testProgressParser.ts
  • packages/test-suite-client/src/types.ts
  • packages/test-suite-client/tsconfig.json
  • packages/test-suite-client/vitest.config.ts
  • packages/vision-client/package.json
  • packages/vision-client/src/brightdateTiming.test.ts
  • packages/vision-client/src/brightdateTiming.ts
  • packages/vision-client/src/events.ts
  • packages/vision-client/src/httpClient.ts
  • packages/vision-client/src/index.ts
  • packages/vision-client/src/networkError.ts
  • packages/vision-client/src/sseIdle.test.ts
  • packages/vision-client/src/sseIdle.ts
  • packages/vision-client/src/todos/steeringTypes.ts
  • packages/vision-client/src/viteEnv.ts
  • packages/vision-client/src/viteEnv.web.ts
  • playwright.config.ts
  • playwright.integration.config.ts
  • playwright.llm.config.ts
  • pyproject.toml
  • scripts/activate-resolve-probe.sh
  • scripts/cecli-open-upstream-pr.sh
  • scripts/dogfood-check.sh
  • scripts/e2e-preview.sh
  • scripts/ensure-venv.sh
  • scripts/git_describe_pep440.sh
  • scripts/init-brightdate-python-submodule.sh
  • scripts/lab.sh
  • scripts/lms-warmup-for-tests.sh
  • scripts/local-llm-warmup-for-tests.sh
  • scripts/ollama-warmup-for-tests.sh
  • scripts/prepare-cecli-upstream-pr.sh
  • scripts/repair-vision-api.sh
  • scripts/verify-activate-resolve.sh
  • scripts/verify-cecli-hopper.sh
  • scripts/verify-cecli-pre-commit.sh
  • scripts/verify-cecli-spec.sh
  • scripts/verify-e2e-fixture-pack.sh
  • scripts/verify-ears.sh
  • scripts/verify_submodule_workspace.py
  • scripts/vision.sh
  • src-tauri/Cargo.toml
  • src-tauri/src/local_llm_config.rs
  • src-tauri/src/local_llm_runtime.rs
  • src-tauri/src/main.rs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review

qodo-code-review Bot commented Jun 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (4) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Verify commands run via shell 📘 Rule violation ⛨ Security
Description
The verify gate extracts verify: strings from tasks_md and executes them via
subprocess.run(..., shell=True) without validation or an allowlist, enabling command injection and
arbitrary code execution in the workspace context. Because verification is enabled by default
(BV_IMPLEMENT_VERIFY) and invoked automatically after steps, LLM-authored or modified tasks_md
can trigger arbitrary shell commands without explicit user intent.
Code

bright_vision_core/implement_verify.py[R133-147]

+        proc = subprocess.run(
+            command,
+            shell=True,
+            cwd=str(Path(workspace).resolve()),
+            capture_output=True,
+            text=True,
+            timeout=timeout_s,
+            check=False,
+        )
+    except subprocess.TimeoutExpired:
+        return False, f"verify command timed out after {int(timeout_s)}s: {command}"
+    except OSError as e:
+        return False, f"verify command failed to start: {e}"
+
+    output = ((proc.stdout or "") + (proc.stderr or "")).strip()
Evidence
Rule 9 requires sanitizing/validating any shell/process input and following allowlist expectations,
but the implementation parses verify: commands out of markdown (tasks_md) and passes the
resulting string to subprocess.run(..., shell=True), which allows arbitrary shell syntax and
metacharacters to be interpreted and executed. Additionally, verification is enabled by default and
the session loop automatically runs the verify path whenever a verify: line is present for the
active step, making this arbitrary shell execution reachable directly from tasks_md content.

AGENTS.md: Sanitize Shell Input and Follow Tauri CSP and Command Allowlists
bright_vision_core/implement_verify.py[62-71]
bright_vision_core/implement_verify.py[122-147]
bright_vision_core/implement_verify.py[35-56]
bright_vision_core/implement_verify.py[122-141]
bright_vision_core/session.py[892-909]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`run_verify_command()` executes a `verify:` command extracted from `tasks_md` using `subprocess.run(..., shell=True)`, and verification is enabled by default. Because the command content is effectively user-controlled (LLM/spec/task markdown) and runs automatically after an implement step when a `verify:` line exists, this creates a command-injection/arbitrary local code execution path.

## Issue Context
Compliance requirements disallow passing unsanitized input into shell/process execution paths and expect validation/sanitization and preferably allowlisting. Here, the verify command is parsed from markdown (`tasks_md`) and executed through a shell (`shell=True`), and the session flow will invoke verification automatically whenever a `verify:` entry exists for the active step.

## Fix Focus Areas
- bright_vision_core/implement_verify.py[35-56]
- bright_vision_core/implement_verify.py[62-71]
- bright_vision_core/implement_verify.py[122-150]
- bright_vision_core/session.py[892-909]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. vision_api_fetch allows arbitrary URLs 📘 Rule violation ⛨ Security
Description
New Tauri commands accept base_url and path from the webview and issue backend reqwest
requests without restricting them to the local Vision API, potentially bypassing CSP expectations
and enabling SSRF-style access if the webview is compromised.
Code

src-tauri/src/main.rs[R730-767]

+async fn vision_api_request_json(
+    method: reqwest::Method,
+    base_url: &str,
+    path: &str,
+    bearer_token: Option<&str>,
+    body: Option<Value>,
+    timeout_secs: u64,
+) -> Result<VisionApiResponse, String> {
+    let base = base_url.trim().trim_end_matches('/');
+    let path = path.trim_start_matches('/');
+    let label = format!("{} /{path}", method);
+    let client = reqwest::Client::builder()
+        .timeout(Duration::from_secs(timeout_secs))
+        .build()
+        .map_err(|e| e.to_string())?;
+    let url = format!("{base}/{path}");
+    let mut req = client.request(method, &url);
+    if body.is_some() {
+        req = req.header("Content-Type", "application/json");
+    }
+    if let Some(payload) = body {
+        req = req.json(&payload);
+    }
+    if let Some(token) = bearer_token {
+        let trimmed = token.trim();
+        if !trimmed.is_empty() {
+            req = req.header("Authorization", format!("Bearer {}", trimmed));
+        }
+    }
+    let res = req.send().await.map_err(|e| format!("{label}: {e}"))?;
+    let status = res.status().as_u16();
+    let text = res.text().await.unwrap_or_default();
+    let body = if text.trim().is_empty() {
+        Value::Null
+    } else {
+        serde_json::from_str(&text).unwrap_or(Value::String(text))
+    };
+    Ok(VisionApiResponse { status, body })
Evidence
Rule 9 requires validating/sanitizing inputs used in shell/command contexts and adhering to Tauri
security controls/allowlist expectations. The backend HTTP proxy behavior is controlled by
base_url/path strings from the webview and is not validated to be 127.0.0.1/localhost or an
approved allowlist.

AGENTS.md: Sanitize Shell Input and Follow Tauri CSP and Command Allowlists
src-tauri/src/main.rs[730-767]
src-tauri/src/main.rs[770-796]
src-tauri/src/main.rs[805-833]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new `vision_api_fetch*` Tauri commands allow the frontend to provide an arbitrary `base_url` (and `path`) that the Rust backend will request using `reqwest`. This can bypass frontend CSP/network constraints and should be constrained to the intended local Vision API target.

## Issue Context
These commands are meant as a workaround for WebKit fetch failures to localhost, but they should not become a generic network proxy.

## Fix Focus Areas
- src-tauri/src/main.rs[730-767]
- src-tauri/src/main.rs[770-796]
- src-tauri/src/main.rs[805-833]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Shell redirect bypass 🐞 Bug ⛨ Security
Description
_UNSAFE_SHELL fails to block common redirection forms like > file and 2>file, but
run_prose_shell_recovery() still executes the command with shell=True. This allows LLM-provided
“read-only” prose shell fences to perform arbitrary file writes (including outside the workspace)
when /agent prose-shell recovery runs.
Code

bright_vision_core/agent_turn.py[R70-74]

+_UNSAFE_SHELL = re.compile(
+    r"[;&`$]|(?<![-\w/])>(?!\s)|\brm\b|\bmv\b|\bsudo\b|"
+    r"(?:^|\s)curl\s+(?:https?://|ftp://)|\bwget\b|\bchmod\b|\bchown\b",
+    re.IGNORECASE,
+)
Evidence
_UNSAFE_SHELL uses >(?!\s), which does not match > file and also misses redirections like
2>file; run_prose_shell_recovery() then runs the command with shell=True. The session runtime
automatically extracts fenced shell from assistant text and calls this recovery runner, so the
bypass is reachable from LLM output.

bright_vision_core/agent_turn.py[58-74]
bright_vision_core/agent_turn.py[290-322]
bright_vision_core/session.py[1016-1042]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The prose-shell recovery path executes assistant-provided shell strings with `shell=True`, but the `_UNSAFE_SHELL` regex does not block typical redirections like `> file` (with whitespace) or `2>file`, enabling file writes despite the intended “read-only” allowlist.

## Issue Context
- `/agent` may output fenced ```bash blocks.
- `Session` calls `run_prose_shell_recovery()` on those extracted commands.
- The allowlist currently permits pipes and fails to reliably reject redirection tokens.

## Fix Focus Areas
- Tighten the safety filter to reject any redirection operators (`>`, `>>`, `<`, `2>`, `&>`, etc.) and other shell metacharacters, OR
- Avoid `shell=True` entirely by parsing argv with `shlex.split()` and executing with `shell=False` (and either remove `|` support or implement safe pipelining without a shell).

- bright_vision_core/agent_turn.py[58-74]
- bright_vision_core/agent_turn.py[290-322]
- bright_vision_core/session.py[1016-1042]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Loopback host mismatch risk 🐞 Bug ☼ Reliability
Description
Defaults switch the Vision API base URL from 127.0.0.1 to localhost in both desktop config and
the shared client, while the server still defaults to binding 127.0.0.1. On systems where
localhost resolves to ::1 first, this can cause intermittent connection failures or delays until
fallback occurs.
Code

src/ipc/config.ts[79]

+  coreApiUrl: 'http://localhost:8741',
Evidence
The desktop and vision-client defaults are now http://localhost:8741, but the server’s default
bind host remains 127.0.0.1, which can be incompatible with IPv6-first localhost resolution on
some machines.

src/ipc/config.ts[67-80]
packages/vision-client/src/httpClient.ts[39-49]
bright_vision_core/vision_serve.py[10-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Client defaults now use `http://localhost:8741` while `vision_serve.py` still defaults to `--host 127.0.0.1`. Depending on resolver/network stack behavior, `localhost` may preferentially resolve to `::1`, causing failures when the server listens only on IPv4.

## Issue Context
This affects out-of-the-box connectivity for users who don’t customize host/URL.

## Fix Focus Areas
- Either revert client defaults back to `127.0.0.1`, OR
- Change server default bind host to `localhost` (or dual-stack bind) so it accepts both IPv4 and IPv6 loopback consistently.

- src/ipc/config.ts[67-80]
- packages/vision-client/src/httpClient.ts[39-49]
- bright_vision_core/vision_serve.py[10-13]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. New deps lack audit notes 📘 Rule violation ⛨ Security
Description
This PR adds multiple npm dependencies (e.g., @dnd-kit/*, @testing-library/*, fast-check,
jsdom) without any evidence in-repo that license permissiveness, bundle-size impact, and security
implications were reviewed.
Code

package.json[R89-91]

+    "@dnd-kit/core": "^6.3.1",
+    "@dnd-kit/sortable": "^10.0.0",
+    "@dnd-kit/utilities": "^3.2.2",
Evidence
Rule 7 requires newly added dependencies to be permissively licensed and audited for size/security
impact. The PR adds several new dependency entries in package.json, but the diff does not include
any accompanying audit record or check.

AGENTS.md: Dependencies Must Use Permissive Licenses and Be Audited for Size and Security
package.json[89-91]
package.json[111-119]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New third-party dependencies were added, but there is no accompanying record/check in the repo demonstrating license permissiveness and basic size/security review.

## Issue Context
Compliance requires auditing new dependencies for permissive licensing and considering size/security impact.

## Fix Focus Areas
- package.json[89-91]
- package.json[111-119]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. SteeringFilesHint missing Cecli credit 📘 Rule violation ≡ Correctness
Description
The new SteeringFilesHint UI copy describes steering injection behavior for spec turns but does
not attribute the capability to Cecli / the BrightVision+Cecli partnership.
Code

src/components/spec/SteeringFilesHint.tsx[R86-98]

+  const summary = snapshot?.has_content
+    ? `${snapshot.file_count} steering file(s) injected on spec-focus / generate-spec turns`
+    : snapshot?.main
+      ? 'STEERING.md is empty — add rules or use Create template'
+      : 'No project steering yet — optional but recommended for spec sessions'
+
+  return (
+    <Box
+      data-testid="steering-files-hint"
+      sx={{
+        px: 1.5,
+        py: 1,
+        borderRadius: 1,
Evidence
Rule 1 requires new/modified user-facing copy that references the agent/system to credit Cecli and
reflect the partnership framing. The SteeringFilesHint summary text explains steering injection on
spec turns but contains no Cecli attribution.

AGENTS.md: User-Facing Copy Must Credit Cecli Partnership
src/components/spec/SteeringFilesHint.tsx[86-98]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New user-facing copy about steering/spec behavior should credit Cecli and reflect the partnership framing (Cecli + BrightVision Vision HTTP layer).

## Issue Context
The compliance checklist requires attribution in newly added/modified user-facing text that references the agent/system.

## Fix Focus Areas
- src/components/spec/SteeringFilesHint.tsx[86-98]
- src/components/spec/SteeringFilesHint.tsx[114-124]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@qodo-code-review

Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: audit

Failed stage: Install brightdate + cecli + bright_vision_core (editable) [❌]

Failed test name: ""

Failure summary:

The action failed during pip install -e of the repository
(file:///home/runner/work/BrightVision/BrightVision) while "Getting requirements to build editable".

The build backend (vcs_versioning) tried to derive the package version from Git metadata in a
shallow checkout and produced a non-PEP-440 version string (11c5e41).
This caused
packaging.version.InvalidVersion: Invalid version: '11c5e41' (raised from packaging/version.py:438
via vcs_versioning/_scm_version.py), aborting the editable build requirements step and exiting with
code 1.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

596:  Downloading wcwidth-0.8.1-py3-none-any.whl (323 kB)
597:  Building wheels for collected packages: cecli-dev
598:  Building editable for cecli-dev (pyproject.toml): started
599:  Building editable for cecli-dev (pyproject.toml): finished with status 'done'
600:  Created wheel for cecli-dev: filename=cecli_dev-0.1.dev1-0.editable-py3-none-any.whl size=14784 sha256=505351c47ec0792ae78699ac4c620776f67e829fd26e96b81b4a2cab2f1aaa3c
601:  Stored in directory: /tmp/pip-ephem-wheel-cache-rxa3a9no/wheels/78/a5/2b/341923abc2cf81fa67f0bf0a88e88d4b021f2f62cedddb0275
602:  Successfully built cecli-dev
603:  Installing collected packages: pyperclip, pydub, ptyprocess, zipp, xxhash, wcwidth, urllib3, uc-micro-py, typing-extensions, truststore, tree-sitter-yaml, tree-sitter-embedded-template, tree-sitter-c-sharp, tree-sitter, tqdm, tomlkit, soupsieve, socksio, sniffio, smmap, shtab, shellingham, rpds-py, regex, rapidfuzz, PyYAML, python-multipart, python-dotenv, pypandoc, pyjwt, pygments, pyflakes, pycparser, pycodestyle, py-cymbal, psutil, propcache, platformdirs, pillow, pexpect, pathspec, packaging, numpy, ngram, multidict, mslex, mdurl, mccabe, MarkupSafe, marisa-trie, json5, json-repair, jiter, importlib_resources, idna, httpx-sse, hf-xet, h11, fsspec, frozenlist, filelock, fastuuid, distro, diskcache, diff-match-patch, configargparse, click, charset_normalizer, certifi, backoff, attrs, annotated-types, annotated-doc, aiohappyeyeballs, yarl, uvicorn, typing-inspection, tree_sitter_languages, tree-sitter-language-pack, scipy, rustworkx, requests, referencing, pydantic-core, prompt_toolkit, oslex, markdown-it-py, linkify-it-py, jinja2, importlib-metadata, httpcore, gitdb, flake8, cffi, beautifulsoup4, anyio, aiosignal, watchfiles, tiktoken, starlette, soundfile, sounddevice, rich, pydantic, mdit-py-plugins, jsonschema-specifications, httpx, GitPython, cryptography, aiohttp, typer, textual, sse-starlette, pydantic-settings, openai, jsonschema, mcp, huggingface-hub, tokenizers, litellm, cecli-dev
604:  Successfully installed GitPython-3.1.50 MarkupSafe-3.0.3 PyYAML-6.0.3 aiohappyeyeballs-2.6.2 aiohttp-3.14.1 aiosignal-1.4.0 annotated-doc-0.0.4 annotated-types-0.7.0 anyio-4.13.0 attrs-26.1.0 backoff-2.2.1 beautifulsoup4-4.15.0 cecli-dev-0.1.dev1 certifi-2026.5.20 cffi-2.0.0 charset_normalizer-3.4.7 click-8.4.1 configargparse-1.7.5 cryptography-49.0.0 diff-match-patch-20241021 diskcache-5.6.3 distro-1.9.0 fastuuid-0.14.0 filelock-3.29.4 flake8-7.3.0 frozenlist-1.8.0 fsspec-2026.4.0 gitdb-4.0.12 h11-0.16.0 hf-xet-1.5.1 httpcore-1.0.9 httpx-0.28.1 httpx-sse-0.4.3 huggingface-hub-1.19.0 idna-3.18 importlib-metadata-8.9.0 importlib_resources-7.1.0 jinja2-3.1.6 jiter-0.15.0 json-repair-0.60.1 json5-0.14.0 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 linkify-it-py-2.1.0 litellm-1.89.0 marisa-trie-1.4.1 markdown-it-py-4.2.0 mccabe-0.7.0 mcp-1.27.2 mdit-py-plugins-0.6.1 mdurl-0.1.2 mslex-1.3.0 multidict-6.7.1 ngram-4.0.3 numpy-2.4.6 openai-2.41.1 oslex-2.0.0 packaging-26.2 pathspec-1.1.1 pexpect-4.9.0 pillow-12.2.0 platformdirs-4.10.0 prompt_toolkit-3.0.52 propcache-0.5.2 psutil-7.2.2 ptyprocess-0.7.0 py-cymbal-0.1.24 pycodestyle-2.14.0 pycparser-3.0 pydantic-2.13.4 pydantic-core-2.46.4 pydantic-settings-2.14.1 pydub-0.25.1 pyflakes-3.4.0 pygments-2.20.0 pyjwt-2.13.0 pypandoc-1.17 pyperclip-1.11.0 python-dotenv-1.2.2 python-multipart-0.0.32 rapidfuzz-3.14.5 referencing-0.37.0 regex-2026.5.9 requests-2.34.2 rich-15.0.0 rpds-py-2026.5.1 rustworkx-0.17.1 scipy-1.17.1 shellingham-1.5.4 shtab-1.8.0 smmap-5.0.3 sniffio-1.3.1 socksio-1.0.0 sounddevice-0.5.5 soundfile-0.14.0 soupsieve-2.8.4 sse-starlette-3.4.4 starlette-1.3.1 textual-8.2.7 tiktoken-0.13.0 tokenizers-0.23.1 tomlkit-0.15.0 tqdm-4.68.2 tree-sitter-0.25.2 tree-sitter-c-sharp-0.23.5 tree-sitter-embedded-template-0.25.0 tree-sitter-language-pack-0.13.0 tree-sitter-yaml-0.7.2 tree_sitter_languages-1.10.2 truststore-0.10.4 typer-0.25.1 typing-extensions-4.15.0 typing-inspection-0.4.2 uc-micro-py-2.0.0 urllib3-2.7.0 uvicorn-0.49.0 watchfiles-1.2.0 wcwidth-0.8.1 xxhash-3.7.0 yarl-1.24.2 zipp-4.1.0
605:  Obtaining file:///home/runner/work/BrightVision/BrightVision
606:  Installing build dependencies: started
607:  Installing build dependencies: finished with status 'done'
608:  Checking if build backend supports build_editable: started
609:  Checking if build backend supports build_editable: finished with status 'done'
610:  Getting requirements to build editable: started
611:  Getting requirements to build editable: finished with status 'error'
612:  error: subprocess-exited-with-error
613:  × Getting requirements to build editable did not run successfully.
614:  │ exit code: 1
615:  ╰─> [95 lines of output]
616:  /tmp/pip-build-env-myvjzs_n/overlay/lib/python3.12/site-packages/vcs_versioning/_backends/_git.py:377: UserWarning: "/home/runner/work/BrightVision/BrightVision" is shallow and may cause errors
617:  pre_parse(wd)
...

695:  return meta(tag=tag, distance=distance, dirty=dirty, node=node, config=config)
696:  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
697:  File "/tmp/pip-build-env-myvjzs_n/overlay/lib/python3.12/site-packages/vcs_versioning/_scm_version.py", line 367, in meta
698:  parsed_version = _parse_tag(tag, preformatted, config)
699:  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
700:  File "/tmp/pip-build-env-myvjzs_n/overlay/lib/python3.12/site-packages/vcs_versioning/_scm_version.py", line 328, in _parse_tag
701:  version = tag_to_version(tag, config)
702:  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
703:  File "/tmp/pip-build-env-myvjzs_n/overlay/lib/python3.12/site-packages/vcs_versioning/_scm_version.py", line 157, in tag_to_version
704:  version = config.version_cls(version_str)
705:  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
706:  File "/tmp/pip-build-env-myvjzs_n/overlay/lib/python3.12/site-packages/packaging/version.py", line 438, in __init__
707:  raise InvalidVersion(f"Invalid version: {version!r}")
708:  packaging.version.InvalidVersion: Invalid version: '11c5e41'
709:  [end of output]
710:  note: This error originates from a subprocess, and is likely not a problem with pip.
711:  ERROR: Failed to build 'file:///home/runner/work/BrightVision/BrightVision' when getting requirements to build editable
712:  ##[error]Process completed with exit code 1.
713:  Post job cleanup.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Spec-driven dev integration: steering UI + steering scan/scaffold API (cecli)
✨ Enhancement 🧪 Tests ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

Walkthroughs

Description
• Add Project steering hint UI (Active/Missing) with Open and Scaffold template actions.
• Expose steering scan/scaffold over Vision HTTP and typed vision-client helpers.
• Pin cecli engine + extend test gates (core/ears/e2e) to cover steering workflows.
Diagram
graph TD
  UI["Desktop UI"] --> Hint["SteeringFilesHint"] --> Client["CoreHttpClient"] --> API["Vision HTTP API"] --> Logic["Steering scan/scaffold"] --> FS[("Workspace .cecli/")]

  subgraph Legend
    direction LR
    _ui["UI"] ~~~ _api(["API/Client"]) ~~~ _fs[("Filesystem")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Desktop-only steering scaffold (no Vision HTTP)
  • ➕ No new API surface area
  • ➕ Potentially less backend maintenance
  • ➖ Doesn't support web/remote apps consistently
  • ➖ Duplicates engine behavior; higher drift risk vs cecli spec implementation
2. Wrap cecli CLI commands from core instead of importing APIs
  • ➕ Treats cecli as a black-box tool
  • ➕ Avoids re-export shims in Python
  • ➖ More brittle (parsing stdout/stderr)
  • ➖ Harder to provide structured responses and stable typing

Recommendation: The chosen approach—Vision HTTP endpoints returning structured scan/scaffold results backed by cecli’s canonical spec implementation—best preserves cross-client parity and avoids duplication. Consider caching scan results later if filesystem scans become hot-path.

Grey Divider

File Changes

Enhancement (6)
SteeringFilesHint.tsx New steering hint banner with scan/scaffold actions +156/-0

New steering hint banner with scan/scaffold actions

• Adds a new MUI component that fetches steering status via CoreHttpClient, shows Active/Missing chips, and supports scaffolding a template plus opening steering files in the desktop editor.

src/components/spec/SteeringFilesHint.tsx


SpecAgentPanel.tsx Show steering hint in Spec tab and extend spec UX hooks +157/-15

Show steering hint in Spec tab and extend spec UX hooks

• Wires SteeringFilesHint into spec sessions and expands props around session/project mismatch, blocked generate-spec reasons, and spec job debug/export hooks.

src/components/spec/SpecAgentPanel.tsx


TodoPanel.tsx Show steering hint in Tasks tab + resume/spec-job controls +300/-65

Show steering hint in Tasks tab + resume/spec-job controls

• Integrates SteeringFilesHint into the Tasks UI and adds new callbacks/props for resume work, recent spec job handling, timeout retry, and steering notifications.

src/components/todos/TodoPanel.tsx


http_api.py Add steering scan/scaffold endpoints and response models +314/-8

Add steering scan/scaffold endpoints and response models

• Introduces SteeringFilesResponse/SteeringScaffoldResponse models and adds GET /workspaces/steering-files plus POST /workspaces/steering-files/scaffold. Also adds test-suite protections to avoid launching browsers during automated runs.

bright_vision_core/http_api.py


steeringTypes.ts Add typed steering scan/scaffold result shapes +16/-0

Add typed steering scan/scaffold result shapes

• Defines TypeScript interfaces for steering file records and scan/scaffold results consumed by UI and client code.

packages/vision-client/src/todos/steeringTypes.ts


httpClient.ts Extend vision-client HTTP types and helpers (incl. steering) +179/-44

Extend vision-client HTTP types and helpers (incl. steering)

• Adds steering-related types/imports and improves network error reporting in health checks. Also updates DEFAULT_VISION_API_BASE to use localhost and adds a helper to fetch spec-job debug payloads.

packages/vision-client/src/httpClient.ts


Refactor (1)
spec_steering.py Re-export steering implementation from cecli.spec +4/-48

Re-export steering implementation from cecli.spec

• Replaces local steering logic with a compatibility shim that re-exports symbols from cecli.spec.steering to keep BrightVision behavior aligned with the engine.

bright_vision_core/spec_steering.py


Tests (2)
test_http_steering_files.py Add unit test for steering scan/scaffold routes +41/-0

Add unit test for steering scan/scaffold routes

• Validates that scan reports missing state in a fresh workspace and scaffold creates .cecli/STEERING.md and returns updated status.

tests/core/test_http_steering_files.py


tasks-steering.spec.ts Add e2e coverage for steering hint in Tasks +27/-0

Add e2e coverage for steering hint in Tasks

• Adds Playwright tests asserting Missing/Active UI states and verifying scaffold toggles status and enables Open STEERING.md.

e2e/tasks-steering.spec.ts


Other (3)
verify-ears.sh Harden venv selection and gate steering HTTP tests +19/-8

Harden venv selection and gate steering HTTP tests

• Prefers repo .venv python, attempts to ensure pytest exists, and expands the verification set to include cecli spec tests and steering HTTP tests.

scripts/verify-ears.sh


package.json Update scripts and test gates for dev-integration +18/-3

Update scripts and test gates for dev-integration

• Adds scripts for cecli spec verification and test-lab runs, expands test:bright-core to include steering-related tests, and adds additional dev dependencies needed by the new UI/test coverage.

package.json


cecli Pin cecli submodule to engine commit with steering support +1/-1

Pin cecli submodule to engine commit with steering support

• Updates cecli submodule SHA to the revision that provides steering scan/scaffold and related spec-driven dev integration commands.

cecli


Grey Divider

Qodo Logo

Comment on lines +133 to +147
proc = subprocess.run(
command,
shell=True,
cwd=str(Path(workspace).resolve()),
capture_output=True,
text=True,
timeout=timeout_s,
check=False,
)
except subprocess.TimeoutExpired:
return False, f"verify command timed out after {int(timeout_s)}s: {command}"
except OSError as e:
return False, f"verify command failed to start: {e}"

output = ((proc.stdout or "") + (proc.stderr or "")).strip()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Verify commands run via shell 📘 Rule violation ⛨ Security

The verify gate extracts verify: strings from tasks_md and executes them via
subprocess.run(..., shell=True) without validation or an allowlist, enabling command injection and
arbitrary code execution in the workspace context. Because verification is enabled by default
(BV_IMPLEMENT_VERIFY) and invoked automatically after steps, LLM-authored or modified tasks_md
can trigger arbitrary shell commands without explicit user intent.
Agent Prompt
## Issue description
`run_verify_command()` executes a `verify:` command extracted from `tasks_md` using `subprocess.run(..., shell=True)`, and verification is enabled by default. Because the command content is effectively user-controlled (LLM/spec/task markdown) and runs automatically after an implement step when a `verify:` line exists, this creates a command-injection/arbitrary local code execution path.

## Issue Context
Compliance requirements disallow passing unsanitized input into shell/process execution paths and expect validation/sanitization and preferably allowlisting. Here, the verify command is parsed from markdown (`tasks_md`) and executed through a shell (`shell=True`), and the session flow will invoke verification automatically whenever a `verify:` entry exists for the active step.

## Fix Focus Areas
- bright_vision_core/implement_verify.py[35-56]
- bright_vision_core/implement_verify.py[62-71]
- bright_vision_core/implement_verify.py[122-150]
- bright_vision_core/session.py[892-909]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src-tauri/src/main.rs
Comment on lines +730 to +767
async fn vision_api_request_json(
method: reqwest::Method,
base_url: &str,
path: &str,
bearer_token: Option<&str>,
body: Option<Value>,
timeout_secs: u64,
) -> Result<VisionApiResponse, String> {
let base = base_url.trim().trim_end_matches('/');
let path = path.trim_start_matches('/');
let label = format!("{} /{path}", method);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(timeout_secs))
.build()
.map_err(|e| e.to_string())?;
let url = format!("{base}/{path}");
let mut req = client.request(method, &url);
if body.is_some() {
req = req.header("Content-Type", "application/json");
}
if let Some(payload) = body {
req = req.json(&payload);
}
if let Some(token) = bearer_token {
let trimmed = token.trim();
if !trimmed.is_empty() {
req = req.header("Authorization", format!("Bearer {}", trimmed));
}
}
let res = req.send().await.map_err(|e| format!("{label}: {e}"))?;
let status = res.status().as_u16();
let text = res.text().await.unwrap_or_default();
let body = if text.trim().is_empty() {
Value::Null
} else {
serde_json::from_str(&text).unwrap_or(Value::String(text))
};
Ok(VisionApiResponse { status, body })

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Vision_api_fetch allows arbitrary urls 📘 Rule violation ⛨ Security

New Tauri commands accept base_url and path from the webview and issue backend reqwest
requests without restricting them to the local Vision API, potentially bypassing CSP expectations
and enabling SSRF-style access if the webview is compromised.
Agent Prompt
## Issue description
The new `vision_api_fetch*` Tauri commands allow the frontend to provide an arbitrary `base_url` (and `path`) that the Rust backend will request using `reqwest`. This can bypass frontend CSP/network constraints and should be constrained to the intended local Vision API target.

## Issue Context
These commands are meant as a workaround for WebKit fetch failures to localhost, but they should not become a generic network proxy.

## Fix Focus Areas
- src-tauri/src/main.rs[730-767]
- src-tauri/src/main.rs[770-796]
- src-tauri/src/main.rs[805-833]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +70 to +74
_UNSAFE_SHELL = re.compile(
r"[;&`$]|(?<![-\w/])>(?!\s)|\brm\b|\bmv\b|\bsudo\b|"
r"(?:^|\s)curl\s+(?:https?://|ftp://)|\bwget\b|\bchmod\b|\bchown\b",
re.IGNORECASE,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

5. Shell redirect bypass 🐞 Bug ⛨ Security

_UNSAFE_SHELL fails to block common redirection forms like > file and 2>file, but
run_prose_shell_recovery() still executes the command with shell=True. This allows LLM-provided
“read-only” prose shell fences to perform arbitrary file writes (including outside the workspace)
when /agent prose-shell recovery runs.
Agent Prompt
## Issue description
The prose-shell recovery path executes assistant-provided shell strings with `shell=True`, but the `_UNSAFE_SHELL` regex does not block typical redirections like `> file` (with whitespace) or `2>file`, enabling file writes despite the intended “read-only” allowlist.

## Issue Context
- `/agent` may output fenced ```bash blocks.
- `Session` calls `run_prose_shell_recovery()` on those extracted commands.
- The allowlist currently permits pipes and fails to reliably reject redirection tokens.

## Fix Focus Areas
- Tighten the safety filter to reject any redirection operators (`>`, `>>`, `<`, `2>`, `&>`, etc.) and other shell metacharacters, OR
- Avoid `shell=True` entirely by parsing argv with `shlex.split()` and executing with `shell=False` (and either remove `|` support or implement safe pipelining without a shell).

- bright_vision_core/agent_turn.py[58-74]
- bright_vision_core/agent_turn.py[290-322]
- bright_vision_core/session.py[1016-1042]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

agentpike and others added 8 commits June 15, 2026 12:41
Add Ollama/vLLM/llama.cpp routing (Rust dispatcher, Python registry, UI capabilities), mocked pytest gate, e2e local-llm-backend spec, and a dedicated Test Lab step so backend tests are visible instead of buried in dogfood.

Co-authored-by: Cursor <cursoragent@cursor.com>
Move pool/classify/apply-route into cecli (65 unit tests, yarn verify:cecli-hopper), thin bright_vision_core re-exports with preload hooks, Test Lab verify:cecli-hopper step, and dev-integration cecli pin.

Co-authored-by: Cursor <cursoragent@cursor.com>
… #577

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
dev-integration cecli lost cecli.spec.progress after hopper cherry-picks;
restore from pr/spec-development. Pre-commit script checks out PR branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
Bump cecli to 3769282b6 (cherry-picks for upstream #574 and #577).

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
All LM Studio load paths use load_with_options directly (persistent or
TTL for router hopper); the thin load helper was dead code.

Co-authored-by: Cursor <cursoragent@cursor.com>
agentpike and others added 5 commits June 16, 2026 21:22
Cecli #574 spec implement (checklist paths + resume tasks), #579
ContextManager add→create, #580 reject_yield hook. Session wires yield
guard and code-tier routing for implement/agent; auto-advance requires
EditText. Forward LITELLM_EXTRA_PARAMS from local-llm.env; hopper prefs
on Vision start; resume keeps todo inject id.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ix async_bridge for graceful cancellation

Co-authored-by: cecli (openai/qwen/qwen3.6-35b-a3b)
cecli @ 5b3572ad8 (cherry-pick of pr/spec-development 06c484b14 for #574).

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants