mirror of
https://github.com/nexu-io/open-design.git
synced 2026-09-20 06:15:06 +08:00
2aee23f11c
* fix(analytics): stamp $os/$os_version on daemon-emitted events posthog-node (unlike posthog-js) does not auto-enrich device props, so every daemon-emitted event (run_created/run_finished/project_create_result/ file_upload_result/...) landed in the null/unknown bucket on any OS breakdown. The daemon runs on the user's machine, so process.platform is authoritative; stamp the canonical PostHog $os (Mac OS X|Windows|Linux) + $os_version on both capture() and captureSafety() so backend events join the same OS segmentation as the web client's posthog-js events. * feat(analytics): track HyperFrames as a first-class project_kind HyperFrames is a peer task type in the router (its own Home chip), but the data model stores it as a 'video' project with videoModel='hyperframes-html', so analytics recorded project_kind=video and HyperFrames was invisible in the project-type dimension. Add 'hyperframes' to TrackingProjectKind, make projectKindToTracking(kind, videoModel?) split it out of generic video, and thread videoModel through every web/daemon emit site (project_create_result, run_created/run_finished, recent projects, DS apply target). * feat(analytics): instrument chat composer controls + per-send run context Adds ui_click coverage across the home + in-project chat composer bottom bar, which was almost entirely untracked: - ask/design session-mode toggle (ComposerSessionModeClickProps, home + chat_panel) - design toolbox open / action / resource (DesignToolboxClickProps) - the rest of the bar (ComposerBarClickProps): + menu open/pick/add connector|plugin|mcp, design-system switch, working-dir switch, agent + model selection, context-chip removal - home composer: working-dir picker, task-type chips And enriches run_created/run_finished with the per-send context the spec asks for: session_mode, plugin_id, mcp_ids[], skill_ids[] (model_id/agent_provider_id/ design_system_id already present; mcp_id no longer hardcoded null). * feat(analytics): instrument the workspace tab launcher The tab strip's '+' launcher (search/filter files, New Terminal, New Browser, open file as tab, focus an open tab) had no tracking. Add TabLauncherClickProps (page_name=file_manager, area=tab_launcher) and an onTrack hook on TabLauncherMenu that FileWorkspace fills with page/area/project_id, covering open / filter / create / open_file / open_tab. * fix(analytics): cover home + menu and desktop working-dir switch Review follow-up: - HomeChatComposerClickProps gains plus_menu_open / plus_pick / plus_add (+ resource_kind/resource_id); HomeHero wraps the ComposerPlusMenu open/pick/add callbacks so the home '+' menu emits the same gestures the in-project composer already records. - WorkingDirPill funnels both success paths (browser applyDir + desktop host pickAndReplaceHostProjectWorkingDir) through a shared trackWorkingDirSwitch() so packaged/desktop replacements are counted too. * fix(analytics): fold persistent skillId into run skill_ids set Review follow-up: skill_ids only carried the staged per-turn skillIds, so a project run with a persisted skillId but no staged skills emitted skill_id=<id> but skill_ids=[]. Build a de-duped skill_ids from [skillId, ...skillIds] so the array field is the complete per-send skill context; keep singular skill_id. * fix(analytics): emit agent_selector_open when the AvatarMenu opens Review follow-up: the contract added ComposerBarClickProps.element= 'agent_selector_open' but nothing emitted it, so open-to-select dropoff was unmeasurable. Add an onOpen prop to AvatarMenu fired on the closed->open transition (not on close) and wire ProjectView to emit agent_selector_open with the same project_id context as agent_select/agent_model_select. * fix(analytics): gate session_mode to composer-originated runs Review follow-up: session_mode defaulted a missing reqBody.sessionMode to 'ask', so DS-generation runs (DesignSystemFlow sends no sessionMode) were classified as Ask runs on run_created/run_finished, polluting composer-mode dashboards. Only spread session_mode when !isDesignSystemRun && typeof reqBody.sessionMode === 'string'; the field is optional in the contract for DS runs. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com>
21 lines
709 B
TypeScript
21 lines
709 B
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { sessionModeToTracking } from '../src/analytics/events.js';
|
|
|
|
describe('sessionModeToTracking', () => {
|
|
it('maps the wire `chat` mode to the product term `ask`', () => {
|
|
expect(sessionModeToTracking('chat')).toBe('ask');
|
|
});
|
|
|
|
it('keeps `design` as `design`', () => {
|
|
expect(sessionModeToTracking('design')).toBe('design');
|
|
});
|
|
|
|
it('buckets unknown / null / undefined into the lighter `ask` default', () => {
|
|
expect(sessionModeToTracking(null)).toBe('ask');
|
|
expect(sessionModeToTracking(undefined)).toBe('ask');
|
|
expect(sessionModeToTracking('')).toBe('ask');
|
|
expect(sessionModeToTracking('bogus')).toBe('ask');
|
|
});
|
|
});
|