feat: add periscope ECC bundle - #8
Closed
ecc-tools[bot] wants to merge 233 commits into
Closed
Conversation
## Summary - Update GitHub Actions: checkout v6.0.2, upload-artifact v6.0.0, download-artifact v7.0.0 - Update npm deps: svelte 5.53.2 (SSR vulnerability fix), vite-plugin-svelte 6.2.4, vite 6.4.1, typescript 5.9.3, svelte-check 4.4.1, @tsconfig/svelte 5.0.8, @tanstack/virtual-core 3.13.18 - Add engines.node constraint for vite-plugin-svelte 6.x minimum - Fix search.test.ts timing for Svelte 5.53.2 reactive system changes Closes #1, closes #2, closes #3, closes #4, closes #5, closes #6, closes #7, closes #8 ## Test plan - [ ] CI passes: Go tests, frontend unit tests, E2E tests, lint, type check - [ ] `npm audit` shows 0 vulnerabilities - [ ] Frontend builds cleanly with vite 6.4.1 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Playwright outputs test-results/ at the repo root when run from there. frontend/test-results/ was already ignored but the root directory was not. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Overhaul session message viewer for readability: system font stack, role icon circles, proportional body text at 14px, darker code blocks, refined tool/thinking blocks - Sync header project filter to analytics dashboard so selecting a project in the top bar filters the dashboard - Highlight selected activity timeline bar instead of re-rendering the chart with a single bar - Fix excessive CPU usage by making the file watcher sync only changed files instead of running full SyncAll with SHA-256 hashing of every file - Fix duplicate fetchAll on analytics page mount and activity timeline staleness ## Test plan - [x] All 304 frontend vitest tests pass (including new analytics tests) - [x] All Go tests pass across all packages (including 5 new SyncPaths tests) - [ ] Manual: verify message viewer readability in light/dark themes - [ ] Manual: verify selecting a project in header updates the analytics dashboard - [ ] Manual: verify clicking a timeline bar highlights it and dims others - [ ] Manual: verify CPU usage is reduced during active file watching 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Align the standalone export HTML template with the current app CSS: - Color palette: warm beige/brown → cool gray/blue-gray (both themes) - Accent purple: gold #b08d24 → actual purple #7c3aed - Font stacks: add JetBrains Mono, match Noto Sans system stack - Code blocks: use dark --code-bg/--code-text instead of --bg-inset - Message styling: 4px border, 14px/1.7 prose, 14px 20px padding - Thinking blocks: 2px border, purple label, larger text - Tool blocks: 2px border, monospace font - Role labels: 13px (was 11px uppercase), timestamps 12px (was 10px) - Body: 14px base font (was 13px), add moz-osx-font-smoothing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Group continuation sessions with their originals via `parent_session_id` chaining, extracted from Claude JSONL `sessionId` fields - Frontend walks `parent_session_id` chains to find root sessions and groups all sessions sharing the same root - Prune command excludes sessions that have children to avoid breaking continuity chains - Old databases (missing `parent_session_id` column) are dropped and rebuilt from scratch on startup ## How it works Claude JSONL files have a `sessionId` field on user/assistant records. For original sessions, `sessionId` matches the file's UUID. For continuations, it carries the parent file's UUID, forming a linked list (A -> B -> C). The parser extracts this and stores it as `parent_session_id`. The frontend walks the chain to find the root and groups all sessions sharing the same root. ## Test plan - [x] `go vet ./... && go test -tags fts5 ./...` -- all pass - [x] `cd frontend && npx vitest run` -- all 318 tests pass - [ ] Manual: delete DB, restart agentsview, verify continuation sessions group under original with correct first message --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- **Insights feature** for AI-generated analysis of agent sessions,
supporting Claude, Codex, and Gemini as generation backends
- Full-stack: `insights` SQLite table with FTS5, Go HTTP handlers
(`GET/DELETE /api/v1/insights/{id}`, `POST /api/v1/insights/generate`
with SSE streaming), prompt builder with session context, and
multi-agent CLI dispatch
- **Date range analysis**: insights can cover a single day or a date
range (e.g., a week). DB schema uses `date_from`/`date_to` columns. The
generate endpoint validates both fields and supports `date_to >=
date_from`
- **Mode-driven UI**: type selector with three modes -- Daily Activity
(single date), Date Range Activity (from/to inputs with 7-day and 30-day
presets), and Agent Analysis (single date). Mode is derived reactively
from store state
- Svelte 5 Insights page with sidebar controls (type, date, project,
agent), concurrent generation tasks with live status spinners, date
display on in-progress tasks, and markdown content viewer with delete
support
- **Structured API errors**: `ApiError` class with `status` field for
programmatic error handling; empty response bodies fall back to `"API
<status>"` message
- **ListInsights capped at 500 rows** with `created_at DESC` index to
prevent unbounded queries
- `internal/insight` package: prompt construction from session data with
date-aware text ("Date" vs "Date Range"), streaming response parsing for
Claude/Codex/Gemini CLI output
- **Session breadcrumb bar** showing project name, agent badge
(color-coded), and session start time
- **Header navigation** with always-visible Sessions/Insights buttons
and active state highlighting
- Design polish: Inter font, refined color tokens for light/dark themes,
tighter typography and spacing
## Test plan
- [x] `go test -tags fts5 ./...` -- all Go tests pass (insights CRUD,
filters, 500-row cap, date range round-trip, prompt builder with
single/range dates, server handler validation)
- [x] `npx vitest run` -- all 360 frontend tests pass (insights store,
date sync, mode switching, generate payloads, ApiError handling with
empty-body fallback)
- [x] `npx tsc --noEmit` -- no type errors
- [x] `go vet ./...` -- clean
- [ ] Manual: generate a Daily Activity insight, verify single date in
list and content header
- [ ] Manual: switch to Date Range Activity, verify from/to inputs and
presets appear, generate and verify range displays
- [ ] Manual: verify all insights appear in the list regardless of
selected generation dates
- [ ] Manual: verify in-progress task items show the date being analyzed
- [ ] Manual: delete an insight, verify removal from list and content
area
Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
#18) ## Summary - Extract and persist structured tool call metadata (`tool_use_id`, `input_json`, `skill_name`, `result_content_length`) from session files into the `tool_calls` table - Pair `tool_result` content lengths back to their originating `tool_call` via `tool_use_id` in the sync engine, then filter empty user carrier messages - Expose structured `tool_calls` in the message API response and enrich frontend tool block rendering with parsed arguments (Bash commands, Task prompts, TaskCreate/Update metadata, Skill names, etc.) - Canonicalize worktree project names during import so archived worktree sessions group with the main repository even when worktree paths no longer exist on disk - Batch tool-call hydration queries to avoid SQLite bind-variable limits on large sessions ## Test plan - [x] All Go tests pass (`CGO_ENABLED=1 go test -tags fts5 ./...`) - [x] All frontend tests pass (380 tests) - [x] Worktree project normalization: online worktree, offline worktree with branch hint, offline worktree without branch - [x] Tool-call batch hydration across batch boundaries (500+25 messages) - [ ] Manual: open a session with tool calls, confirm tool blocks show arguments and no empty user messages appear 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: CL Kao <clkao@datarecce.io> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Import `time/tzdata` in `cmd/agentsview/main.go` to embed the IANA timezone database in the binary (~450KB) - `time.LoadLocation` fails on Windows release builds (built with `-trimpath`) for any non-UTC timezone, breaking all analytics endpoints - Add non-UTC timezone test case (`America/New_York`) to catch regressions Closes #13 ## Test plan - [x] All Go tests pass (`CGO_ENABLED=1 go test -tags fts5 ./...`) - [x] `NonUTCTimezone` test exercises `America/New_York` through the analytics handler - [x] Windows CI already in test matrix (`windows-latest`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Replace `bufio.Scanner` with a custom `lineReader` that uses `bufio.Reader.ReadLine()` to skip lines exceeding 64MB instead of aborting the entire session parse - Propagate I/O errors through `lineReader.Err()` (matching `bufio.Scanner` pattern) rather than silently swallowing them - Replace all three scan sites (Claude parser, Claude hints extractor, Codex parser) Closes #12 ## Test plan - [x] `TestLineReader` — normal lines, oversized skip, all oversized, empty input, blank lines, no trailing newline, exact limit, one over limit - [x] `TestLineReaderIOError` — custom `io.Reader` that yields data then returns a non-EOF error; verifies lines are returned and `Err()` exposes the I/O error - [x] `TestParseCodexSessionOversizedLineSkipped` — integration test placing an oversized line between normal JSONL entries - [x] All Go tests pass (`CGO_ENABLED=1 go test -tags fts5 ./...`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Strip `ANTHROPIC_API_KEY` and `CLAUDECODE` from the environment when invoking agent CLIs (`claude`, `codex`, `gemini`) for insight generation, forcing subscription-based auth. Also sets `CLAUDE_NO_SOUND=1`. - Fix test isolation: `TestGenerateInsight_DefaultAgent` was spawning a real `claude` process, which created session files that the file watcher synced into the production database. Introduce `insight.GenerateFunc` and `Server.generateFunc` (injectable via `WithGenerateFunc` option) so tests use a stub. - Show the agent name on in-progress insight tasks in the sidebar, matching completed entries. ## Test plan - [x] `CGO_ENABLED=1 go test -tags fts5 ./internal/insight/` passes - [x] `CGO_ENABLED=1 go test -tags fts5 ./internal/server/` passes - [x] `go vet ./...` clean - [x] Manual: run insight generation with `ANTHROPIC_API_KEY` set in shell, verify Claude uses subscription auth - [x] Manual: verify in-progress insight tasks show agent name in sidebar 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…uidelines Set CLAUDE_NO_SOUND=1 on the claude command directly (appended to inherited env) to suppress audible notifications during automated insight generation. Add review guideline #8: subprocess env inheritance is intentional and env sanitization is the user's responsibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - **Sync performance**: Replace SHA-256 hash skip check with file_size + file_mtime comparison, add path-based DB lookup for codex/gemini files, and cache non-interactive session results. Reduces sync from ~14s to sub-second for unchanged sessions with 7000+ files. - **Startup logging**: Add timing to each startup phase (discovery, sync, file watcher, total) so it's clear where time is spent. - **Insights filtering**: Stop filtering insights list by project so global insights remain visible when a project is selected. - **CLI failure recovery**: Try parsing claude CLI stdout before checking exit status, so insights are captured when the CLI exits non-zero but produced valid output. ## Test plan - [ ] `CGO_ENABLED=1 go test -tags fts5 ./...` passes - [ ] `npx tsc --noEmit` passes in frontend - [ ] Start agentsview with large session count, verify timing logs appear and startup is faster on second run - [ ] Generate insight with project filter active, verify global insights stay visible - [ ] Verify insights still generate and save correctly 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Gate the cancellation check in `generateClaude` on `runErr != nil` so a successful `cmd.Run` followed by a post-completion context cancel doesn't discard a valid result ## Test plan - [x] Existing `TestGenerateClaude_CancelledContext` passes (pre-cancelled context still errors) - [x] `TestGenerateClaude_SalvageOnNonZeroExit` passes (salvage behavior preserved) - [x] Full `go test ./...` green 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Add OpenCode (opencode.ai) as a fourth supported agent alongside Claude Code, Codex, and Gemini CLI - OpenCode stores sessions in a SQLite database (`~/.local/share/opencode/opencode.db`) with schema: `project` → `session` → `message` → `part`, where role and part type live inside JSON `data` columns - Parse sessions, messages, tool calls, and reasoning parts from the OpenCode DB into the same `ParsedSession`/`ParsedMessage` structures used by other agents - Add persistent skip cache (`skipped_files` table) so non-interactive sessions survive process restarts without re-parsing ~7000 codex files - Add per-session change detection for OpenCode using `time_updated` comparison instead of fragile WAL fingerprinting - Add incremental message sync (append-only) to avoid expensive FTS5 delete+reinsert when re-syncing large active sessions - Add sync telemetry (timing logs per phase) for diagnosing performance - Add `OPENCODE_DIR` env var and config, purple agent color in UI - Use `gemini-3-pro-preview` model for insight generation ## Test plan - [ ] `CGO_ENABLED=1 go test -tags fts5 ./...` — all tests pass - [ ] `golangci-lint run ./...` — no issues - [ ] Manual: `make build && ./agentsview` with OpenCode installed — sessions appear with correct project names, messages, tool calls - [ ] Verify second restart skips opencode sessions (0 updated) and file sync uses incremental append 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Add GitHub Copilot CLI as a supported agent, parsing JSONL session data from `~/.copilot/session-state/` - Support both bare (`<uuid>.jsonl`) and directory (`<uuid>/events.jsonl`) storage layouts - Extract user/assistant messages, tool calls with content-length pairing, and reasoning text - Add `COPILOT_DIR` env var and file watcher for live updates - Fix interleaved log output during initial sync progress bar closes #23 ## Changes **Parser** (`internal/parser/copilot.go`): JSONL parser handling `session.start`, `user.message`, `assistant.message`, `tool.execution_complete`, and `assistant.reasoning` events. Uses `gjson` Raw fallback for non-string tool results (objects, arrays). **Taxonomy** (`internal/parser/taxonomy.go`): Map `view` -> Read, `report_intent` -> Tool. Existing mappings cover `edit_file`, `shell`, `grep`, `glob`. **Config** (`internal/config/config.go`): `CopilotDir` field, default `~/.copilot`, `COPILOT_DIR` env var. **Discovery** (`internal/sync/discovery.go`): `DiscoverCopilotSessions` walks session-state/ for both layouts. `FindCopilotSourceFile` checks both paths. **Sync engine** (`internal/sync/engine.go`): Wire copilot into discover, process, classify, find-source, and single-session sync. Suppress verbose log lines when progress callback is active to fix garbled initial sync output. **Frontend**: Amber agent color for copilot dot in SessionItem, CommandPalette, App badge. Added to InsightsPage agent filter dropdown. ## Test plan - [x] `CGO_ENABLED=1 go test -tags fts5 ./internal/parser/` -- 8 copilot parser tests + taxonomy tests pass - [x] `CGO_ENABLED=1 go test -tags fts5 ./internal/sync/` -- sync integration tests pass (including new OpenCode bulk-sync tests) - [x] `CGO_ENABLED=1 go test -tags fts5 ./...` -- all tests pass - [x] Smoke test: parsed 19/19 real copilot sessions with 0 errors, correct project extraction, both file layouts 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Adds a clickable session ID to the session detail breadcrumb bar - Shows first 8 characters of the session ID in a monospace styled element - Hovering shows the full session ID as a tooltip - Clicking copies the full session ID to clipboard with "Copied!" feedback (1.5s) - Extracted a reusable `copyToClipboard` utility with tests This lets users easily grab session IDs for `claude --resume <id>`. ## Demo https://github.com/user-attachments/assets/b7ef65c8-d80a-40c7-8a90-13d5e049c494 ## Tests Ran - [x] `copyToClipboard` utility tested (success + failure paths) - [x] All 383 frontend tests passing - [x] Go tests passing (no backend changes) - [x] Manual: navigate to session, verify truncated ID visible - [x] Manual: hover shows full ID tooltip - [x] Manual: click copies full ID, shows "Copied!" for 1.5s 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Wes McKinney <wesmckinn+git@gmail.com>
Symlinked project directories under `CLAUDE_PROJECTS_DIR` were silently skipped, making it impossible to scan a subset of projects by symlinking selected project directories into a custom directory. ## Summary - `os.ReadDir` returns `DirEntry` where `IsDir()` is `false` for symlinks to directories, causing `DiscoverClaudeProjects` and Gemini discovery to silently skip symlinked project directories - Adds `isDirOrSymlink()` helper that also checks `ModeSymlink`, applied to all three affected call sites (Claude projects, Gemini session discovery, Gemini source file lookup) ## Test plan - [x] Verified with `/tmp/filtered-projects/` containing a symlink to one project: before fix discovers 0 claude files, after fix discovers 4 - [x] All existing discovery tests pass - [x] Full test suite passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Wes McKinney <wesmckinn+git@gmail.com>
## Summary - Add activity indicator and filter dropdown to the session sidebar (recently active, min prompts, agent) - Filter recently active sessions by last activity timestamp, not start date - Add `user_message_count` column to track actual user prompts (excluding tool-result messages) - Validate `active_since` query param server-side in both sessions and analytics endpoints (400 on malformed RFC3339) - Fix stale "Active 24h" cutoff on analytics page by computing the timestamp at fetch time - Sync filter state between sidebar and analytics dashboard, including clears - Fix Gemini sessions showing as "unknown" project (#36) — support named project directories with worktree resolution - Deterministic Gemini project map iteration on duplicate names - Add in-app full resync: gear icon in header opens a modal that re-parses all session files via SSE-streamed progress, without deleting the database - Serialize sync runs with engine-level mutex to prevent concurrent sync/resync races - Extract shared modal CSS into global styles scoped under `.modal-panel` - Fix E2E test fixture to include `user_message_count` Closes #36 ## Test plan - [x] `go test ./...` — all packages pass - [x] `npx vitest run` — 392 tests pass - [x] `npx svelte-check` — 0 errors - [x] E2E tests updated for `user_message_count` display change - [x] Enable "Recently Active" in sidebar, switch to analytics tab, verify chip appears, clear chip, verify sidebar dropdown updates - [ ] Send `?active_since=garbage` to `/api/sessions` — expect 400 - [x] Click gear icon → confirm resync → verify progress streams → done summary → sessions reload - [x] Click gear icon while sync is running → verify error state with Retry/Close - [x] Verify Gemini sessions show correct project names after re-sync 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Adds a `postMessage` listener to `UIStore` that accepts `{type:
"theme:set", theme: "light"|"dark"}` messages
- Enables parent windows to control agentsview's theme without reloading
the iframe
- Closes #31
## Details
When agentsview is embedded as a cross-origin iframe, the host
application can now send a `theme:set` message to switch themes
instantly. This avoids the jarring reload previously needed when using
the `?theme=` URL parameter approach.
The implementation is minimal — a single
`window.addEventListener("message", ...)` in the UIStore constructor.
Since `this.theme` is a `$state` field, assigning it triggers the
existing `$effect` that updates the DOM class and persists to
localStorage.
## Protocol
```js
iframe.contentWindow.postMessage({ type: "theme:set", theme: "dark" }, "*");
```
Only `"light"` and `"dark"` are accepted; other values are silently
ignored.
## Test plan
- [x] Valid `theme:set` message changes theme
- [x] Invalid theme value (e.g. "purple") is ignored
- [x] Unrelated message types are ignored
- [x] Full test suite passes (384/384, +3 new)
## Summary - Fix command palette freeze when a search query returns zero results (e.g. "spamalot") - Root cause: Go nil slice serializes as JSON `null`, not `[]`. The frontend crashed on `null.length`, breaking the component and its Escape handler. - Server now coerces nil results to an empty slice before serialization - Frontend adds `?? []` null-coalesce as defense in depth ## Test plan - [x] New `TestSearch_ZeroResults` server test asserts results is `[]` not `null` - [x] Existing search store tests pass - [ ] Manual: open command palette, search for a term with no matches, verify "No results" shown and Escape works Fixes #34 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…er warnings, add polling fallback for unwatchable dirs (#38) ## Summary - `config.json` can have multiple paths, to support Windows & WSL on the same box eg ```json "claude_project_dirs": [ "C:\\Users\\Nat\\.claude\\projects", "\\\\wsl.localhost\\Ubuntu-24.04\\home\\gnat\\.claude\\projects" ], ``` - `WatchRecursive` now returns watched/unwatched counts silently instead of logging one warning per failed subdirectory - `startFileWatcher` prints a single condensed line per root dir (e.g. "Couldn't watch 15 directories under \wsl.localhost\..., will poll every 2m") - Adds a 2-minute polling goroutine for unwatchable directories, supplementing the existing 15-minute periodic sync (wsl can't be watched from Windows) ## Test plan - [x] `go vet -tags fts5 ./internal/sync/ ./cmd/agentsview/` passes - [x] `CGO_ENABLED=1 go test -tags fts5 ./internal/sync/ ./internal/config/ ./internal/server/` passes - [ ] Manual: run with WSL dirs configured, confirm one summary line instead of many warnings 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Nat Torkington <Nat@Ontempo.co.nz> Co-authored-by: Wes McKinney <wesmckinn+git@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
… colors (kenn-io#44) ## Summary - **Read `trustedFolders.json`** alongside `projects.json` when building the Gemini hash-to-project map. `trustedFolders.json` persists longer than `projects.json`, recovering project names for orphaned SHA-256 hash directories that Gemini CLI has cleaned up. - **Add `exclude_project` API filter** (`project != ?` SQL predicate) and a "Hide unknown" toggle in the sidebar filter dropdown, letting users hide sessions with unresolvable project names. Conflicting `project=unknown` + `exclude_project=unknown` is prevented centrally in `apiParams` -- explicit project selection always wins. - **Fix Gemini/Claude color collision** (fixes kenn-io#42). Both agents used `--accent-blue`. Gemini now uses `--accent-rose` (light: `#e11d48`, dark: `#fb7185`) for maximum distinction from all other agent colors. - **Show agent name in session list.** Replace the plain dot indicator with a colored dot + agent name label (e.g. "Claude", "Gemini") in the agent's accent color. Width is capped with ellipsis truncation to prevent sidebar squeeze. Also adds missing `agent-gemini` and `agent-opencode` badge classes in the breadcrumb. ## Test plan - [x] Go tests: `TestBuildGeminiProjectMapTrustedFolders`, `TestBuildGeminiProjectMapBothFiles`, `TestBuildGeminiProjectMapProjectsWin` verify trustedFolders.json reading and precedence - [x] Go tests: `TestSessionFilterExcludeProject` covers exclude_project SQL filter (4 cases) - [x] Frontend tests: 10 store tests cover API serialization, conflicting filter clearing (toggle, URL params, centralized apiParams guard), `hasActiveFilters`, and `clearSessionFilters` - [x] Agent color test updated to assert Gemini uses `--accent-rose` - [x] Vite build produces no warnings - [x] All existing Go and frontend tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
… model (kenn-io#45) ## Summary - **Fix message count discrepancy**: `sessions.message_count` and `user_message_count` now reflect post-filter counts (after `pairAndFilter` removes empty user+tool_result messages), matching the status bar totals. Previously analytics showed inflated counts from pre-filter parser output. - **Add "All" time range preset**: New preset in the analytics date picker sets the start date to `1970-01-01`, showing all sessions regardless of age. - **Update Gemini insight model**: Changed `geminiInsightModel` from `gemini-3-pro-preview` to `gemini-3.1-pro-preview`. > **Note:** Existing sessions will retain stale (inflated) counts until re-synced. Users who see a discrepancy between the analytics dashboard and the status bar should use the in-app resync button to reprocess all sessions. New and incrementally synced sessions will have correct counts automatically. ## Test plan - [x] `postFilterCounts` unit test covers mixed roles, empty slice, all-user, no-user cases - [x] `TestSyncEnginePostFilterCounts` integration test verifies `writeBatch` stores post-filter counts with tool_result filtering - [x] `TestSyncSingleSessionPostFilterCounts` integration test verifies `writeSessionFull` path by corrupting DB counts and forcing reparse - [x] Existing `TestGenerateGemini_ModelFlag` passes with updated model constant - [x] All Go tests pass (`go test -tags fts5 ./internal/...`) - [x] Frontend type check (`tsc --noEmit`) and tests (`vitest run`) pass - [x] Frontend build (`vite build`) produces no warnings 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Closes #17 ## Summary - Detect conversation forks in Claude Code sessions by building a uuid/parentUuid DAG, splitting large-gap branches into separate session records - Link Task tool calls to their spawned subagent sessions via queue-operation parsing (JSON and XML formats) - Add inline subagent conversation expansion in the frontend ## End-User Impact - **Fork detection**: Conversation branches (e.g., from Claude Code's "retry from here") are detected and split into separate session entries instead of being jumbled together. Small retries (≤3 user turns) fold into the main session; larger forks appear as standalone sessions. - **Subagent session linking**: Task subagent conversations are linked to the specific tool call that launched them. Task tool blocks show an expandable inline view of the subagent's conversation. - **Cleaner session list**: Subagent and fork sessions are hidden from the top-level list — accessible only through their parent session context. ## Design **DAG from uuid/parentUuid:** Every Claude Code JSONL entry carries `uuid` and `parentUuid` fields forming a tree. The parser builds a parent→children adjacency map in a single pass, then walks from root following first-child links. At fork points (nodes with multiple children), a heuristic counts user turns remaining on the first branch: >3 turns = real fork (split into separate `ParseResult`), ≤3 turns = retry (follow latest child, discard older branch). **Subagent linking from queue-operation:** Claude Code writes `queue-operation` entries with `operation: "enqueue"` when spawning subagents. The `content` field maps `tool_use_id` → `task_id`. Two formats exist in the wild: JSON (`{"task_id":"...","tool_use_id":"..."}`) and XML (`<task-id>...</task-id><tool-use-id>...</tool-use-id>`). Parser tries JSON first via `gjson.Get`, falls back to regex for XML tags. **Data model — relationship_type:** Sessions gain a `relationship_type` column (`""`, `"continuation"`, `"subagent"`, `"fork"`). Fork sessions get ID `{parent}-{first-uuid}` with `parent_session_id` pointing to main session. Tool calls gain `subagent_session_id` linking to the agent session. **API — child sessions endpoint:** `GET /api/v1/sessions/{id}/children` returns fork/continuation/subagent sessions for a parent. ## Test plan - [ ] Verify fork detection unit tests pass (`go test ./internal/parser/ -run TestForkDetection`) - [ ] Verify subagent linking tests pass (`go test ./internal/parser/ -run TestSubagent`) - [ ] Verify integration tests pass (`go test ./internal/sync/ -run TestSync`) - [ ] Manual: load a session with Task subagents and verify inline expansion works - [ ] Manual: verify subagent/fork sessions don't appear in top-level session list 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Wes McKinney <wesmckinn+git@gmail.com>
## Summary - Split monolithic parser tests (`parser_test.go`) into per-agent files (`claude_parser_test.go`, `codex_parser_test.go`, `gemini_parser_test.go`) - Convert many tests to table-driven format - Add test fixture files under `internal/parser/testdata/` - Refactor watcher tests to use real fsnotify events instead of mocking internal state - Make analytics test assertions dynamic (derived from seed data instead of hardcoded) - Small production code improvements: deterministic prune output, http.Method constants in export.go, error handling on io.ReadAll ## Test plan - [ ] `make test` passes - [ ] `make vet` passes - [ ] No coverage regressions (test count increased from 23 to 33 parser functions) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.2.0 to 6.3.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/setup-go/releases">actions/setup-go's releases</a>.</em></p> <blockquote> <h2>v6.3.0</h2> <h2>What's Changed</h2> <ul> <li>Update default Go module caching to use go.mod by <a href="https://github.com/priyagupta108"><code>@priyagupta108</code></a> in <a href="https://redirect.github.com/actions/setup-go/pull/705">actions/setup-go#705</a></li> <li>Fix golang download url to go.dev by <a href="https://github.com/178inaba"><code>@178inaba</code></a> in <a href="https://redirect.github.com/actions/setup-go/pull/469">actions/setup-go#469</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-go/compare/v6...v6.3.0">https://github.com/actions/setup-go/compare/v6...v6.3.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/setup-go/commit/4b73464bb391d4059bd26b0524d20df3927bd417"><code>4b73464</code></a> Fix golang download url to go.dev (<a href="https://redirect.github.com/actions/setup-go/issues/469">#469</a>)</li> <li><a href="https://github.com/actions/setup-go/commit/a5f9b05d2d216f63e13859e0d847461041025775"><code>a5f9b05</code></a> Update default Go module caching to use go.mod (<a href="https://redirect.github.com/actions/setup-go/issues/705">#705</a>)</li> <li>See full diff in <a href="https://github.com/actions/setup-go/compare/7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5...4b73464bb391d4059bd26b0524d20df3927bd417">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…-io#47) Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.53.2 to 5.53.5. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/sveltejs/svelte/releases">svelte's releases</a>.</em></p> <blockquote> <h2>svelte@5.53.5</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: escape <code>innerText</code> and <code>textContent</code> bindings of <code>contenteditable</code> (<a href="https://github.com/sveltejs/svelte/commit/0df5abcae223058ceb95491470372065fb87951d"><code>0df5abcae223058ceb95491470372065fb87951d</code></a>)</p> </li> <li> <p>fix: sanitize <code>transformError</code> values prior to embedding in HTML comments (<a href="https://github.com/sveltejs/svelte/commit/0298e979371bb583855c9810db79a70a551d22b9"><code>0298e979371bb583855c9810db79a70a551d22b9</code></a>)</p> </li> </ul> <h2>svelte@5.53.4</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: set server context after async transformError (<a href="https://redirect.github.com/sveltejs/svelte/pull/17799">#17799</a>)</p> </li> <li> <p>fix: hydrate if blocks correctly (<a href="https://redirect.github.com/sveltejs/svelte/pull/17784">#17784</a>)</p> </li> <li> <p>fix: handle default parameters scope leaks (<a href="https://redirect.github.com/sveltejs/svelte/pull/17788">#17788</a>)</p> </li> <li> <p>fix: prevent flushed effects from running again (<a href="https://redirect.github.com/sveltejs/svelte/pull/17787">#17787</a>)</p> </li> </ul> <h2>svelte@5.53.3</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: render <code>:catch</code> of <code>#await</code> block with correct key (<a href="https://redirect.github.com/sveltejs/svelte/pull/17769">#17769</a>)</p> </li> <li> <p>chore: pin aria-query@5.3.1 (<a href="https://redirect.github.com/sveltejs/svelte/pull/17772">#17772</a>)</p> </li> <li> <p>fix: make string coercion consistent to <code>toString</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/17774">#17774</a>)</p> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md">svelte's changelog</a>.</em></p> <blockquote> <h2>5.53.5</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: escape <code>innerText</code> and <code>textContent</code> bindings of <code>contenteditable</code> (<a href="https://github.com/sveltejs/svelte/commit/0df5abcae223058ceb95491470372065fb87951d"><code>0df5abcae223058ceb95491470372065fb87951d</code></a>)</p> </li> <li> <p>fix: sanitize <code>transformError</code> values prior to embedding in HTML comments (<a href="https://github.com/sveltejs/svelte/commit/0298e979371bb583855c9810db79a70a551d22b9"><code>0298e979371bb583855c9810db79a70a551d22b9</code></a>)</p> </li> </ul> <h2>5.53.4</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: set server context after async transformError (<a href="https://redirect.github.com/sveltejs/svelte/pull/17799">#17799</a>)</p> </li> <li> <p>fix: hydrate if blocks correctly (<a href="https://redirect.github.com/sveltejs/svelte/pull/17784">#17784</a>)</p> </li> <li> <p>fix: handle default parameters scope leaks (<a href="https://redirect.github.com/sveltejs/svelte/pull/17788">#17788</a>)</p> </li> <li> <p>fix: prevent flushed effects from running again (<a href="https://redirect.github.com/sveltejs/svelte/pull/17787">#17787</a>)</p> </li> </ul> <h2>5.53.3</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: render <code>:catch</code> of <code>#await</code> block with correct key (<a href="https://redirect.github.com/sveltejs/svelte/pull/17769">#17769</a>)</p> </li> <li> <p>chore: pin aria-query@5.3.1 (<a href="https://redirect.github.com/sveltejs/svelte/pull/17772">#17772</a>)</p> </li> <li> <p>fix: make string coercion consistent to <code>toString</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/17774">#17774</a>)</p> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/sveltejs/svelte/commit/ed14b499d6ea6821b5e8f81a723164eb8198dfa9"><code>ed14b49</code></a> Version Packages (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17802">#17802</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/0df5abcae223058ceb95491470372065fb87951d"><code>0df5abc</code></a> Merge commit from fork</li> <li><a href="https://github.com/sveltejs/svelte/commit/0298e979371bb583855c9810db79a70a551d22b9"><code>0298e97</code></a> Merge commit from fork</li> <li><a href="https://github.com/sveltejs/svelte/commit/96fd3ce763525ce6276520ca605dba5ece74ae93"><code>96fd3ce</code></a> Version Packages (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17786">#17786</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/1b3e6605190ab8ca21292ddd3ccf2a71387d79fe"><code>1b3e660</code></a> fix: prevent flushed effects from running again (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17787">#17787</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/673a1ab9643644fe31beda33eacfdec9ee1f2668"><code>673a1ab</code></a> fix: set server context after async transformError (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17799">#17799</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/3a289797bd205182e7677f58daf472caf537afc2"><code>3a28979</code></a> fix: handle default parameters scope leaks (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17788">#17788</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/fcdc0289db5e6b0f7cf68cd3988450dad567392f"><code>fcdc028</code></a> fix: hydrate if blocks correctly (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17784">#17784</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/97f3ac557158dd7754264dfe735ed83c2ce95e1f"><code>97f3ac5</code></a> Version Packages (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17775">#17775</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/7deedc5bb4fd6d0f033d00fa9741c7141fffd730"><code>7deedc5</code></a> fix: render <code>:catch</code> of <code>#await</code> block with correct key (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/17769">#17769</a>)</li> <li>Additional commits viewable in <a href="https://github.com/sveltejs/svelte/commits/svelte@5.53.5/packages/svelte">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…nd (kenn-io#48) Bumps [@types/dompurify](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/dompurify) from 3.0.5 to 3.2.0. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/dompurify">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…frontend (kenn-io#49) Bumps [@tanstack/virtual-core](https://github.com/TanStack/virtual/tree/HEAD/packages/virtual-core) from 3.13.18 to 3.13.19. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/TanStack/virtual/releases"><code>@tanstack/virtual-core</code>'s releases</a>.</em></p> <blockquote> <h2><code>@tanstack/virtual-core</code><a href="https://github.com/3"><code>@3</code></a>.13.19</h2> <h3>Patch Changes</h3> <ul> <li>Fix crash when component unmounts during <code>scrollToIndex</code> by adding a null guard for <code>targetWindow</code> inside the <code>requestAnimationFrame</code> callback (<a href="https://redirect.github.com/TanStack/virtual/pull/1129">#1129</a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/TanStack/virtual/blob/main/packages/virtual-core/CHANGELOG.md"><code>@tanstack/virtual-core</code>'s changelog</a>.</em></p> <blockquote> <h2>3.13.19</h2> <h3>Patch Changes</h3> <ul> <li>Fix crash when component unmounts during <code>scrollToIndex</code> by adding a null guard for <code>targetWindow</code> inside the <code>requestAnimationFrame</code> callback (<a href="https://redirect.github.com/TanStack/virtual/pull/1129">#1129</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/TanStack/virtual/commit/e0e4dcde5c99906eab2ab5aefd75e568b2ece967"><code>e0e4dcd</code></a> ci: Version Packages (<a href="https://github.com/TanStack/virtual/tree/HEAD/packages/virtual-core/issues/1131">#1131</a>)</li> <li><a href="https://github.com/TanStack/virtual/commit/843109c5bf780591a762f9767f3808fd15e3f94e"><code>843109c</code></a> fix(virtual-core): guard against null targetWindow in scrollToIndex rAF callb...</li> <li>See full diff in <a href="https://github.com/TanStack/virtual/commits/@tanstack/virtual-core@3.13.19/packages/virtual-core">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Restores the max-token denominator that was dropped when the header was changed to show turn count.
Missing entry caused unknown capacity for opus-4-7 sessions, hiding max token display and the context window block map.
Updates app header, about modal, settings, update modal, browser/desktop titles, and Tauri config. localStorage keys left unchanged to preserve existing user preferences.
Import the JetBrains IDE plugin that renders the agentsview web UI in a JCEF tool window. Rename from sample-plugin to periscope-plugin and update README with build instructions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Skip <synthetic> model name in pickPrimaryModel so sessions whose last message is a synthetic tool-result row resolve the real model and its context window size. - Use ContextTokens > 0 (not TokenPresence) to detect a measured context snapshot; TokenPresence returns true for any message with input_tokens, which reset cumulative to 0 when ContextTokens was absent.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ging
- Add POST /api/v1/sessions/{id}/summarize endpoint to manually enqueue
a session for turn summarization (fallback when auto-reconcile misses it)
- Add "Generate summaries" button in the context page alongside the
coverage pill, shown when status is idle or pending
- Improve startup logging to distinguish unset key, init failure, and
successful LLM client initialization
Rename project from 'agentsview' to 'Periscope' in README.
…gineering section
- Rename to Periscope, attribute upstream agentsview repo - Add Context Engineering section with spec link - Update hero image to periscope context view screenshot
…d/periscope-instincts.yaml)
cursor Bot
pushed a commit
that referenced
this pull request
Jul 28, 2026
> ℹ️ **Note**
>
> This PR body was truncated due to platform limits.
This PR contains the following updates:
| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@inlang/paraglide-js](https://paraglidejs.com) ([source](https://redirect.github.com/opral/paraglide-js)) | [`2.19.0` → `2.20.1`](https://renovatebot.com/diffs/npm/@inlang%2fparaglide-js/2.19.0/2.20.1) |  |  |
| [@lucide/svelte](https://lucide.dev) ([source](https://redirect.github.com/lucide-icons/lucide/tree/HEAD/packages/svelte)) | [`1.17.0` → `1.21.0`](https://renovatebot.com/diffs/npm/@lucide%2fsvelte/1.17.0/1.21.0) |  |  |
| [@playwright/test](https://playwright.dev) ([source](https://redirect.github.com/microsoft/playwright)) | [`1.60.0` → `1.61.0`](https://renovatebot.com/diffs/npm/@playwright%2ftest/1.60.0/1.61.0) |  |  |
| [@playwright/test](https://playwright.dev) ([source](https://redirect.github.com/microsoft/playwright)) | [`1.55.1` → `1.61.0`](https://renovatebot.com/diffs/npm/@playwright%2ftest/1.55.1/1.61.0) |  |  |
| [@tanstack/virtual-core](https://tanstack.com/virtual) ([source](https://redirect.github.com/TanStack/virtual/tree/HEAD/packages/virtual-core)) | [`3.17.0` → `3.17.1`](https://renovatebot.com/diffs/npm/@tanstack%2fvirtual-core/3.17.0/3.17.1) |  |  |
| [@tauri-apps/cli](https://redirect.github.com/tauri-apps/tauri) | [`2.11.2` → `2.11.3`](https://renovatebot.com/diffs/npm/@tauri-apps%2fcli/2.11.2/2.11.3) |  |  |
| [@testing-library/svelte](https://redirect.github.com/testing-library/svelte-testing-library) ([source](https://redirect.github.com/testing-library/svelte-testing-library/tree/HEAD/packages/svelte)) | [`5.3.1` → `5.4.1`](https://renovatebot.com/diffs/npm/@testing-library%2fsvelte/5.3.1/5.4.1) |  |  |
| [openapi-typescript-codegen](https://redirect.github.com/ferdikoomen/openapi-typescript-codegen) | [`^0.30.0` → `^0.31.0`](https://renovatebot.com/diffs/npm/openapi-typescript-codegen/0.30.0/0.31.0) |  |  |
| [svelte](https://svelte.dev) ([source](https://redirect.github.com/sveltejs/svelte/tree/HEAD/packages/svelte)) | [`5.56.1` → `5.56.3`](https://renovatebot.com/diffs/npm/svelte/5.56.1/5.56.3) |  |  |
| [vite](https://viteplus.dev/guide) ([source](https://redirect.github.com/voidzero-dev/vite-plus/tree/HEAD/packages/core)) | [`0.1.24` → `0.2.1`](https://renovatebot.com/diffs/npm/vite/0.1.24/0.2.1) |  |  |
| [vite-plus](https://viteplus.dev/guide) ([source](https://redirect.github.com/voidzero-dev/vite-plus/tree/HEAD/packages/cli)) | [`0.1.24` → `0.2.1`](https://renovatebot.com/diffs/npm/vite-plus/0.1.24/0.2.1) |  |  |
---
### Release Notes
<details>
<summary>opral/paraglide-js (@​inlang/paraglide-js)</summary>
### [`v2.20.1`](https://redirect.github.com/opral/paraglide-js/blob/HEAD/CHANGELOG.md#2201)
##### Patch Changes
- [`8c3493d`](https://redirect.github.com/opral/paraglide-js/commit/8c3493d): Fix server cookie locale parsing when Cookie headers omit whitespace after semicolons.
### [`v2.20.0`](https://redirect.github.com/opral/paraglide-js/blob/HEAD/CHANGELOG.md#2200)
##### Minor Changes
- [`2c34351`](https://redirect.github.com/opral/paraglide-js/commit/2c34351): Emit `messages/package.json` with `{ "type": "module", "sideEffects": false }` for `message-modules` output, declaring the generated message modules side-effect-free.
This lets bundlers (notably Vite 8 / Rolldown) drop unused re-exports from the `m` barrel per entry, instead of bundling every message used anywhere in the app into one shared chunk that every entry downloads. Without it, per-page JS scales with the union of all messages used across the app rather than with the messages a given route actually uses.
The declaration is scoped to `messages/`, so `runtime.js` (which has real side effects) is unaffected. `type: "module"` is included because the package.json creates a new module scope for `messages/`; without it, the generated ESM files would default to CommonJS (a package.json without `type` is CJS in Node, even when the consuming project is `type: "module"`).
See [#​668](https://redirect.github.com/opral/paraglide-js/issues/668)
##### Patch Changes
- [`921c3be`](https://redirect.github.com/opral/paraglide-js/commit/921c3be): `experimentalMiddlewareLocaleSplitting`: the injected inline script now reuses the nonce from the response's `Content-Security-Policy` header, so it is allowed under a strict CSP instead of being blocked and breaking hydration. Automatic - no configuration needed.
</details>
<details>
<summary>lucide-icons/lucide (@​lucide/svelte)</summary>
### [`v1.21.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.21.0): Version 1.21.0
[Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.20.0...1.21.0)
#### What's Changed
- ci(release.yml): Remove new-version in release flow by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4478](https://redirect.github.com/lucide-icons/lucide/pull/4478)
- ci(release.yml): Fix workflow and remove `version` scripts in package scripts by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4479](https://redirect.github.com/lucide-icons/lucide/pull/4479)
- fix(docs): rename navigation category label by [@​Hsiii](https://redirect.github.com/Hsiii) in [#​4483](https://redirect.github.com/lucide-icons/lucide/pull/4483)
- feat(icons): added `broken-bone` icon by [@​Patolord](https://redirect.github.com/Patolord) in [#​4131](https://redirect.github.com/lucide-icons/lucide/pull/4131)
#### New Contributors
- [@​Hsiii](https://redirect.github.com/Hsiii) made their first contribution in [#​4483](https://redirect.github.com/lucide-icons/lucide/pull/4483)
- [@​Patolord](https://redirect.github.com/Patolord) made their first contribution in [#​4131](https://redirect.github.com/lucide-icons/lucide/pull/4131)
**Full Changelog**: <https://github.com/lucide-icons/lucide/compare/1.20.0...1.21.0>
### [`v1.20.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.20.0): Version 1.20.0
[Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.19.0...1.20.0)
#### What's Changed
- fix(icons): decreased size of arrows inside `square-arrow-*` icons by [@​jguddas](https://redirect.github.com/jguddas) in [#​3926](https://redirect.github.com/lucide-icons/lucide/pull/3926)
- chore(tags): Add tags to `search-` icons by [@​jamiemlaw](https://redirect.github.com/jamiemlaw) in [#​4099](https://redirect.github.com/lucide-icons/lucide/pull/4099)
- feat(icons): added `save-check` icon by [@​Konixy](https://redirect.github.com/Konixy) in [#​3120](https://redirect.github.com/lucide-icons/lucide/pull/3120)
- feat(icons): added `tag-plus` and `tag-x` icons by [@​adam-kov](https://redirect.github.com/adam-kov) in [#​3980](https://redirect.github.com/lucide-icons/lucide/pull/3980)
- feat(icons): added `banknote-check` icon by [@​mfjramirezf](https://redirect.github.com/mfjramirezf) in [#​3956](https://redirect.github.com/lucide-icons/lucide/pull/3956)
- feat(icons): added `clock-arrow-in` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2403](https://redirect.github.com/lucide-icons/lucide/pull/2403)
- feat(icons): added `summary` icon by [@​jpjacobpadilla](https://redirect.github.com/jpjacobpadilla) in [#​3114](https://redirect.github.com/lucide-icons/lucide/pull/3114)
- feat(icons): added `user-round-arrow-in` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2283](https://redirect.github.com/lucide-icons/lucide/pull/2283)
- feat(icons): added `clock-arrow-out` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2404](https://redirect.github.com/lucide-icons/lucide/pull/2404)
- docs(docs): fix broken Svelte package source link in README by [@​SRKrukowski](https://redirect.github.com/SRKrukowski) in [#​4468](https://redirect.github.com/lucide-icons/lucide/pull/4468)
- chore(deps-dev): bump [@​angular/compiler](https://redirect.github.com/angular/compiler) from 21.2.5 to 21.2.17 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4474](https://redirect.github.com/lucide-icons/lucide/pull/4474)
- chore(deps-dev): bump [@​angular/core](https://redirect.github.com/angular/core) from 21.2.5 to 21.2.17 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4470](https://redirect.github.com/lucide-icons/lucide/pull/4470)
- chore(deps-dev): bump vitest from 4.0.12 to 4.1.0 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4429](https://redirect.github.com/lucide-icons/lucide/pull/4429)
- chore(deps-dev): bump markdown-it from 14.1.1 to 14.2.0 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4475](https://redirect.github.com/lucide-icons/lucide/pull/4475)
- chore(deps-dev): bump [@​angular/common](https://redirect.github.com/angular/common) from 21.2.5 to 21.2.17 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4471](https://redirect.github.com/lucide-icons/lucide/pull/4471)
- feat(icons): added `pencil-sparkles` icon by [@​jennieboops](https://redirect.github.com/jennieboops) in [#​4445](https://redirect.github.com/lucide-icons/lucide/pull/4445)
#### New Contributors
- [@​Konixy](https://redirect.github.com/Konixy) made their first contribution in [#​3120](https://redirect.github.com/lucide-icons/lucide/pull/3120)
- [@​adam-kov](https://redirect.github.com/adam-kov) made their first contribution in [#​3980](https://redirect.github.com/lucide-icons/lucide/pull/3980)
- [@​mfjramirezf](https://redirect.github.com/mfjramirezf) made their first contribution in [#​3956](https://redirect.github.com/lucide-icons/lucide/pull/3956)
- [@​SRKrukowski](https://redirect.github.com/SRKrukowski) made their first contribution in [#​4468](https://redirect.github.com/lucide-icons/lucide/pull/4468)
- [@​jennieboops](https://redirect.github.com/jennieboops) made their first contribution in [#​4445](https://redirect.github.com/lucide-icons/lucide/pull/4445)
**Full Changelog**: <https://github.com/lucide-icons/lucide/compare/1.19.0...1.20.0>
### [`v1.19.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.19.0): Version 1.19.0
[Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.18.0...1.19.0)
#### What's Changed
- chore(deps): upgrade pnpm to version 11.6.0 by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4458](https://redirect.github.com/lucide-icons/lucide/pull/4458)
- feat(icons): added `star-*` icons by [@​RajnishKMehta](https://redirect.github.com/RajnishKMehta) in [#​3918](https://redirect.github.com/lucide-icons/lucide/pull/3918)
- chore(suggest-tags): Update metadata suggestion script by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4462](https://redirect.github.com/lucide-icons/lucide/pull/4462)
- feat(icons): added `save-pen` icon by [@​vaporvee](https://redirect.github.com/vaporvee) in [#​4179](https://redirect.github.com/lucide-icons/lucide/pull/4179)
- feat(icons): added `wrench-off` icon by [@​nilsjonsson](https://redirect.github.com/nilsjonsson) in [#​4434](https://redirect.github.com/lucide-icons/lucide/pull/4434)
- feat(icons): added `ad` icon by [@​jamiemlaw](https://redirect.github.com/jamiemlaw) in [#​4323](https://redirect.github.com/lucide-icons/lucide/pull/4323)
- feat(icons): added `eye-dashed` icon by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4415](https://redirect.github.com/lucide-icons/lucide/pull/4415)
- feat(icons): added `save-plus` icon by [@​jwlinqx](https://redirect.github.com/jwlinqx) in [#​4448](https://redirect.github.com/lucide-icons/lucide/pull/4448)
- feat(icons): added `list-sort-descending` icon by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4457](https://redirect.github.com/lucide-icons/lucide/pull/4457)
- fix(lucide-react-native): Fix provider exports by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4463](https://redirect.github.com/lucide-icons/lucide/pull/4463)
- fix(site): reserve space for icon detail drawer by [@​vyctorbrzezowski](https://redirect.github.com/vyctorbrzezowski) in [#​4344](https://redirect.github.com/lucide-icons/lucide/pull/4344)
- fix(icons): changed `wallet-cards` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​3888](https://redirect.github.com/lucide-icons/lucide/pull/3888)
- feat(site): Improve search and add sorting options by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4453](https://redirect.github.com/lucide-icons/lucide/pull/4453)
- feat(icons): added `podium` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2124](https://redirect.github.com/lucide-icons/lucide/pull/2124)
#### New Contributors
- [@​vaporvee](https://redirect.github.com/vaporvee) made their first contribution in [#​4179](https://redirect.github.com/lucide-icons/lucide/pull/4179)
- [@​nilsjonsson](https://redirect.github.com/nilsjonsson) made their first contribution in [#​4434](https://redirect.github.com/lucide-icons/lucide/pull/4434)
- [@​jwlinqx](https://redirect.github.com/jwlinqx) made their first contribution in [#​4448](https://redirect.github.com/lucide-icons/lucide/pull/4448)
- [@​vyctorbrzezowski](https://redirect.github.com/vyctorbrzezowski) made their first contribution in [#​4344](https://redirect.github.com/lucide-icons/lucide/pull/4344)
**Full Changelog**: <https://github.com/lucide-icons/lucide/compare/1.18.0...1.19.0>
### [`v1.18.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.18.0): Version 1.18.0
[Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.17.0...1.18.0)
#### What's Changed
- chore(site): Remove survey from site by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4417](https://redirect.github.com/lucide-icons/lucide/pull/4417)
- feat(icons): added `play-off` icon by [@​Ahmed-Dghaies](https://redirect.github.com/Ahmed-Dghaies) in [#​4412](https://redirect.github.com/lucide-icons/lucide/pull/4412)
- fix(metadata): add missing use-cases prop on play-off.json by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4423](https://redirect.github.com/lucide-icons/lucide/pull/4423)
- fix(docs): force hide #bb-banner, if html.has-bb-banner is missing by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4422](https://redirect.github.com/lucide-icons/lucide/pull/4422)
- fix(docs): Remove `@next` from installation instructions for`@lucide/svelte` by [@​alecglassford](https://redirect.github.com/alecglassford) in [#​4432](https://redirect.github.com/lucide-icons/lucide/pull/4432)
- feat(packages/angular): add support for Angular v22 and onwards by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4450](https://redirect.github.com/lucide-icons/lucide/pull/4450)
- fix(ci): add check to skip release if latest tag was created today by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4085](https://redirect.github.com/lucide-icons/lucide/pull/4085)
- feat(icons): added `webcam-off` icon by [@​jordan-burnett](https://redirect.github.com/jordan-burnett) in [#​4242](https://redirect.github.com/lucide-icons/lucide/pull/4242)
#### New Contributors
- [@​alecglassford](https://redirect.github.com/alecglassford) made their first contribution in [#​4432](https://redirect.github.com/lucide-icons/lucide/pull/4432)
- [@​jordan-burnett](https://redirect.github.com/jordan-burnett) made their first contribution in [#​4242](https://redirect.github.com/lucide-icons/lucide/pull/4242)
**Full Changelog**: <https://github.com/lucide-icons/lucide/compare/1.17.0...1.18.0>
</details>
<details>
<summary>microsoft/playwright (@​playwright/test)</summary>
### [`v1.61.0`](https://redirect.github.com/microsoft/playwright/releases/tag/v1.61.0)
[Compare Source](https://redirect.github.com/microsoft/playwright/compare/v1.60.0...v1.61.0)
##### 🔑 WebAuthn passkeys
New [Credentials](https://playwright.dev/docs/api/class-credentials) virtual authenticator, available via [browserContext.credentials](https://playwright.dev/docs/api/class-browsercontext#browser-context-credentials), lets tests register passkeys and answer `navigator.credentials.create()` / `navigator.credentials.get()` ceremonies in the page — no real hardware key required, works in all browsers:
```js
const context = await browser.newContext();
// Seed a passkey your backend provisioned for a test user.
await context.credentials.create('example.com', {
id: credentialId,
userHandle,
privateKey,
publicKey,
});
await context.credentials.install();
const page = await context.newPage();
await page.goto('https://example.com/login');
// The page's navigator.credentials.get() is answered with the seeded passkey.
```
You can also let the app register a passkey once in a setup test, read it back with [credentials.get()](https://playwright.dev/docs/api/class-credentials#credentials-get), and seed it into later tests — see [Credentials](https://playwright.dev/docs/api/class-credentials) for details.
##### 🗃️ Web Storage
New [WebStorage](https://playwright.dev/docs/api/class-webstorage) API, available via [page.localStorage](https://playwright.dev/docs/api/class-page#page-local-storage) and [page.sessionStorage](https://playwright.dev/docs/api/class-page#page-session-storage), reads and writes the page's storage for the current origin:
```js
await page.localStorage.setItem('token', 'abc');
const token = await page.localStorage.getItem('token');
const items = await page.sessionStorage.items();
```
##### New APIs
##### Network
- [apiResponse.securityDetails()](https://playwright.dev/docs/api/class-apiresponse#api-response-security-details) and [apiResponse.serverAddr()](https://playwright.dev/docs/api/class-apiresponse#api-response-server-addr) mirror the browser-side [response.securityDetails()](https://playwright.dev/docs/api/class-response#response-security-details) and [response.serverAddr()](https://playwright.dev/docs/api/class-response#response-server-addr).
##### Browser and Screencast
- New option `artifactsDir` in [browserType.connectOverCDP()](https://playwright.dev/docs/api/class-browsertype#browser-type-connect-over-cdp) controls where artifacts such as traces and downloads are stored when attached to an existing browser.
- New option `cursor` in [screencast.showActions()](https://playwright.dev/docs/api/class-screencast#screencast-show-actions) controls the cursor decoration rendered for pointer actions.
- The `onFrame` callback in [screencast.start()](https://playwright.dev/docs/api/class-screencast#screencast-start) now receives a `timestamp` of when the frame was presented by the browser.
##### Test runner
- The [testOptions.video](https://playwright.dev/docs/api/class-testoptions#test-options-video) option now supports the same set of modes as `trace`: new `'on-all-retries'`, `'retain-on-first-failure'` and `'retain-on-failure-and-retries'` values. See the [video modes table](https://playwright.dev/docs/test-use-options#video-modes) for which runs are recorded and kept in each mode.
- Supported `expect.soft.poll(...)`.
- New [fullConfig.argv](https://playwright.dev/docs/api/class-fullconfig#full-config-argv) — a snapshot of `process.argv` from the runner process, handy for reading custom arguments passed after the `--` separator.
- New [fullConfig.failOnFlakyTests](https://playwright.dev/docs/api/class-fullconfig#full-config-fail-on-flaky-tests) mirrors the config option, so reporters can explain why a flaky run failed.
- [testInfo.errors](https://playwright.dev/docs/api/class-testinfo#test-info-errors) now lists each sub-error of an `AggregateError` as a separate entry.
- New `-G` command line shorthand for `--grep-invert`.
##### 🛠️ Other improvements
- Playwright now supports Ubuntu 26.04.
- HAR and trace recordings now include WebSocket requests.
##### Browser Versions
- Chromium 149.0.7827.55
- Mozilla Firefox 151.0
- WebKit 26.5
This version was also tested against the following stable channels:
- Google Chrome 149
- Microsoft Edge 149
</details>
<details>
<summary>TanStack/virtual (@​tanstack/virtual-core)</summary>
### [`v3.17.1`](https://redirect.github.com/TanStack/virtual/blob/HEAD/packages/virtual-core/CHANGELOG.md#3171)
[Compare Source](https://redirect.github.com/TanStack/virtual/compare/@tanstack/virtual-core@3.17.0...@tanstack/virtual-core@3.17.1)
##### Patch Changes
- [#​1199](https://redirect.github.com/TanStack/virtual/pull/1199) [`ef69ea3`](https://redirect.github.com/TanStack/virtual/commit/ef69ea31738caa2819142e922efa03d3c408e25c) - Fix "items jump while scrolling up": the default scroll-adjustment predicate now compensates scrollTop on the first measurement of an above-viewport item even while scrolling backward (the estimate→actual delta must be absorbed), and only skips compensation for re-measurements during backward scroll to avoid the cascading jank
</details>
<details>
<summary>tauri-apps/tauri (@​tauri-apps/cli)</summary>
### [`v2.11.3`](https://redirect.github.com/tauri-apps/tauri/releases/tag/%40tauri-apps/cli-v2.11.3): @​tauri-apps/cli v2.11.3
[Compare Source](https://redirect.github.com/tauri-apps/tauri/compare/@tauri-apps/cli-v2.11.2...@tauri-apps/cli-v2.11.3)
#### \[2.11.3]
##### Bug Fixes
- [`50b0237ed`](https://www.github.com/tauri-apps/tauri/commit/50b0237edb9ed683979b7954975b98a4d22a9f70) ([#​15549](https://redirect.github.com/tauri-apps/tauri/pull/15549) by [@​Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Escape special characters in `productName` when generating Android `strings.xml`
- [`728c8d4a5`](https://www.github.com/tauri-apps/tauri/commit/728c8d4a5d9e3badf4683eb2e493d950d27d6b66) ([#​15473](https://redirect.github.com/tauri-apps/tauri/pull/15473) by [@​Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Skip building bundles when using `tauri android run`
- [`be0cb0d43`](https://www.github.com/tauri-apps/tauri/commit/be0cb0d4378ddf26bc33066b3750f2639ade15f5) ([#​15344](https://redirect.github.com/tauri-apps/tauri/pull/15344) by [@​raglady](https://www.github.com/tauri-apps/tauri/../../raglady)) Fix NDK\_HOME environment variable not honored when set
- [`ed8fd411f`](https://www.github.com/tauri-apps/tauri/commit/ed8fd411fe10469da33f63ed5bd9d7ae19e77d84) ([#​15552](https://redirect.github.com/tauri-apps/tauri/pull/15552) by [@​Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Make `ureq_proto` show trace level logs only on `-vvv` instead of `-vv`
- [`fca4a31f9`](https://www.github.com/tauri-apps/tauri/commit/fca4a31f94f8ba709d1b28e073e69867b8704e6e) ([#​15454](https://redirect.github.com/tauri-apps/tauri/pull/15454) by [@​fallintoplace](https://www.github.com/tauri-apps/tauri/../../fallintoplace)) Fix `tauri migrate` generating invalid namespace imports for aliased pluginified imports from `@tauri-apps/api`.
Inputs like `import { cli as superCli } from "@​tauri-apps/api"` now migrate to `import * as superCli from "@​tauri-apps/plugin-cli"` instead of producing invalid ESM syntax. The migration tests also reparse migrated JS, Svelte, and Vue output so syntax regressions are caught directly.
##### Dependencies
- Upgraded to `tauri-cli@2.11.3`
</details>
<details>
<summary>testing-library/svelte-testing-library (@​testing-library/svelte)</summary>
### [`v5.4.1`](https://redirect.github.com/testing-library/svelte-testing-library/releases/tag/%40testing-library/svelte%405.4.1)
[Compare Source](https://redirect.github.com/testing-library/svelte-testing-library/compare/@testing-library/svelte@5.4.0...@testing-library/svelte@5.4.1)
#### [@​testing-library/svelte](https://redirect.github.com/testing-library/svelte) [5.4.1](https://redirect.github.com/testing-library/svelte-testing-library/compare/@testing-library/svelte@5.4.0...@testing-library/svelte@5.4.1) (2026-06-21)
##### Dependencies
- **[@​testing-library/svelte-core](https://redirect.github.com/testing-library/svelte-core):** upgraded to 1.1.2
### [`v5.4.0`](https://redirect.github.com/testing-library/svelte-testing-library/releases/tag/%40testing-library/svelte%405.4.0)
[Compare Source](https://redirect.github.com/testing-library/svelte-testing-library/compare/@testing-library/svelte@5.3.1...@testing-library/svelte@5.4.0)
#### [@​testing-library/svelte](https://redirect.github.com/testing-library/svelte) [5.4.0](https://redirect.github.com/testing-library/svelte-testing-library/compare/@testing-library/svelte@5.3.1...@testing-library/svelte@5.4.0) (2026-06-20)
##### Features
- add wrapper option ([#​492](https://redirect.github.com/testing-library/svelte-testing-library/issues/492)) ([959f8c5](https://redirect.github.com/testing-library/svelte-testing-library/commit/959f8c5a5d7b1540907043bef23cc070757903e8))
##### Dependencies
- **[@​testing-library/svelte-core](https://redirect.github.com/testing-library/svelte-core):** upgraded to 1.1.0
</details>
<details>
<summary>ferdikoomen/openapi-typescript-codegen (openapi-typescript-codegen)</summary>
### [`v0.31.0`](https://redirect.github.com/ferdikoomen/openapi-typescript-codegen/releases/tag/v0.31.0)
[Compare Source](https://redirect.github.com/ferdikoomen/openapi-typescript-codegen/compare/v0.30.0...v0.31.0)
#### v0.31.0
Maintenance release: dependency upgrades (including several major-version bumps), TypeScript 6 compatibility, and a build script fix. No changes to the generator's output or public API.
##### Dependencies
- commander 14.0.2 → 14.0.3
- fs-extra 11.3.3 → 11.3.5
- handlebars 4.7.8 → 4.7.9
##### Dev dependencies
- [@​angular-devkit/build-angular](https://redirect.github.com/angular-devkit/build-angular) 21.0.4 → 22.0.3
- [@​angular/animations](https://redirect.github.com/angular/animations) 21.0.6 → 22.0.2
- [@​angular/cli](https://redirect.github.com/angular/cli) 21.0.4 → 22.0.3
- [@​angular/common](https://redirect.github.com/angular/common) 21.0.6 → 22.0.2
- [@​angular/compiler](https://redirect.github.com/angular/compiler) 21.0.6 → 22.0.2
- [@​angular/compiler-cli](https://redirect.github.com/angular/compiler-cli) 21.0.6 → 22.0.2
- [@​angular/core](https://redirect.github.com/angular/core) 21.0.6 → 22.0.2
- [@​angular/forms](https://redirect.github.com/angular/forms) 21.0.6 → 22.0.2
- [@​angular/platform-browser](https://redirect.github.com/angular/platform-browser) 21.0.6 → 22.0.2
- [@​angular/platform-browser-dynamic](https://redirect.github.com/angular/platform-browser-dynamic) 21.0.6 → 22.0.2
- [@​angular/router](https://redirect.github.com/angular/router) 21.0.6 → 22.0.2
- [@​babel/cli](https://redirect.github.com/babel/cli) 7.28.3 → 7.29.7
- [@​babel/core](https://redirect.github.com/babel/core) 7.28.5 → 7.29.7
- [@​babel/preset-env](https://redirect.github.com/babel/preset-env) 7.28.5 → 7.29.7
- [@​babel/preset-typescript](https://redirect.github.com/babel/preset-typescript) 7.28.5 → 7.29.7
- [@​eslint/js](https://redirect.github.com/eslint/js) 9.39.2 → 10.0.1
- [@​rollup/plugin-commonjs](https://redirect.github.com/rollup/plugin-commonjs) 29.0.0 → 29.0.3
- [@​rollup/plugin-terser](https://redirect.github.com/rollup/plugin-terser) 0.4.4 → 1.0.0
- [@​types/node](https://redirect.github.com/types/node) 25.0.3 → 26.0.0
- [@​types/qs](https://redirect.github.com/types/qs) 6.14.0 → 6.15.1
- [@​typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin) 8.50.1 → 8.61.1
- [@​typescript-eslint/parser](https://redirect.github.com/typescript-eslint/parser) 8.50.1 → 8.61.1
- axios 1.13.2 → 1.18.0
- eslint 9.39.2 → 10.5.0
- eslint-plugin-prettier 5.5.4 → 5.5.6
- eslint-plugin-simple-import-sort 12.1.1 → 13.0.0
- form-data 4.0.5 → 4.0.6
- glob 13.0.0 → 13.0.6
- globals 16.5.0 → 17.6.0
- jest 30.2.0 → 30.4.2
- jest-cli 30.2.0 → 30.4.2
- prettier 3.7.4 → 3.8.4
- puppeteer 24.34.0 → 24.43.1
- qs 6.14.0 → 6.15.2
- rimraf 6.1.2 → 6.1.3
- rollup 4.54.0 → 4.62.2
- typescript 5.9.3 → 6.0.3
- typescript-eslint 8.50.1 → 8.61.1
- zone.js 0.16.0 → 0.16.2
**Full Changelog**: <https://github.com/ferdikoomen/openapi-typescript-codegen/compare/v0.30.0...v0.31.0>
</details>
<details>
<summary>sveltejs/svelte (svelte)</summary>
### [`v5.56.3`](https://redirect.github.com/sveltejs/svelte/blob/HEAD/packages/svelte/CHANGELOG.md#5563)
[Compare Source](https://redirect.github.com/sveltejs/svelte/compare/svelte@5.56.2...svelte@5.56.3)
##### Patch Changes
- fix: ignore errors that occur in destroyed effects ([#​18384](https://redirect.github.com/sveltejs/svelte/pull/18384))
- fix: type BigInts in `$state.snapshot(...)` return values ([#​18388](https://redirect.github.com/sveltejs/svelte/pull/18388))
### [`v5.56.2`](https://redirect.github.com/sveltejs/svelte/blob/HEAD/packages/svelte/CHANGELOG.md#5562)
[Compare Source](https://redirect.github.com/sveltejs/svelte/compare/svelte@5.56.1...svelte@5.56.2)
##### Patch Changes
- fix: properly track effect end node for async sibling component ([#​18371](https://redirect.github.com/sveltejs/svelte/pull/18371))
- fix: prevent false-positive reactivity loss warning ([#​18373](https://redirect.github.com/sveltejs/svelte/pull/18373))
- chore: bump esrap dependency ([#​18372](https://redirect.github.com/sveltejs/svelte/pull/18372))
- fix: ignore declaration tags for animation directive ([#​18366](https://redirect.github.com/sveltejs/svelte/pull/18366))
- fix: reject pending async deriveds on discard ([#​18308](https://redirect.github.com/sveltejs/svelte/pull/18308))
</details>
<details>
<summary>voidzero-dev/vite-plus (vite)</summary>
### [`v0.2.1`](https://redirect.github.com/voidzero-dev/vite-plus/releases/tag/v0.2.1): vite-plus v0.2.1
[Compare Source](https://redirect.github.com/voidzero-dev/vite-plus/compare/v0.2.0...v0.2.1)
Restores support for older Node.js (back to `20.19.0`) and makes `vp exec --fail-if-no-match` fail correctly on unmatched filters.
##### Fixes & Enhancements
- Stop blocking older Node.js versions: v0.2.0 blocked commands when the resolved Node.js version fell outside the declared range. This reverts that enforcement and widens `engines.node` to `^20.19.0 || ^22.18.0 || >=24.11.0`, matching Vite's own `^20.19.0` floor, so older Node that works in practice (e.g. Node 20 in rolldown CI) is no longer rejected ([#​1865](https://redirect.github.com/voidzero-dev/vite-plus/pull/1865)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- `vp exec --fail-if-no-match`: exit non-zero when one or more `--filter` expressions match no workspace packages. Strict mode previously only warned and returned success, so typoed filters looked successful in CI even though no package command ran ([#​1859](https://redirect.github.com/voidzero-dev/vite-plus/pull/1859)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
##### Bundled Versions
| Tool | Version | Source |
| --------------- | -------- | ------------------------------------------------------------------------------------------------- |
| vite | `8.0.16` | [`f94df87`](https://redirect.github.com/vitejs/vite/commit/f94df87ff03b40b65e29bacdc04cc18c7bccaa4a) |
| rolldown | `1.1.1` | [`d7f919c`](https://redirect.github.com/rolldown/rolldown/commit/d7f919c18980e6b4a26d06bd071d7cf14cf810a7) |
| tsdown | `0.22.3` | [npm](https://npmx.dev/package/tsdown/v/0.22.3) |
| vitest | `4.1.9` | [npm](https://npmx.dev/package/vitest/v/4.1.9) |
| oxlint | `1.70.0` | [npm](https://npmx.dev/package/oxlint/v/1.70.0) |
| oxlint-tsgolint | `0.23.0` | [npm](https://npmx.dev/package/oxlint-tsgolint/v/0.23.0) |
| oxfmt | `0.55.0` | [npm](https://npmx.dev/package/oxfmt/v/0.55.0) |
##### Upgrade
```bash
vp upgrade
```
##### Upgrading from 0.1.x to 0.2.1 Prompt
```md
You are upgrading a project that uses Vite+ (the `vp` CLI) from v0.1.x to v0.2.1.
v0.2.1 has one breaking change vs v0.1.x: it consumes upstream Vitest directly. The `@voidzero-dev/vite-plus-test` wrapper package is removed. `vitest` and the base browser runtime (`@vitest/browser`, `@vitest/browser-preview`) now come in transitively through `vite-plus`. The opt-in browser providers (`@vitest/browser-playwright`, `@vitest/browser-webdriverio`) are NOT shipped by `vite-plus`: any project that runs browser-mode tests must install the provider it uses itself.
Do not run `vp migrate` for this upgrade; it is not reliable enough yet. Make the changes yourself by editing the project's files, then verify by running the tools.
How to run vp: if a global `vp` is available, use it. Otherwise this project only ships the local CLI from the `vite-plus` package, so run vp as the project-local binary (for example via the package manager's exec: pnpm exec, npx, yarn, or bunx). After any install, re-resolve vp so you always run the version currently in the project.
Do the following:
1. Set the `vite-plus` dependency to the exact version `0.2.1` and reinstall, so the new toolchain is installed and the lockfile moves off 0.1.x. In a monorepo, do this for every workspace package that depends on `vite-plus` (a shared `catalog:` entry covers them all at once). Changing the spec to `0.2.1` is what moves the lockfile off the old resolution; a reinstall that leaves the spec unchanged would keep the old version.
2. Remove the `@voidzero-dev/vite-plus-test` wrapper from the project. Search everywhere it could appear: package.json, the lockfile, any workspace or catalog config (such as pnpm-workspace.yaml or .yarnrc.yml), and the source files. Then classify the project and apply the matching case. Note these are not exclusive: a browser-mode project is also handled by case C in addition to removing the wrapper config.
First, determine the project's Vitest usage:
- BROWSER MODE: the project runs Vitest in the browser. It does if a config or test file imports a real browser provider (`vite-plus/test/browser-playwright` or `vite-plus/test/browser-webdriverio`, or the pre-upgrade raw forms `@vitest/browser-playwright` / `@vitest/browser-webdriverio`), or sets `test.browser.enabled`. This needs extra deps regardless of anything below; see case C.
- DIRECT vitest usage: a source or test file imports directly from `vitest` or `@vitest/...`, or a `@vitest/*` package is listed in its dependencies (for example a coverage provider). Plain imports from `vite-plus/test` and `vite-plus/test/*` do NOT count as direct usage; a `vite-plus/test/browser-*` provider import is a browser-mode signal (case C), not direct usage.
Case A - node-mode only (no direct vitest usage, no browser mode; the common case): remove the vitest configuration entirely. In package.json, delete the `vitest` entry from `dependencies` / `devDependencies` in whatever form it takes (a `@voidzero-dev/vite-plus-test` alias, a `catalog:` reference, or a plain version). Also remove the `vitest` entry from every dependency-resolution mechanism in the project: both `overrides` and `resolutions`, pnpm `overrides`/`catalog` (in package.json or pnpm-workspace.yaml), and any catalog entry. If `vitest` appears in more than one of these, remove all of them. Do not add a pinned `vitest`; it arrives transitively through `vite-plus` and the node-mode test command works without it.
Case B - direct vitest usage: pin upstream vitest to the version bundled with vite-plus (4.1.9 for v0.2.1), and upgrade every vitest ecosystem package the project depends on so the whole tree resolves to a single vitest. Set each `@vitest/*` package the project lists (for example `@vitest/coverage-v8`, `@vitest/ui`, `@vitest/browser`) to that same version (4.1.9), since those are pinned to an exact vitest version. Also update any other vitest integration package (such as `vitest-browser-*`) to a release compatible with that vitest version. Leaving an ecosystem package on an older version pulls in a second copy of vitest, which Vitest rejects at runtime.
Case C - browser mode (in addition to removing the wrapper config): you MUST add two deps to the workspace package that runs the browser tests (not the repo root, unless that is where the tests live), both pinned to the bundled vitest version so the tree still resolves to a single vitest:
- The browser provider the project actually uses: `@vitest/browser-playwright@4.1.9` and/or `@vitest/browser-webdriverio@4.1.9`. Without it, config load fails with `Cannot find package '@​vitest/browser-playwright'` from `vite-plus/test/browser-playwright`. Make sure its framework peer is present too (`playwright` for Playwright, `webdriverio` for WebdriverIO); the project usually already has it.
- A direct `vitest@4.1.9`. This is the one case where you DO add a pinned vitest, and it contradicts the "never add vitest" rule that holds for node mode. Reason: under pnpm's isolated node_modules, `vitest` is only a transitive dep of `vite-plus`, so the browser-tester Vite server (rooted at the consumer project) cannot resolve `vitest/internal/browser` or the `vitest > ...` optimizeDeps entries. The symptom is `Failed to resolve import "vitest/internal/browser"` followed by `Failed to connect to the browser session ... within the timeout` and a `no tests` run. vite-plus 0.2.1 ships a `vite-plus:vitest-resolver` plugin meant to rescue this, but it does not reach the separate `@vitest/browser` orchestrator server, so a direct `vitest@4.1.9` (matching the bundled version, single copy preserved) is required. (If a future vite-plus fixes the resolver to cover the browser-tester server, this direct `vitest` may become unnecessary; re-check.)
In all cases, also delete any dependency-resolution config that existed only to accommodate the wrapper or the old vitest, for example pnpm `peerDependencyRules` entries (`allowedVersions` / `ignoreMissing`) referencing `vitest`, `@vitest/*`, or `@voidzero-dev/vite-plus-test`, and the equivalent peer-tweak config in other package managers (such as yarn `packageExtensions`). Leave rules that are unrelated to vitest or the wrapper untouched.
3. Keep the `vite` -> Vite+ core override (it is still required) and set it to the matching exact version: map `vite` to `npm:@​voidzero-dev/vite-plus-core@0.2.1` in whatever override, resolution, or catalog form the project already uses. `@voidzero-dev/vite-plus-core` is released in lockstep with `vite-plus`.
4. Leave imports from `vite-plus/test` (and `vite-plus/test/*`, including `vite-plus/test/browser-playwright`) unchanged; that is the stable public API. Only if a file imports directly from `@voidzero-dev/vite-plus-test`, repoint it to `vite-plus/test`. Leave `declare module 'vitest'` / `declare module '@​vitest/browser*'` type augmentations pointing at the upstream module (they must target the upstream identity to merge).
5. Reinstall so the lockfile reflects your edits, then verify:
- No reference to `@voidzero-dev/vite-plus-test` remains anywhere outside node_modules (source, configs, lockfile).
- The dependency tree resolves to a single `vitest` version (4.1.9) with no duplicate copies. Note that one `vitest@4.1.9:` entry in the lockfile `packages:` section plus one `vitest@4.1.9(...)` key in `snapshots:` is still a single version, not a duplicate.
- The project's tests pass with Vitest's native banner; for browser mode, confirm the suite actually runs in the browser (you get passing test files, not `no tests` or a session timeout). Browser tests also need the browser binary installed (e.g. `npx playwright install chromium`).
- The Vite+ check workflow passes (exit 0). A pre-existing lint/format warning in a file you did not touch is not a failure; report it but do not fix it.
Troubleshooting: if you hit `vitest/internal/browser` resolution errors, or see duplicate `@vitest/browser` / `vite-plus` peer-variant directories under `node_modules/.pnpm` after several sequential installs across this dependency-graph change, do a clean reinstall (remove `node_modules` in the root and all workspaces, remove the Vite optimize caches `node_modules/.vite`, then reinstall) to collapse the stale variants before concluding it is a code problem.
Constraints:
- Do not run `vp migrate`.
- Do not bypass git hooks. If a pre-existing failure blocks you, report it rather than forcing through.
- Make the smallest set of edits that reaches the end state above; do not reformat unrelated files. (For browser mode, the added `vitest` + provider pins ARE part of that minimal end state.)
- When done, give me a short summary: old vs new `vite-plus` version, the files you changed, the test/check results, and call out explicitly any dependency you added beyond the wrapper removal (especially a direct `vitest`) with the reason.
```
**Full Changelog**: <https://github.com/voidzero-dev/vite-plus/compare/v0.2.0...v0.2.1>
##### Published Packages
- `@voidzero-dev/vite-plus-core@0.2.1`
- `vite-plus@0.2.1`
##### Installation
**macOS/Linux:**
```bash
curl -fsSL https://vite.plus | bash
```
**Windows:**
```powershell
irm https://vite.plus/ps1 | iex
```
Or download and run `vp-setup.exe` from the assets below.
### [`v0.2.0`](https://redirect.github.com/voidzero-dev/vite-plus/releases/tag/v0.2.0): vite-plus v0.2.0
[Compare Source](https://redirect.github.com/voidzero-dev/vite-plus/compare/v0.1.24...v0.2.0)
Vite+ now consumes upstream Vitest directly (no wrapper), raises the minimum supported Node.js version to 22.18.0, and ships corepack and devEngines support.
##### Highlights
- **`vp test` now runs upstream Vitest directly (breaking)**: Vite+ used to ship `@voidzero-dev/vite-plus-test`, a rebundled copy of Vitest that lagged upstream releases. That package is removed; `vp test` now runs the real upstream `vitest`, which is installed automatically as a dependency of `vite-plus` (you no longer add `vitest` or `@vitest/*` yourself, and `vite` still resolves to `@voidzero-dev/vite-plus-core` via package-manager overrides). Your `import ... from 'vite-plus/test'` code keeps working unchanged and `vp migrate` updates existing projects ([#​1588](https://redirect.github.com/voidzero-dev/vite-plus/pull/1588)), by [@​Brooooooklyn](https://redirect.github.com/Brooooooklyn)
- **Minimum supported Node.js version raised to `^22.18.0 || >=24.11.0` (breaking)**: Node 20 reached end-of-life and the bundled tsdown already required `^22.18.0`, so the published engines range now matches what `vp pack` can actually deliver; `vp exec` / `vp run` / `vp dlx` reject projects resolving an older Node with the existing incompatibility error ([#​1813](https://redirect.github.com/voidzero-dev/vite-plus/pull/1813)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- **Corepack now works under Vite+**: `corepack` now set up by default, so `corepack enable` and the pnpm/yarn launchers just work, even on Node 25+ which no longer ships it. ([#​1808](https://redirect.github.com/voidzero-dev/vite-plus/pull/1808)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- **devEngines support for runtime and package-manager selection**: Vite+ reads `devEngines.runtime` (ranked above `engines.node`) and `devEngines.packageManager`; auto-pin and `vp migrate` write `devEngines.packageManager`, `vp env pin` / `unpin` target `devEngines.runtime`, and `vp env doctor` reports conflicts instead of silently resolving them ([#​1760](https://redirect.github.com/voidzero-dev/vite-plus/pull/1760)), by [@​fengmk2](https://redirect.github.com/fengmk2)
##### Features
- `vp pm approve-builds`: forward to npm's new `approve-scripts` / `deny-scripts` (npm >= 11.16.0) instead of the previous no-op, matching `pnpm approve-builds` / `bun pm trust`; mixed approve+deny is rejected with actionable guidance and npm's advisory-only caveat is surfaced ([#​1733](https://redirect.github.com/voidzero-dev/vite-plus/pull/1733)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- `vp create`: support local monorepo templates declared in `create.templates` in `vite.config.ts`; `vp create vite:generator` scaffolds a Bingo generator and auto-registers it in the picker, replacing the old package.json-keyword inference ([#​1777](https://redirect.github.com/voidzero-dev/vite-plus/pull/1777)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- `vp create`: detect direct dependencies whose build scripts the package manager gated (e.g. native builds like `better-sqlite3`) and act on them; prompt to approve each (default off) interactively, point at `vp pm approve-builds` non-interactively, or build them with `--approve-builds` ([#​1828](https://redirect.github.com/voidzero-dev/vite-plus/pull/1828)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- `vp config`: add `--no-hooks` and `--no-agent` opt-outs to skip git-hook installation and coding-agent instruction updates ([#​1842](https://redirect.github.com/voidzero-dev/vite-plus/pull/1842)), by [@​leno23](https://redirect.github.com/leno23)
- `vp list -g`: sort the global package list output so entries appear in a stable order ([#​1748](https://redirect.github.com/voidzero-dev/vite-plus/pull/1748)), by [@​liangmiQwQ](https://redirect.github.com/liangmiQwQ)
- Upgrade upstream dependencies: rolldown `1.0.3 -> 1.1.1`, tsdown `0.22.1 -> 0.22.3`, oxlint `1.67.0 -> 1.70.0`, oxfmt `0.52.0 -> 0.55.0`, vitest `4.1.8 -> 4.1.9`, and the oxc toolchain `0.133.0 -> 0.136.0` ([#​1749](https://redirect.github.com/voidzero-dev/vite-plus/pull/1749), [#​1767](https://redirect.github.com/voidzero-dev/vite-plus/pull/1767), [#​1812](https://redirect.github.com/voidzero-dev/vite-plus/pull/1812), [#​1834](https://redirect.github.com/voidzero-dev/vite-plus/pull/1834), [#​1855](https://redirect.github.com/voidzero-dev/vite-plus/pull/1855)), by [@​voidzero-guard](https://redirect.github.com/voidzero-guard)\[bot]
##### Fixes & Enhancements
- Security: resolve open Rust Dependabot advisories by bumping transitive `openssl` `0.10.76 -> 0.10.80` (`openssl-sys` `0.9.112 -> 0.9.116`), fixing five high-severity rust-openssl issues (buffer overflows in key derivation, AES key wrap, and digest finalization; an unchecked PSK/cookie trampoline length leaking adjacent memory; and OCSP-responder undefined behavior: [GHSA-pqf5-4pqq-29f5](https://redirect.github.com/advisories/GHSA-pqf5-4pqq-29f5), [GHSA-8c75-8mhr-p7r9](https://redirect.github.com/advisories/GHSA-8c75-8mhr-p7r9), [GHSA-ghm9-cr32-g9qj](https://redirect.github.com/advisories/GHSA-ghm9-cr32-g9qj), [GHSA-hppc-g8h3-xhp3](https://redirect.github.com/advisories/GHSA-hppc-g8h3-xhp3), [GHSA-xp3w-r5p5-63rr](https://redirect.github.com/advisories/GHSA-xp3w-r5p5-63rr)), and drop the unmaintained, unsound `libyml` ([GHSA-gfxp-f68g-8x78](https://redirect.github.com/advisories/GHSA-gfxp-f68g-8x78), high) by removing dead `serde_yml` code ([#​1742](https://redirect.github.com/voidzero-dev/vite-plus/pull/1742)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- Security (docs site): update `mermaid` `11.13.0 -> 11.15.0` to fix improper `classDef` sanitization in state diagrams that allowed HTML injection ([CVE-2026-41149](https://nvd.nist.gov/vuln/detail/CVE-2026-41149) / [GHSA-ghcm-xqfw-q4vr](https://redirect.github.com/advisories/GHSA-ghcm-xqfw-q4vr), medium severity; `<script>` tags are stripped so it does not reach XSS) ([#​1745](https://redirect.github.com/voidzero-dev/vite-plus/pull/1745)), by [@​renovate](https://redirect.github.com/renovate)\[bot]
- `vp check --fix` / `vp staged`: create/migrate now wrap inline Vite `plugins: [...]` arrays with `lazyPlugins(...)` so plugin factories aren't eagerly executed (and don't hang on open handles) during lint/format/check config loading ([#​1752](https://redirect.github.com/voidzero-dev/vite-plus/pull/1752)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- `vp migrate`: complete pending migration work for projects that already have `vite-plus` installed (scripts, imports, tsconfig types, ESLint/Prettier, legacy hooks, package-manager settings) instead of treating `vite-plus` as migration-complete; fully migrated projects stay idempotent ([#​1821](https://redirect.github.com/voidzero-dev/vite-plus/pull/1821)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- `vp create` / `vp migrate`: detect shorthand `fmt,` / `lint,` config keys so a duplicate inline block is no longer injected ([#​1843](https://redirect.github.com/voidzero-dev/vite-plus/pull/1843)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- IDE oxlint/oxfmt wrappers: set `VP_COMMAND` so `lazyPlugins()` skips framework plugins during LSP config reads, preventing a stray `.svelte-kit` (and similar) directory at the monorepo root ([#​1764](https://redirect.github.com/voidzero-dev/vite-plus/pull/1764)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- `vp lint` / `vp run -r lint` on Windows: keep the absolute `tsgolint` path for workspace lint runs instead of downgrading it to a wrong cwd-relative path ([#​1758](https://redirect.github.com/voidzero-dev/vite-plus/pull/1758)), by [@​semimikoh](https://redirect.github.com/semimikoh)
- oxlint wrapper: set the `tsgolint` path so type-aware lint resolves it ([#​1811](https://redirect.github.com/voidzero-dev/vite-plus/pull/1811)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- `vp install -g`: use a unique backup directory and treat stale-backup cleanup as best-effort so a locked Windows binary no longer fails an otherwise successful reinstall ([#​1753](https://redirect.github.com/voidzero-dev/vite-plus/pull/1753)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- `vp install -g`: remove stale managed binary shims when a reinstalled package drops a bin from its `package.json#bin` ([#​1765](https://redirect.github.com/voidzero-dev/vite-plus/pull/1765)), by [@​liangmiQwQ](https://redirect.github.com/liangmiQwQ)
- `vp create --git`: surface git's actual stdout/stderr when the initial commit fails instead of always blaming `user.name` / `user.email` ([#​1819](https://redirect.github.com/voidzero-dev/vite-plus/pull/1819)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- `vp create vite:generator`: reject `--git` / `--no-git`, since adding a generator to an existing monorepo does not initialize git ([#​1788](https://redirect.github.com/voidzero-dev/vite-plus/pull/1788)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- Global CLI: harden `find_system_tool` against a self-exec loop (skip the running executable's own bin directory) and fix two `vite_global_cli` tests that could hang ([#​1820](https://redirect.github.com/voidzero-dev/vite-plus/pull/1820)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- CLI help: unify alias display ([#​1832](https://redirect.github.com/voidzero-dev/vite-plus/pull/1832)), show supported `run` options ([#​1797](https://redirect.github.com/voidzero-dev/vite-plus/pull/1797)), show `--fail-if-no-match` in `exec` help ([#​1798](https://redirect.github.com/voidzero-dev/vite-plus/pull/1798)), add the `implode` documentation link ([#​1796](https://redirect.github.com/voidzero-dev/vite-plus/pull/1796)), and handle nested-command typo help ([#​1803](https://redirect.github.com/voidzero-dev/vite-plus/pull/1803)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
##### Docs
- Document `vp create` opt-out options ([#​1790](https://redirect.github.com/voidzero-dev/vite-plus/pull/1790)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- Document `vp upgrade` options ([#​1847](https://redirect.github.com/voidzero-dev/vite-plus/pull/1847)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- Align the config overview with the sidebar ([#​1846](https://redirect.github.com/voidzero-dev/vite-plus/pull/1846)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- Sync the documented command lists with the help output ([#​1850](https://redirect.github.com/voidzero-dev/vite-plus/pull/1850)), by [@​jong-kyung](https://redirect.github.com/jong-kyung)
- Clarify lazy plugin side effects ([#​1841](https://redirect.github.com/voidzero-dev/vite-plus/pull/1841)), by [@​leno23](https://redirect.github.com/leno23)
- Add JongKyung's X profile ([#​1844](https://redirect.github.com/voidzero-dev/vite-plus/pull/1844)) and update Christoph's X profile ([#​1845](https://redirect.github.com/voidzero-dev/vite-plus/pull/1845)) on the team page, by [@​jong-kyung](https://redirect.github.com/jong-kyung)
##### Refactor
- Remove the CLI tips system; the shortcuts it printed on `vp install` are already covered by the help system and added unnecessary complexity ([#​1799](https://redirect.github.com/voidzero-dev/vite-plus/pull/1799)), by [@​cpojer](https://redirect.github.com/cpojer)
##### Chore
- Re-enable Renovate dependency updates with a targeted ignore-list ([#​1744](https://redirect.github.com/voidzero-dev/vite-plus/pull/1744)), by [@​fengmk2](https://redirect.github.com/fengmk2)
- Keep generated NAPI bindings during upgrade-deps ([#
> ✂ **Note**
>
> PR body was truncated to here.
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/kenn-io/agentsview).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
Co-authored-by: renovate[bot] <renovate[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Auto-generated ECC bundle from repository analysis.
What This Does
Merging this PR adds repo-local ECC artifacts for both Claude Code and Codex. The generated bundle captures repository patterns, Codex baseline config, and reusable workflow scaffolds derived from git history analysis.
Analysis Scope
Files
.claude/ecc-tools.json.claude/skills/periscope/SKILL.md.agents/skills/periscope/SKILL.md.agents/skills/periscope/agents/openai.yaml.claude/identity.json.codex/config.toml.codex/AGENTS.md.codex/agents/explorer.toml.codex/agents/reviewer.toml.codex/agents/docs-researcher.toml.claude/homunculus/instincts/inherited/periscope-instincts.yamlOptional: Continuous Learning (15 instincts)
This PR also includes instincts for the continuous-learning-v2 skill. These are optional and only useful if you use that skill.
Import after merging:
Review Checklist
ECC Tools | Everything Claude Code