Releases: CHATS-lab/VibeLens
Releases · CHATS-lab/VibeLens
v1.0.8
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>.jsonlplus<sid>/subagents/agent-*.jsonl), Kilo (~/.local/share/kilo/kilo.db, OpencodeParser subclass), Cursor, and Kiro. Auto-discovered by LocalStore; frontendAgentTypeand 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 onstate.output(fallback) +session.parent_idreverse link; Code Buddy viafunction_call_result.providerData.toolResult.renderer.valueJSONtaskId(primary) + regex onoutput.text(fallback). Copilot's sub-agents have no separate trajectory file — thesubagent.started/subagent.completedsummary events fold onto the spawnToolCall.extra.subagent. - Code Buddy multimodal:
image_blob_refcontent parts are read from disk (~/.codebuddy/blobs/<hash>/<hash>.png) and inlined as base64 onContentPart.source.base64so 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.jsonlstem 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 unifiedToolCallBlockpill (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
PLATFORMSrows cite upstream filesystem-layout docs orskills-managedb.rs. /api/extensions/agentsenriched: eachAgentCapabilitynow carriesdirs_by_typeandcounts_by_typeso the frontendsyncTargets.get()cache derivesRecord<type, SyncTarget[]>from one source. NewEXTENSION_TYPE_DIR_FIELDmap +platform_dir_for(platform, type)helper centralize the per-type dir lookup.- Upload pipeline overhaul:
services/upload/agents.pybecomes the per-agent registry with import-time drift checks; content-hash idempotency via theX-Zip-Sha256header lets the server skip body reads for already-imported zips;to_friendly_errormapsjson.JSONDecodeError,sqlite3.DatabaseError,UnicodeDecodeError,FileNotFoundError, andPermissionErrorto 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
VibeLensbrand; 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.
useClickOutsidehook,errorMessageutility, named timing constants (FRICTION_HIGHLIGHT_MS,SCROLL_RETRY_BASE_MS,SCROLL_INITIAL_DELAY_MS), andPERSONALIZATION_TAB_KEYstorage-key constant added to consolidate frontend duplication.
Changed
ExtensionSourceenum collapsed intoAgentType: removes the duplicate 14-value enum andCENTRAL(which had no real users); every consumer now reads fromAgentTypedirectly. Affectsservices/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 (mirrorsclaude.py) and dropped rather than emitted as empty SYSTEM steps. Diagnostics records each drop as a skip. BaseParserrefactored for multi-session-per-file formats; the parser registry consolidates ontoALL_PARSER_CLASSES/PARSERS_BY_AGENT_TYPE, andingest/discovery.pyis 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); restartvibelens serveonce after upgrade. - Anonymizer hardened:
redact_patternsreturns input unchanged when over a 1 MB cap (avoids catastrophic regex backtracking);_transform_valueenforces a 100-frame recursion bound;path_hasherreturns the original match on missing username instead of raisingKeyError. - 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 singleMODE_API_BASE; 8 hardcoded"vibelens-personalization-tab"literals named; 3 magic timing numbers insession-view.tsxnamed. - Spec documentation refreshed across 14 files for accuracy and tighter writing;
spec-context-extractor-refactor.mdrenamed tospec-context.mdsince the refactor it described has shipped.
Fixed
- Upload e2e reliability across every supported agent: SQLite
*.db*sidecar globs in zip discovery, parser-specificALLOWED_EXTENSIONS, deterministic Cursor child step IDs (replacesuuid4()so dedup distinguishes replays), Hermes session-id deny-list, dedup that skips uploads withsessions_parsed=0orerrors>0, and dedup-result reachability viashare_prior_upload_with_tokenso cached responses aren't filtered out by the per-token visibility layer. - Copilot sub-agent:
first_messageand parent step ref were missing on direct file walks; now backfilled. - Claude-web parser: null-id
tool_use/tool_resultpairs 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_contentpreserved 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_inagents 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
Added
- Search disabled by default:
SearchConfig.enabled(defaultfalse) 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/settingsall honour the flag; restart withsettings.search.enabled = true(orVIBELENS_SEARCH__ENABLED=true) to opt back in.
Changed
- Trajectory schema:
Trajectory.timestampis split intoTrajectory.created_at(session start, derived from the first step) andTrajectory.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_atinstead ofcreated_at, and rows sort byupdated_at(withcreated_atfallback) so the most-recently-active session surfaces first. - Search index recency tie-breaker: ranks by
updated_at(withcreated_atfallback) so a long-running active session out-ranks a freshly-started one with no edits. - Cross-agent overlap correlator: interval end uses
updated_atfor accurate bounds, falling back tocreated_at + durationonly whenupdated_atis absent. - Dashboard CSV export: gains an
updated_atcolumn alongsidecreated_at. Period bucketing, daily anchoring, hourly heatmap, and date-range filters keepcreated_atsemantics ("session started in this period"). - LLM digest and context formatter headers: emit
STARTED:always andLAST_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.timestampare renamed tocreated_atto match the schema;SessionContextalso gains anupdated_atfield used by the sampler's recency score. - Dashboard tooltips: every chart and stat card switches to a
MetricListtwo-columnlabel: valuelayout 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,Cacheis split intoCache read+Cache write, per-daySessionsbecomesSessions started,Cost → Est. cost, and percent values move to a dedicatedSharerow. - Session view nav panel polish: the right-side prompt-nav panel drops outer
px-3padding (~24 px narrower), the User/Sub-Agents toggle becomes a square pill flush to both edges, and content keeps a smallpl-2gutter matching the left sidebar.
Fixed
- Skeleton parsers (claude, codex): head-of-file scans only saw the first event, so both
created_atandupdated_atcollapsed to the same value and the session list rendered creation time as if it were activity time. Both parsers now deriveupdated_atfrom the source file'smtime(JSONL files are append-only, so mtime is the timestamp of the latest event). - OpenClaw skeleton: now reads
createdAtfromsessions.jsonseparately fromupdatedAtinstead 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_ator had them collapsed) repopulate from source files. Restartvibelens serveonce after upgrade.
v1.0.6
Added
- Thinking off by default across every LLM backend.
InferenceConfig.thinkinggates reasoning on all backends; the default isfalseand 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.jsonaliasvibelens-nothinkwiththinkingBudget: 0andincludeThoughts: false— there is no upstream env var, see google-gemini/gemini-cli#25122), LiteLLM/Aider/Cursor/Kimi via their per-CLI flag. - Structured
inference.jsonlog per analysis run at~/.vibelens/logs/personalization/{mode}/{id}/inference.jsonand~/.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 reportsmetrics.cost_usd; previously only Claude Code surfaced cost natively. scripts/inference/verify.py— inspectsinference.jsonto confirm runtime matched intent. Flagsthinking=Falseyet 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--modelfrom 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).--versionflag on thevibelensCLI.- 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, andvibelens/data/examples/recipe-book/ship inside the package.discover_config_path()falls back to the bundled default when CWD search finds nothing, andDemoConfig.session_pathsresolves to the bundledrecipe-bookwhenexample_sessionsis empty. PyPI users runningvibelens servefrom 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 defaultlogging.diris now~/.vibelens/logs/instead of<repo>/logs/. Users who overridelogging.dirin 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, sopersonalization/creation/{id}.jsonandlogs/personalization/creation/{id}/share the same{id}. - Removed backend-side JSON schema augmentation.
cli_base.SCHEMA_INSTRUCTION_TEMPLATEand_augment_prompt_with_schemaare gone; the schema is rendered exclusively byprompts/_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.pyrestructured 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-shellstep sovibelens serveworks immediately afteruv 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, andcostalign withdaily_breakdown. - DST-aware
local_date_keyso 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_serverexcluded 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
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.DEFAULTis the initial dropdown value;PERSONALIZED(was "For You") uses the saved user profile; legacypopularityandrelevancesort 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 inlocalStorage), dev-build detection (current > PyPI latest), and a retry affordance when the PyPI fetch fails. Opt-out viaVIBELENS_DISABLE_UPDATE_CHECK=1. New endpoint:GET /api/version. - Timing helpers in
utils/timestamps.py:log_durationcontext manager,timeddecorator, andlog_duration_summaryfor 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/costto 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_costmoved fromservices/dashboard/pricing.py(deleted) tollm/pricing.py, and the parser writes the derived USD cost back tostep.metrics.cost_usdfor every agent step.final_metrics.total_cost_usdis no longerNonefor 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.pyandscoring.pydeleted. - Frontend API and hook conventions enforced: I/O lives in
frontend/src/api/<domain>.ts, cross-cutting state infrontend/src/hooks/, shared timing constants infrontend/src/constants.ts.useEffect-to-notify-parent anti-pattern removed. - LiteLLM backend module renamed from
llm/backends/litellm_backend.pytollm/backends/litellm.py; the "avoid shadowing" concern behind the old suffix doesn't apply to absolute imports. Internal only. - Replaced the
scikit-learndependency withrank-bm25for 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
AgentTypevalue was"claude_code"but the backend enum uses"claude", so/api/upload/commandsreturned 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) andMitigationCard(friction mitigations). Both hold localuseState, 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
Added
- Hermes agent parser (
ingest/parsers/hermes.py) covering JSONL stream + snapshot formats, state.db enrichment, chat-surface project paths, andsystem_prompt/base_urlsurfaced in trajectoryextra. - Frontend test harness (Vitest + jsdom + @testing-library). 34 tests covering every API client and the highest-value hooks.
npm run testruns the full suite in under 1s. Wired into CI. - Per-domain API clients in
frontend/src/api/:analysis.ts(friction + 3 personalization modes, sharesbaseUrl),llm.ts,sessions.ts,dashboard.ts,upload.ts,donation.ts. Components no longer callfetchWithTokendirectly. - 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) runningtsc --noEmit,npm run test, andnpm run buildon 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.py→claude.py(classClaudeCodeParser→ClaudeParser);claude_code_web.py→claude_web.py(ClaudeCodeWebParser→ClaudeWebParser). ExternalAgentTypevalues ("claude","claude_web") unchanged. BaseParser.iter_jsonl_safeaccepts either aPath(file streaming) orstr(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_PREFIXESin codex, claude's already in claude). Base's union renamed to_ALL_KNOWN_SYSTEM_TAG_PREFIXESand 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 touseSessionData, share flow touseShareSession, top-bar rendering toSessionViewHeader.dashboard-view.tsx: 707 → 629 lines. Three fetching effects extracted touseDashboardData; export flow extracted touseDashboardExport.extension-detail-view.tsx: shared layout extracted todetail-shell.tsxso 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 infrontend/src/constants.ts. Previously duplicated across four files with drifted values. CLAUDE.md/DESIGN.mdupdated to describe theapi/,hooks/, andtest/layers, the factory-client pattern, testing conventions, and theuseEffect-to-notify-parent anti-pattern.
Fixed
- Claude duplicate-step-id regression: some
~/.claudesessions (12 out of 3,357 observed locally) were rejected by theTrajectoryvalidator because Claude Code re-emitted identical JSONL entries after compaction replay. Entries are now deduplicated byuuidbefore 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
Tooltipwrapper'sinline-flexspan was not forwarding width, so the innertruncateclass never triggered.
v1.0.3
Fixed
- npm wrapper Python discovery on Windows:
npm/bin/vibelens.jspreferred thepylauncher overpython3/pythonon Windows, which could resolve to a different Python interpreter than the one on PATH wherepip install vibelensran. The wrapper now prefers PATH-basedpython3/pythonfirst and falls back topyonly if neither has vibelens installed. A two-pass search (vibelens-installedfirst, thenany Python ≥3.10) keeps thenot installederror 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
Fixed
- Windows install: lazy-import
fcntl(POSIX-only) and add amsvcrt.lockingfallback sovibelensinstalls and runs on Windows. The previous top-levelimport fcntlinutils/json.pycrashed the CLI at startup. Path.home()captured at import time:StorageConfig/UploadConfig/DonationConfigdefault paths and thePLATFORMSdict both froze the user home at module import, so tests monkey-patchingHOMEorPath.homesaw stale state. Defaults now usedefault_factory;PLATFORMSgets arebuild_platforms()helper for fixtures that need a fresh build.test_agents_endpoint/test_plugin_routes: fixtures now callrebuild_platforms()on setup/teardown so the platform table reflects the patched tmp home.- npm wrapper Python discovery on Windows:
npm/bin/vibelens.jspreferred thepylauncher overpython3/pythonon Windows, which could resolve to a different Python interpreter than the one on PATH wherepip install vibelensran. The wrapper now prefers PATH-basedpython3/pythonfirst and falls back topyonly if neither has vibelens installed. A two-pass search (vibelens-installedfirst, thenany Python ≥3.10) keeps thenot installederror 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 thatNPM_TOKENmust be a granular automation token with 2FA bypass (classic personal access tokens now get a 403 from the registry).
v1.0.1
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}/treeand/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.
ClaudePluginStorenow scans~/.claude/plugins/cache/<marketplace>/<name>/<version>/instead of a singlevibelens/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.pyconvertsagent-tool-huboutput into the bundled two-tier catalog (summary + offsets + per-type JSONs).MCP_SERVERextension type.SessionToolUsagemodel +tool_usage_cachemodule backing the per-session warming cache.build_partial_session_indexfor path-scoped trajectory-index rebuilds.
Fixed
- Explore detail content returned "No content available" for every subagent and command. The catalog emits
tree/.../file.mdURLs for ~5,700 single-file items;_resolve_contentappended/SKILL.mdto any tree URL, producing 404s. A newis_github_single_file_treeheuristic (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/repowithout a/tree/suffix. AddedGITHUB_REPO_RE+ a sharedparse_github_urlnormalizer;download_directory,list_github_tree, andfetch_github_tree_fileall accept bare-repo URLs now (walked from default branch root). - Plugin content display.
_resolve_contenthas a plugin branch that fetchesREADME.mdfirst, then.claude-plugin/plugin.json, instead of always looking forSKILL.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 whatuninstall_extensionexpected. Directory-shaped items keep the{dir}/{name}/layout. - Recommendation L4 crash when catalog items had
description=None. Extracted template building into_build_rationale_candidateswithitem.description or ""coercion; the pipeline now returns rationales end-to-end instead of raisingAttributeError. - LiteLLM pricing: Kimi / DeepSeek / Qwen rates corrected against official sources;
claude-opus-4-7pricing 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-hubformat.AgentExtensionItemfield 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
categoryandplatformquery parameters (accepted-but-ignored for backward compatibility). Metadata endpoint returnstopicsinstead ofcategories. - 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_cacheonly 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-controltrack withbg-panel shadow-smactive 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.jsonschema 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_methodpayloads. Every install now fetches fromsource_urlat install time. - Frontend "Category" and "Platform" filter dropdowns in the Explore tab.
Disabled (temporarily)
_enrich_continuation_refsis 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
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
CatalogInstallButtonwith diff-based sync target dialog replaces static "Installed" badges - GitHub auth —
GITHUB_TOKENenv 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.