Muse spark - #108
Muse spark#108
Conversation
Two related charging-accuracy fixes: 1. Charge energy delta baselines now use State() strictly before StartedAt instead of at StartedAt, since Fleet Telemetry can emit the session-start batch after energy has already begun accumulating, causing undercounted energy in both the live handler and the completed-session tracker. 2. New Tesla Supercharger invoice overlay: ChargingHandler.Get resolves the vehicle's VIN and matches it against tesla_charging_history via a new FindBestMatch repo method (closest charge_start_datetime within a 2h window). When a match is found, billed energy/cost/currency/rate are added to the response and preferred for display on the frontend KPI tiles, with vehicle-measured energy shown as a secondary subtitle.
Treat spurious trip-meter resets and implausible counter jumps as discontinuities instead of driven distance. Adds reset/restore cursor logic and tests so include_fields zero snap-backs do not inflate FSD or driving aggregates.
Adds a live Grok powertrain read to Driving Dynamics using motor and chassis signals, with interpretation logic and tests. Also adds shared client-side pagination for FSD insight lists and DataTable-backed FSD tables.
Adds honesty-focused UI across the fleet dashboard, status bar, charging, battery, driving, and FSD views. Surfaces Supercharger bill site/fee metadata, preserves signal ingest timestamps for Tesla physics clocks, paginates physics evidence instead of truncating it, and fixes nav highlighting to prefer the most specific active route.
Add trip selection and date-scoped motor history, preserve active drives, and evenly sample backend history responses across the selected window.
Preserve and backfill charge coordinates without creating geofences from stale GPS, use Tesla billed energy for tariff pricing, and resolve date windows in the vehicle timezone.
Expand the drive detail FSD insights range to look around 24 hours so sparse counter bookends are included, preventing unknown/blank attribution for valid deltas. Adds backend and frontend regression coverage for the wider range behavior.
Adds drive_id support for FSD insights with a 7-day bookend lookup and focused attribution, while filtering negligible fidget drives so they do not steal sparse counter deltas. Updates drive detail and list UI to use the drive-scoped hook and omit unknown FSD badges.
Wire always-on charge autopilot, shared-charger queue planning, OCPP charge points, Tesla bill variance, session share reports, TCO fixed ledger, and related warranty, silence, and trip copilot surfaces. Register new i18n namespaces (autopilot, chargeQueue, ocpp) so the strict namespace audit and Docker web build pass. Fix TypeScript i18n count types, geofence hook typing, and AutomationFull.conflicts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep ChargingDetailPage share-session UI from muse-spark and billed-energy display from main (#104). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add per-vehicle autopilot profiles, TOU-based charge previews, health guardrails, and savings tracking. Integrate the configuration and preview panel into Smart Charge with API and UI tests.
Add next-charge recommendations comparing home TOU costs with Supercharger quotes, surfaced on dashboards and vehicle details. Expand automation, routine, and alert template catalogs with category filtering, localization, and tests.
Adds ecosystem automation presets and routine templates covering more Tesla commands, locations, charging, climate, media, and security scenarios. Updates catalogue tests and alert rule template coverage thresholds for the expanded preset set.
Watches Open-Meteo forecasts at each armed vehicle's home coords and pre-charges before storms: hourly evaluator raises the charge limit on fresh warnings when SOC is below target. Includes status/config/events API, StormGuardPanel on Emergency Resilience, and backend+UI tests.
Polls a per-vehicle ICS subscription, finds the next offsite event in the lead window, and preconditions once per event (5-minute evaluator). Includes next/config/now/runs API, ComfortPanel on Automations, offline refusal for the actuation endpoint, and backend+UI tests.
BuildClaimDraft assembles a ready-to-paste ticket from the owner issue, live warranty countdown, matched TSBs, ranked symptoms, and evidence. New claim-draft endpoint, ClaimDraftPanel on Service Intelligence, and backend+UI tests.
Flags recent drives that fit no named profile and sit far from their cluster centroid (median-adaptive score, deterministic pure function). New GET /driver-attribution/ghost-drives endpoint plus a GhostDrivesPanel on the Driver Attribution page with alert banner, score table, and one-click labelling that re-anchors the cluster.
Predicts queue waits per site and arrival time: hour-of-week demand from tesla_charging_sessions feeds Little's-law load plus an Erlang-C queue model (stalls estimated from peak overlap, documented lower bound). Read-only GET /waitoracle/sites + /forecast; WaitOraclePanel on the fleet sessions page with site/arrival pickers, verdict hero, best-hour suggestion, and the full-day wait curve.
Allow one Tesla 1-mile wire quantum above the physical travel threshold so valid 10-second counter samples are retained, while still rejecting implausible jumps. Add unit and drive analytics regression coverage.
Route new panels through Icons, SI seconds for wait forecasts, queryPolicy/scopedPath on hooks, ICS host allowlist, catalog i18n keys, and useDataState fatalError surfaces. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Slice 1 of Journey Autopilot: persistent journey_sessions (planned/active/paused/completed/aborted, one active per vehicle, race-safe conditional transitions) plus append-only versioned plans for future replan diffs. New /journeys page with session manager: plan form, status filter, lifecycle actions driven by server next_statuses, plan history. Also regenerates routetemplates_gen.go, absorbing 19 previously unregenerated routes so the freshness gate passes.
Refresh the VitePress theme, navigation, landing pages, and onboarding. Add generated screen catalogues, Markdown page tools, and new homepage visuals.
Cap journey list limits at 100 with safe defaults and tests. Localize status labels and inherit theme-aware icon colors.
Add English translations for planned, active, paused, completed, and aborted journey statuses.
Update localized JourneyPanel assertions and align journey namespace ordering in English manifests.
Keep localized journey status tests; take main's trips/journey i18n manifest order. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extract weekly FSD digest logic from the API package, remove unused helpers, document migrations 235–242, clean up translations and lint findings, and refresh gRPC and telemetry dependencies.
Adds package documentation and layer annotations, upgrades gRPC to v1.83.2, and removes an unused React test import.
EmptyState CTA audit now passes with documented no-action comments. Gitleaks policy self-test writes fixtures under the workspace and scans directories so Docker bind-mounts work on self-hosted runners. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move fleet state handler into handler/v1/fleetstate so internal/handler/v1 stays under the max_files ratchet. Waive SharedSessionReport legend toggle. Install Node before CodeQL JS extraction. Refresh Windows visual baselines from the failing Playwright actuals. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename scored-stop unit_price JSON and chargeNeed UI state so the SI-canonical gate stops treating new kWh suffixes as legacy units. Register 000243/000244 in the ops migration manifest. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Check-in, checklist run, and site-sync are already on the panels; the empty copy is informational. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
This PR introduces a “Journey Autopilot” feature set across the web UI and API, adding stop scoring, departure advice, readiness checklist, live trip trail/check-ins (with offline queuing), replans, arrival prep, and trip reporting, plus the supporting storage/migrations and i18n.
Changes:
- Add new journey UI panels (stop scoring, departure, checklist, live, replan, arrival, report, nudge) and wire them into the journey detail view.
- Add backend APIs + domain logic for scoring/ranking, trail checkpoints, checklist runs, departure/nudge advice, arrival prep, and report cards.
- Add DB migrations for checklist runs + trail checkpoints, plus i18n/icon updates and test coverage.
Reviewed changes
Copilot reviewed 59 out of 59 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| web/src/lib/icons.ts | Adds new icons used by new journey panels. |
| web/src/i18n/en/locale-trips.json | Adds English strings for scoring/departure/checklist panels. |
| web/src/i18n/en/locale-detail-toast.json | Adds English toasts for stop scoring and checklist outcomes. |
| web/src/i18n/en.json | Rolls up new i18n keys into the consolidated English bundle. |
| web/src/features/trips/lib/checkInOutbox.ts | Implements localStorage-backed offline check-in outbox. |
| web/src/features/trips/lib/checkInOutbox.test.ts | Adds unit tests for outbox behavior (dedupe, cap, corrupt storage). |
| web/src/features/trips/hooks/useQueuedCheckIn.ts | Adds hook to queue check-ins offline and flush on reconnect. |
| web/src/features/trips/hooks/useQueuedCheckIn.test.tsx | Adds hook harness tests for queueing/flushing behaviors. |
| web/src/features/trips/components/StopScoreTable.tsx | Adds shared scored-stop table used by score + replan UIs. |
| web/src/features/trips/components/StopScorePanel.tsx | Adds UI to pick candidate sites and submit stop scoring. |
| web/src/features/trips/components/StopScorePanel.test.tsx | Adds StopScorePanel behavior tests (submit, error/empty states). |
| web/src/features/trips/components/ReportPanel.tsx | Adds trip report “card” panel UI. |
| web/src/features/trips/components/ReportPanel.test.tsx | Adds ReportPanel behavior tests. |
| web/src/features/trips/components/ReplanPanel.tsx | Adds deviation assessment + one-click replan UI. |
| web/src/features/trips/components/ReplanPanel.test.tsx | Adds ReplanPanel behavior tests. |
| web/src/features/trips/components/NudgePanel.tsx | Adds planned-journey “leave now?” nudge UI. |
| web/src/features/trips/components/NudgePanel.test.tsx | Adds NudgePanel behavior tests. |
| web/src/features/trips/components/LiveTripPanel.tsx | Adds live-trip status + “check in” UI (queued offline). |
| web/src/features/trips/components/LiveTripPanel.test.tsx | Adds LiveTripPanel behavior tests. |
| web/src/features/trips/components/JourneyPanel.tsx | Wires new panels into the journey detail layout. |
| web/src/features/trips/components/JourneyPanel.test.tsx | Expands JourneyPanel test mocks to cover added hooks. |
| web/src/features/trips/components/DeparturePanel.tsx | Adds departure-advice UI panel. |
| web/src/features/trips/components/DeparturePanel.test.tsx | Adds DeparturePanel behavior tests. |
| web/src/features/trips/components/ChecklistPanel.tsx | Adds readiness checklist UI panel with refresh action. |
| web/src/features/trips/components/ChecklistPanel.test.tsx | Adds ChecklistPanel behavior tests. |
| web/src/features/trips/components/ArrivalPanel.tsx | Adds arrival prep UI panel (ETA + energy advice). |
| web/src/features/trips/components/ArrivalPanel.test.tsx | Adds ArrivalPanel behavior tests. |
| ops/migrations/manifest.yaml | Registers migrations for checklist runs and checkpoints. |
| migrations/000244_journey_checkpoints.up.sql | Creates journey_checkpoints table + index for live trail points. |
| migrations/000244_journey_checkpoints.down.sql | Drops journey_checkpoints. |
| migrations/000243_journey_checklist.up.sql | Creates journey_checklist_runs table + index. |
| migrations/000243_journey_checklist.down.sql | Drops journey_checklist_runs. |
| internal/api/stormguard/assess_test.go | Adds tests for per-hour severity grading. |
| internal/api/stormguard/assess.go | Adds HourLevel helper used by departure-slot ranking. |
| internal/api/router.go | Wires new journey endpoints and handler dependencies into router. |
| internal/api/journey/trail.go | Adds checkpoint persistence + trail queries + route learning helpers. |
| internal/api/journey/signals.go | Adds site price/health signal readers for stop scoring. |
| internal/api/journey/score_test.go | Adds tests for stop ranking/scoring logic. |
| internal/api/journey/score.go | Implements stop ranking algorithm + evidence generation. |
| internal/api/journey/runs.go | Implements checklist run persistence + retrieval. |
| internal/api/journey/report_test.go | Adds tests for report computations and handler response. |
| internal/api/journey/report.go | Implements trip report card computations + handler. |
| internal/api/journey/replan.go | Implements deviation assessment + replan rescoring handler. |
| internal/api/journey/nudge_test.go | Adds tests for nudge verdicting and handler behaviors. |
| internal/api/journey/nudge.go | Implements “leave now?” nudge verdicting + handler. |
| internal/api/journey/learn_test.go | Adds tests for route-factor learning logic. |
| internal/api/journey/learn.go | Implements route-factor learning from prior trip legs. |
| internal/api/journey/handler.go | Extends journey handler with stop scoring endpoint + signal gathering. |
| internal/api/journey/departure_test.go | Adds tests for departure slot ranking + handler behaviors. |
| internal/api/journey/departure.go | Implements departure slot ranking and departure advice handler. |
| internal/api/journey/checklist_test.go | Adds tests for checklist evaluation + handler behaviors. |
| internal/api/journey/checklist.go | Implements checklist evaluation + checklist handler. |
| internal/api/journey/arrival_test.go | Adds tests for arrival computations + handler behaviors. |
| internal/api/journey/arrival.go | Implements arrival prep computations + handler. |
Suppressed comments (2)
web/src/features/trips/components/StopScoreTable.tsx:1
- Using
key={line}can produce duplicate keys ifevidencecontains repeated strings, which leads to unstable React reconciliation and warnings. Prefer a guaranteed-unique key (e.g., include the index or another stable identifier such as${row.site}-${index}for this row).
web/src/features/trips/components/JourneyPanel.tsx:1 - The PR description template is still unfilled (no linked issue, no type-of-change selection, checklist unchecked), but the code changes introduce a substantial new feature area (multiple new panels + APIs + migrations). Please update the PR description to summarize the feature slices being shipped and link the relevant issue(s) so reviewers can validate scope and rollout risk.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| func NudgeVerdict(now time.Time, recommended *time.Time, blockers []Item) string { | ||
| if len(blockers) > 0 { | ||
| return NudgeWait | ||
| } | ||
| if recommended == nil { | ||
| return NudgeDelay | ||
| } | ||
| if recommended.After(now.Add(nudgeLate)) { | ||
| return NudgeWait | ||
| } | ||
| return NudgeLeaveNow | ||
| } |
| func latestScoredPlan(plans []*PlanVersion) ([]Candidate, float64, bool) { | ||
| best := -1 | ||
| for i, p := range plans { | ||
| if _, _, ok := savedCandidates(p.Plan); ok && (best < 0 || p.Version > plans[best].Version) { | ||
| best = i | ||
| } | ||
| } | ||
| if best < 0 { | ||
| return nil, 0, false | ||
| } | ||
| return savedCandidates(plans[best].Plan) | ||
| } |
| out = append(out, fmt.Sprintf("%d slots scored, %d warning, %d watch", len(slots), warn, watch)) | ||
| if recommended != nil { | ||
| out = append(out, "earliest calm slot "+recommended.Format("Mon 15:04")) | ||
| } else if len(slots) > 0 { | ||
| out = append(out, "every covered slot warns — delay or ride it out") | ||
| } else { | ||
| out = append(out, "forecast covers none of the window") | ||
| } |
| rows, err := s.db.Pool.Query(ctx, ` | ||
| SELECT | ||
| (SELECT MAX(c.odometer_m) - MIN(c.odometer_m) | ||
| FROM journey_checkpoints c WHERE c.session_id = s.id) AS dist, | ||
| 6371000 * 2 * ASIN(SQRT( | ||
| POWER(SIN(RADIANS(s.dest_lat - s.origin_lat) / 2), 2) + | ||
| COS(RADIANS(s.origin_lat)) * COS(RADIANS(s.dest_lat)) * | ||
| POWER(SIN(RADIANS(s.dest_lng - s.origin_lng) / 2), 2) | ||
| )) AS straight | ||
| FROM journey_sessions s | ||
| WHERE s.vehicle_id = $1 AND s.status = 'completed' | ||
| AND s.origin_lat IS NOT NULL AND s.origin_lng IS NOT NULL | ||
| AND s.dest_lat IS NOT NULL AND s.dest_lng IS NOT NULL | ||
| AND ((s.origin_name = $2 AND s.dest_name = $3) | ||
| OR (s.origin_name = $3 AND s.dest_name = $2)) | ||
| ORDER BY s.ended_at DESC NULLS LAST LIMIT $4`, | ||
| vehicleID, origin, dest, limit) |
| // HourLevel grades one forecast hour with the same thresholds Assess | ||
| // uses over a window: warning for thunder or destructive gusts, watch | ||
| // for heavy precip or strong gusts, else none. Pure: no I/O, | ||
| // deterministic. Journey Autopilot's departure advisor ranks slots | ||
| // through it so both surfaces agree on what "severe" means. |
Wire EmptyState actions for checklist run, live check-in, charging history, and plan-journey instead of audit exemption comments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 60 out of 60 changed files in this pull request and generated 3 comments.
Suppressed comments (3)
web/src/features/trips/components/ChecklistPanel.tsx:1
ITEM_LABEL_KEYS[...]/ITEM_DEFAULTS[...]andSTATUS_LABEL_KEYS[item.status]can evaluate toundefinedat runtime if the API ever returns a new/unknownitem.keyoritem.status. Passingundefinedintot()risks runtime errors and would break the checklist UI for forward-compatible backend changes. Prefer a safe lookup with a fallback (e.g., default to the raw key/status string, or a dedicated “unknown” translation key) before callingt().
web/src/features/trips/components/StopScoreTable.tsx:1- Using
key={line}can produce duplicate React keys if evidence lines repeat (which would cause React reconciliation issues and warnings). Use a stable unique key (e.g., combinelinewith the index, or use an id if available).
web/src/i18n/en/locale-trips.json:1 StopScorePanelreferencest('journey.scoring.openHistory', 'Open charging history'), butjourney.scoring.openHistoryis not present in this locale section. Adding the missing key here (and in the flattenedweb/src/i18n/en.jsonentry) will prevent gaps when/if defaults are removed and ensures translations can be completed for other locales.
| return | ||
| } | ||
| if req.EnergyWh <= 0 || req.EnergyWh > 200000 { | ||
| httpx.WriteError(w, http.StatusBadRequest, "energy_wh must be within 0..200000") |
| journeyStore := apijourney.NewStore(db) | ||
| journeyHandler := apijourney.NewHandler( | ||
| journeyStore, | ||
| journeyStore, | ||
| apiwaitoracle.NewStore(db), | ||
| ) |
| apiwaitoracle.NewStore(db), | ||
| ) |
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 60 out of 60 changed files in this pull request and generated 2 comments.
Suppressed comments (3)
web/src/features/trips/components/ChecklistPanel.tsx:1
- The
run == nullbranch at lines 113–125 is redundant/unreachable given the precedingneverRan || (run == null && !runState.fatalError)andrunState.fatalErrorbranches, and it duplicates the same EmptyState UI. Simplify the conditional to a single empty-state branch to reduce complexity and future drift.
web/src/features/trips/components/StopScoreTable.tsx:1 - Using
key={line}can produce duplicate keys when evidence lines repeat, which can cause React reconciliation issues and warnings. Use a stable unique key (e.g., include an index or a composite like${row.site}-${idx}) for the mapped evidence rows.
ops/migrations/manifest.yaml:1 - The PR description still contains placeholders (e.g.,
Closes #and unchecked change-type/checklist items), but the changes introduce new user-facing features plus migrations and new API routes. Please update the PR description to explicitly state the feature scope and link the relevant issue(s) so reviewers/operators understand rollout and impact.
| return | ||
| } | ||
| if req.EnergyWh <= 0 || req.EnergyWh > 200000 { | ||
| httpx.WriteError(w, http.StatusBadRequest, "energy_wh must be within 0..200000") |
| var exists bool | ||
| if err := s.db.Pool.QueryRow(ctx, | ||
| `SELECT EXISTS(SELECT 1 FROM journey_sessions WHERE id = $1)`, sessionID).Scan(&exists); err != nil { | ||
| return nil, fmt.Errorf("journey: checklist session check: %w", err) | ||
| } | ||
| if !exists { | ||
| return nil, ErrNoSession | ||
| } | ||
| run := &Run{} | ||
| var stored json.RawMessage | ||
| if err := s.db.Pool.QueryRow(ctx, ` | ||
| INSERT INTO journey_checklist_runs (session_id, items) | ||
| VALUES ($1, $2) | ||
| RETURNING id, session_id, run_at, items`, sessionID, string(raw), | ||
| ).Scan(&run.ID, &run.SessionID, &run.RunAt, &stored); err != nil { |
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Copilot reviewed 60 out of 60 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
web/src/features/trips/components/JourneyPanel.tsx:1
- When
detailState.fatalErroris set anddetailis null (the typical error state), this renders the EmptyState instead ofQueryErrorbecause theselectedId == null || detail == nullbranch matches first. Reorder the conditions sodetailState.fatalErroris checked before the empty-state branch (or include!detailState.fatalErrorin the empty-state condition) to ensure errors are surfaced.
web/src/features/trips/components/ChecklistPanel.tsx:1 - The
run == nullbranch at lines 113–124 is unreachable because the earlierneverRan || (run == null && !runState.fatalError)branch already covers therun == null && !fatalErrorcase, and therunState.fatalErrorbranch handles the remaining case. Removing the duplicate EmptyState (or simplifying the conditional chain) will reduce dead code and make the render logic easier to reason about.
web/src/features/trips/components/StopScoreTable.tsx:1 - Using
key={line}can cause React key collisions ifevidencecontains duplicate strings (which is plausible for repeated/templated evidence lines). Prefer a stable unique key (e.g., include the index or combine withrow.site) to avoid rendering bugs/warnings.
web/src/features/trips/components/ReportPanel.tsx:1 - Same issue as other evidence lists:
key={line}can collide when evidence strings repeat. Use a unique key (e.g., index or${index}-${line}) to prevent duplicate-key warnings and potential mis-renders.
| return | ||
| } | ||
| if req.EnergyWh <= 0 || req.EnergyWh > 200000 { | ||
| httpx.WriteError(w, http.StatusBadRequest, "energy_wh must be within 0..200000") |
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
Description
Closes #
Type of Change
Checklist
Screenshots (if applicable)