Repository navigation
[Feature] 支持厂商中立的前端业务语义属性 #989
Description
实现进展 / Implementation: 前端实现已提交 PR #1010 供评审,覆盖范围已从原始 8 点起步清单扩展到完整前端业务域;下方保留提案与讨论历史。Frontend implementation is now available in PR #1010 for review; its broader inventory supersedes the initial eight-point slice.
范围更新 / Scope update
本议题收敛为前端被动语义 HTML 属性(点位、测试与文档);后端事件出口已拆为独立 RFC:https://github.com/iflytek/skillhub/issues/1009,分别评审、不互相阻塞。属性命名和具体点位仍待维护者确认。
This issue now tracks passive frontend semantic HTML markers, tests and documentation. Backend export is a separate RFC at #1009; the two are reviewed independently. Exact markers/conventions remain proposed.
以下保留原始提案及双语图,后端部分作为历史上下文。Original proposal and bilingual diagrams are preserved below; its backend sections are historical context.
Problem
我们在自托管 SkillHub 的使用推广中,需要将产品行为接入企业已有的分析系统,了解“搜索 → 发现 Skill → 请求获取”,以及发布/治理操作的实际结果。我们希望继续使用官方镜像和正常升级路径,由部署方选择分析平台,而不是在各页面绑定某个厂商 SDK 或维护长期 fork。
目前缺少一条稳定、受支持的外部接入路径:
- 前端:关键交互没有统一的业务语义 HTML 属性。外部采集器依赖文案、CSS 或 DOM 层级时,会随多语言、样式或页面重构失效。局部
data-testid、辅助功能属性和组件状态属性也不是完整的业务标记契约。 - 后端:已有 Spring 领域事件、选择性审计、请求日志和技术观测,但没有找到面向部署方的统一业务事件订阅/外发接口。现有审计与计数可以补充分析,却不能统一覆盖逐人搜索、获取及操作结果。下载计数也不能证明客户端安装或执行完成。
相关议题与现状核对
- [Feature] 为空间管理员提供技能使用分析仪表盘(Analytics) #432 提过内建 Analytics 仪表盘,已关闭为 completed。本提案关注部署方自选外部分析系统的接入能力,不要求再建设一套内建报表。
- [Feature] 实现面向治理流程的 Outgoing Webhooks #433 提过面向治理流程的 Outgoing Webhooks,已关闭为 not_planned,且未看到进一步的范围说明。这里明确承认后端诉求存在重叠:希望确认当时的产品边界是否也适用于本次“可选外部事件接入”。如果后端方向仍不在计划中,可将它保留为讨论,先独立推进前端标记;不以新提案绕过此前决定。
- Feat: Introduce 'Skill Health Score' and Automated Degradation Alerts for Enterprise Governance #587 的运行质量/健康评分与告警是更大的另一类需求,本提案不要求采集 Skill 实际运行指标或构建健康评分。
源码核对以 main@0f8867f5f13fb77bbdbeec11ff6c619bd5f94194 为边界,并对照了 v0.2.21。例如:搜索栏交互、基础 Button 属性透传、下载领域事件、既有 Provider 装配方式。这是源码核查,不是已完成的采集实现或生产联调。
Proposed Solution
将需求拆成两个可独立讨论、分步交付的部分,保持厂商中立。
A. 前端:被动、稳定的语义属性
在搜索提交、Skill 卡片/详情、下载请求、复制安装指引、发布提交等关键位置添加稳定的 data-* 属性,例如:
// 仅为命名示例,最终属性与点位由维护者确认
<Button data-analytics-id="skill.download.request" onClick={handleDownload}>
{t('skillDetail.download')}
</Button>- 标记描述动作,独立于样式、文案、语言与布局;必要的对象/版本上下文另行最小化设计。
- 属性本身不发送数据、不绑定 SDK、不加载第三方脚本;部署方自行选择可选采集器与加载方式。
- 复用已有共享组件;对无法透传属性的业务组件补明确落点,而不是假设基础 Button 一处改动就能覆盖全站。
- 键盘提交等非点击入口,需要统计“提交尝试”时应在共用动作入口考虑单独语义事件;不能只按按钮点击推断。服务端结果仍以服务端事实为准。
B. 后端:统一事件扩展点 + 可配置出口(待确认边界)
如果维护者认可后端方向,建议沿现有 Spring 事件和接口装配风格演进,而不是为埋点引入完整的插件市场或热加载框架:
- 复用已存在的领域事件,为缺失的关键动作补事件,并保留必要的稳定主体、资源/版本、发生时间、来源、结果和事件标识。匿名/未知主体如实表达;不从 IP 或 UA 猜测员工身份。
- 在业务事实形成时捕获可信上下文。写操作的成功结果在提交后形成;读取/获取类动作按其真实完成阶段表达,不把链接发放叫作安装完成。
- 提供统一 hook/sink 接口;建议以一个官方内置、配置开启的通用 HTTP Webhook/exporter作为首个实现,投递到部署方自己的接收端。具体 SPI/协议及范围由维护者选择。
- 仅暴露 Java 接口、要求每个部署方自建镜像,仍无法解决保持官方镜像升级路径的诉求;是否提供开箱即用出口,是希望重点讨论的部分。
- 默认关闭、明确授权/作用域;外发异步且有界,不让分析系统故障拖住业务。配置、签名/鉴权、重试与失败可见性应随最小实现一起定义,不承诺 exactly-once。
- 不发送密钥、Token、包文件或正文内容;具体分析厂商的字段转换、身份归一和报表继续留在外部。
Alternatives Considered
- 审计 API/只读 ETL:适合其覆盖范围内的治理事实与对账,但不是全量行为流;现有分页/去重和管理权限仍需处理。
- HTTP 日志、Micrometer、OTLP tracing:适合技术趋势与排障,不能自动补齐稳定的逐人业务语义,也不天然代表客户端安装/执行结果。
- CSS/文本选择器、反代注入脚本:可以做部署侧集成,但不能替代稳定语义标记;不将这种自定义集成描述为现成插件。
- 直接绑定某个分析 SDK 或维持长期 fork:增加厂商与升级耦合,希望避免。
Impact
- 前端标记是加法式改动,保留已有交互、样式、可访问性及 i18n;不开启采集时不自动外发。
- 后端是显式可选的能力;保持鉴权、命名空间隔离、发布/下载/治理规则不变。数据最小化、投递可靠性和升级兼容性需要在后端切片中评审,不能仅凭“小改动”推定无风险。
- 注册表获取/下载发放、客户端安装完成、Agent 执行成功分开定义。 后两者需要可信客户端/执行载体提供证据,不要求注册表猜测。
- 本提案不包含内建分析大屏、Skill 运行健康评分、任意第三方插件热加载,或自动启用遥测。
Contract Or SDK Impact
前端新增稳定属性约定及相应测试/文档,不更改 Skill 包格式或 CLI 协议。若后端获准推进,再定义版本化事件契约、受支持的配置/鉴权、投递语义和部署文档;涉及 OpenAPI 或生成式客户端时按仓库规则同步。不在本议题预先固定完整事件枚举或强制某个厂商模型。
维护者问题:是否愿意接收这个以“被动前端语义标记”为首个小切片、后端外发出口另行确认的厂商中立外接采集方向? 我们愿意在范围确认后参与点位规划、实现、测试和文档,先以前端小 PR 验证,再按认可的后端契约分步推进。
比喻图
像给工具库加稳定铭牌和业务回执出口:铭牌由外部采集器读取,业务事实通过可选出口交给自有接收端。示意的是待讨论方案,不是已上线功能或安装/执行成功证明。
English version
Problem
In a self-hosted SkillHub deployment, we want to integrate product usage with an existing enterprise analytics system: search → discover a Skill → request acquisition, plus actual publishing/governance outcomes. We would like to retain official images and the normal upgrade path, with the analytics platform chosen by the deployment rather than a vendor SDK embedded across pages or a long-lived fork.
There is no stable, supported end-to-end external integration path that we could identify:
- Frontend: key interactions do not expose a consistent business-semantic HTML attribute contract. External collectors tied to translated text, CSS or DOM structure are fragile. The limited test IDs, accessibility attributes and component state attributes do not constitute complete business markers.
- Backend: Spring domain events, selective audit logs, request logs and technical observability exist, but we could not find a unified deployer-facing business-event subscription/export surface. Existing audits and counters are useful supplementary sources, not uniform coverage of per-user search/acquisition/outcomes. Download counters do not prove client installation or execution.
Related work and source scope
- [Feature] 为空间管理员提供技能使用分析仪表盘(Analytics) #432 proposed a built-in Analytics dashboard and is closed as completed. This proposal concerns integration with deployment-selected external analytics, not another built-in reporting product.
- [Feature] 实现面向治理流程的 Outgoing Webhooks #433 proposed governance Outgoing Webhooks and is closed as not_planned, without a further scope explanation in the discussion we found. The backend overlap is explicit: we would like to confirm whether that product boundary also applies to this optional external-event use case. If backend exports remain out of scope, they can stay a discussion while frontend markers proceed independently; this proposal is not intended to bypass that earlier decision.
- Feat: Introduce 'Skill Health Score' and Automated Degradation Alerts for Enterprise Governance #587 covers runtime health scores and alerts, a separate larger scope. We do not ask for Skill runtime metrics or health scoring here.
The source review is pinned to main@0f8867f5f13fb77bbdbeec11ff6c619bd5f94194, with v0.2.21 as a comparison. Relevant anchors are the search bar, shared Button props forwarding, download event and provider assembly linked in the Chinese section above. This is source review, not an implemented collector or completed production integration test.
Proposed Solution
Two independently discussable and deliverable, vendor-neutral parts:
A. Frontend: passive, stable semantic attributes
Add stable data-* attributes at search submission, Skill cards/details, download requests, copy-installation-guidance and publish submission. The data-analytics-id="skill.download.request" snippet above is only a naming example for maintainer discussion.
- Identify the action independently of styling, translated copy or layout; minimize any resource/version context separately.
- Attributes do not send data, bind an SDK, or load third-party scripts. The deployment selects an optional collector and its loading mechanism.
- Reuse shared components and add explicit markers where custom business components do not forward attributes. A shared Button change alone does not mark the whole product.
- Keyboard and other non-click submission paths need a semantic signal at their common action entry if submission attempts are measured; button clicks alone cannot represent them. Backend outcomes remain backend facts.
B. Backend: unified event extension point and configurable export (scope to confirm)
If maintainers support the backend direction, build on existing Spring events and interface assembly rather than introducing a full plugin marketplace or hot-loading framework:
- Reuse domain events, add missing key actions and retain the necessary stable actor, resource/version, occurrence time, origin, outcome and event identity. Represent anonymous/unknown actors honestly; do not infer employees from IP/UA.
- Capture trusted context when the fact is formed. Successful mutations become facts after commit; read/acquisition events describe the stage actually reached, not installation success merely because a link was issued.
- Expose a consistent hook/sink contract. Consider an official built-in, configuration-enabled generic HTTP webhook/exporter as the first implementation, sending to the deployment's own receiver. Maintainers choose the precise SPI/protocol/scope.
- A Java interface alone, requiring custom images for each deployment, would not meet the official-image upgrade-path goal; an out-of-the-box export option is an important discussion point.
- Default off, explicit authorization/scope, bounded asynchronous delivery and business-path independence. Define configuration, signing/authentication, retries and visible failures with the minimum implementation; do not promise exactly-once delivery.
- Exclude credentials, tokens, package files and content bodies. Vendor mapping, identity normalization and reporting stay external.
Alternatives Considered
- Audit API/read-only ETL: useful for covered governance facts and reconciliation, not a complete usage stream; pagination/deduplication and admin permissions still need handling.
- HTTP logs, Micrometer and OTLP tracing: useful for technical trends and diagnosis, but not automatically stable per-user business semantics or client installation/execution outcomes.
- CSS/text selectors and reverse-proxy script injection: possible deployment integrations, not substitutes for stable markers or an existing native plugin contract.
- A vendor SDK embedded in core or a long-lived fork: adds vendor/upgrade coupling that we want to avoid.
Impact
- Additive frontend markers preserve interaction, styling, accessibility and i18n. No automatic outbound collection when not enabled.
- Backend export is explicit opt-in, preserving authorization, namespace isolation and publishing/download/governance policy. Data minimization, delivery guarantees and upgrade compatibility require review in that slice; a small diff does not establish zero risk.
- Registry acquisition/download issuance, completed client installation and successful Agent execution are separate facts. The last two require trusted client/execution receipts, not registry inference.
- No built-in analytics dashboard, runtime health scoring, arbitrary plugin hot loading or automatically enabled telemetry is requested.
Contract Or SDK Impact
Add a frontend attribute convention with tests/docs, without changing Skill package format or CLI protocol. If backend work is accepted, define a versioned event contract, supported configuration/authentication, delivery semantics and operator docs; synchronize OpenAPI/generated clients if affected, following repository rules. This issue does not predefine an exhaustive event enum or require a vendor-specific data model.
Maintainer question: would you accept this vendor-neutral direction with passive frontend markers as the first small slice, and backend export to be confirmed separately? We are willing to contribute marker planning, implementation, tests and docs after scope agreement, starting with a small frontend PR and then proceeding in stages under an agreed backend contract.
Metaphor illustration
Like stable nameplates and an optional receipt exit in a tool library: the collector reads passive labels, while confirmed business facts go to the deployment's own receiver. This illustrates a proposal, not a deployed feature or proof of successful installation/execution.


