Skip to content

Releases: CHATS-lab/VibeLens

v1.0.8

28 Apr 02:31

Choose a tag to compare

Added

  • Six new parsers: GitHub Copilot CLI (~/.copilot/session-state/<uuid>/events.jsonl), OpenCode (~/.local/share/opencode/opencode.db), Code Buddy (~/.codebuddy/projects/<hash>/<sid>.jsonl plus <sid>/subagents/agent-*.jsonl), Kilo (~/.local/share/kilo/kilo.db, OpencodeParser subclass), Cursor, and Kiro. Auto-discovered by LocalStore; frontend AgentType and upload constants gain entries for all six.
  • Sub-agent linkage for the new parsers where the format records it: OpenCode/Kilo via tool.state.metadata.sessionId (primary) + regex on state.output (fallback) + session.parent_id reverse link; Code Buddy via function_call_result.providerData.toolResult.renderer.value JSON taskId (primary) + regex on output.text (fallback). Copilot's sub-agents have no separate trajectory file — the subagent.started/subagent.completed summary events fold onto the spawn ToolCall.extra.subagent.
  • Code Buddy multimodal: image_blob_ref content parts are read from disk (~/.codebuddy/blobs/<hash>/<hash>.png) and inlined as base64 on ContentPart.source.base64 so the UI can render screenshots without filesystem-sandboxing concerns.
  • Hermes parser: <skill_view> / <skill_call> events tagged on parser output; the strict \d{8}_\d{6}_[0-9a-f]+ session-id regex is replaced with a deny-list of non-session filenames so any other .jsonl stem is a session candidate.
  • Compaction + skill detection promoted to typed fields on ToolCall (is_compaction, is_skill); semantics unified across every parser. Skill activations now render through the unified ToolCallBlock pill (Skill /<name>) instead of a separate user-source step.
  • Twelve new agent types for the extension system (AMP, AUGMENT, AUTOCLAW, EASYCLAW, FACTORY, JUNIE, OB1, QCLAW, QODER, TRAE, TRAE_CN, WORKBUDDY). Corresponding PLATFORMS rows cite upstream filesystem-layout docs or skills-manage db.rs.
  • /api/extensions/agents enriched: each AgentCapability now carries dirs_by_type and counts_by_type so the frontend syncTargets.get() cache derives Record<type, SyncTarget[]> from one source. New EXTENSION_TYPE_DIR_FIELD map + platform_dir_for(platform, type) helper centralize the per-type dir lookup.
  • Upload pipeline overhaul: services/upload/agents.py becomes the per-agent registry with import-time drift checks; content-hash idempotency via the X-Zip-Sha256 header lets the server skip body reads for already-imported zips; to_friendly_error maps json.JSONDecodeError, sqlite3.DatabaseError, UnicodeDecodeError, FileNotFoundError, and PermissionError to one-line summaries while preserving the raw text in collapsible details. Frontend wizard rebuilt around the registry with select-all / clear bulk actions and an "Already imported" amber result variant.
  • CLI startup banner with live progress spinner across parsing and index-build phases.
  • Friction empty-state guidance when no productivity tips are produced; tutorial close buttons added to personalization and friction panels.
  • Frontend logo wordmark replaces the text-only VibeLens brand; per-agent icons + session counts surface in filter dropdowns; session duration moves into the cost-pill tooltip; dashboard totals card renders duration as decimal hours.
  • ToolCall + Result merged into a single collapsible pill in the session view.
  • useClickOutside hook, errorMessage utility, named timing constants (FRICTION_HIGHLIGHT_MS, SCROLL_RETRY_BASE_MS, SCROLL_INITIAL_DELAY_MS), and PERSONALIZATION_TAB_KEY storage-key constant added to consolidate frontend duplication.

