- 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.
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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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!".
- 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. - Replaced the
scikit-learndependency withrank-bm25for a smaller install footprint.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
.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).
- 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.
- 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.
- 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.
- Catalog
install_content/install_methodpayloads. Every install now fetches fromsource_urlat install time. - Frontend "Category" and "Platform" filter dropdowns in the Explore tab.
_enrich_continuation_refsis commented out — the chain extractor has a bug that misses some links. Re-enable once the bug is fixed.
- 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).
- Unified extensions system:
BaseExtensionService[T]generic base with Skill, Command, Subagent, and Hook services. Central + per-agent store architecture with install/sync/unsync lifecycle. - Extensions API package: Consolidated 5 standalone routers into a single
api/extensions/package with typed factory and per-type endpoints. - Typed frontend extensions client:
ExtensionsClientwith context provider, replacing raw fetch calls across all extension components. - Catalog install via services: Skills, commands, subagents, and hooks route through their respective services for central + agent sync instead of direct file writes.
- CatalogInstallButton component: Reusable install/manage button for catalog and recommendation cards with sync target dialog.
- Install target dialog: Diff-based dialog showing add/remove changes per platform, with central-only fallback.
- GitHub auth for downloads:
GITHUB_TOKEN/GH_TOKENenv var support raises API rate limit from 60 to 5000 req/hr. - Domain-based logging: Routing table maps logger prefixes to 8 domains with per-domain log files and configurable levels.
- Donation UI: Donation history, withdraw form links, and redesigned consent/result dialogs.
- One-liner install scripts:
install.sh(macOS/Linux) andinstall.ps1(Windows) bootstrap uv and runuvx vibelens serve. - Recommendation pipeline: L1-L4 engine with TF-IDF retrieval, multi-signal scoring, LLM profiling, and frontend view.
- Light mode: Full light/dark/system theme with CSS custom property tokens and semantic color migration.
- Catalog explorer: Browse, search, filter, and install from 1499 catalog items with GitHub metadata enrichment.
- Context extraction framework: Pluggable
ContextExtractorABC with metadata, summary, and detail extractors. - LLM config UI: Redesigned form with CLI badges, LiteLLM presets, and expanded pricing.
- Font selector: Atkinson Hyperlegible and other font families with live preview.
- Extensions refactor: Renamed
catalog_installtocatalog_resolver. Migrated all services toBaseExtensionServicewith string agent keys. Unified extension schemas. - Frontend restructure: Renamed
conversation/tosession/,analysis/todashboard/, extracted shared components, split large files. - Backend model reorganization: New
models/recommendation/,models/creation/,models/evolution/,models/friction/,models/session/packages. - Inference config persistence: Only saves fields that differ from defaults so users pick up new defaults on upgrade.
- Demo guard routes: Updated blocked routes for
/extensionsprefix. - GitHub downloads: Reuse single
httpx.Clientacross recursive directory fetches instead of one per request. - Installable platform stores: Created eagerly (with
create=True) so catalog installs succeed even if the directory doesn't exist yet.
- ExtensionSource StrEnum: Use plain string values instead of
AgentType.XXXreferences, which stored repr strings on some Python versions. - Installed extension management: "Installed" badge replaced with actionable "Manage" button to change sync targets.
- Partial install error reporting: Frontend throws with per-platform failure messages instead of silently succeeding.
- Python 3.10 compatibility:
datetime.UTCtotimezone.utc,StrEnumshim, minimum Python raised to 3.10. - Personalization prompt hardening: Guard against LLM hallucinations in recommendation/creation parsers.
- Legacy modules: Deleted
retrieval.py, oldstorage/conversation/,catalog/module,services/catalog/, analysis shared code.
- Recommendation pipeline: L1-L4 engine with TF-IDF retrieval, multi-signal scoring, LLM profiling/rationale, catalog loader, API endpoints, and frontend view.
- Recommend CLI:
vibelens recommendwith backend auto-discovery and lightweight compaction-based extraction. - Catalog CLI:
vibelens build-catalogandvibelens update-catalogcommands. - Light mode: Full light/dark/system theme with CSS custom property tokens, semantic color migration across all components, and settings toggle.
- Expanded tool categories: Added interact, browser, and infra groups.
- Recommendation 404: Bundled catalog with static assets to resolve missing route.
- Python 3.10 compatibility: Replaced
datetime.UTCwithtimezone.utc, addedStrEnumshim, raised minimum Python to 3.10.
- Frontend restructure: Renamed
conversation/tosession/,analysis/todashboard/, extractedfriction/andupload/directories, split large components (step-block, friction-panel, skill-analysis-views), promoted shared state components to root. - Backend model reorganization: New
models/recommendation/,models/creation/,models/evolution/,models/friction/,models/session/packages. Moved prompts tosrc/vibelens/prompts/. - GEMINI_CLI merged: Consolidated
GEMINI_CLIintoGEMINIenum across backend and frontend. - Naming updates:
AgentType/BackendTyperenamed to official product names.cached_input_per_mtoktocache_read_per_mtok.
- Skill importer: New
services/skill/importer.pyauto-imports agent skills from Claude Code, Codex, and third-party agent skill directories at startup. - Skill download service: New
services/skill/download.pyfor fetching featured skills from the catalog. - Upload zip commands: Extracted per-agent zip commands to
services/upload/commands.pyfor cleaner upload processor. - Utility modules: Added
utils/content.py(text extraction helpers),utils/identifiers.py(timestamped ID generation),utils/json.py(JSONL locking, reading). - Trajectory storage package: New
storage/trajectory/package replacingstorage/conversation/with clearer naming (BaseTrajectoryStore,DiskTrajectoryStore,LocalTrajectoryStore). - Store tests: Added
tests/storage/test_disk_store.pyandtests/storage/test_local_store.pywith full ABC compliance tests. - Session route tests: Added
tests/api/test_session_routes.py.
- Analysis session index alignment: LLM sometimes used batch indices (e.g.
"12") instead of session UUIDs in StepRef outputs, causing all step references to be silently dropped. Addedsession_indexfield toSessionContext, index-to-UUID fallback inSessionContextBatch.resolve_step_ref, and per-batch 0-based reindexing in the session batcher. - Example analyses invisible in result view:
is_exampleflag was on Meta schemas but missing fromFrictionAnalysisResultandSkillAnalysisResultmodels. Pydantic silently stripped the flag when loading full results, so the "Example" badge never appeared on result detail views. Addedis_exampleto both result models. - Extraction index gaps on skipped sessions:
extract_all_contextsusedenumerate()causing index gaps when sessions were skipped. Now useslen(contexts)for sequential 0-based indices.
- Storage rename:
storage/conversation/renamed tostorage/trajectory/.TrajectoryStoretoBaseTrajectoryStore,DiskStoretoDiskTrajectoryStore,LocalStoretoLocalTrajectoryStore. All imports updated across the codebase. - Skill store unification: Removed
storage/skill/codex.py(CodexSkillStore). Codex skills now useDiskSkillStorewithSkillSourceType.CODEX, matching the Claude Code skill store pattern. - Dependency renames:
get_store()toget_trajectory_store(),get_skill_store()toget_claude_skill_store(). - Utils consolidation:
utils/text.pymerged intoutils/content.py(extract_textrenamed tocontent_to_text).utils/json_helpers.pymerged intoutils/json.py. Removedutils/paths.py,utils/github.py,utils/json_extract.py. - Upload processor simplified: Extracted zip commands, replaced
uuid4()withgenerate_timestamped_id(), reduced module from ~460 to ~250 lines. - Analysis loading UI: Stop button moved above informational text in both friction and skill analysis waiting screens. Text reordered: "Usually takes 2-5 minutes" before "Running in background".
- Background startup: Renamed
_lightweight_startupto_run_background_startup, now runsimport_agent_skills()andseed_example_analyses().
- Deleted modules:
storage/conversation/(replaced bystorage/trajectory/),storage/skill/codex.py,utils/github.py,utils/json_extract.py,utils/json_helpers.py,utils/paths.py,utils/text.py. - Deleted tests: Removed outdated tests for deleted modules (
tests/api/test_e2e.py,tests/config/,tests/ingest/anonymize/,tests/live/,tests/services/friction/,tests/services/session/,tests/utils/).
- Example analyses in self-use mode: Pre-built friction and skill analysis examples are now loaded alongside user analyses in self-use mode, not just demo mode. Configured via
examples.sessionsinself-use.yaml. is_exampleflag: Addedis_examplefield toFrictionMetaandSkillAnalysisMetaschemas. Injected during startup file copy so frontend can distinguish bundled examples from user-generated analyses.- Example badge on result headers: Friction and skill analysis result headers show an amber "Example" badge when viewing a bundled example analysis.
- Example badge logic: History cards now use
is_exampleflag (ormodel.startsWith("mock/")fallback) instead of demo-mode check, so badges appear correctly in both demo and self-use modes. - Store resolver in self-use mode:
list_all_metadata(),load_from_stores(),load_from_all_stores(), andget_metadata_from_stores()now include example store sessions alongside user sessions in self-use mode. - Example seeding refactored: Startup copies pre-built analysis JSON files from
examples/recipe-book/into user stores (appending to existing index), replacing the previous demo-only mock generation approach. - Donation consent dialog redesign: Wider modal with colored icons per consent item, card layout, cyan intro banner, and Heart icon in header and button.
- Refresh button feedback: Session list refresh button shows spin animation and disabled state while loading.
- Donate consent dialog redesign: Each consent item now has a colored icon, card layout, and a highlighted research team banner. Wider modal, Heart icon in header and Donate button.
- Example badge on mock results: Friction and skill analysis result headers show an "Example" badge when
backend_idismock, replacing the demo-mode-only badge on history cards. - History "Example" badge logic: Friction and skill history cards now show "Example" based on
model.startsWith("mock/")instead ofisDemo, so real analyses in demo mode are not mislabeled. - "Analyze your own sessions" tooltip: New button tooltip on friction and skill result headers replaces generic "Analyze new sessions".
- Seed example friction analysis: App startup now seeds a mock friction analysis alongside skill analyses, so new users see example results in the Productivity Tips history.
- Tutorial tour improvements: Reworded all tour step titles and descriptions for clarity. Added "Conversation" step targeting the browse tab. Reordered Personalization before Productivity Tips. Back-navigation now correctly skips missing targets instead of always advancing forward.
- Refresh button loading state: Session list refresh button is disabled and spins while loading.
- Config path cleanup: Demo config uses
~/.vibelens/donationsand~/.vibelens/uploads(removed-v2suffix).
- Shared uploaded sessions 404: Share links for uploaded sessions failed with "Share not found or has been revoked" because the share endpoint resolved sessions using the viewer's token (which differs from the uploader's). Added
load_from_all_stores()that searches all upload stores regardless of token, used by share resolution endpoints.
- Removed summary and user_profile fields: Dropped
summary,user_profilefrom all analysis models (friction, skill retrieval/creation/evolution), LLM prompts, synthesis templates, mock data, and frontend types. Analysis results now show only title, tips/recommendations, and issue cards. - Self-explanatory titles: All LLM prompt templates now enforce a 10-word max self-explanatory
titlethat readers can understand without reading the rest of the report. - Plain-language friction types: Removed hardcoded friction type taxonomy from prompts. LLM now generates plain-language kebab-case labels (e.g. "changed-wrong-files") instead of fixed categories. Frontend converts kebab-case to Title Case dynamically.
- Audience section in all prompts: Added "Audience" block to all analysis and skill prompt templates requiring plain, everyday language with no coding jargon.
- Rationale format standardized: All rationale Field descriptions and prompt rules now enforce "one sentence (max 15 words), then
\n-bullets (max 10 words each)" across friction and skill models. - Tutorial banners: Added
TutorialBannercomponent shown on welcome pages, loading screens, and result pages explaining how each analysis feature works. - Collapsible rationale sections: "Why This is Useful" renamed to "Why this helps" and made collapsible (expanded by default) across all card types: MitigationCard, RecommendationCard, CreatedSkillCard, EvolutionCard.
- Section label renames: "Addressed Issues" renamed to "What this fixes", "Addressed Workflow Patterns" to "What this covers", "Issues Found" to "What Went Wrong", "Workflow Patterns" to "How You Work".
- Section heading font size: Section headers (friction and skill panels) enlarged from
text-basetotext-lg. - Demo mode guards: Added
useDemoGuardhook that intercepts write actions (create/edit/delete skills, install, sync) in demo mode and shows the install-locally dialog instead. Applied across local-skills-tab, explore-skills-tab, skill-cards, skill-analysis-views, friction-history, skills-history. - Example badge in history: Friction and skill history cards show an "Example" badge when in demo mode.
- Share dialog redesign: Session share flow now opens a modal with a copyable URL input instead of inline "Link copied!" text. Demo mode blocks sharing uploaded sessions with an explanation dialog.
- Session download via fetch: Export button now uses
fetchWithToken(supporting auth tokens) instead of direct<a>link navigation. - Header collapse toggle: Session header collapse toggle moved from a separate button to clicking the header row itself, using
ChevronRight/ChevronDowninstead ofChevronUp/ChevronDown. - Prompt nav default state: Prompt navigation sidebar now starts expanded instead of collapsed.
- Skill detail popup polish: Tags and Allowed Tools sections switched from stacked to inline row layout. Description text lightened. Font sizes increased for stats, source links, and sync buttons.
- Install locally dialog extracted:
InstallLocallyDialogextracted fromanalysis-welcome.tsxto its own file for reuse by demo guard hooks. - Demo store resolver: Demo mode now always shows example sessions alongside user uploads, instead of showing only uploads when present.
- Session export logging: Added structured logging to session export and download endpoints for debugging 404s.
- CopyButton on mitigation tips: MitigationCard action text now has a copy button.
- Hidden detail sections: Added
SHOW_ANALYSIS_DETAIL_SECTIONSconstant (defaultfalse) to hide "What Went Wrong" and "How You Work" sections, keeping the UI focused on tips and recommendations.
- Friction type taxonomy: Removed the 10-item hardcoded taxonomy from the analysis prompt. LLM now freely names friction types.
FRICTION_TYPE_LABELSmap: Removed the static label lookup in favor of dynamic kebab-to-title conversion.SHARE_STATUS_RESET_MSconstant: No longer needed with the modal-based share flow.- Example data files: Removed
examples/claude-example-v2/(session data, friction analyses, skill analyses) from tracked files.
- Skill evolution color theme: Replaced amber accent with teal to match recommendation cards across all evolution UI elements (borders, badges, buttons, icons, confidence bars).
- Skill selection dialog for evolution: Users now choose which installed skills to evolve before analysis starts, with checkbox list and select-all toggle. Selection passed through API to filter skills sent to LLM.
- Skill Description label: All skill cards (Recommendation, Creation, Evolution) now display a bold "Skill Description:" prefix before the description text.
- BulletText markdown rendering: Rewrote component to parse
**bold**into<strong>elements and handle\n\nrobustly between bullets. - Model field descriptions: Refined
rationale,summary, anduser_profilefield descriptions across all skill models for conciseness and plain language with explicit bullet-point format guidance. - LLM prompt bullet format rules: All skill prompt templates now enforce bullet-point format for rationale, summary, and user_profile via two concise lines in Output Rules. No over-emphasis.
- Waiting page text styling: Unified analysis loading text to
text-sm text-zinc-400for better readability.
- Tooltip overlap on Reference buttons: Removed nested
<Tooltip>wrappers fromFrictionRefListandStepRefList, keeping only individual button tooltips. - Duplicate evolution proposals: Added server-side dedup keeping first proposal per skill, plus prompt-level "one proposal per skill" rule in evolution proposal template.
- Friction panel redesigned: Productivity Tips (MitigationCard) restyled as sectioned cards with title, action, "Why This is Useful" rationale, and expandable "Addressed Issues" with step reference links. Added
rationalefield toMitigationmodel. - Issues Found cards: Boxed card layout with severity badge left of title, description always visible, and clickable whole-block toggle for Details section showing Impact (steps, duration, tokens) and Reference step links.
- Workflow Patterns cards: Redesigned to match Issues Found style with frequency badge left of title, description visible, whole-block clickable toggle for Reference links.
- Unified Reference style: Both friction and skill analyses now use the same enlarged Reference label (
text-sm,w-4 h-4icon) and step buttons (text-xs,px-3 py-1.5). - Impact section: Added "Impact:" highlight title with Zap icon and concise tooltips ("Steps affected", "Duration affected", "Tokens affected") replacing verbose descriptions.
- Friction type names enlarged:
text-smtotext-basein both Issues Found cards and Addressed Issues within MitigationCards. user_profilebullet format: Propagated "one-sentence + bullet points" format across all friction and skill models, prompt templates, mock data, and example JSONs.- Tab persistence: Personalization sub-tab selection saved to localStorage and respected during demo auto-load.
- Enlarged font sizes: Skill names, card titles, section labels ("Why This is Useful", "Addressed Issues") enlarged from
text-xs/text-smtotext-sm/text-base. - Legacy friction migration removed: All
model_validatormigration methods andAny/model_validatorimports removed fromfriction.py. Example data updated to newfriction_typesformat.
- Structured output format for all LLM analysis: Summary, rationale, and description fields across friction, retrieval, creation, and evolution models now require "one-sentence conclusion + bullet points" format with explicit word limits, replacing free-form prose.
- Title field descriptions tightened: All LLM-generated titles capped at 8 words with "clear, reader-friendly" guidance.
- Skill description propagated to recommendations and evolutions:
SkillRecommendationandSkillEvolutionnow carry adescriptionfield;SkillCreationgainsaddressed_patterns. WorkflowPattern.gapremoved: Redundant with pattern description; removed from model, types, templates, and UI.- Skill analysis views redesigned: Summary and user profile merged into a single card with divider. Purple/violet theme replaced with zinc/teal to match recommendation cards. Workflow pattern cards now expandable inline within each skill card.
- Prompt templates refined: All skill and friction Jinja2 templates updated for tighter output constraints, consistent bullet-point formatting, and reduced verbosity.
- Model field ordering:
SkillAnalysisResultandSkillEvolutionfields reordered for logical grouping (metadata, content, metrics, warnings). SkillEditmodel relocated: Moved afterSkillEvolutionProposalResultfor better reading order inevolution.py.- Demo examples updated: Friction and skill analysis example JSONs in
examples/claude-example-v2/refreshed to match new model shapes.
- Friction panel UI: Mitigation
titlefield added to model and displayed in friction cards. User profile card styling and confidence score placement improved. - Sub-agent block and flow diagram: Minor layout and color adjustments for readability.
- Collapsible pill: Styling tweak for consistent appearance.
- Cost estimate dialog for skill analysis: Pre-flight cost confirmation before running retrieval, creation, and evolution analyses, matching friction's existing flow. Shared
CostEstimateDialogcomponent used by both panels. SessionContextdomain model: Newmodels/context.pyconsolidates session context, step-ref resolution, and trajectory aggregation into a single Pydantic model, replacing loose tuples andIdMapping/remap_session_ids.- Agent message extraction: Context extraction now includes truncated agent text messages alongside tool calls, controlled by new
ContextParamsfields. - Analysis ID log correlation: All log records during an analysis run are tagged with
[analysis_id]via aContextVar, making it easy to trace multi-batch runs in logs. max_analysis_sessionssetting: Configurable limit (default 30) on sessions per analysis request, exposed via/api/settingsand enforced in the frontend with a warning banner.user_profileandconfidenceon friction results: Friction analysis now returns a user working-style profile and per-mitigation confidence scores.
- Friction model overhaul: Flattened
FrictionLLMEvent/FrictionLLMBatchOutput/FrictionSynthesisOutputinto a singleFrictionAnalysisOutput. Renamed fields (friction_detailtodescription,estimated_costtofriction_cost,eventstofriction_events). Removed per-type aggregation (TypeSummary),claude_helpfulness,friction_id,project_path, andcross_batch_patterns. - Friction panel UI: Events grouped by friction type with collapsible sections. Severity descriptions reworded to second-person. Human-readable friction type labels.
- Trajectory field renames:
last_trajectory_reftoprev_trajectory_ref,continued_trajectory_reftonext_trajectory_ref. - Session view modes:
"timeline"renamed to"detail","flow"to"workflow". - Share service rewritten: Registry-based model (
shared.json) instead of per-token snapshot files. Shares load from the normal trajectory store at read time. - Session batcher restructured:
SessionBatchreplaced bySessionContextBatch. Oversized session splitting happens before chaining. Clearer function naming throughout. - Skill prompt caps tightened: Per-batch proposals capped at 3 patterns and 3 proposals. Synthesis caps: 5 patterns, 5 creation proposals, 8 evolution proposals.
- Models reorganized:
models/inference.py,models/pricing.py,models/prompts.pymoved tomodels/llm/subpackage. - Friction and skill analysis share more infrastructure: Extracted
log_analysis_summary(),format_batch_digest(), andmerge_batch_refs()as shared helpers.
services/friction/digest.py: Merged intoanalysis_shared.format_batch_digest().StepSignalmodel and signal-based digest path: All analysis usesSessionContextexclusively.- Two-step proposal/create API: Removed
/api/skills/analysis/proposalsand/api/skills/analysis/createendpoints; consolidated into single analysis flow. - Share snapshot files: Per-token
.json/.meta.jsonfiles on disk no longer created.
- Consistent skill field naming:
SkillCreationProposal.name→skill_name,SkillRecommendation.match_reason→rationale. All three skill modes now shareskill_name,rationale, andaddressed_patternsfields. - Structured evolution proposal result:
_infer_skill_evolution_proposalsreturnsSkillEvolutionProposalResultinstead of a raw 6-tuple, matching the creation pipeline pattern. - Session filtering for deep creation: Proposals with
relevant_session_indicesnow load only the referenced sessions instead of all sessions, reducing token cost. - Skill template naming convention: Renamed to
{mode}_{stage}_{role}.j2--deep_creation_*→creation_*,deep_edit_*→evolution_*,proposal_*→creation_proposal_*. - Template prompt consistency: Added missing
titlefield to retrieval pattern instructions,addressed_patternsto evolution proposal rules, "Output Rules" section to retrieval system prompt, and batch titles to all synthesis user prompts. - Diagnostic logging: Token budget breakdown and truncation stats in
truncate_digest_to_fit. Proposal and recommendation names logged after LLM generation in all three skill services.
- Claude Web parser: New
claude_code_webparser for claude.ai "Export Data" ZIP files. Upload dialog shows dedicated instructions when this source is selected. Multi-conversation files are split into independent sessions automatically. - Agent-level dashboard filtering: Clicking an agent row in the distribution chart drills down into that agent's stats. Breadcrumb navigation shows
Agent / Projecthierarchy with clickable segments. - Skill preview dialog: Unified
SkillPreviewDialogreplaces the old inline-edit and direct-install flows. Users can read, edit, and confirm SKILL.md content before installing or updating -- used for catalog recommendations, new creations, and evolution suggestions. - CLI model selector: LLM config now shows available models per CLI backend with inline pricing. Backends declare
available_models,default_model, andsupports_freeform_model. NewGET /llm/cli-modelsendpoint powers the selector. - LLM pricing in status bar:
GET /llm/statusandPOST /llm/configurenow returnpricing(input/output per MTok) for the configured model. - Skill evolution selection step: New LLM-powered pre-filter asks which installed skills are relevant before loading full SKILL.md content, reducing context bloat for large skill collections.
- Featured skill preview:
GET /skills/featured/{slug}/contentfetches raw SKILL.md from GitHub with 1-hour cache, enabling preview-before-install in the Explore tab.
- Shared analysis infrastructure: Extracted
analysis_shared.pywithrequire_backend(),run_batches_concurrent(),build_digest_from_contexts(), and other helpers that were duplicated across friction, retrieval, creation, and evolution services. - Configurable context extraction: Replaced hardcoded truncation constants with
ContextParamsdataclass and three presets (PRESET_CONCISE,PRESET_MEDIUM,PRESET_DETAIL). Added path shortening ($HOME→~). - Batched skill analysis: Retrieval, creation, and evolution now use the same batch + synthesis pattern as friction -- concurrent LLM calls per batch with a synthesis pass when multiple batches exist.
- Skill models split: Monolithic
models/skill/skills.pysplit intopatterns.py,retrieve.py,create.py,evolve.py,results.pywith mode-specific output types replacing the catch-allSkillLLMOutput. - Simplified
SkillEditmodel: Droppedkind/target/replacement/conflict_typeenum pattern in favor ofold_string/new_string/replace_all-- mirrors text editor semantics and is less ambiguous for LLM output. - Template directory reorganization: Flat
templates/Jinja2 files moved intotemplates/friction/,templates/highlights/,templates/skill/subdirectories. - Two-tier search index: Replaced single-tier 5-minute-TTL index with lazy two-tier architecture -- Tier 1 (metadata-only) loads synchronously at startup for instant search; Tier 2 (full text) builds asynchronously in a thread pool. Incremental
add_sessions_to_index()after uploads instead of full invalidation. - Evolution diff view: Now computes real 1-based line numbers from original file content and shows grey context lines alongside red/green diff rows.
- Gemini CLI system prompt: System prompt now passed via
GEMINI_SYSTEM_MDenv var temp file instead of stdin concatenation. OpenCode CLI gained--systemflag support. - CLI backend model resolution: When user config has the LiteLLM default or is empty, falls back to each backend's own
default_model. - Skills tab labels: "Discover" renamed to "Recommend". "Apply & Edit" renamed to "Preview & Update". Explore tab gains a "Recommend" shortcut button.
- Tour steps: Single "AI-Powered Insights" stop split into "Productivity Tips" and "Personalization" with distinct icons.
- Nav tooltips: Native
titleattributes replaced with sharedTooltipcomponents on all main-nav tab buttons. WorkflowPattern.pain_pointrenamed togapacross models, templates, and UI.
- StepSignal-based digest path: Deleted
services/friction/signals.pyandservices/skill/digest.py. All analysis now uses theSessionContextpath fromcontext_extraction.py. skill_creation.pyprompt: Single-call creation prompt removed; creation now uses the proposal + deep-creation two-phase pipeline exclusively.- Dead skill constants:
EDIT_KIND_*,CONFLICT_TYPE_*,MODE_COLORSremoved from frontend constants.
- CLI tempfile concurrency:
generate()now isolates temp files per call via save/restore, preventing concurrent coroutines from deleting each other's files. - Amp NDJSON parsing:
AmpCliBackendno longer setssupports_native_json = True(which skipped schema instructions). Overrides_parse_outputto extract the last valid JSON line from the NDJSON stream. - Overly broad exception in LiteLLM cost extraction: Narrowed
except Exceptiontoexcept (ValueError, litellm.exceptions.NotFoundError)in_extract_cost()so unexpected errors surface instead of being silently swallowed.
modelproperty onInferenceBackendABC: Added a concretemodelproperty (default"unknown") to the base class, overridden inCliBackendandLiteLLMBackend. Removed the duplicated_get_backend_model()helper from 4 service files.- Shared
monotonic_ms(): Deduplicated identical_now_ms()functions fromcli_base.pyandlitellm_backend.pyintoutils/timestamps.monotonic_ms(). - Top-level
import importlib: Moved from inside_create_cli_backend()to the module's stdlib import group inbackends/__init__.py.
- Background job system: Friction and skill analyses now run as background async jobs with polling, cancellation, and a periodic cleanup task. New
job_trackerservice and/jobs/{id}+/jobs/{id}/cancelendpoints for both pipelines. - Skill proposals + deep creation: Two-phase skill creation workflow.
POST /skills/analysis/proposalsgenerates lightweight proposals;POST /skills/analysis/createproduces full SKILL.md content for an approved proposal. - CLI backend expansion: Added Gemini, Cursor, Kimi, OpenClaw, OpenCode, Aider, and Amp CLI backends via a lazy-import registry (
_CLI_BACKEND_REGISTRY), replacing the monolithicSubprocessBackend. - Skill evolution diff view: PR-review-style unified diff UI for evolution suggestions with two-column line number gutters, red/green diff lines, hunk separators, and conflict type badges.
- Analysis endpoints return jobs:
POST /frictionandPOST /skills/analysisnow returnAnalysisJobResponseinstead of blocking until completion. Frontend polls for results. - Frontend job-aware panels: Friction and skill panels accept
activeJobId, poll for completion, and show a cancellable "running in background" spinner. - LLM config form: CLI backends hide API key, model, and advanced settings. Shows a "uses local installation" hint instead.
- Text readability: Brightened and enlarged body text across skill analysis views and friction panel for better contrast on dark backgrounds.
- Donation: upload store resolution: Donation sender now includes per-user upload stores when searching for sessions, fixing "Source file not found" errors when donating uploaded sessions in demo mode.
- Donation error logging: All error paths in the donation pipeline now emit
WARNING-level log messages with diagnostic context (store names, file paths, parser types, tracebacks). Previously errors were only returned to the frontend with no server-side logging. - Parser file read errors:
BaseParser.parse_fileOSError logging upgraded fromDEBUGtoWARNINGwith exception detail. - Store load failures:
TrajectoryStore.loadnow logs a warning when a parser returns no trajectories for an indexed session.
- Git-enriched donations: Donation ZIPs now include
git bundle --allfor each repository referenced by donated sessions. Enables matching agent edits to git commits for edit-persistence analysis. - Git utilities (
utils/git.py):resolve_git_root(),create_git_bundle(),compute_repo_hash()for repo resolution, bundling, and deduplication. - Repo-to-session mapping: Manifest
reposarray lists bundles withsession_idslinking back to sessions. Per-sessionrepo_hashandgit_branchfields added.
- Donation ZIP layout: Migrated from flat
raw/+parsed/tosessions/raw/+sessions/parsed/, with newrepos/directory for git bundles. - Donation sender:
_resolve_repo_bundles()deduplicates by bothproject_pathstring (avoids redundant subprocess calls) and resolved git root (avoids duplicate bundles). Returns a mapping instead of mutating sessions. Bundle creation runs viaasyncio.to_thread. - Friction panel: Renamed "Top Recommendations" to "Top Productivity Tips".
- Skill analysis UI: Restyled result header, summary card, section headers, and metadata footer to match friction panel. Moved Workflow Patterns section to bottom. Removed count badges from section headers.
- Analysis welcome: Moved session-selection hint into a tooltip on the disabled button.
- Tooltip: Skip rendering portal when text is empty.
- README: Added comic blurb, new screenshots (01-06), grouped figures, linked
docs/blurb.md, updated feature table and supported agents.
- Per-user upload stores: Replaced single
DiskStore(upload_dir)with per-user upload stores keyed bysession_token. Visibility is now enforced at the storage level -- each user's stores only contain their uploads. Eliminates full rglob rebuild after every upload, cross-user cache invalidation, and runtime visibility filtering. - Upload registry: New
register_upload_store()andreconstruct_upload_registry()indeps.py. Uploads register a per-upload DiskStore under the user's token instead of invalidating the global store index. Registry is rebuilt frommetadata.jsonlon server restart. - Store resolver:
list_all_metadata(),load_from_stores(), andget_metadata_from_stores()now acceptsession_tokenand iterate per-user stores in demo mode, falling back to the example store when a user has no uploads. - Projects endpoint:
/api/projectsnow acceptsx-session-tokenheader for per-user project listing. - Rule Anonymizer: Expand path section with Windows/WSL modes
- visibility.py: Deleted
filter_visible()andis_session_visible()(11 call sites across 8 service files). Access control is now implicit via store-level isolation. _all_metadatafield: Removed fromTrajectoryStorebase class andDiskStore. No longer needed since duplicate session_ids across users don't coexist in a single store._require_disk_store(): Removed fromprocessor.py. Demo mode check usesis_demo_mode()directly.invalidate_index()on refresh/upload: Removed fromapi/sessions.py(refresh) andprocessor.py(post-upload). Per-user stores are self-contained.
- Spotlight tutorial: Replaced modal onboarding dialog with a step-by-step spotlight tour that highlights UI elements in place. Works in both self and demo modes. Relaunch via Settings > Start Tutorial.
- Donation consent dialog: Rewrote consent copy for clarity. Anonymization is now handled by the research team (removed self-review burden). Added permissions reminder, non-commercial use clause, and right-to-delete. Migrated to shared Modal components.
- Prompt nav panel: Starts collapsed as a thin strip with expand button. Redesigned with cyan-tinted dark background, card-style entries, and active-state highlighting for sub-agents.
- User prompt collapse: Long user prompts (>15 lines) now auto-collapse with a "Show full prompt" toggle.
- Session list polish: Upload and Donate buttons use larger text. Agent filter uses custom dropdown instead of native
<select>. View mode toggle uses fixed width to prevent layout shift. First project auto-expands on load. Session messages truncate with ellipsis instead of multi-line clamp. Search defaults include session_id. - Tab bar: Stronger bottom border with shadow. "Pain Points" renamed to "Productivity Tips" with updated empty-state description. AI tabs grouped with
data-tourattributes. - Friction panel: Sidebar width constants unified from shared
styles.ts.
- Session row overflow: Project name and timestamp no longer push each other off-screen in narrow sidebars (
truncate,shrink-0,whitespace-nowrap).
- Stateless session visibility: Eliminated in-memory state (
_token_uploadsdict,_rebuilt_from_diskflag) that became stale after the first metadata rebuild. Visibility is now a pure function of_session_tokenmetadata tags written into each upload'sindex.jsonl. - Upload isolation between browser tabs: Each upload's DiskStore
default_tagsnow includes_session_token(the browser's UUID) alongside_upload_id, enabling stateless per-user visibility filtering. - Duplicate session_id dedup ordering: Sorted
rglobindex discovery so newer upload directories (timestamp-prefixed) are processed last, ensuring the most recent upload wins dedup forget_metadata()/load(). - Multi-upload metadata preservation: Added
_all_metadatalist toTrajectoryStoresolist_metadata()returns ALL entries (including duplicate session_ids from different uploads), enablingfilter_visible()to correctly match per-upload tokens.
- Donation ZIP wrapping directory: Donation ZIPs now unzip to a single
{donation_id}/directory containingmanifest.json,raw/, andparsed/. Previously files were at the ZIP root. - Upload-then-donate raw files: When donating uploaded sessions,
raw/now contains the original upload ZIP instead of parsed JSON duplicates. Multiple sessions from the same upload share a single deduplicated ZIP entry. - Donation manifest: Includes
donation_idfield and optionalsource_upload_idper session entry. Raw file paths include the wrapping directory prefix. - Donation receiver: Reads
donation_idfrom manifest for ZIP filename (falls back to generated ID for legacy ZIPs). Manifest discovery searches both root and one-level deep for backward compatibility. - Donation index: Uses
donation_idfield instead ofupload_idin index entries.
- Anonymize test suite: 97 tests in
tests/ingest/anonymize/covering patterns, path hasher, redactor, traversal, rule anonymizer, and stubs. Full coverage of credential/PII detection, camelCase name variant derivation, path hashing, and deep trajectory tree walking. - Batch anonymization script:
scripts/anonymize_sessions.pyCLI for batch-anonymizing all local Claude Code sessions with dry-run and output modes, per-file error handling, and summary reporting. - Anonymization report:
docs/reports/anonymization-report.mddocumenting two-round batch testing across 309 sessions with zero-leak verification. - Concise view mode: New "Concise" toggle in session viewer strips tool calls and thinking blocks, showing only user prompts and agent text responses for quick conversation overview.
- Plan step navigation: Auto-prompt steps (plan mode) now appear in the prompt nav panel with teal-colored Plan badges and previews instead of being hidden.
- camelCase name variant anonymization:
PathHashernow splits camelCase usernames (e.g.JohnDoe) into name parts and derives space/underscore/hyphen-separated variants with case variations. Eliminates username leaks in author fields, filenames, and free text. Path anonymization coverage increased 38% in batch testing. - Partial parse failure handling:
scripts/anonymize_sessions.pynow handles file-level parse failures independently — sub-agent files are still processed when the main session file fails.
- Test directory reorganized: Moved misplaced test files to mirror
src/structure —tests/llm/for cost estimator and pricing,tests/services/for context extraction and session batcher. Added missingtests/friction/__init__.py. - Sidebar redesigned: Donate button promoted to top of session list with full-width styling. Download button moved to footer alongside pagination. View mode toggle (Project/Time) compacted into a single switch button. Upload toolbar only renders in demo mode.
- Tab styling refreshed: Main navigation tabs use distinct accent colors with inner shadow — indigo for Browse, cyan for Analyze, amber for Pain Points, teal for Personalization. "Friction" tab renamed to "Pain Points", "Skills" tab renamed to "Personalization".
- Auto-prompt styling: Auto-prompt steps restyled from violet to teal with "Plan" label replacing "Auto".
- Donation service: New
services/donation/package with sender and receiver modules. Self-use instances package raw session files + parsed trajectories into a ZIP and POST to the configured donation server. Demo instances receive and store donated ZIPs with append-only index. NewPOST /donation/receiveendpoint. - Trajectory anonymization: Pluggable
ingest/anonymize/package withBaseAnonymizerABC and rule-based implementation.RuleAnonymizerchains credential, PII, high-entropy, and custom-string redaction with path username hashing. Deep traversal engine walks ATIF trees applying transforms to text fields while preserving structural data. Configurable viaAnonymizeConfigwith per-category toggles. - Session file resolution:
BaseParser.get_session_files()returns all files for a session (main + sub-agents).ClaudeCodeParseroverrides to includesubagents/agent-*.jsonlfiles. - Store source lookup:
TrajectoryStore.get_session_source()returns the file path and parser for any session, enabling donation to locate raw files. - LocalStore data dir access:
LocalStore.get_data_dir()exposes per-parser data directories for computing relative ZIP paths in donations. - Multi-store resolver: New
services/session/store_resolver.pyextractslist_all_metadata,load_from_stores,get_metadata_from_stores— primary-then-fallback-to-examples business logic separated from DI. - Donation config:
donation_urlanddonation_dirsettings with YAML mapping inconfig/loader.py. - Examples dir setting:
examples_dirfield in Settings for demo mode example storage location.
- deps.py registry pattern: Replaced 13 module-level globals and
globalstatements with a single_registrydict and_get_or_create()helper. Addedreset_singletons()for complete test isolation (previously only 2 of 13 globals were reset between tests). - Upload visibility scoping: Tokens with uploads now see only the last upload's sessions — example sessions are hidden. Previous behavior showed all uploads plus examples.
_token_uploads: dict[str, set[str]]replaced with_token_last_upload: dict[str, str]. - Upload button demo-only: Upload toolbar button only renders in demo mode (
appMode === "demo"). - Upload dialog redesigned: New multi-step flow with confirmation screen and dedicated result screen showing session count with check icon, progress bar, and detailed stats.
- Dashboard refresh on upload:
dashboardPreloadedref and cache state reset whenrefreshKeychanges.DashboardViewremounts viakey={refreshKey}to reflect uploaded data immediately. - Upload processor refactored: Removed hardcoded
DATASETS_ROOTglobal; all paths derive fromsettings.upload_dir. Upload metadata stored in append-onlymetadata.jsonlinstead of per-uploadmetadata.json. Sub-agent-only files skipped during parsing. - Demo store uses settings:
deps.pydemo mode store switched fromDiskStore(DATASETS_ROOT)toDiskStore(settings.upload_dir). - Donation endpoint moved:
POST /sessions/donatemoved fromapi/sessions.pyto dedicatedapi/donation.pyrouter. Business logic extracted fromservices/session/crud.pytoservices/session/donation.py. - DiskStore index filename: Renamed
_index.jsonl→index.jsonlthroughout DiskStore and docstrings. - Index cache filename: Renamed
index_cache.json→session_index.jsonwithindent=2formatting. - macOS resource fork filtering:
discover_all_session_files()andClaudeCodeParser.discover_session_files()skip._*Apple Double files.
- OpenClaw parser: New
openclaw.pyparser for~/.openclaw/agents/main/sessions/event-based JSONL format. Registered in discovery, local store, and settings withopenclaw_dirconfig field.
- Think block ordering: ThinkingBlock (reasoning_content) now renders BEFORE message text in timeline view, matching the actual agent workflow (think first, then respond).
- Flow mode interleaving: Phase groups in flow view are now split at user prompt boundaries, so user prompts appear interleaved between agent steps instead of being clustered after a single phase block.
- CLAUDE.md updated: Added OpenClaw to parsers list and agent data directories. Added Release section with versioning workflow.
- Multi-agent skill stores: Added 9 new agent interfaces (Cursor, OpenCode, Antigravity, Kimi CLI, OpenClaw, OpenHands, Qwen Code, Gemini CLI, GitHub Copilot) with skill directory scanning and auto-import into the central store on startup.
- Agent skill registry:
AGENT_SKILL_REGISTRYmaps each agent to its default skills directory. Only agents installed on disk are activated.
- Skill storage refactored: Replaced
ClaudeCodeSkillStorehierarchy withDiskSkillStoreas the shared concrete base. All agent stores are now parallel peers — Claude Code and third-party agents are plainDiskSkillStoreinstances,CodexSkillStoreandCentralSkillStoreextend it for agent-specific behavior. - AgentType expanded: Added 9 skill-only agent types.
SkillSourceTypemirrors allAgentTypevalues, keeping a single source of truth.
claude_code.py— logic moved todisk.py.AgentSkillStoreclass — replaced by plainDiskSkillStoreinstances.
- Services restructured: Grouped 13 root-level service files into domain subdirs (
session/,dashboard/,upload/). Mergedanalysis/package into consuming service subdirs. Deleted obsoleteservices/mock/package. - Skill analysis split: Split monolithic
skill/analysis.pyintoretrieval.py,creation.py,evolvement.pywith thin dispatcher inskill/__init__.py. - CSV export expanded: Added
agent,cache_read_tokens,cache_creation_tokens,cost_usdcolumns. Eliminated duplicated aggregation logic by reusingaggregate_session()from stats. - Pricing cleanup: Removed
__all__and dead re-exports frompricing.py. Consumers now importnormalize_model_nameandlookup_pricingfrom their source modules. - Skill store renamed:
skill/analysis_store.py→skill/store.py.
- Pre-flight cost estimation: New
POST /friction/estimateendpoint andCostEstimateDialogmodal show estimated LLM cost (min/max range) before running friction analysis. Users must confirm before incurring charges. - Onboarding dialog: Two-step welcome guide on first visit covering privacy guarantees and LLM cost transparency. Shown once per browser (
localStorage), re-triggerable from Settings. - Cost estimator module:
llm/cost_estimator.pycomputes input/output token costs with optimistic/pessimistic output ratios and synthesis call estimates. - Session ID remapping:
IdMappingand_IndexTrackerin context extraction replace verbose UUIDs with 0-indexed integers in LLM prompts, reducing token usage._resolve_synthetic_ids()converts back after inference. - User prompt truncation: Long user prompts (>2000 chars) are truncated to head (1500) +
[...truncated...]+ tail (500) to save tokens. - Compaction interleaving: Compaction summaries are inserted at their chronological position among steps instead of being grouped at the top, giving the LLM better temporal context.
- Step-boundary session splitting: Oversized sessions that exceed the batch token budget are split at
[step_id=...]boundaries with the session header preserved on each part. - Affinity-based batch packing: Session batcher seeds each batch then greedily fills by project affinity and time proximity, keeping related sessions together.
- Mitigation model simplified:
action_type+targetfields replaced with a singleactionlabel (e.g., "Update CLAUDE.md code style section"). Backward-compatiblemodel_validatormigrates old data. - Multiple top mitigations:
top_mitigation(singular) →top_mitigations(list of up to 3), ranked by batch severity and deduplicated by content. - Friction events grouped by project: UI groups events by project name instead of session ID, with per-group session count display.
- Prompt quality: Max events per batch reduced from 7 to 5 with minimum severity 2 threshold. Added recurring-pattern prioritization, merge instructions for same-type events, and noise filtering guidance.
- Models reorganized: Moved
models/analysis/dashboard.py→models/dashboard/,models/analysis/pricing.py→models/pricing.py,models/analysis/prompts.py→models/prompts.py,models/analysis/skills.py→models/skill/skills.py. Imports unchanged via re-exports. - Tests reorganized: Friction tests moved to
tests/friction/subdirectory. Expanded session batcher tests covering affinity packing, chain preservation, and step-boundary splitting.
- Mitigation tags enlarged and highlighted: Bigger tags (
text-sm font-semibold) with vivid colors — violet for CLAUDE.md, emerald for tests, cyan for skills, amber for linting, rose for workflows, teal default. - First friction event auto-expanded: The highest-severity event in the first project group starts expanded, matching the skill panel pattern.
- Resizable history sidebar: Drag-to-resize (180–400px range) with collapse/expand toggle buttons.
- Cost confirmation dialog: Modal with session count, batch count, token breakdown, model name, and estimated cost range before analysis runs.
- Event cards: Inline session ID badge, "Jump" button to open step in new tab, project-grouped layout sorted by max severity.
- Friction synthesis LLM call: After per-batch analysis, a lightweight LLM call synthesizes all batch results into a cohesive user-facing report with title, summary, per-type descriptions, cross-session patterns, and top mitigations.
- Friction synthesis prompts: New Jinja2 templates (
friction_synthesis_system.j2,friction_synthesis_user.j2) andFRICTION_SYNTHESIS_PROMPTregistration. - Synthesis output model:
FrictionSynthesisOutputwith title, summary, type descriptions, cross-session patterns, and 0-3 structured mitigations. - Type descriptions:
TypeSummarynow carries an optional LLM-generateddescriptionfield explaining the specific friction pattern observed. - Category logging: Refactored logging to use shared category log files (
parsers.log,analysis-friction.log,analysis-skill.log) instead of per-module files. Multiple modules in the same category share a single FileHandler. - Friction API error handling: Unexpected exceptions in the friction analysis endpoint now return structured 500 responses with type and message.
- Non-blocking dashboard cache warming: Cache warming now loads sessions in batches of 20 with GIL-releasing sleeps between batches. Runs as an async background task instead of a blocking thread. Friction history, LLM status, and skill endpoints respond in 1-3 seconds on cold start instead of waiting ~55 seconds for cache warming to finish.
- Friction prompts rewritten for users: Synthesis prompt writes for a developer audience — no references to batches, chunks, or internal processing. Summary capped at 80 words (down from 150) for scanability.
- Cross-session patterns: Renamed
cross_batch_patterns→cross_session_patternsthroughout models, prompts, and templates. - Synthesis mitigations override batch mitigations: If the synthesis call produces mitigations, the first one replaces the per-batch
top_mitigation. - Batch token budget: Default
max_batch_tokensincreased from 24K to 80K for fewer batches and better context per analysis call. - Session load resilience:
_extract_all_contextsnow catches and skips sessions that fail to load instead of aborting the entire analysis. - Claude Code parser guard:
_read_persisted_agent_idrejects paths longer than 1024 chars or containing newlines before touching the filesystem.
- Helpfulness badge: Removed
HelpfulnessBadgefrom friction event cards, along withHELPFULNESS_LABELS,HELPFULNESS_COLORSconstants, andHearticon import. - Batch count in UI: Removed batch count display from the friction result header subtitle.
- Session severity sort: Friction events section now sorts session groups by max event severity (highest first).
- Analysis title: Result header displays the LLM-generated title (falls back to "Friction Analysis").
- Cross-session patterns: Summary section renders cross-session patterns as a bullet list.
- Type descriptions: Friction type cards show the LLM-generated description below the badge row.
- History card titles: History sidebar cards display the analysis title when available.
- Fast metrics scanner: New
ingest/fast_metrics.pyextracts aggregate token counts, tool call counts, model name, and duration from raw JSONL without full Pydantic parsing. Deduplicates assistant entries by message ID. - Persistent index cache: New
ingest/index_cache.pyserializes session metadata and file mtimes to~/.vibelens/index_cache.jsonfor near-instant startup. Incremental updates re-parse only changed files (< 30% threshold; full rebuild otherwise). - Metadata-based dashboard stats:
compute_dashboard_stats_from_metadata()computes all dashboard charts from enriched metadata cache, eliminating full trajectory loading for the dashboard. - Friction analysis logging: Each LLM call saves
system_prompt.txt,user_prompt_{N}.txt, andraw_output_{N}.txttologs/friction/{YYYYMMDD_HHMMSS}/. Persists even on inference errors. - Friction analysis summary log: Append-only
logs/analysis-friction.logrecords session IDs, batch composition, token counts, and model for each run. - Session continuation refs:
TrajectoryStore.load()enriches loaded trajectories withlast_trajectory_ref/continued_trajectory_reffrom the metadata cache, fixing missing continuation tags in the UI.
- Flow mode scroll navigation: Clicking user prompts in the right sidebar now scrolls to the correct position in the flow diagram. Added matching
idandscrollMarginTopto flow anchor divs. - Missing "Spawned by" tag: Sessions with
parent_trajectory_refnow show both the link icon in the sidebar and the "Spawned by" navigation tag in the session header. - Overlapping x-axis dates: Usage Over Time chart skips the last-point label when it overlaps the previous interval label (< 40px gap).
- LLM returning markdown instead of JSON: Strengthened prompt enforcement with "Your entire response must be a single JSON object" directive and explicit zero-friction JSON template.
- Duplicate "History" label: Removed inner "HISTORY" text from
FrictionHistorycomponent; only the panel header label remains. - History sidebar toggle: Sidebar now stays visible when clicking a history item instead of collapsing.
- Parser log spam: Downgraded "Cannot read file" and "Invalid JSON" warnings to DEBUG level for edge case test files.
- Friction store → single JSONL: Replaced per-analysis
.meta.jsonfiles with a single append-onlymeta.jsonlfile. Delete rewrites the file minus the removed entry. - Friction type sort: Type summary section now sorts by average severity (descending) instead of event count.
- Friction ID → server-side UUID: Removed
friction_idfrom LLM output schema.FrictionEventgenerates a UUID viadefault_factory. Removedrelated_friction_idsfield entirely — each event is self-contained. - Default LLM model → Haiku: Changed default from
anthropic/claude-sonnet-4-5toanthropic/claude-haiku-4-5for faster, cheaper analysis. Frontend model presets reordered accordingly. - LLM config path: Default config moved from
config/llm.yamlto~/.vibelens/llm.yamlwith legacy fallback. - Friction prompt word limits: Added explicit max word counts —
user_intention(15),friction_detail(20),summary(50),mitigation.content(30). - Loading animation: Friction panel now uses the shared
LoadingSpinner(triple-ring animation) instead of a simple spinner. - History sidebar UI: Cards show amber/green event badges, violet session count, amber cost icon, split date/time with calendar+clock icons, and whiter text for readability.
- Background startup: Skill import, mock seeding, and cache warming run in a background thread so the server accepts requests immediately.
- Token-based batch budgeting: New
llm/tokenizer.pymodule using tiktoken for accurate token counting. Session batcher now packs batches by token budget instead of character count. - Skill creation & evolution prompts: Dedicated Jinja2 prompt templates for skill creation (
skill_creation_system.j2,skill_creation_user.j2) and evolution (skill_evolution_system.j2,skill_evolution_user.j2) LLM pipelines. - Install target dialog: New
install-target-dialog.tsxfor choosing which agent interface to install skills into. - Sync after save dialog: New
sync-after-save-dialog.tsxfor cross-agent skill sync after editing. - Mock service modules: Extracted mock data into
services/friction/mock.pyandservices/skill/mock.pyfor cleaner test/demo separation.
- Missing sessions: Claude Code Desktop sessions not in
history.jsonlare now discovered via orphaned file fallback in the index builder. - Explore tab crash:
TypeError: Q.map is not a function— handle paginated API response ({items, total}) instead of assuming flat array. - Log spam: Downgraded 13K+ repeated Pydantic validator warnings (orphaned tool calls, observation mismatches) to DEBUG level.
- Tab switching stale content: Switching between Retrieve/Create/Evolve tabs now clears the previous analysis result.
- Session refresh: Added
refresh=trueparameter to/sessionsendpoint for cache invalidation on page load.
- Skill analysis views: Richer UI with icons, confidence progress bars, color-coded edit kinds, auto-expanding first pattern card, and improved mock data covering all edge cases.
- API rename:
skills.py→skill_management.pyfor clarity. - Settings: Replaced
max_batch_charswithmax_batch_tokensfor token-based budgeting.
- Featured skill install: Download complete skill directories from GitHub (SKILL.md + templates, scripts, etc.) instead of generating a stub.
- Skill sync error: Handle symlinked skill directories (e.g. from skillshub) when syncing to agent interfaces.
- Skill history not loading: Fix API route mismatch — frontend now calls correct
/api/skills/analysis/endpoints. - Refresh button: Force backend cache invalidation on manual refresh so deleted/added skills are reflected immediately.
- CI: Skip live LLM tests when
ANTHROPIC_API_KEYis not set.
- Skill detail popup: Render SKILL.md content as markdown instead of raw text. Enlarged title and tags for readability.
- Main tab buttons: Equal minimum width (
min-w-[100px]) for consistent layout.
- GitHub skill downloader:
utils/github.py— recursively downloads skill directories from GitHub via the Contents API with raw file fallback.
- Multi-agent skill ecosystem: Central skill store (
~/.vibelens/skills/) aggregates skills from Claude Code and Codex on startup. Cross-agent sync API copies skills between interfaces. - Featured skill catalog: Browse and install community skills from the Anthropic registry via the new Explore Skills tab.
- LLM-powered skill analysis: Three modes — retrieval (recommend existing skills), creation (generate new SKILL.md), evolution (suggest edits) — with persistent history.
- Context extraction & session batching: Reusable modules for compressing trajectories into LLM-ready batches, shared by friction and skill analysis.
- Shared UI components: Extracted
Modal, portal-basedTooltip, and skill UI primitives (badges, search bar, filter bar, empty states) into reusable files. - Separated LLM config: Decoupled
LLMConfigintoconfig/llm.yamlwith hot-reload support.
- Storage restructure: Conversation stores moved to
storage/conversation/; skill stores expanded withCentralSkillStoreandCodexSkillStore. - Friction service refactor: Split into
services/friction/sub-package (analysis.py,store.py,digest.py). Reworked prompt templates. - Skills panel refactor: Split 1,777-line monolith into 7 focused files (~138-line orchestrator). Unified violet theme across all sub-tabs.
- Renamed
get_managed_skill_store→get_central_skill_store. - CLAUDE.md: Added frontend conventions (component size, shared UI patterns, color theme, file splitting).
- Deleted
llm/digest_friction.py,models/analysis/behavior.py,models/skill.py, and legacystorage/base.py/disk.py/local.py(all moved or consolidated).
Friction Analysis (Roadmap §6)
- LLM-powered friction detection: Multi-session analysis identifies wasted effort, wrong approaches, excessive retries, and other friction patterns. Produces severity-rated events with root causes, evidence, and actionable mitigations.
- CLAUDE.md suggestions: LLM generates concrete CLAUDE.md rules derived from observed friction, with section placement and rationale linking back to source events.
- StepRef model: Reusable locator for step or step range within a session, supporting point refs, range refs, and tool call pinning. Shared across friction and skill analysis.
- Friction analysis UI: Full-page panel with severity-colored event cards, mode summary stats, CLAUDE.md suggestion cards, and LLM config section. History sidebar lists past analyses with load/delete.
- Friction persistence: JSON-based store (
~/.vibelens/friction/) with full result + lightweight metadata files for fast listing.
Skill Management (Roadmap §9)
- Skill storage abstraction:
SkillStoreABC instorage/skill/withSkillInfomodel usingAgentTypeenum.ClaudeCodeSkillStorereads~/.claude/skills/, parses YAML frontmatter, detects subdirectories (scripts, references, agents, assets). - Skill CRUD API:
GET /api/skills/local,GET /api/skills/local/{name},POST /api/skills/install,PUT /api/skills/local/{name},DELETE /api/skills/local/{name},GET /api/skills/search?q=.... - Skills UI: New "Skills" tab with search bar, expandable skill cards showing allowed tools/subdirectories/path, create/edit dialog with SKILL.md editor, and delete confirmation.
- Skill personalization spec: Comprehensive design document (
docs/spec-skill-personalization.md) for LLM-powered skill retrieval, creation, and evolution from trajectory analysis.
LLM Inference Backend
- Pluggable inference:
InferenceBackendABC withLiteLLMBackend(supports 100+ models via litellm) and subprocess backends (claude-cli, codex-cli). - Runtime hot-swap:
POST /api/llm/configureto change API key and model without restart.GET /api/llm/statusreports backend availability. - Jinja2 prompt templates: System and user prompts for friction analysis rendered from
.j2templates withAnalysisPromptmodel. - Step signals:
StepSignalmodel packages trajectory steps with session context for LLM digest, with configurable truncation limits.
Ingest Improvements
- Index builder:
index_builder.pyconstructs skeleton trajectories from parser indexes for fast session listing without full file I/O. - Parsed trajectory parser:
ParsedTrajectoryParserreads pre-parsed ATIF JSON files, enabling round-trip save/load. - Parser discovery methods: Each parser now implements
discover_session_files()for agent-specific file filtering, replacing centralized discovery functions. - Auto-prompt detection: Claude Code parser classifies plan mode and automated workflow prompts (
is_auto_promptextra field).
Architecture
- TrajectoryStore ABC refactor: Unified index pattern with
_indexand_metadata_cache. Concrete methods (list_metadata, load, exists, session_count, get_metadata) operate on shared structures. Subclasses only implementinitialize(),save(), and_build_index(). - LocalStore simplification: Uses
LOCAL_PARSER_CLASSESlist and delegates to parserdiscover_session_files(). Removed manual per-agent discovery logic. - DiskStore simplification: Streamlined save with incremental index updates. Uses rglob for subdirectory session discovery.
- Parser
AGENT_NAME→AGENT_TYPE: All parsers now useAgentTypeenum instead of string identifiers. - Schema layer: Extracted API boundary models into
schemas/package (session, share, upload, friction, llm). Deleted standalone model files (session_requests.py,share.py,upload.py). - Dependency injection: Added
get_friction_store(),get_skill_store(),get_inference_backend(),set_inference_backend(),is_test_mode()singletons. - Settings expansion: Added
skills_dir,friction_dir, and LLM config fields (llm_backend,llm_api_key,llm_model,llm_timeout,llm_max_tokens). - AppMode.TEST: New test mode for isolated testing with mock backends.
Frontend
- Four-tab navigation: Added "Friction" (amber) and "Skills" (violet) tabs alongside Conversation and Dashboard.
- Session deep linking: URL params
?session=...&step=...for direct navigation to specific sessions and steps. - Flow diagram improvements: Reworked phase grouping, layout engine, and tool chip rendering.
- Session list: Client-side pagination, improved search with debouncing, sticky project headers.
Dependencies
- Added
litellm>=1.40.0andjinja2>=3.1.0to core dependencies.
- Fingerprint module: Deleted
ingest/fingerprint.py(format auto-detection via confidence scoring). Replaced by direct parser dispatch. - Legacy model files: Removed
models/session_requests.py,models/share.py,models/upload.py(migrated toschemas/). - Old frontend assets: Cleaned up stale bundled JS/CSS from previous builds.
UI Polish
- Session header collapse toggle: Chevron button to expand/collapse meta pills and token stats rows, keeping the title row always visible.
- Title hover tooltip: Hovering truncated first-message title shows the full text in a native tooltip.
- MetaPill hover interaction: Subtle background brightness boost on hover for interactivity cue.
- Consistent icons: Added icons to all token stat labels (Input, Output, Cache Read, Cache Write, Total, Est. Cost) and all dashboard section headers (Peak Hours, Agent/Model/Tool Distribution, Project Activity).
Dashboard
- Per-project details: Project Activity rows now show messages count, token count, and estimated cost per project with inline icons.
- Dashboard loading fallback: Direct API fetch when background cache preload hasn't arrived, preventing stuck loading state.
- Dashboard stuck loading: Added fallback fetch when cache prop is null, resolving infinite loading spinner.
- Double dollar sign: Removed redundant
DollarSignicon from project row cost display whereformatCost()already returns$X.XX.
Cost Tracking (Roadmap §1)
- Cost estimation: Model-aware pricing engine covering 45+ models across 12 providers. Per-step and per-trajectory USD cost computed from token metrics. Dashboard surfaces total cost, cost-by-model breakdown, and per-session cost.
Session Graphs (Roadmap §4)
- Conversation flow diagram: Phase-grouped visualization of user → agent → tool interactions with color-coded tool chips and hover-based dependency highlighting. Lazy-loaded via Timeline/Flow toggle.
Sharing & Integration (Roadmap §10)
- Shareable session links: Generate permalink URLs to share session details. Backend persists trajectory snapshots on disk; frontend renders a read-only shared view.
Dashboard
- Tool distribution chart: Horizontal stacked bar chart showing per-tool call counts, percentages, avg/session, and error rates.
- Cache warming: Background pre-computation of dashboard stats on startup for instant first page load.
Packaging (Roadmap §7)
- PyPI metadata: MIT license, authors, classifiers, project URLs, PEP 561
py.typedmarker. - CI/CD: GitHub Actions workflows for tests and PyPI publishing.
- Auto-open browser:
vibelens serveopens the browser automatically (--no-opento disable).
Architecture
- Layered module split: Enforced strict
api → services → analysis → modelsdependency direction. All Pydantic models extracted fromanalysis/intomodels/analysis/. Monolithicdashboard_service.pysplit into focused computation modules (dashboard_stats.py,session_analytics.py,tool_usage.py). Request models split by domain. Export and flow logic extracted into dedicated services. llm/package: New top-level package for LLM utilities — model name normalization (llm/normalizer.py) and pricing table + lookup (llm/pricing.py).stores/→storage/: Renamed for clarity.- Tool graph rework: Nodes and edges now use tool call IDs with refined relation types (read_before_write, search_then_read, write_then_test, multi_edit, error_retry).
- Image support: Multimodal content rendering for image content blocks with click-to-expand lightbox.
- Step timestamps: Clock time alongside elapsed time (
33:51 · 1:23 PM) with gap-since-previous indicator. - Usage chart crosshair: X-axis hover snaps to nearest data point with vertical dashed indicator line.
- Settings dialog: Gear icon in top nav opens settings dialog.
- Timeline redesign: Narrow dot-and-line rail with inline time header, replacing wide stacked layout.
- Dashboard stat cards: Added description subtitles and per-row tooltips with token breakdowns.
Session Graphs (Roadmap §4)
- Analytics dashboard: Stat cards (sessions, messages, tokens, duration), usage-over-time chart, GitHub-style activity heatmap, peak hours, model distribution, and project ranking. Supports project filtering and CSV/JSON export.
Multi-Agent Analytics (Roadmap §3)
- Agent filter: Sidebar dropdown filters sessions by agent type. Configurable via
visible_agents.
Agent Parsers (Roadmap §5)
- Codex parser improvements: Structured output parsing, reasoning extraction, session metadata, error detection, tool result metadata.
- Session header tooltips: Metadata pills show descriptive tooltips on hover.
- Prompts / Skills split: Separate prompt and skill counts in session header.
- Auto-expand short results: Tool results ≤20 lines display inline without collapse.
- UI cleanup: Removed redundant header, fixed text overflow, improved message type differentiation.
- Logging: One log file per module, overwritten each restart.
Privacy & Security (Roadmap §8)
- Upload isolation: Session-token scoped uploads for multi-tab browser safety.
- Donate consent dialog: Consent form with attribution and agreement checkbox.
- Upload result reports main session count instead of total trajectory count.
- Increased default upload limits: 10 GB zip, 20 GB extracted, 10K files.
- Unused settings and VibeLens Export parser.
Architecture
- ATIF v1.6 trajectory model:
Trajectory→Stephierarchy with multimodal content support (text, image, PDF). - Service layer: Business logic extracted from API routes into
session_service,upload_service,demo_loader. - Storage backends:
LocalStorereads from~/.claude/;DiskStorefor demo mode and uploads.
Session Insights (Roadmap §2)
- Step timeline: Visual timeline with elapsed time between steps and step-source indicators.
Agent Parsers (Roadmap §5)
- Session file discovery: Recursive finder for Claude Code, Codex, and Gemini session directories.
- Two-mode system: self-use (default) and demo mode with in-memory storage.
- Pre-loaded example sessions, per-tab client isolation, TTL cleanup for demo uploads.
- Config templates and example sessions.
- Claude Code parser: timestamp, duration, token counts, project path extraction.
- Gemini parser: empty content, token aggregation, project resolution.
- File upload with auto-format detection.
- Session export, view modes (By Time / By Project), resizable panels.
- MongoDB target/source with push/pull API.
- YAML-first configuration package.
- Frontend session viewer with message rendering, sub-agent display, and prompt navigation.
Session Insights (Roadmap §2)
- Phase detection and tool dependency graph with typed edges.
Multi-Agent Analytics (Roadmap §3)
- Cross-agent correlation by project path with overlapping time windows.
Agent Parsers (Roadmap §5)
- Codex CLI and Gemini CLI parsers with auto-detection.
- Project skeleton: FastAPI backend, React frontend, Typer CLI.
- Claude Code and Dataclaw parsers.
- SQLite database, Pydantic models, test suite.