Activity
github-actions commentedon Oct 20, 2026
Issue Triage
triage/corepriority/p1(4.0/5)effort/l(5/5)5/5highrules-onlyWhy
High-Risk Signals
Maintainer Brief
Summary: In a self-hosted SkillHub deployment, we want to integrate product usage with an existing enterprise analytics system: search → discover a Skill → request acquisition, plus actual publishing/governance outcomes. We would like to retain official images and the normal upgrade path, with the analytics platform chosen by the deployment rather than a vendor SDK embedded across pages or a long-lived fork. There is no stable, supported end-to-end external integration path that we could identify: - Frontend: key interactions do not expose a consistent business-semantic HTML attribute contract. External collectors tied to translated text, CSS or DOM structure are fragile. The limited test IDs, accessibility attributes and component state attributes do not constitute complete business markers. - Backend: Spring domain events, selective audit logs, request logs and technical observability exist, but we could not find a unified deployer-facing business-event subscription/export surface. Existing audits and counters are useful supplementary sources, not uniform coverage of per-user search/acquisition/outcomes. Download counters do not prove client installation or execution. #### Related work and source scope - #432 proposed a built-in Analytics dashboard and is closed as completed. This proposal concerns integration with deployment-selected external analytics, not another built-in reporting product. - #433 proposed governance Outgoing Webhooks and is closed as not_planned, without a further scope explanation in the discussion we found. The backend overlap is explicit: we would like to confirm whether that product boundary also applies to this optional external-event use case. If backend exports remain out of scope, they can stay a discussion while frontend markers proceed independently; this proposal is not intended to bypass that earlier decision. - #587 covers runtime health scores and alerts, a separate larger scope. We do not ask for Skill runtime metrics or health scoring here. The source review is pinned to
main@0f8867f5f13fb77bbdbeec11ff6c619bd5f94194, withv0.2.21as a comparison. Relevant anchors are the search bar, shared Button props forwarding, download event and provider assembly linked in the Chinese section above. This is source review, not an implemented collector or completed production integration test.Why core:
Reproduction or operator path:
Suspected areas:
Risks to watch:
Validation checklist:
Next Action
问题分流结果
triage/corepriority/p1(4.0/5)effort/l(5/5)5/5高rules-only原因
高风险信号
维护者交接摘要
概要: In a self-hosted SkillHub deployment, we want to integrate product usage with an existing enterprise analytics system: search → discover a Skill → request acquisition, plus actual publishing/governance outcomes. We would like to retain official images and the normal upgrade path, with the analytics platform chosen by the deployment rather than a vendor SDK embedded across pages or a long-lived fork. There is no stable, supported end-to-end external integration path that we could identify: - Frontend: key interactions do not expose a consistent business-semantic HTML attribute contract. External collectors tied to translated text, CSS or DOM structure are fragile. The limited test IDs, accessibility attributes and component state attributes do not constitute complete business markers. - Backend: Spring domain events, selective audit logs, request logs and technical observability exist, but we could not find a unified deployer-facing business-event subscription/export surface. Existing audits and counters are useful supplementary sources, not uniform coverage of per-user search/acquisition/outcomes. Download counters do not prove client installation or execution. #### Related work and source scope - #432 proposed a built-in Analytics dashboard and is closed as completed. This proposal concerns integration with deployment-selected external analytics, not another built-in reporting product. - #433 proposed governance Outgoing Webhooks and is closed as not_planned, without a further scope explanation in the discussion we found. The backend overlap is explicit: we would like to confirm whether that product boundary also applies to this optional external-event use case. If backend exports remain out of scope, they can stay a discussion while frontend markers proceed independently; this proposal is not intended to bypass that earlier decision. - #587 covers runtime health scores and alerts, a separate larger scope. We do not ask for Skill runtime metrics or health scoring here. The source review is pinned to
main@0f8867f5f13fb77bbdbeec11ff6c619bd5f94194, withv0.2.21as a comparison. Relevant anchors are the search bar, shared Button props forwarding, download event and provider assembly linked in the Chinese section above. This is source review, not an implemented collector or completed production integration test.为何进入 core:
复现路径或操作路径:
怀疑影响区域:
重点风险:
验证清单:
下一步
XiaoSeS commentedon Oct 22, 2026
我们认可这个方向,欢迎参与实现并提交 PR。
希望保持厂商中立,提供稳定的业务语义标记,默认不采集或外发数据,并保持现有交互、权限和业务行为不变。
具体点位、属性约定、外部接入方式及 PR 拆分可以按你的建议提出,附上测试和使用说明,我们结合实现一起评审。后端事件出口也欢迎提出设计,是否纳入本次实现再共同确认。
[-][Feature] 支持厂商中立的外部埋点接入:前端语义属性与可选后端事件出口[/-][+][Feature] 支持厂商中立的前端业务语义属性[/+]xiaoyaner0201 commentedon Oct 22, 2026
感谢 @XiaoSeS 的回复。我理解已认可的是厂商中立、稳定业务语义标记、默认不采集/外发,以及保持现有交互、权限和业务行为不变;具体点位、属性和 PR 拆分仍需评审,后端出口是否纳入尚未确定。下面先把 #989 收敛为前端被动语义属性;后端设计独立讨论:https://github.com/iflytek/skillhub/issues/1009。原文中的后端探索、#433 边界说明和双语示意图保留为讨论历史,不代表本次前端交付范围。
1. 建议约定(提案,不是已定标准)
data-analytics-id,值采用小写domain.object.action,例如skill.download.request。这是针对 SkillHub 的建议,请维护者确认;不以其他项目的选择作为约束。id,同类卡片可重复使用同一值;不要求每个 DOM 实例唯一。data-testid继续独立服务测试,不替换、不改名,例如现有install-for-agent-button测试 ID 保留。dispatchEvent等语义事件。部署方若另行配置采集器,可按约定属性和下表的原生 DOM 事件接入;那是单独配置的部署侧行为,不是这些属性自带的能力。使用说明应要求只读静态白名单属性,不自动抓取表单值、文本、完整 URL 或整个 DOM。submit,不是按钮click;普通按钮看激活产生的click;自定义卡片还需处理键盘。详情根节点仅是结构锚点。下表明确哪些意图可以观察、哪些结果不能推断。2. 首批点位:搜索 → 详情 → 下载/复制指引 → 发布
源码冻结于
e88ebf57c2e9123ef9697ce9a08492fd7e18b7a8。下列落点是拟新增属性的位置,不是声称源码已经带有这些标记。search.query.submitweb/src/features/search/search-bar.tsx·SearchBar的<form onSubmit={handleSubmit}>(L54),只由SearchPage的调用 显式启用submit覆盖搜索按钮与输入框 Enter;handleSubmit调onSearch,搜索页再更新路由参数skill.card.openweb/src/features/skill/skill-card.tsx·SkillCard的交互根<Card>(最终是 div),由SearchPage结果列表调用 显式启用,仅在onClick存在时落点click;现有onKeyDown对 Enter / Space 直接调用onClick。语义是“请求打开卡片”,搜索页处理器负责路由导航click会漏掉该 div 的键盘路径。部署侧需按此键盘契约处理并避免重复计数;不改变键盘实现来迁就采集。激活不证明导航或详情数据成功;不自动覆盖首页、命名空间或收藏列表skill.detail.renderweb/src/pages/skill-detail.tsx·SkillDetailPage,通过 loading/error/缺失/deleted 分支之后的内容根<div>(L867)skill.download.requestweb/src/pages/skill-detail.tsx侧栏整包下载<Button onClick={handleDownload}>(L1423–1434)click(含键盘激活)表示下载意图;handleDownload仍先判断匿名访问条件与版本可下载性,再触发浏览器链接<a>,前端同时更新缓存计数,均非完整文件传输回执。点击 ≠ 服务端成功 ≠ 文件落盘 ≠ 安装/执行成功。文件预览的单文件下载handleDownloadFile不在首批skill.command.copyweb/src/features/skill/install-command.tsx的CommandBlock内复制<Button>(L79–89),限详情页InstallCommand宿主 启用;SkillHub / ClawHub 两个 tab 的复制按钮共用该语义click表示请求复制 CLI 安装命令;保留异步copy(command)与现有反馈publishedVersion.version,不应声称必然等于侧栏当前选择版本skill.prompt.copyweb/src/features/skill/install-for-agent-button.tsx·InstallForAgentButton的原生<button>(L55–67),保留data-testid="install-for-agent-button";详情宿主见 S6click表示请求复制 Agent 安装提示,既有处理器生成提示并异步写剪贴板;保留禁用和版本安全检查skill.publish.requestweb/src/pages/dashboard/publish.tsx·PublishPage的主<Button onClick={handlePublish}>(L355–362),仅非avatarOnly模式带此标记click表示包发布/更新/重新提交意图;不是<form submit>。保持canSubmit、busy 和重复提交 guardavatarOnly时是保存头像,不能标为发布。请求激活不证明 API 已调用或发布成功;publishSkill有预检确认、错误、待审核与已发布等分支。首批不细分新建/更新/重新提交skill.publish.confirmPublishPage的预检警告ConfirmDialog调用(L365–384)→web/src/shared/components/confirm-dialog.tsx·ConfirmDialog的确认<Button>(L73)click表示接受预检警告并继续;现有onConfirm={() => publishSkill(true)}保持不变为什么不在基础 Button 上统一“打全站点位”:
Button已透传原生属性,但不会自动产生业务语义;SearchBar、SkillCard、CommandBlock、ConfirmDialog等业务封装的参数需逐个检查。建议只补必要的可选属性传递,在本表指明的宿主显式启用;不让共享基础控件猜测动作,不因用了 Button 就宣称全站覆盖。3. PR 切片与使用说明建议
建议以一个前端小 PR提交这 8 个静态标记、必要的调用方限定属性透传、测试和约定文档;后端作为独立 PR,不作为前端前置依赖。若维护者希望更窄,可先提交搜索/详情部分,其余随后补齐。
建议稳定性采用 best effort:尽量保持语义 ID;调整或移除时在更新说明中记录,同时允许正常 UI 演进。这也是待维护者确认的约定。
文档给出每个静态选择器(如
[data-analytics-id="search.query.submit"])及其 DOM 事件、重复实例规则、首次/再次渲染限制、键盘卡片漏计风险和不收集字段清单;不捆绑实际采集器,不声称当前已有官方外部分析插件。下载/复制/发布只暴露意图类别;业务结果或可信客户端回执另在后端/客户端议题讨论。4. 拟验证(尚未执行)
这次只完成冻结源码核对与点位设计,没有实现属性,也没有运行组件测试、E2E、构建或网络验证。现有测试只是后续扩展入口,不是本次通过证据:
search-bar.test.tsx扩展 DOM 属性与submit断言;在search-card-interaction.spec.ts的导航/键盘场景扩展搜索→卡片→详情断言。验证点击与 Enter 搜索各一次,输入/清空不计为提交,卡片 click/Enter/Space 保持行为且无重复记录;非首批宿主不被误标。publish-flow-ui.spec.ts及发布组件测试扩展发布主按钮/警告确认/取消/busy/失败/待审核/已发布/头像单独保存断言;不因标记修改预检、权限、提交次数或最终状态。希望先确认的三点
data-analytics-id+ 小写domain.object.action,首批仅静态动作类别、不追加资源或身份上下文,并与data-testid分离?English version
Thank you for the maintainer reply. I understand that the direction—vendor neutrality, stable business-semantic markers, no collection/export by default, and unchanged interactions, permissions and business behavior—is supported. The precise markers, convention and PR split still need review; backend export has not been accepted into this implementation scope. I suggest keeping #989 frontend-only, with backend design discussed separately at #1009. The original backend discussion, #433 boundary and bilingual illustrations remain historical context, not frontend acceptance criteria.
Proposed contract, not an established convention
Use
data-analytics-idwith lowercasedomain.object.actionvalues. This is a proposal for SkillHub, not a convention already fixed by maintainers or imposed by another project. It is independent ofdata-testid; preserve existing test IDs. Repeated cards may share a semantic value—it is not a unique HTML ID.Add only static semantic values. Do not add query text, Skill names/slugs/resource IDs, versions, commands/prompts, package content, account/organization identity or credentials to analytics attributes. Existing displayed content is not expanded by this proposal. This slice provides action-category anchors, not per-person/per-resource attribution or a joined funnel.
No SDK, collector, script loader, outbound integration, identity stitching, automatic telemetry or runtime semantic-event dispatch is included. An independently configured deployment-side collector may use the documented selectors and native DOM events; it is not supplied by the markers. Usage guidance should read only an explicit static-attribute allowlist, not scrape input values, text, full URLs or the DOM.
First marker inventory
Reviewed source:
e88ebf57c2e9123ef9697ce9a08492fd7e18b7a8. These are proposed insertion points, not existing attributes.search.query.submitweb/src/features/search/search-bar.tsx·SearchBar,<form onSubmit={handleSubmit}>, opted in only bySearchPagesubmit, covering the submit button and input Enter; not typing/clearing. URL entry/history/filter/sort/pagination data loads are not this action. Submission does not prove a new request, search success or returned results.skill.card.openweb/src/features/skill/skill-card.tsx·SkillCard, interactive rootCard/div, explicitly opted in by theSearchPageresult-list callclickand existing Enter/Spacekeydownactivation. The div directly callsonClickon those keys: click-only collection misses keyboard activation. Document keyboard handling/deduplication without changing interaction. Activation does not prove navigation/detail success. Other card hosts are not automatically included.skill.detail.renderweb/src/pages/skill-detail.tsx·SkillDetailPage, content root div at L867 after loading/error/missing/deleted branchesskill.download.requestweb/src/pages/skill-detail.tsx, sidebar package-download Button at L1423–1434click, including keyboard activation, expresses intent.handleDownloadcan redirect to login or stop at guards. The temporary anchor and local counter/cache updates are not transfer receipts: click ≠ server success ≠ saved file ≠ installation/execution. Single-file preview download is excluded.skill.command.copyweb/src/features/skill/install-command.tsx·CommandBlock, copy Button at L79–89, opted in for the detail-page hostpublishedVersion.version, not necessarily the currently selected sidebar version.skill.prompt.copyweb/src/features/skill/install-for-agent-button.tsx·InstallForAgentButton, native button at L55–67; preserve itsdata-testidand detail-host gatingskill.publish.requestweb/src/pages/dashboard/publish.tsx·PublishPage, primary Button at L355–362, marked only when notavatarOnlyclick, not formsubmit, for package publish/update/resubmission intent. Avatar-only mode saves an avatar and must not carry this marker. KeepcanSubmit, busy and duplicate guards.publishSkillhas confirmation, error, pending-review and published branches; activation is not a sent request or successful publication. These package modes are not distinguished in the first slice.skill.publish.confirmPublishPagewarning-dialog call →web/src/shared/components/confirm-dialog.tsx·ConfirmDialog, confirm Button at L73clickaccepts precheck warnings and continues via existingpublishSkill(true). Add a narrow optional attribute-forwarding prop, set only by this publish caller—not a publish marker on every shared dialog. Not the initial attempt or success; cancellation has no such ID.Buttonalready forwards native props, but business wrappers need explicit, caller-scoped forwarding where missing. A generic Button modification does not provide product-wide semantic coverage.Suggested PRs and usage documentation
Propose one small frontend PR containing these eight static markers, narrowly scoped prop forwarding, tests and convention docs. Backend export is an independent PR, not a prerequisite. If a narrower first slice is preferred, search/detail can go first.
Propose best-effort stability: preserve semantic IDs where practical, document changes/removals in release notes, and allow normal UI evolution. This policy also awaits maintainer agreement.
Document selectors, native event types, repeated instances, render/remount limitations, card-keyboard coverage and field exclusions. Do not bundle a collector or claim an existing official analytics plugin. Business outcomes and trusted client receipts need separate backend/client contracts.
Planned verification — not executed
This is frozen-source review and marker design only: no markers implemented; no component tests, E2E, builds or network checks run. Existing files are extension points, not passing evidence:
search-bar.test.tsxandsearch-card-interaction.spec.tsfor static attributes, one submit per button/Enter action, no submission on typing/clearing, click/Enter/Space card behavior without duplication, detail-root presence/absence and unmarked out-of-scope hosts.publish-flow-ui.spec.tsand component tests for main activation, warning confirm/cancel, busy, failure, pending/published responses and avatar-only saving, preserving authorization, prechecks, submission counts and final state.Three confirmations requested
data-analytics-id, lowercasedomain.object.action, static action categories only, no resource/identity context, independent ofdata-testid?xiaoyaner0201 commentedon Oct 22, 2026
已提交前端实现 PR:#1010 — #1010 。
在前面的 8 点起步清单上,进一步核对了完整路由、共享组件及条件交互,扩展到搜索/发现、技能与 Suite、发布管理、审核治理、命名空间、GitHub 同步、通知、账号与管理端;补入有业务意义的确认、取消和重试。当前清单是 54 个注册路由、804 个唯一静态语义 ID、821 处 literal JSX 属性位置,这些是源码口径,不是采集事件数或业务成功次数。
实现仍只提供被动属性和明确的 DOM 透传,默认不采集、不外发,不改现有交互与权限。部署方可选用 Nginx 在 HTML 注入独立 JS 引用;PR 附配置、脚本小白名单示例、CSP/压缩/缓存/子路径/关闭说明。实际采集与厂商适配留在外部,后端继续独立在 #1009 讨论。
已验证:前端全量 1,217 项测试、101 项聚焦测试、类型/lint/build/清单检查通过;独立审查无阻塞发现。实际构建配 Nginx 的 25 项 HTTP 检查,以及 Chrome 根路径/子路径/弹窗交互共 28 项通过,API 使用合成夹具,不作为生产或真实后端验收。远端 CI 结果以 PR Checks 为准。
请结合实现审阅属性命名、覆盖与部署侧接入边界;具体选择可在 PR 中调整。原提案和讨论保留。
English
The frontend implementation is ready for review in PR #1010. The initial eight-marker inventory has been expanded through route/component/conditional-action audits: 54 registered routes, 804 unique static categories and 821 literal JSX attribute sites. These are source counts, not runtime event or successful-operation totals.
Core remains passive and vendor-neutral, with no collection/export or SDK by default and unchanged interactions/permissions. Optional deployment-owned Nginx script-reference injection is documented with a small explicit collector example and CSP/compression/cache/sub-path/rollback guidance. Backend export stays separate in #1009.
All 1,217 frontend tests, 101 focused tests, typecheck/lint/build/manifest checks passed locally; independent review found no blocking findings. Actual compiled UI and Nginx passed 25 HTTP checks and 28 Chrome checks with synthetic APIs, not production/backend acceptance. Live CI is reported on the PR. Feedback on semantic naming, coverage and deployment boundaries is welcome.
chore(analytics): refresh manifest line numbers after main merge
docs(analytics): add Chinese guide and split delivery scope
docs(analytics): keep upstream override and bypass module cache in guide
feat(web): add passive semantic analytics attributes across frontend …
xiaoyaner0201 commentedon Oct 29, 2026
@XiaoSeS 第二步的配置化接入已经提了 PR #1037,有空帮忙看看 🙏
简单说一下:
验证结果和还没覆盖的部分(Helm 本地没跑、release Compose 的 S3/auth 冒烟)都列在 PR 正文里。#989 等这个 PR 合并并验证后再关。
test(chart): pass analytics JSON through a values file