Changed

  • ExtensionSource enum collapsed into AgentType: removes the duplicate 14-value enum and CENTRAL (which had no real users); every consumer now reads from AgentType directly. Affects services/extensions/{platforms, catalog_resolver}.py, deps.py, schemas/extensions.py, and the corresponding test files.
  • Code Buddy CLI command echoes dropped: <command-name>, <local-command-stdout>, <system-reminder>, etc. detected via regex (mirrors claude.py) and dropped rather than emitted as empty SYSTEM steps. Diagnostics records each drop as a skip.
  • BaseParser refactored for multi-session-per-file formats; the parser registry consolidates onto ALL_PARSER_CLASSES / PARSERS_BY_AGENT_TYPE, and ingest/discovery.py is deleted — parsers now self-declare allowed extensions and the index walk picks them up by file type.
  • Index cache version bumped 11 → 19 across this cycle. Each bump forces a rebuild so existing caches repopulate with the new fields (multimodal blobs, typed is_compaction / is_skill, unified skill rendering); restart vibelens serve once after upgrade.
  • Anonymizer hardened: redact_patterns returns input unchanged when over a 1 MB cap (avoids catastrophic regex backtracking); _transform_value enforces a 100-frame recursion bound; path_hasher returns the original match on missing username instead of raising KeyError.
  • Frontend duplication consolidated: 3 dropdown click-outside handlers → useClickOutside; 25 error-message expressions → errorMessage; 4 maps for tab → mode → API → endpoint indirection collapsed onto a single MODE_API_BASE; 8 hardcoded "vibelens-personalization-tab" literals named; 3 magic timing numbers in session-view.tsx named.
  • Spec documentation refreshed across 14 files for accuracy and tighter writing; spec-context-extractor-refactor.md renamed to spec-context.md since the refactor it described has shipped.

Fixed

  • Upload e2e reliability across every supported agent: SQLite *.db* sidecar globs in zip discovery, parser-specific ALLOWED_EXTENSIONS, deterministic Cursor child step IDs (replaces uuid4() so dedup distinguishes replays), Hermes session-id deny-list, dedup that skips uploads with sessions_parsed=0 or errors>0, and dedup-result reachability via share_prior_upload_with_token so cached responses aren't filtered out by the per-token visibility layer.
  • Copilot sub-agent: first_message and parent step ref were missing on direct file walks; now backfilled.
  • Claude-web parser: null-id tool_use / tool_result pairs collided on a single dict key — pair positionally via FIFO so all artifact tools survive; attachment-only human messages no longer drop (synthesise [Attached: ...] placeholder); extracted_content preserved on attachment dicts for downstream analytics.
  • Session list filter switch: switching agent / view mode left the previous expanded-project set and page index intact, leaving users on a fully collapsed list past the end of the new shorter list. Now resets both.
  • Local extensions card: installed_in agents render alphabetically rather than in filesystem-walk order.
  • Frontend session view: new sub-agents on expand now scroll into view; user / plan / sub-agent first-message previews truncate to one line; logo mark / wordmark gap tightened.
  • Friction empty-state copy polished.

CI

  • PyPI and npm publish workflow made idempotent on tag re-runs so a re-pushed tag doesn't double-publish or fail with a non-recoverable error.

v1.0.7

26 Apr 01:26

Choose a tag to compare

Added

  • Search disabled by default: SearchConfig.enabled (default false) gates the BM25F session-search index. Profiling on a 1.5 K-session corpus showed the index owned 80-90% of process RSS (3.7 GB → 739 MB after this change); most users never type into the sidebar search box, so the build is now skipped on startup. Lifespan, /api/sessions/search, and /api/settings all honour the flag; restart with settings.search.enabled = true (or VIBELENS_SEARCH__ENABLED=true) to opt back in.

Changed

  • Trajectory schema: Trajectory.timestamp is split into Trajectory.created_at (session start, derived from the first step) and Trajectory.updated_at (last activity, derived from the last step). The parser pipeline backfills both, and the model validator does the same on direct construction.
  • Session list time: the sidebar now shows updated_at instead of created_at, and rows sort by updated_at (with created_at fallback) so the most-recently-active session surfaces first.
  • Search index recency tie-breaker: ranks by updated_at (with created_at fallback) so a long-running active session out-ranks a freshly-started one with no edits.
  • Cross-agent overlap correlator: interval end uses updated_at for accurate bounds, falling back to created_at + duration only when updated_at is absent.
  • Dashboard CSV export: gains an updated_at column alongside created_at. Period bucketing, daily anchoring, hourly heatmap, and date-range filters keep created_at semantics ("session started in this period").
  • LLM digest and context formatter headers: emit STARTED: always and LAST_ACTIVE: only when it differs, so prompts don't carry redundant timestamps.
  • Session view header: adds a "Last activity" pill next to the existing "Session start time" pill, shown only when the two differ.
  • Internal renames for clarity: SessionAggregate.timestamp / SessionContext.timestamp / _Chain.timestamp are renamed to created_at to match the schema; SessionContext also gains an updated_at field used by the sampler's recency score.
  • Dashboard tooltips: every chart and stat card switches to a MetricList two-column label: value layout with monospace right-aligned values and a tone palette (input / output / cache_read / cache_write / total / cost / count / percent / muted). Wording cleanups in the same pass: Total → All time, Cache is split into Cache read + Cache write, per-day Sessions becomes Sessions started, Cost → Est. cost, and percent values move to a dedicated Share row.
  • Session view nav panel polish: the right-side prompt-nav panel drops outer px-3 padding (~24 px narrower), the User/Sub-Agents toggle becomes a square pill flush to both edges, and content keeps a small pl-2 gutter matching the left sidebar.

Fixed

  • Skeleton parsers (claude, codex): head-of-file scans only saw the first event, so both created_at and updated_at collapsed to the same value and the session list rendered creation time as if it were activity time. Both parsers now derive updated_at from the source file's mtime (JSONL files are append-only, so mtime is the timestamp of the latest event).
  • OpenClaw skeleton: now reads createdAt from sessions.json separately from updatedAt instead of mapping both fields to one value.
  • Index cache version bumped to v12: forces a clean rebuild so existing v11 caches (whose entries lacked created_at / updated_at or had them collapsed) repopulate from source files. Restart vibelens serve once after upgrade.

v1.0.6

24 Apr 20:09

Choose a tag to compare

Added

  • Thinking off by default across every LLM backend. InferenceConfig.thinking gates reasoning on all backends; the default is false and each backend translates this to its native disable mechanism: Claude Code (CLAUDE_CODE_DISABLE_THINKING=1), Codex (-c web_search=disabled -c model_reasoning_effort=none), OpenClaw (--thinking off), OpenCode (--variant minimal), Gemini (project-scoped <cwd>/.gemini/settings.json alias vibelens-nothink with thinkingBudget: 0 and includeThoughts: false — there is no upstream env var, see google-gemini/gemini-cli#25122), LiteLLM/Aider/Cursor/Kimi via their per-CLI flag.
  • Structured inference.json log per analysis run at ~/.vibelens/logs/personalization/{mode}/{id}/inference.json and ~/.vibelens/logs/friction/{id}/inference.json. Captures the config snapshot (backend, model, thinking, timeout, max_output_tokens, temperature) plus per-call metrics (prompt/completion/reasoning/thinking tokens, cost, duration) for every LLM call in the pipeline.
  • Post-parse cost backfill via pricing.compute_cost_from_tokens. Every CLI backend now reports metrics.cost_usd; previously only Claude Code surfaced cost natively.
  • scripts/inference/verify.py — inspects inference.json to confirm runtime matched intent. Flags thinking=False yet reasoning > 0, missing cost, and config-vs-runtime drift.
  • scripts/inference/run_all_backends.py — fans one analysis mode across N backends in parallel, resolving each backend's own catalog-default model (prevents a single --model from breaking the fan-out). Defaults to 5 backends, --no-thinking, 15 sampled sessions. Produces a comparison table and per-backend stderr tails on failure.
  • scripts/inference/CLAUDE.md — documents the Test → Verify → Report loop, the thinking-disable matrix per backend, raw CLI session-log locations, the config-propagation pitfall, and per-backend quirks (Gemini schema-type drift without reasoning, OpenCode provider auth, Codex --ephemeral, OpenClaw stderr envelope).
  • --version flag on the vibelens CLI.
  • Agent logo icons (Claude, Codex, Gemini, Aider, OpenClaw, OpenCode, Cursor, Kimi, Amp) across the docs site and the frontend agent filter.
  • Copy All tips dialog in the friction panel for quick exporting of every actionable fix.
  • Dedicated analysis cwd per mode: ~/.vibelens/personalization/{creation,evolution,recommendation}/ and ~/.vibelens/friction/. Keeps CLI session files (claude/codex/gemini/openclaw) segregated from the user's working directories.
  • Bundled default config and example sessions in the wheel. vibelens/data/config/default.yaml, vibelens/data/config/demo.yaml, and vibelens/data/examples/recipe-book/ ship inside the package. discover_config_path() falls back to the bundled default when CWD search finds nothing, and DemoConfig.session_paths resolves to the bundled recipe-book when example_sessions is empty. PyPI users running vibelens serve from any directory see the example sessions and inherit sane defaults.
  • Demo mode seeds bundled example skills into the central extension store so recommendations and evolution have populated starting state.
  • Session scroll controls (jump-to-top and jump-to-bottom buttons) in the session viewer.

Changed

  • Log home moved to ~/.vibelens/logs/. The default logging.dir is now ~/.vibelens/logs/ instead of <repo>/logs/. Users who override logging.dir in YAML are unaffected.
  • Analysis IDs are now time-sortable. generate_analysis_id() returns {YYYYMMDDTHHMMSS}-{8char} (e.g. 20260423T171405-sJtL_vC1) instead of an opaque 16-char token. Old IDs on disk keep working — the format is not validated on read. Each per-run log directory is named by the analysis ID, so personalization/creation/{id}.json and logs/personalization/creation/{id}/ share the same {id}.
  • Removed backend-side JSON schema augmentation. cli_base.SCHEMA_INSTRUCTION_TEMPLATE and _augment_prompt_with_schema are gone; the schema is rendered exclusively by prompts/_output_envelope.j2. Small models (gpt-5-nano in particular) no longer see a duplicate schema block and no longer echo the schema verbatim as their response.
  • services/inference_shared.py restructured into focused helpers (extract_all_contexts, run_batches_concurrent, run_synthesis, aggregate_final_metrics) with output-cap guards to keep per-call prompts under model limits.
  • Prompts consolidated: unified example-reference markup, parameterized output caps (max proposals / workflow patterns), and restructured output rules for consistency across creation, evolution, recommendation, and friction modes.
  • Sidebar session-group sort now places analysis-internal cwds (~/.vibelens/personalization/*, ~/.vibelens/friction/*) at the bottom of the left bar. Real user projects surface first, dot-prefixed projects next, analysis runs last.
  • Install scripts rewritten with confirmation prompts and a uv tool update-shell step so vibelens serve works immediately after uv install.
  • README rewritten with clearer install section, bundled-examples documentation, and an updated feature summary.

Fixed

  • Dashboard daily stats now bucket by step timestamp (not session creation). Cross-day sessions contribute to each day they touched; messages, tokens, and cost align with daily_breakdown.
  • DST-aware local_date_key so day boundaries fall on the user's wall-clock date instead of UTC.
  • "Why this helps" card is now fully clickable and the SearchBar styling is aligned with the rest of the controls.
  • mcp_server excluded from the bundled catalog (was slipping in and confusing the extension browser).
  • Publish workflow (.github/workflows/publish.yml) is idempotent when a release tag already exists on GitHub.

v1.0.5

22 Apr 20:03

Choose a tag to compare

Added

  • Ranked BM25F session search. /api/sessions/search?q=... now returns [{session_id, score}] ordered by relevance instead of a flat id list. Session search scores across four fields (user_prompts, agent_messages, tool_calls, session_id) with a session_id exact/first-segment-prefix tier that dominates content matches. Cold Tier 2 build ~42s on 1,362 real sessions; query p50 1.5ms, p95 2.5ms. Session list UI renders results in rank order; source-filter checkbox dialog removed.
  • Shared BM25F search core at services/search/ (tokenizer, InvertedIndex, ranking helpers). Both the extension catalog and session search build on the same engine, so ranking improvements land in both places automatically.
  • Redesigned extension catalog search with tiered name-match (exact > all-tokens > partial-token > substring) dominating a BM25F composite blended with quality, popularity, recency, and profile signals. New SortMode.DEFAULT is the initial dropdown value; PERSONALIZED (was "For You") uses the saved user profile; legacy popularity and relevance sort values coerced at the API boundary. Query p50 ~37ms at 28K items.
  • Version display and update prompt in the sidebar. Shows the running version, polls PyPI (1 h TTL) for the latest stable release, and surfaces a copyable upgrade command matching the detected install method (uv / pip / npx). Supports skip-this-version (persisted in localStorage), dev-build detection (current > PyPI latest), and a retry affordance when the PyPI fetch fails. Opt-out via VIBELENS_DISABLE_UPDATE_CHECK=1. New endpoint: GET /api/version.
  • Timing helpers in utils/timestamps.py: log_duration context manager, timed decorator, and log_duration_summary for batch aggregates. Grepable output format (timing op=... duration_ms=...) applied to session-search build, ingest parsing, and dashboard analytics hot paths.
  • Copy buttons on user, agent, and plan blocks in the session view.
  • Click-to-copy on the session id badge in the session header. Click copies the full UUID; the Hash icon briefly becomes a Check and the tooltip shows "Copied!".

Changed

  • Dashboard daily / period stats split by step timestamp. A session spanning two days now contributes messages / tokens / cost to both daily bars and both period windows based on when each step happened, not the session's creation timestamp. Session-level metrics (session_count, hourly_distribution, weekday_hour_heatmap, duration) still anchor to creation time so "peak hours" and the yearly activity heatmap keep their intended semantics.
  • Per-step cost now populated during ingest. compute_step_cost / compute_trajectory_cost moved from services/dashboard/pricing.py (deleted) to llm/pricing.py, and the parser writes the derived USD cost back to step.metrics.cost_usd for every agent step. final_metrics.total_cost_usd is no longer None for Claude / Hermes / Codex sessions. CACHE_VERSION bumped to 5 to force a one-time rebuild of the on-disk index cache.
  • Recommendation engine now uses the shared ranker — "Personalized" catalog sort and L3 recommendation retrieval go through rank_catalog(SortMode.PERSONALIZED) instead of a separate TF-IDF path. services/recommendation/retrieval.py and scoring.py deleted.
  • Frontend API and hook conventions enforced: I/O lives in frontend/src/api/<domain>.ts, cross-cutting state in frontend/src/hooks/, shared timing constants in frontend/src/constants.ts. useEffect-to-notify-parent anti-pattern removed.
  • LiteLLM backend module renamed from llm/backends/litellm_backend.py to llm/backends/litellm.py; the "avoid shadowing" concern behind the old suffix doesn't apply to absolute imports. Internal only.
  • Replaced the scikit-learn dependency with rank-bm25 for a smaller install footprint.

Fixed

  • Storage now auto-detects new and modified sessions without requiring a server restart.
  • Upload dialog "Failed to load command" for Claude Code. The frontend AgentType value was "claude_code" but the backend enum uses "claude", so /api/upload/commands returned 400 and the panel fell back to the error placeholder. Renamed the frontend value to "claude" (display label "Claude Code" unchanged).
  • React state leaks from index-based keys on PatternCard (workflow patterns) and MitigationCard (friction mitigations). Both hold local useState, and the mitigations list is sorted by confidence each render, so reordering leaked expansion state between cards. Switched to stable title-based keys.
  • Frontmatter parse warnings now include the source path so skill/command/subagent authors can locate a malformed document without grepping for the exception.

v1.0.4

20 Apr 22:49

Choose a tag to compare

Added

  • Hermes agent parser (ingest/parsers/hermes.py) covering JSONL stream + snapshot formats, state.db enrichment, chat-surface project paths, and system_prompt / base_url surfaced in trajectory extra.
  • Frontend test harness (Vitest + jsdom + @testing-library). 34 tests covering every API client and the highest-value hooks. npm run test runs the full suite in under 1s. Wired into CI.
  • Per-domain API clients in frontend/src/api/: analysis.ts (friction + 3 personalization modes, shares baseUrl), llm.ts, sessions.ts, dashboard.ts, upload.ts, donation.ts. Components no longer call fetchWithToken directly.
  • Reusable frontend hooks in frontend/src/hooks/: useJobPolling (terminal-state job polls), useCostEstimate (POST-estimate → dialog flow), useCopyFeedback (clipboard + tri-state feedback), useResetOnKey (monotonic reset signal), useSessionData (trajectories + stats + flow), useShareSession (share dialog + link copy), useDashboardData, useDashboardExport.
  • Frontend CI job (.github/workflows/ci.yml) running tsc --noEmit, npm run test, and npm run build on every push and PR, in parallel with the existing Python matrix.
  • Sticky back button on extension detail pages (Local + Explore + Recommend/Customize/Evolve) that stays pinned at the top-left while scrolling.

Changed

  • Renames: ingest/parsers/claude_code.pyclaude.py (class ClaudeCodeParserClaudeParser); claude_code_web.pyclaude_web.py (ClaudeCodeWebParserClaudeWebParser). External AgentType values ("claude", "claude_web") unchanged.
  • BaseParser.iter_jsonl_safe accepts either a Path (file streaming) or str (in-memory content), replacing the private per-parser JSONL loops that lived in claude, codex, hermes, openclaw.
  • Agent-specific system-tag prefixes moved out of base into their owning parsers (_CODEX_SYSTEM_TAG_PREFIXES in codex, claude's already in claude). Base's union renamed to _ALL_KNOWN_SYSTEM_TAG_PREFIXES and documented as an agent-agnostic fallback for demo-mode ATIF loading.
  • Route-level code splitting via React.lazy. Main bundle dropped from 924 KB to 302 KB (gzip 260 KB → 89 KB, ~3× smaller). Heavy dependencies (markdown renderer 103 KB gzip, syntax highlighting, flow diagram) now load on demand.
  • session-view.tsx: 814 → 407 lines. Data fetching extracted to useSessionData, share flow to useShareSession, top-bar rendering to SessionViewHeader.
  • dashboard-view.tsx: 707 → 629 lines. Three fetching effects extracted to useDashboardData; export flow extracted to useDashboardExport.
  • extension-detail-view.tsx: shared layout extracted to detail-shell.tsx so catalog and local detail views share scaffolding without duplication.
  • Extension detail back-button label shortened from "Back to extensions" / "Back to local extensions" to just "Back".
  • Shared frontend timing constants (COPY_FEEDBACK_MS, JOB_POLL_INTERVAL_MS, RESIZE_DEBOUNCE_MS) consolidated in frontend/src/constants.ts. Previously duplicated across four files with drifted values.
  • CLAUDE.md / DESIGN.md updated to describe the api/, hooks/, and test/ layers, the factory-client pattern, testing conventions, and the useEffect-to-notify-parent anti-pattern.

Fixed

  • Claude duplicate-step-id regression: some ~/.claude sessions (12 out of 3,357 observed locally) were rejected by the Trajectory validator because Claude Code re-emitted identical JSONL entries after compaction replay. Entries are now deduplicated by uuid before step assembly.
  • Gemini missing agent.model_name: the agent-level model was never populated (0% local coverage). Derived it from the most recently-seen step model, restoring 100% coverage.
  • Sub-tab bar now hides for every detail page (Local, Explore, and the Recommend/Customize/Evolve analysis detail views), not just Local. Viewing an extension no longer shows the noisy sub-tab header.
  • Filter-bar skill counts refresh after uninstall from the detail view. Previously "Claude (5)" stayed stale after deleting the last Claude-synced skill.
  • Re-clicking the top-level "Personalization" nav while on a detail page returns to the list. Previously it was a no-op because setMainView("skills") was already the current state.
  • File-tree filename truncation now shows ellipsis for long paths. The Tooltip wrapper's inline-flex span was not forwarding width, so the inner truncate class never triggered.

v1.0.3

20 Apr 22:47

Choose a tag to compare

Fixed

  • npm wrapper Python discovery on Windows: npm/bin/vibelens.js preferred the py launcher over python3 / python on Windows, which could resolve to a different Python interpreter than the one on PATH where pip install vibelens ran. The wrapper now prefers PATH-based python3 / python first and falls back to py only if neither has vibelens installed. A two-pass search (vibelens-installed first, then any Python ≥3.10) keeps the not installed error path working for end users who haven't installed the package yet.

Changed

  • Publish workflow (.github/workflows/publish.yml) now creates a GitHub Release (with changelog-extracted release notes and dist/ artifacts attached) after PyPI upload succeeds. Previously the workflow only pushed to PyPI and the GitHub Releases page was not auto-updated.

v1.0.2

19 Apr 04:48

Choose a tag to compare

Fixed

  • Windows install: lazy-import fcntl (POSIX-only) and add a msvcrt.locking fallback so vibelens installs and runs on Windows. The previous top-level import fcntl in utils/json.py crashed the CLI at startup.
  • Path.home() captured at import time: StorageConfig / UploadConfig / DonationConfig default paths and the PLATFORMS dict both froze the user home at module import, so tests monkey-patching HOME or Path.home saw stale state. Defaults now use default_factory; PLATFORMS gets a rebuild_platforms() helper for fixtures that need a fresh build.
  • test_agents_endpoint / test_plugin_routes: fixtures now call rebuild_platforms() on setup/teardown so the platform table reflects the patched tmp home.
  • npm wrapper Python discovery on Windows: npm/bin/vibelens.js preferred the py launcher over python3 / python on Windows, which could resolve to a different Python interpreter than the one on PATH where pip install vibelens ran. The wrapper now prefers PATH-based python3 / python first and falls back to py only if neither has vibelens installed. A two-pass search (vibelens-installed first, then any Python ≥3.10) keeps the not installed error path working for end users who haven't installed the package yet.

Changed

  • Publish workflow (.github/workflows/publish.yml) now creates a GitHub Release (with changelog-extracted release notes and dist/ artifacts attached) after PyPI upload succeeds. Previously the workflow only pushed to PyPI and the GitHub Releases page was not auto-updated.

Docs

  • .github/workflows/npm-publish.yml: header note flagging that NPM_TOKEN must be a granular automation token with 2FA bypass (classic personal access tokens now get a 403 from the registry).

v1.0.1

19 Apr 04:48

Choose a tag to compare

Added

  • Local extensions tab now manages skills, subagents, commands, and plugins under one "Local" header with a pill-style type selector. Each type gets install, uninstall, sync-to-agents, and (for editable types) inline editing. Cards click through to a full detail page.
  • Extension detail page (shared by Local and Explore) with a collapsible file-tree sidebar, per-file preview/code modes, optional Save in code mode, and a sticky "On this page" TOC that follows scroll. Non-markdown files (json, yaml, py, sh, …) render in syntax-highlighted code blocks; JSON is pretty-printed.
  • Explore pill-style type selector replacing the type dropdown. Plugin pill sits between Skill and Subagent; Local tab mirrors the same ordering.
  • Per-type tree/file API: GET /api/extensions/{type}s/{name}/tree and /files/{path} expose the on-disk directory for any locally-installed extension. Path-traversal guarded, 500-entry walk cap, 200 KB file-read cap. Catalog gets an equivalent /catalog/{id}/tree + /files/{path} pair that walks GitHub's Contents API.
  • Claude plugin discovery across every marketplace. ClaudePluginStore now scans ~/.claude/plugins/cache/<marketplace>/<name>/<version>/ instead of a single vibelens/ bucket, so plugins installed via /plugin install (superpowers, local-plugins, etc.) surface in Local. Plugins auto-import into the central VibeLens store on startup, mirroring the skill flow.
  • Uninstall confirmation dialog shared by the card and the detail page. Lists every agent the item is synced to and warns that confirming removes it from all of them.
  • Topics "+N more" toggle on the detail page when an item has more than 5 topics.
  • scripts/build_catalog.py converts agent-tool-hub output into the bundled two-tier catalog (summary + offsets + per-type JSONs).
  • MCP_SERVER extension type.
  • SessionToolUsage model + tool_usage_cache module backing the per-session warming cache.
  • build_partial_session_index for path-scoped trajectory-index rebuilds.

Fixed

  • Explore detail content returned "No content available" for every subagent and command. The catalog emits tree/.../file.md URLs for ~5,700 single-file items; _resolve_content appended /SKILL.md to any tree URL, producing 404s. A new is_github_single_file_tree heuristic (extension whitelist) routes single-file sources through the correct raw URL.
  • Catalog plugin install + content fetch for bare-repo URLs. Around 10% of catalog plugins use https://github.com/owner/repo without a /tree/ suffix. Added GITHUB_REPO_RE + a shared parse_github_url normalizer; download_directory, list_github_tree, and fetch_github_tree_file all accept bare-repo URLs now (walked from default branch root).
  • Plugin content display. _resolve_content has a plugin branch that fetches README.md first, then .claude-plugin/plugin.json, instead of always looking for SKILL.md. Non-plugin bare-repo URLs fall back to the repo's top-level README at HEAD.
  • Subagent / command install layout. Single-file items land at {dir}/{name}.md, matching what uninstall_extension expected. Directory-shaped items keep the {dir}/{name}/ layout.
  • Recommendation L4 crash when catalog items had description=None. Extracted template building into _build_rationale_candidates with item.description or "" coercion; the pipeline now returns rationales end-to-end instead of raising AttributeError.
  • LiteLLM pricing: Kimi / DeepSeek / Qwen rates corrected against official sources; claude-opus-4-7 pricing added + normalizer prefix extended.
  • Files that produce no parseable trajectory (Claude Code Desktop file-history snapshots, etc.) are memoized in the index cache and skipped on subsequent startups, eliminating the per-startup parse-and-fail loop.

Changed

  • Catalog schema migrated to agent-tool-hub format. AgentExtensionItem field names aligned to the hub; tags → topics, license_name → license. Detail-only fields (scores, item_metadata, readme_description, repo_description, author, author_followers, contributors_count, created_at, discovery_origin, validation_errors) load on demand via byte offsets.
  • Catalog list API drops category and platform query parameters (accepted-but-ignored for backward compatibility). Metadata endpoint returns topics instead of categories.
  • Catalog scoring weights rebalanced (relevance 50%, quality 30%, popularity 15%, composability 5%) since platforms is unavailable this release.
  • Plugin store layout: central store remains at ~/.vibelens/plugins/ (canonical Claude layout); Claude agent store widens to ~/.claude/plugins/cache/ and walks two levels (<marketplace>/<name>/).
  • Cache gating in services/extensions/catalog: _content_cache / _tree_cache only cache successful results, so a transient GitHub 503 no longer pins an hour of errors.
  • Type selector (Local + Explore) uses the DESIGN.md Apple-style pill pattern (bg-control track with bg-panel shadow-sm active pill) instead of the old segmented toggle or dropdown.
  • Recommendation card background matches the Explore list card (border-card bg-panel hover:bg-control/80).
  • Startup latency increases ~1–3s to warm the new catalog. The legacy ~/.vibelens/catalog/ user cache is deleted on startup (contents not migrated).
  • Trajectory-index cache uses per-file invalidation instead of all-or-nothing. Touching one session JSONL re-parses only that file (~200 ms) rather than rebuilding the whole index (~12 s). Cache file ~/.vibelens/session_index.json schema bumps to v3; pre-existing v2 caches are discarded cleanly on first startup.
  • Dashboard tool-usage warming uses a persisted per-session cache at ~/.vibelens/tool_usage_cache.json. Warm restarts skip ~99% of trajectory loading and complete in <1 s instead of ~2 m 43 s. Cold start cost is unchanged but writes the cache for subsequent runs.

Removed

  • Catalog install_content / install_method payloads. Every install now fetches from source_url at install time.
  • Frontend "Category" and "Platform" filter dropdowns in the Explore tab.

Disabled (temporarily)

  • _enrich_continuation_refs is commented out — the chain extractor has a bug that misses some links. Re-enable once the bug is fixed.

Unsupported this release

  • HOOK install from the catalog returns 501. Hook items still browse and view fine.
  • MCP_SERVER install from the catalog returns 501.
  • REPO install from the catalog returns 501 (the hub does not emit REPO items).

v1.0.0

17 Apr 04:13

Choose a tag to compare

Highlights

  • Unified extensions system with BaseExtensionService[T], consolidated API package, and typed frontend client
  • Catalog install via services — skills, commands, subagents, and hooks route through their respective services for central + agent sync
  • Install/manage UI — reusable CatalogInstallButton with diff-based sync target dialog replaces static "Installed" badges
  • GitHub authGITHUB_TOKEN env var support raises API rate limit from 60 to 5,000 req/hr
  • Recommendation pipeline — L1-L4 engine with TF-IDF retrieval, multi-signal scoring, and frontend view
  • Light mode — full light/dark/system theme with semantic color tokens
  • Catalog explorer — browse, search, filter, and install from 1,499 catalog items
  • Domain-based logging — 8-domain routing table with per-domain log files and configurable levels

See CHANGELOG.md for full details.