@thinkingai/ae-cli 6.1.20 → 6.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/README.zh.md +2 -1
- package/dist/{auth-FUM37MHF.js → auth-XZNXFRJS.js} +5 -5
- package/dist/{capability-AXFQW5WM.js → capability-FYTU3X6L.js} +42 -12
- package/dist/{chunk-LNZBEQXW.js → chunk-4NRCTUZJ.js} +27041 -474
- package/dist/{chunk-VXNMYUXU.js → chunk-57RRFUEZ.js} +23 -7
- package/dist/{chunk-WZ6YVQSF.js → chunk-7FTTULED.js} +1 -1
- package/dist/{chunk-ATSM5XAW.js → chunk-7XGFSUOM.js} +2 -2
- package/dist/chunk-CCS66K4K.js +155 -0
- package/dist/{chunk-I4WQAEYB.js → chunk-DVMLWQD4.js} +8 -186
- package/dist/{chunk-CZU3V3DQ.js → chunk-DX5CDO34.js} +27 -6
- package/dist/chunk-EQ255HKO.js +38248 -0
- package/dist/{chunk-BBEFP4SB.js → chunk-HBGADCKA.js} +3 -3
- package/dist/{chunk-QJQZH5GQ.js → chunk-HFGZGYCG.js} +10 -6
- package/dist/{chunk-ECBLHAZO.js → chunk-JOCDD4ON.js} +1 -1
- package/dist/{chunk-TKHSULJT.js → chunk-KPQY44JQ.js} +6 -0
- package/dist/{chunk-4P355ZWB.js → chunk-MAPZ7VB6.js} +21 -1
- package/dist/chunk-V2NUHPXF.js +196 -0
- package/dist/{chunk-RSG4ONOI.js → chunk-VYXXOKYS.js} +5 -5
- package/dist/{community-report-client-XXWGSBSD.js → community-report-client-CU22W53K.js} +1 -1
- package/dist/{config-EXUGQN5T.js → config-XO3LI3SA.js} +4 -4
- package/dist/context-IFJI3LIT.js +46 -0
- package/dist/{data-integration-4NZ53OMT.js → data-integration-HNGUKFIC.js} +44 -35
- package/dist/index.js +101 -64
- package/dist/{local-data-upload-client-KYOKVYZV.js → local-data-upload-client-GTRIT64F.js} +3 -2
- package/dist/{memory-ATNKZNW5.js → memory-QGPSNCQS.js} +4 -4
- package/dist/{metadata-VZVC7YMH.js → metadata-DI5BMYFU.js} +8 -8
- package/dist/{model-E4JMQ4V2.js → model-RNPQXIBI.js} +4 -4
- package/dist/{personal-semantic-preference-7S2SQ3UV.js → personal-semantic-preference-5C3WUXFI.js} +11 -8
- package/dist/{project-semantic-2SZP2OPO.js → project-semantic-3LF6Q6JZ.js} +27 -21
- package/dist/{sync-YV3E66IF.js → sync-O45NXEQY.js} +7 -6
- package/dist/{te-agent-JB5T3PO7.js → te-agent-K5MSPNHJ.js} +5 -5
- package/dist/{te-analysis-3YJAAT2D.js → te-analysis-AISWCOOZ.js} +1086 -354
- package/dist/{te-community-UDBI672N.js → te-community-4OYU3BDA.js} +4 -4
- package/dist/{te-dataops-ZLYOCXZ4.js → te-dataops-NFIPB6FX.js} +5 -5
- package/dist/{te-engage-4XG6OJML.js → te-engage-BAM3GBFX.js} +7 -7
- package/dist/{te-experiment-VXUWPINJ.js → te-experiment-GUTZXZ5Z.js} +132 -14
- package/dist/{te-kb-WYQWHFSC.js → te-kb-3TS73NO6.js} +454 -194
- package/dist/{te-system-7G6F2LJA.js → te-system-STMHLS5J.js} +12 -7
- package/dist/{te-team-E7FBBXMQ.js → te-team-3I5AOX3N.js} +6 -6
- package/dist/{update-D47BUG25.js → update-RZXLPCRH.js} +4 -4
- package/package.json +21 -14
- package/skills/ae-analysis/SKILL.md +91 -78
- package/skills/ae-analysis/references/adhoc_export.md +11 -18
- package/skills/ae-analysis/references/adhoc_run.md +15 -7
- package/skills/ae-analysis/references/agent_review_detail.md +11 -0
- package/skills/ae-analysis/references/agent_review_evidence.md +46 -0
- package/skills/ae-analysis/references/agent_review_list.md +9 -0
- package/skills/ae-analysis/references/agent_review_preflight.md +96 -0
- package/skills/ae-analysis/references/agent_review_priorities_comparisons.md +76 -0
- package/skills/ae-analysis/references/agent_review_records.md +9 -0
- package/skills/ae-analysis/references/agent_review_retry.md +12 -0
- package/skills/ae-analysis/references/agent_review_review.md +16 -0
- package/skills/ae-analysis/references/agent_review_submit_to_page.md +184 -0
- package/skills/ae-analysis/references/ai_models/attribution.md +29 -0
- package/skills/ae-analysis/references/ai_models/distribution.md +40 -0
- package/skills/ae-analysis/references/ai_models/event.md +108 -0
- package/skills/ae-analysis/references/ai_models/funnel.md +46 -0
- package/skills/ae-analysis/references/ai_models/heat_map.md +26 -0
- package/skills/ae-analysis/references/ai_models/interval.md +20 -0
- package/skills/ae-analysis/references/ai_models/path.md +38 -0
- package/skills/ae-analysis/references/ai_models/prop_analysis.md +39 -0
- package/skills/ae-analysis/references/ai_models/rank_list.md +25 -0
- package/skills/ae-analysis/references/ai_models/retention.md +70 -0
- package/skills/ae-analysis/references/ai_models/revenue.md +28 -0
- package/skills/ae-analysis/references/ai_models/sql.md +74 -0
- package/skills/ae-analysis/references/ai_models/tag.md +19 -0
- package/skills/ae-analysis/references/ai_models.md +32 -473
- package/skills/ae-analysis/references/alert_create.md +7 -7
- package/skills/ae-analysis/references/alert_delete.md +4 -6
- package/skills/ae-analysis/references/alert_detail_list.md +7 -9
- package/skills/ae-analysis/references/alert_get.md +5 -7
- package/skills/ae-analysis/references/alert_job_list.md +4 -6
- package/skills/ae-analysis/references/alert_list.md +6 -8
- package/skills/ae-analysis/references/alert_notice_config_list.md +4 -6
- package/skills/ae-analysis/references/alert_start.md +5 -7
- package/skills/ae-analysis/references/alert_stop.md +5 -7
- package/skills/ae-analysis/references/alert_update.md +8 -8
- package/skills/ae-analysis/references/analysis_data_export.md +72 -0
- package/skills/ae-analysis/references/analysis_data_retrieval.md +32 -196
- package/skills/ae-analysis/references/analysis_gateway_assets.md +23 -180
- package/skills/ae-analysis/references/analysis_interpretation.md +37 -17
- package/skills/ae-analysis/references/asset_abnormal_get.md +0 -1
- package/skills/ae-analysis/references/asset_abnormal_list.md +0 -1
- package/skills/ae-analysis/references/asset_authentication_export.md +4 -0
- package/skills/ae-analysis/references/asset_authentication_list.md +7 -1
- package/skills/ae-analysis/references/asset_authentication_update.md +5 -1
- package/skills/ae-analysis/references/asset_batch_dashboard_schedule_freeze.md +8 -6
- package/skills/ae-analysis/references/asset_batch_delete.md +6 -6
- package/skills/ae-analysis/references/asset_batch_disable_auto_backup.md +4 -5
- package/skills/ae-analysis/references/asset_batch_disable_auto_update.md +5 -6
- package/skills/ae-analysis/references/asset_batch_handover.md +4 -5
- package/skills/ae-analysis/references/asset_batch_info_export.md +4 -5
- package/skills/ae-analysis/references/asset_batch_sql_export.md +5 -6
- package/skills/ae-analysis/references/asset_dependency_list.md +4 -5
- package/skills/ae-analysis/references/asset_export.md +4 -5
- package/skills/ae-analysis/references/asset_impact_list.md +5 -9
- package/skills/ae-analysis/references/asset_lineage_get.md +5 -6
- package/skills/ae-analysis/references/asset_list.md +4 -5
- package/skills/ae-analysis/references/asset_query_history_list.md +4 -8
- package/skills/ae-analysis/references/asset_recent_list.md +0 -1
- package/skills/ae-analysis/references/asset_search.md +12 -9
- package/skills/ae-analysis/references/asset_url_get.md +3 -4
- package/skills/ae-analysis/references/bi_panel_copy.md +2 -2
- package/skills/ae-analysis/references/bi_panel_page_data_export.md +4 -12
- package/skills/ae-analysis/references/bi_panel_page_data_run.md +2 -0
- package/skills/ae-analysis/references/catalog_export.md +4 -17
- package/skills/ae-analysis/references/catalog_list.md +4 -4
- package/skills/ae-analysis/references/check_delete.md +5 -7
- package/skills/ae-analysis/references/check_export.md +11 -11
- package/skills/ae-analysis/references/check_get.md +8 -10
- package/skills/ae-analysis/references/check_list.md +4 -6
- package/skills/ae-analysis/references/check_retry.md +8 -10
- package/skills/ae-analysis/references/check_run.md +2 -4
- package/skills/ae-analysis/references/command_index.md +44 -26
- package/skills/ae-analysis/references/dashboard_report_data_export.md +5 -13
- package/skills/ae-analysis/references/dashboard_report_data_run.md +1 -1
- package/skills/ae-analysis/references/dashboard_update.md +14 -3
- package/skills/ae-analysis/references/datatable_columns_get.md +0 -1
- package/skills/ae-analysis/references/datatable_influence_list.md +0 -1
- package/skills/ae-analysis/references/datatable_version_get.md +0 -1
- package/skills/ae-analysis/references/datatable_version_list.md +0 -1
- package/skills/ae-analysis/references/debug_device_add.md +1 -2
- package/skills/ae-analysis/references/drilldown_entities_export.md +3 -3
- package/skills/ae-analysis/references/drilldown_events_export.md +3 -2
- package/skills/ae-analysis/references/drilldown_user_events_export.md +2 -2
- package/skills/ae-analysis/references/entity_detail_export.md +3 -2
- package/skills/ae-analysis/references/entity_detail_run.md +1 -0
- package/skills/ae-analysis/references/event_blacklist_add.md +5 -7
- package/skills/ae-analysis/references/event_blacklist_list.md +4 -6
- package/skills/ae-analysis/references/event_blacklist_update.md +6 -8
- package/skills/ae-analysis/references/event_changelog_list.md +0 -1
- package/skills/ae-analysis/references/event_create.md +0 -1
- package/skills/ae-analysis/references/event_detail_export.md +3 -2
- package/skills/ae-analysis/references/event_detail_run.md +1 -0
- package/skills/ae-analysis/references/event_export.md +0 -1
- package/skills/ae-analysis/references/event_get.md +0 -1
- package/skills/ae-analysis/references/event_hide_update.md +0 -1
- package/skills/ae-analysis/references/event_influence_list.md +0 -1
- package/skills/ae-analysis/references/event_list.md +0 -1
- package/skills/ae-analysis/references/event_property_bundle_export.md +5 -14
- package/skills/ae-analysis/references/event_property_bundle_import.md +2 -6
- package/skills/ae-analysis/references/event_relation_update.md +0 -1
- package/skills/ae-analysis/references/event_update.md +0 -1
- package/skills/ae-analysis/references/exchange_config_update.md +0 -1
- package/skills/ae-analysis/references/exchange_rate_refresh.md +0 -1
- package/skills/ae-analysis/references/exchange_rule_list.md +0 -1
- package/skills/ae-analysis/references/exchange_rule_update.md +0 -1
- package/skills/ae-analysis/references/exchange_rule_validate.md +0 -1
- package/skills/ae-analysis/references/governance_recommendation_decisions.md +23 -0
- package/skills/ae-analysis/references/governance_recommendation_export.md +108 -0
- package/skills/ae-analysis/references/governance_recommendation_submit.md +41 -0
- package/skills/ae-analysis/references/history_tag_data_drilldown_export.md +4 -4
- package/skills/ae-analysis/references/history_tag_data_export.md +3 -3
- package/skills/ae-analysis/references/ingest_error_list.md +7 -9
- package/skills/ae-analysis/references/ingest_summary.md +6 -8
- package/skills/ae-analysis/references/live_data_export.md +10 -10
- package/skills/ae-analysis/references/live_data_list.md +7 -9
- package/skills/ae-analysis/references/metadata_resolution.md +78 -0
- package/skills/ae-analysis/references/metric_export.md +0 -1
- package/skills/ae-analysis/references/metric_get.md +0 -1
- package/skills/ae-analysis/references/metric_list.md +4 -5
- package/skills/ae-analysis/references/metric_update.md +0 -1
- package/skills/ae-analysis/references/operation_record_export.md +4 -5
- package/skills/ae-analysis/references/operation_record_list.md +4 -5
- package/skills/ae-analysis/references/personal_semantic_preference_list.md +18 -1
- package/skills/ae-analysis/references/plan_change_log_export.md +10 -10
- package/skills/ae-analysis/references/plan_change_log_list.md +4 -6
- package/skills/ae-analysis/references/plan_delete_items.md +2 -4
- package/skills/ae-analysis/references/plan_export.md +9 -9
- package/skills/ae-analysis/references/plan_generate.md +2 -4
- package/skills/ae-analysis/references/plan_get.md +4 -6
- package/skills/ae-analysis/references/plan_import_excel.md +6 -8
- package/skills/ae-analysis/references/plan_save_items.md +2 -4
- package/skills/ae-analysis/references/plan_sync_from_meta.md +4 -6
- package/skills/ae-analysis/references/project_access_detail_get.md +0 -1
- package/skills/ae-analysis/references/project_data_power_get.md +0 -1
- package/skills/ae-analysis/references/project_data_power_list.md +0 -1
- package/skills/ae-analysis/references/project_data_power_upsert.md +0 -1
- package/skills/ae-analysis/references/project_entity_create.md +0 -1
- package/skills/ae-analysis/references/project_entity_event_list.md +0 -1
- package/skills/ae-analysis/references/project_entity_get.md +0 -1
- package/skills/ae-analysis/references/project_entity_list.md +0 -1
- package/skills/ae-analysis/references/project_entity_update.md +0 -1
- package/skills/ae-analysis/references/project_function_list.md +0 -1
- package/skills/ae-analysis/references/project_info_get.md +0 -1
- package/skills/ae-analysis/references/project_info_list.md +0 -1
- package/skills/ae-analysis/references/project_info_update.md +0 -1
- package/skills/ae-analysis/references/project_mark_time_create.md +0 -1
- package/skills/ae-analysis/references/project_mark_time_list.md +0 -1
- package/skills/ae-analysis/references/project_mark_time_update.md +0 -1
- package/skills/ae-analysis/references/project_member_add.md +6 -5
- package/skills/ae-analysis/references/project_member_batch_update.md +0 -1
- package/skills/ae-analysis/references/project_member_candidate_list.md +4 -3
- package/skills/ae-analysis/references/project_member_handover_run.md +2 -3
- package/skills/ae-analysis/references/project_member_list.md +0 -1
- package/skills/ae-analysis/references/project_member_receiver_list.md +0 -1
- package/skills/ae-analysis/references/project_member_update.md +0 -1
- package/skills/ae-analysis/references/project_owner_update.md +0 -1
- package/skills/ae-analysis/references/project_permission_binding_list.md +0 -1
- package/skills/ae-analysis/references/project_role_function_list.md +0 -1
- package/skills/ae-analysis/references/project_role_get.md +0 -1
- package/skills/ae-analysis/references/project_role_list.md +0 -1
- package/skills/ae-analysis/references/project_role_upsert.md +32 -2
- package/skills/ae-analysis/references/project_role_user_list.md +0 -1
- package/skills/ae-analysis/references/project_semantic_knowledge_wiki.md +214 -0
- package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +93 -0
- package/skills/ae-analysis/references/project_timezone_get.md +0 -1
- package/skills/ae-analysis/references/project_timezone_overview.md +0 -1
- package/skills/ae-analysis/references/project_timezone_update.md +0 -1
- package/skills/ae-analysis/references/project_user_id_items_update.md +0 -1
- package/skills/ae-analysis/references/property_changelog_list.md +0 -1
- package/skills/ae-analysis/references/property_create.md +0 -1
- package/skills/ae-analysis/references/property_export.md +0 -1
- package/skills/ae-analysis/references/property_get.md +0 -1
- package/skills/ae-analysis/references/property_hide_update.md +0 -1
- package/skills/ae-analysis/references/property_influence_list.md +0 -1
- package/skills/ae-analysis/references/property_list.md +3 -4
- package/skills/ae-analysis/references/property_related_events.md +0 -1
- package/skills/ae-analysis/references/property_relation_update.md +0 -1
- package/skills/ae-analysis/references/property_update.md +0 -1
- package/skills/ae-analysis/references/report_create.md +4 -2
- package/skills/ae-analysis/references/report_data_export.md +11 -9
- package/skills/ae-analysis/references/report_data_run.md +14 -7
- package/skills/ae-analysis/references/report_get.md +5 -3
- package/skills/ae-analysis/references/report_list.md +2 -0
- package/skills/ae-analysis/references/report_update.md +5 -3
- package/skills/ae-analysis/references/rule_create.md +5 -6
- package/skills/ae-analysis/references/rule_delete.md +5 -5
- package/skills/ae-analysis/references/rule_list.md +3 -4
- package/skills/ae-analysis/references/rule_schema.md +3 -4
- package/skills/ae-analysis/references/rule_update.md +5 -6
- package/skills/ae-analysis/references/sdk_sample_generate.md +2 -4
- package/skills/ae-analysis/references/sql_table_columns.md +1 -1
- package/skills/ae-analysis/references/super_metadata_batch_create.md +1 -1
- package/skills/ae-analysis/references/super_metadata_batch_edit.md +1 -1
- package/skills/ae-analysis/references/system_member_add.md +1 -2
- package/skills/ae-analysis/references/system_member_status_update.md +1 -1
- package/skills/ae-analysis/references/system_ops_alert_contact_list.md +1 -1
- package/skills/ae-analysis/references/system_ops_alert_contact_test.md +0 -1
- package/skills/ae-analysis/references/system_query_monitor_overview.md +3 -3
- package/skills/ae-analysis/references/system_query_task_export.md +4 -14
- package/skills/ae-analysis/references/system_query_task_get.md +1 -1
- package/skills/ae-analysis/references/system_query_task_list.md +5 -6
- package/skills/ae-analysis/references/system_receiver_address_upsert.md +3 -3
- package/skills/ae-analysis/references/system_receiver_detection_get.md +1 -1
- package/skills/ae-analysis/references/system_third_party_login_disable.md +1 -1
- package/skills/ae-analysis/references/system_usage_trend_export.md +3 -12
- package/skills/ae-analysis/references/user_cluster_list.md +1 -1
- package/skills/ae-analysis/references/user_cluster_member_export.md +4 -4
- package/skills/ae-analysis/references/user_tag_list.md +1 -1
- package/skills/ae-analysis/references/user_tag_member_export.md +4 -4
- package/skills/ae-analysis/references/virtual_event_create.md +10 -5
- package/skills/ae-analysis/references/virtual_event_get.md +0 -1
- package/skills/ae-analysis/references/virtual_property_create.md +0 -1
- package/skills/ae-analysis/references/virtual_property_sql_rule_update.md +0 -1
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +1054 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/company-kb.mjs +112 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-rules.md +30 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +2735 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/package-wiki-source-zip.mjs +376 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/plan-kb-source-sync.mjs +264 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/precompiled-source.mjs +49 -0
- package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/upload-kb-sources-concurrently.mjs +200 -0
- package/skills/ae-analysis/scripts/read_results.py +197 -0
- package/skills/ae-analysis-global/SKILL.md +1 -1
- package/skills/ae-capability/SKILL.md +1 -1
- package/skills/ae-community/SKILL.md +1 -1
- package/skills/ae-current-context/SKILL.md +53 -0
- package/skills/ae-data-integration/SKILL.md +5 -4
- package/skills/ae-data-integration/references/lark-bitable-source.md +288 -0
- package/skills/ae-data-integration/references/lark-sheet-source.md +130 -0
- package/skills/ae-data-integration/references/manual-export-source.md +83 -0
- package/skills/ae-data-integration/references/reuse.md +2 -0
- package/skills/ae-data-integration/references/sink-upload.md +32 -0
- package/skills/ae-data-integration/references/tracking-plan.md +4 -1
- package/skills/ae-data-integration/references/ue-mapping.md +2 -2
- package/skills/ae-data-integration-helper/SKILL.md +5 -5
- package/skills/ae-data-integration-helper/references/android_sdk_faq.md +3 -3
- package/skills/ae-data-integration-helper/references/c_sdk_faq.md +3 -3
- package/skills/ae-data-integration-helper/references/cocoscreator_sdk_faq.md +1 -1
- package/skills/ae-data-integration-helper/references/cpp_server_sdk_faq.md +3 -3
- package/skills/ae-data-integration-helper/references/ios_sdk_faq.md +1 -1
- package/skills/ae-data-integration-helper/references/java_sdk_faq.md +3 -3
- package/skills/ae-data-integration-helper/references/javascript_sdk_faq.md +1 -1
- package/skills/ae-data-integration-helper/references/logbus2_guide.md +1 -1
- package/skills/ae-data-integration-helper/references/logbus2_parser_plugin.md +2 -2
- package/skills/ae-data-integration-helper/references/minigame_sdk_faq.md +2 -2
- package/skills/ae-data-integration-helper/references/miniprogram_sdk_faq.md +1 -1
- package/skills/ae-data-integration-helper/references/python_sdk_faq.md +2 -2
- package/skills/ae-data-integration-helper/references/restful_api_notes.md +2 -2
- package/skills/ae-data-integration-helper/references/sdk_log_guide.md +3 -3
- package/skills/ae-data-integration-helper/references/sdk_usage_notes.md +11 -11
- package/skills/ae-data-integration-helper/references/unity_sdk_faq.md +1 -1
- package/skills/ae-dataops/SKILL.md +1 -1
- package/skills/ae-engage/SKILL.md +4 -3
- package/skills/ae-engage/references/build-task-save-guide.md +3 -0
- package/skills/ae-engage/references/flow-metric-update.md +115 -1
- package/skills/ae-engage/references/save-flow.md +3 -0
- package/skills/ae-engage/references/save-task.md +21 -0
- package/skills/ae-engage/references/task-metric-update.md +151 -0
- package/skills/ae-experiment/SKILL.md +14 -7
- package/skills/ae-experiment/references/save_submit_external_experiment.md +52 -0
- package/skills/ae-experiment-design/SKILL.md +3 -3
- package/skills/ae-experiment-design/references/platform-operations.md +1 -1
- package/skills/ae-experiment-insight/SKILL.md +2 -2
- package/skills/ae-experiment-insight/references/platform-operations.md +1 -1
- package/skills/ae-generate-tracking-code/SKILL.md +2 -1
- package/skills/ae-generate-tracking-code/references/client-sdk-insert.md +1 -1
- package/skills/ae-generate-tracking-code/references/datax-config.md +1 -1
- package/skills/ae-generate-tracking-code/references/logbus-config.md +1 -1
- package/skills/ae-generate-tracking-code/references/modes.md +1 -1
- package/skills/ae-generate-tracking-code/references/server-sdk-insert.md +5 -5
- package/skills/ae-generate-tracking-code/references/snippet-delivery.md +3 -3
- package/skills/ae-generate-tracking-plan/SKILL.md +2 -2
- package/skills/ae-generate-tracking-plan/references/te-api.md +1 -0
- package/skills/ae-generate-tracking-plan/references/xlsx-schema.md +3 -2
- package/skills/ae-kb/SKILL.md +41 -2
- package/skills/ae-kb/references/analysis-workflow.md +292 -0
- package/skills/ae-kb/references/source-mutations.md +95 -0
- package/skills/ae-kb-discovery/SKILL.md +5 -1
- package/skills/ae-metadata/SKILL.md +1 -1
- package/skills/ae-migrate-tracking-code/SKILL.md +195 -0
- package/skills/ae-migrate-tracking-code/references/ae-preset-properties.md +76 -0
- package/skills/ae-migrate-tracking-code/references/ir.md +167 -0
- package/skills/ae-migrate-tracking-code/references/mapping-framework.md +112 -0
- package/skills/ae-migrate-tracking-code/references/providers/README.md +58 -0
- package/skills/ae-migrate-tracking-code/references/providers/amplitude.md +208 -0
- package/skills/ae-migrate-tracking-code/references/providers/firebase.md +160 -0
- package/skills/ae-migrate-tracking-code/references/providers/ga4.md +92 -0
- package/skills/ae-migrate-tracking-code/references/providers/mixpanel.md +150 -0
- package/skills/ae-migrate-tracking-code/references/providers/sensors-data.md +146 -0
- package/skills/ae-project-semantic/SKILL.md +1 -1
- package/skills/ae-system/SKILL.md +4 -4
- package/skills/ae-team/SKILL.md +2 -2
- package/skills/ae-use-agent/references/local-agent.md +1 -1
- package/dist/chunk-TAL6CZH6.js +0 -72
- package/skills/ae-analysis/metadata_resolution.md +0 -184
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ae-migrate-tracking-code
|
|
3
|
+
description: "Migrate existing third-party SDK tracking code (Firebase, Amplitude, Sensors Data, Mixpanel, GA4) to the AE SDK (数数 / ThinkingAI / Agentic Engine / AE SDK) — switch (replace) or add alongside existing tracking (dual-write). Trigger words: 埋点迁移、埋点切换、第三方埋点迁移、第三方埋点切换、迁移埋点到数数、把 xx SDK 切换到数数、把已有埋点用数数实现一遍、用数数替换 xx SDK、集成数数并参考已有 xx SDK 埋点、Firebase 迁移、Amplitude 迁移、Mixpanel 迁移、神策迁移、Sensors Data 迁移、GA4 迁移、gtag 迁移、双写、tracking migration、migrate Firebase/Amplitude/Mixpanel/Sensors Data/GA4 to AE、switch xx SDK to ThinkingAI、replace xx SDK with AE、replace logEvent with track、re-implement existing tracking with ThinkingAI、add AE tracking alongside existing analytics、dual-write. Provider-agnostic core with per-provider adapters; reuses ae-generate-tracking-plan and ae-generate-tracking-code."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ae-migrate-tracking-code
|
|
7
|
+
|
|
8
|
+
> **Conversation language**: This skill document is in English, but **all output to the user MUST be in the user's input language**.
|
|
9
|
+
> English input → English reply; Chinese input → Chinese reply; Japanese input → Japanese reply.
|
|
10
|
+
> If uncertain, default to English.
|
|
11
|
+
> This applies to all output: section titles, phase names, prompts, code comments, etc.
|
|
12
|
+
> **⚠️ CRITICAL: Many provider adapter docs contain Chinese glossary notes. When reading them to answer an English/Japanese user, translate headings and comments to the user's language.**
|
|
13
|
+
> Do NOT copy Chinese text verbatim from this document into English/Japanese replies.
|
|
14
|
+
|
|
15
|
+
## Terminology Glossary
|
|
16
|
+
|
|
17
|
+
| 中文 | English | Notes |
|
|
18
|
+
|------|---------|-------|
|
|
19
|
+
| 埋点迁移 | Tracking Migration | Convert existing third-party SDK tracking calls to AE SDK |
|
|
20
|
+
| 源 SDK | Source SDK / Provider | The third-party SDK already in the project (Firebase, Amplitude, ...) |
|
|
21
|
+
| 调用点 | Call Site | A source-SDK invocation (`logEvent` / `setUserId` / `setUserProperty` / Identify) |
|
|
22
|
+
| 归一化中间表示 | IR (Intermediate Representation) | Provider-neutral dump of extracted call sites |
|
|
23
|
+
| 映射 | Mapping | Source event/property → AE event/property translation |
|
|
24
|
+
| 切换 | Switch | Replace source calls with AE `track()` and remove source SDK |
|
|
25
|
+
| 双写 / 新增 | Add / Dual-write | Keep source SDK and add AE `track()` alongside |
|
|
26
|
+
| 依赖标识 | Dependency Identifier | Package/module name used to remove the source SDK in switch mode |
|
|
27
|
+
| 自动采集事件 | Auto-track Event | Events the source SDK collects automatically (e.g. `session_start`) |
|
|
28
|
+
| 公共属性 | Super Property | Property attached to every event automatically. ⚠️ The correct Chinese AE term is "公共属性" or "公共事件属性". Never translate "Super Property" as "超级属性" — that is NOT a valid AE term. |
|
|
29
|
+
| 用户属性 | User Property | Property set on the user profile |
|
|
30
|
+
| 用户体系 | User Identity System | distinct_id / account_id strategy in AE |
|
|
31
|
+
|
|
32
|
+
## When to Trigger
|
|
33
|
+
|
|
34
|
+
Trigger when user says: "migrate Firebase tracking to AE / replace Amplitude with ThinkingAI / my project already has Firebase/Amplitude tracking, switch it to AE SDK / add AE tracking alongside existing analytics" etc. — e.g. 把当前工程里的 xx SDK 切换到数数、把已有埋点用数数实现一遍、用数数替换 xx SDK、集成数数并参考已有的 xx SDK 埋点.
|
|
35
|
+
|
|
36
|
+
The **target AE SDK** may be referred to by any of: 数数 / 数数 SDK / ThinkingAI / ThinkingAI SDK / Agentic Engine / Agentic Engine SDK / AE / AE SDK — they are one SDK. The trigger signal is "an **existing third-party source SDK** + 迁移/切换/替换/实现一遍", or "集成/接入数数 **并参考已有的 xx SDK 埋点**". A bare 接入数数 SDK / 加数数埋点 with no source SDK is greenfield — it belongs to `ae-generate-tracking-code`, not this skill.
|
|
37
|
+
|
|
38
|
+
**Scope**: this skill is codebase-only — it scans existing third-party tracking calls (Phase 0/1). If there is no source code with third-party tracking (only product docs / descriptions), do NOT use this skill; route to `ae-generate-tracking-plan` + `ae-generate-tracking-code` instead. Historical data import into AE is offline data-migration work, **out of scope** — this skill only switches the live client/server SDK, preserving user IDs and event/property names so new data joins the imported data.
|
|
39
|
+
|
|
40
|
+
This skill orchestrates the migration end-to-end but **does not duplicate** the two existing skills:
|
|
41
|
+
|
|
42
|
+
- Plan generation/upload → hand off to `ae-generate-tracking-plan` (codebase path).
|
|
43
|
+
- AE SDK code insertion → hand off to `ae-generate-tracking-code` (insert mode), with insertion sites supplied from the migration mapping instead of grep-discovered business triggers.
|
|
44
|
+
|
|
45
|
+
## Provider Registry (extensible)
|
|
46
|
+
|
|
47
|
+
The core is provider-agnostic. Each third-party platform is one adapter file. **To support a new provider, add one adapter under `references/providers/` and one row below — do not modify this SKILL.md.**
|
|
48
|
+
|
|
49
|
+
| Provider | Adapter | Platforms covered | Detect pattern (summary) |
|
|
50
|
+
|---|---|---|---|
|
|
51
|
+
| Firebase Analytics | `references/providers/firebase.md` | Web v8/v9, Android, iOS, Flutter, React Native, Unity, C++ | `firebase/analytics`, `firebase.analytics()`, `FirebaseAnalytics`, `FIRAnalytics`, `Analytics.logEvent` (iOS Swift), `FirebaseAnalytics.instance` |
|
|
52
|
+
| Amplitude | `references/providers/amplitude.md` | Web legacy (`amplitude-js`), Browser 2.x, Node, Python, Go, Java, Android, iOS, React Native, Flutter, Unity | `amplitude-js`, `@amplitude/analytics-browser`, `@amplitude/analytics-node`, `amplitude.init`, `amplitude.getInstance()`, `amplitude.logEvent`, `amplitude.track`, `Identify`, server imports (`from amplitude import`, `analytics-go`, `com.amplitude:java-sdk`) |
|
|
53
|
+
| Sensors Data (神策) | `references/providers/sensors-data.md` | Web, Android, iOS, Harmony, macOS/tvOS, C++, React Native, Flutter, Unity, Unreal, Cocos2d-x, mini-programs (WeChat/other), QuickApp, APICloud, uni-app, Weex, Egret, LayaAir + server SDKs (Java/Python/Go/Node/PHP/Ruby/C/.NET/Lua) | `sensorsdata.min.js`, `sensors.init`, `sensors.track`, `SensorsDataAPI`, `SensorsAnalyticsSDK`, `profileSet`, `setProfile` (legacy), server `sa-sdk-*` (Python/Go/Node/PHP/Ruby/C/.NET/Lua) |
|
|
54
|
+
| Mixpanel | `references/providers/mixpanel.md` | JavaScript, Node, Python, Go, Java, Ruby, PHP, Android, iOS, Swift, React Native, Flutter, Unity | `mixpanel-browser`, `mixpanel.init`, `mixpanel.track`, `mixpanel.identify`, `mixpanel.people`, `MixpanelAPI`, `mixpanel.NewApiClient` (Go), `Mixpanel::Tracker` (Ruby), `Mixpanel::getInstance` (PHP), `mp.track` / `people_set` (Python) |
|
|
55
|
+
| Google Analytics 4 | `references/providers/ga4.md` | Web (gtag.js / dataLayer), Measurement Protocol (server) | `gtag('event'`, `gtag('config'`, `gtag('set'`, `dataLayer` (GA4 only when `gtag(`/`G-` also present), `G-XXXXXXX`, Measurement Protocol `mp/collect` |
|
|
56
|
+
|
|
57
|
+
Adapter contract (required fields per adapter) is defined in `references/providers/README.md`.
|
|
58
|
+
|
|
59
|
+
**Supported scope**: only the providers/platforms listed above (and the per-platform tables in each adapter's Recognition section) are supported. Anything not listed is out of scope and not supported by this skill — do not fabricate a mapping for unlisted platforms.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Phase 0 — Detect source SDK and version
|
|
64
|
+
|
|
65
|
+
1. Locate the project and its package/dependency manifest (`package.json`, `build.gradle`, `Podfile`, `pubspec.yaml`, `*.csproj`, ...) plus source imports.
|
|
66
|
+
2. Match against the registry above. Read the matching adapter's **Recognition** section to confirm the provider and pin the version variant:
|
|
67
|
+
- Firebase: v8 namespaced vs v9 modular (web), plus Android/iOS/Flutter native forms.
|
|
68
|
+
- Amplitude: legacy (`getInstance().logEvent`) vs SDK 2.x (`amplitude.track` / `@amplitude/analytics-browser`).
|
|
69
|
+
3. If multiple providers are present, list them and ask which to migrate first (one provider per run keeps mapping clean). **Exception — GA4 and Firebase Analytics are the same data stream**: GA4 is Firebase's web layer (one measurement ID is both a GA4 property and a Firebase project). If `gtag(...)` and `logEvent(...)` coexist in one project, they are **not two providers** — merge them into a single migration run: one scan, one `draft.json` / `mapping.json`, one dedup pass over the shared event / property / user-id names. Never produce two drafts for one Google data stream.
|
|
70
|
+
4. If no registry match but tracking code exists → show the found calls, ask the user for the provider name, and (per `references/providers/README.md`) collect a minimal adapter from the user-provided docs/snippet before continuing.
|
|
71
|
+
|
|
72
|
+
## Phase 1 — Extract call sites into IR
|
|
73
|
+
|
|
74
|
+
Scan the project for four call categories, using the adapter's **Recognition** patterns:
|
|
75
|
+
|
|
76
|
+
1. **Event** calls: `logEvent(...)` / `track(...)` and their params/properties.
|
|
77
|
+
2. **Identity** calls: `setUserId(...)` / `identify(...)` / `login(...)`.
|
|
78
|
+
3. **User property** calls: `setUserProperty(...)` / `setUserProperties(...)` / `Identify` operations.
|
|
79
|
+
4. **Super property** calls (common event properties): `register(...)` / `registerSuperProperties(...)` (Mixpanel, Sensors Data) / `setDefaultEventParameters(...)` (Firebase). Record them as `kind: super_property` with the full `props` map — do not misread them as user properties (see `mapping-framework.md` §6). Amplitude and GA4 have no such API.
|
|
80
|
+
|
|
81
|
+
Record each site as `file:line`, call kind, event/param values (literals, or variable names to resolve by reading the surrounding code). Write the normalized dump to `.ae-cli/migration/scan.json` following `references/ir.md`.
|
|
82
|
+
|
|
83
|
+
**Wrapper-layer resolution (reverse call-graph tracing)** — real projects almost never call the source SDK directly at every business event; they wrap it in an analytics helper (`trackEvent(name, props)` → `mixpanel.track(name, props)`). A naive grep sees only the wrapper's single SDK call (event name = parameter → would be `resolved:false`) and misses every real business event. So when an SDK call's event name is a **function parameter** (a runtime variable flowing from an enclosing function's argument), do **not** immediately record `resolved:false`:
|
|
84
|
+
|
|
85
|
+
- Identify the enclosing function `F` — it is an **analytics wrapper** only when `F`'s sole role is forwarding that parameter into the SDK call. If the event name comes from local logic/expressions rather than a parameter, it is NOT a wrapper — record the site as `resolved:false` as usual.
|
|
86
|
+
- Grep for every caller of `F`. Resolve each caller with a static event name into a normal call site: `kind` is inferred from the SDK call `F` delegates to (event / identity / user_property), `event_name` from the caller's literal or constant argument, `source_call` = the caller's invocation line, `file` = the caller's file, and `via_wrapper` = `F`'s name.
|
|
87
|
+
- Callers with a dynamic event name stay `resolved:false`. If no callers are found (an exported wrapper used externally, or dynamic dispatch), fall back to recording the wrapper's own SDK call as a single `resolved:false` site.
|
|
88
|
+
- Record `F` itself in scan.json's top-level `wrappers` array (see `references/ir.md`) — it is the pivot for tracing, not a migration target.
|
|
89
|
+
|
|
90
|
+
**Auto-track note**: source SDK auto-collected events (e.g. Firebase `session_start`, `first_open`, `screen_view`) are not call sites. Handle them per the adapter's **Auto-track decision** table in Phase 2, not here.
|
|
91
|
+
|
|
92
|
+
## Phase 2 — Map to AE (write draft.json + mapping.json)
|
|
93
|
+
|
|
94
|
+
1. Read `references/mapping-framework.md` (generic algorithm) + the provider adapter (differences).
|
|
95
|
+
2. For each extracted event call: map to an AE event (snake_case name, or **verbatim** when forward compatibility is required — `mapping-framework.md` §1; `display_name` in the user's language), map each param to an AE property with a type, and apply naming constraints from the adapter (reserved prefixes, special characters, length caps).
|
|
96
|
+
3. Apply dedup + promotion rules: same property on 3+ events → common event property (super property); preset `#` properties never become super properties. Explicit super-property call sites (`register` / `setDefaultEventParameters`) also land in `draft.json`'s `common_event_properties` pool — see `mapping-framework.md` §6.
|
|
97
|
+
4. Map identity → AE `login(accountId)` (account_id_source `user_account`); plus visitor-id continuity (`setDistinctId` / `identify`, init-time) when forward compatibility with imported historical data is in scope — see `mapping-framework.md` §4. User property ops → AE `user_set` / `user_setOnce` / `user_add` / `user_append` / `user_unset` per the adapter's mapping table. Super property calls → AE `setSuperProperties({...})` (static common event property), per `mapping-framework.md` §6.
|
|
98
|
+
5. Decide each event's `platform` (client / server) from where the call site lives (app code → client; backend → server).
|
|
99
|
+
6. Ask the user to confirm the **migration mode** (see Modes below) and whether **historical source-platform data** has been (or will be) imported into AE **offline** — drives forward-compatible naming per `mapping-framework.md` §1 and visitor-id continuity per §4. The import itself is offline data-migration work, out of scope; this skill only switches the live SDK — then:
|
|
100
|
+
- Write `.ae-cli/migration/mapping.json` (source site → AE event + mode decision, schema in `references/ir.md`).
|
|
101
|
+
- Write `.ae-cli/draft.json` in the AE plan schema (same schema `ae-generate-tracking-plan` produces) so the plan skill can consume it directly.
|
|
102
|
+
|
|
103
|
+
Show the mapping summary table and get user `ok` before proceeding.
|
|
104
|
+
|
|
105
|
+
## Phase 3 — Generate and upload the tracking plan
|
|
106
|
+
|
|
107
|
+
Hand off to `ae-generate-tracking-plan` using the codebase/draft already produced:
|
|
108
|
+
|
|
109
|
+
1. `ae-cli tracking plan draft --in .ae-cli/draft.json --out .ae-cli/draft.xlsx`
|
|
110
|
+
2. `ae-cli tracking plan validate --in .ae-cli/draft.json --fix`
|
|
111
|
+
3. Resolve AE host/login/projectId per the plan skill, then `ae-cli tracking plan upload ...` (ask the user before uploading; append vs replace per that skill's conflict detection).
|
|
112
|
+
|
|
113
|
+
## Phase 4 — Insert AE SDK code (switch or add)
|
|
114
|
+
|
|
115
|
+
Hand off to `ae-generate-tracking-code` (insert mode), but **insertion sites come from `.ae-cli/migration/mapping.json`, not from grep business-trigger discovery**:
|
|
116
|
+
|
|
117
|
+
- Client/server platform + language are already in `draft.json` meta; resolve APP_ID / SERVER_URL as that skill does.
|
|
118
|
+
- For each mapped AE event, the insertion point is the original call site recorded in mapping.json.
|
|
119
|
+
|
|
120
|
+
**Mode `switch`** (replace) — **high-risk, confirm before deleting**:
|
|
121
|
+
- Before any deletion, explicitly list what will be removed (the source call sites and the source SDK dependency from the adapter's **Dependency identifiers**) and get the user's confirmation to delete.
|
|
122
|
+
- Replace the source `logEvent`/`track` call with the AE `track(...)` call at the same site; remove now-unused source imports.
|
|
123
|
+
- **Inline event names that came from a module constant**: emit the literal snake_case name in the AE `track(...)` call (it must match the `// @tracking <event_name>` marker). **Before deleting the constant definition, grep the whole project for its name** — a module constant is often imported by multiple files, fed to a server-side report, or asserted in tests. Only remove it when the migrated call sites are its sole references (then it is dead code); otherwise keep it. Do not keep a constant that only feeds the migrated call.
|
|
124
|
+
- Remove the source SDK dependency using the adapter's **Dependency identifiers** (e.g. `firebase/analytics`, `@amplitude/analytics-browser`).
|
|
125
|
+
- **Remove dead wrappers**: when every call site resolved through a wrapper is `replace`d, the wrapper function is dead code — delete it (and its now-unused source import). If the wrapper's file holds nothing else, remove the file. (`add` mode keeps the wrapper — it still feeds the source SDK — and adds the AE call at each business call site.)
|
|
126
|
+
- Convert identity/user-property calls to `login(...)` / user-property calls similarly; super-property calls → `setSuperProperties({...})` **in place at the original call site** (never hoisted — the source's `register` position encodes when the values become available, e.g. after login; see `mapping-framework.md` §6).
|
|
127
|
+
|
|
128
|
+
**Mode `add`** (dual-write):
|
|
129
|
+
- Keep the source call untouched; add the AE `track(...)` call immediately adjacent (before or after, matching surrounding style).
|
|
130
|
+
- **Keep the two SDKs independent — in both directions.** Dual-write means two independent writes, for **every provider / every SDK** (Firebase, Amplitude, Sensors Data, Mixpanel, GA4, …), not a source-guarded AE write:
|
|
131
|
+
- The AE `track()` / `login()` / user-property / `setSuperProperties()` call must NOT be nested inside the source SDK's availability guard, early-return, or error path — e.g. after `if (!analytics) return`, behind `isSupported()`, or inside the source's `try/catch`. If the source call sits behind such a guard, lift the AE call out so it runs unconditionally.
|
|
132
|
+
- Give **each SDK its own `try/catch`** around its write: a source-SDK failure (unavailable, `isSupported() === false`, or a thrown error) must never suppress the AE write, and an AE failure must never suppress (or crash) the source write.
|
|
133
|
+
- The guard must cover the source SDK's **full failure surface, not a single exception type**. A pre-existing narrow catch (e.g. Python `except ValueError` for 400 validation, Java `catch (IllegalArgumentException)`) is **not** the independence guard — other failures (unconfigured API key → `RuntimeError`, network/timeout) still escape and crash before the AE write. Broaden the catch to all exceptions, run the AE write, then re-raise the source exception so the original status/error semantics (400/503) are unchanged.
|
|
134
|
+
- Give **each SDK's init its own `try/catch`** too, so that one SDK being unloaded or disabled at load time (init throws / module missing) does not take down the other SDK. Both writes must keep working no matter which SDK is unloaded or disabled.
|
|
135
|
+
- This applies to every `add` / `add_after` / `add_before` entry in mixed runs too.
|
|
136
|
+
- Keep the source SDK dependency; only add the AE SDK dependency.
|
|
137
|
+
|
|
138
|
+
**Async call sites** — a source call that is `await`ed (React Native / Flutter `await analytics().logEvent(...)`, some `await mixpanel.track(...)`) returns a Promise, but the AE client `track()` / `login()` / user-property / `setSuperProperties()` calls are synchronous:
|
|
139
|
+
- **`switch`**: drop the `await` on the replaced call — awaiting a synchronous AE call is a lint warning and changes nothing. If the source call sat inside a `try/catch` whose `catch` handled the source SDK's **Promise rejection** (network retry, offline fallback, error reporting), that rejection branch dies with the source SDK: remove the now-dead `catch` logic; if the `try` block then holds only the AE call, collapse the `try/catch` into the bare AE call (AE sync failures then follow the code skill's Code Style — loud in `switch`). Never wrap the AE call in a made-up `async`/`await` to keep the shapes matching.
|
|
140
|
+
- **`add`**: keep the source call's `await` and its `try/catch` exactly as-is, and place the AE call **outside** that block, un-`await`ed, in its own `try/catch` per the independence rule above.
|
|
141
|
+
|
|
142
|
+
Both modes follow the code skill's insert rules: SDK init from the wiki main doc (never guess imports), git-status pre-check, batched Edit with language-style check, `// @tracking <event_name>` comment prefix.
|
|
143
|
+
|
|
144
|
+
**User-property `append` / `unset`** (`ae_call` = `user_append` / `user_unset`): these two are not in the plan's `update_type` enum (only `user_set` / `user_setOnce` / `user_add` are), so they do not enter `draft.json` — in the draft their `update_type` is written `user_set` (placeholder). At code-insertion time, emit the AE SDK call directly per the mapping's `ae_call` (`user_append` → `userAppend`, `user_unset` → `userUnset`), reading the real method signature from the wiki main doc (never guess).
|
|
145
|
+
|
|
146
|
+
**⚠️ `add` mode overrides the code skill's "Do NOT add try/catch" Code Style.** That rule is a single-SDK rule (greenfield insert / `switch` after cut-over): with one SDK a loud failure is the point, so init/track failures must surface rather than be swallowed. Dual-write is the opposite — the "each SDK its own `try/catch`" rule above applies to the generated AE code too:
|
|
147
|
+
- The AE init must be guarded the same way (its own `try/catch` / availability check), so an AE-SDK load failure never throws at load time and never takes down the source SDK.
|
|
148
|
+
- Never emit a load-time SDK capture that becomes a permanently-`undefined` reference and throws on every call (e.g. `var ta = window.TA;` in a wrapper) — a missing AE SDK must be a per-call no-op, not a crash of business logic or the source write.
|
|
149
|
+
- `switch` mode does NOT get this override: after cut-over AE is the only SDK, so it follows the code skill's Code Style as-is (failures stay loud).
|
|
150
|
+
|
|
151
|
+
## Phase 5 — Verify
|
|
152
|
+
|
|
153
|
+
Reuse the code skill's validation flow:
|
|
154
|
+
|
|
155
|
+
1. `ae-cli auth status` / confirm active host; debug device add/select.
|
|
156
|
+
2. Trigger the migrated events and query `ae-cli tracking debug-data list`.
|
|
157
|
+
3. In `add` mode, verify AE data alongside the still-running source SDK; in `switch` mode, confirm the source SDK is fully removed and AE data flows.
|
|
158
|
+
|
|
159
|
+
## Modes
|
|
160
|
+
|
|
161
|
+
| Mode | Source SDK kept? | AE call placement | Dependency change |
|
|
162
|
+
|---|---|---|---|
|
|
163
|
+
| `switch` | removed | replaces source call | remove source dep, add AE dep |
|
|
164
|
+
| `add` | kept | added alongside | add AE dep only |
|
|
165
|
+
|
|
166
|
+
Ask the user once in Phase 2 which mode to use. **Default to `add` (dual-write): present `add` as the recommended option in the confirmation prompt.** Treat `switch` as the non-default, destructive choice — offer it only when the user has explicitly expressed wanting a full cut-over, and never mark it recommended.
|
|
167
|
+
|
|
168
|
+
**Staged / mixed runs**: `mode` is the run-level default, but each mapping entry carries its own `action` (`replace` vs `add_after`/`add_before`), and the per-entry `action` is authoritative. A `switch` run may still keep selected entries as `add_after` for a staged roll-out (e.g. cut over identity + sign-up now, keep `purchase` dual-writing while its data is validated). In that case: replaced files drop the source SDK, dual-write files keep it, and the source SDK dependency is removed **only** on a full cut-over (every entry `replace`). See `references/ir.md` §mapping.json and `mapping-framework.md` §8.
|
|
169
|
+
|
|
170
|
+
> **⚠️ `switch` is destructive (high-risk)**: it deletes source tracking calls, their imports, and the source SDK dependency. Never delete old code by default. Before deleting anything, explicitly tell the user what will be removed (call sites + dependencies) and get their confirmation; re-confirm again at Phase 4 immediately before deletion, even if `switch` was already chosen in Phase 2.
|
|
171
|
+
|
|
172
|
+
## Prohibitions
|
|
173
|
+
|
|
174
|
+
- Guessing AE SDK imports/package names — always read the wiki main doc via `ae-generate-tracking-code` (`references/sdk-index.md`).
|
|
175
|
+
- Modifying event/property names away from the AE plan (`snake_case`, registered names).
|
|
176
|
+
- Migrating source SDK auto-track events as manual `track()` calls — map them to AE auto-track switches or drop them per the adapter.
|
|
177
|
+
- Nesting the AE `track()` / `login()` / user-property calls inside the source SDK's availability guard, early-return, or `try/catch` in `add` mode, or leaving either SDK's init unguarded, or guarding the source write with a narrow exception-type catch that still lets a source failure crash before the AE write — for every provider, dual-write must stay two independent writes (each SDK its own `try/catch`, init included, covering the full failure surface), so one SDK failing or being unloaded never takes down the other.
|
|
178
|
+
- Skipping the mapping summary confirmation in Phase 2.
|
|
179
|
+
- Writing `user_append` / `user_unset` into `draft.json`'s `update_type` (the plan enum is `user_set` / `user_setOnce` / `user_add` only) — append/unset stay in `mapping.json` `ae_call` and are emitted directly at Phase 4.
|
|
180
|
+
- Translating "Super Property" as "超级属性" in any user-facing output.
|
|
181
|
+
- Writing source or AE code before the git-status pre-check (insert mode).
|
|
182
|
+
- Editing the provider adapters to add provider-specific logic into the core — new providers are new adapter files only.
|
|
183
|
+
- Deleting source tracking code or removing the source SDK dependency (`switch` mode) without explicitly warning the user and getting their confirmation immediately before deletion.
|
|
184
|
+
|
|
185
|
+
## Internal Reference
|
|
186
|
+
|
|
187
|
+
- `references/ir.md` — normalized IR schema (`scan.json` / `mapping.json`).
|
|
188
|
+
- `references/mapping-framework.md` — provider-agnostic mapping algorithm.
|
|
189
|
+
- `references/ae-preset-properties.md` — authoritative AE `#` preset-property list + system fields (only these `#` names ingest).
|
|
190
|
+
- `references/providers/README.md` — adapter contract + how to add a provider.
|
|
191
|
+
- `references/providers/firebase.md` — Firebase adapter.
|
|
192
|
+
- `references/providers/amplitude.md` — Amplitude adapter.
|
|
193
|
+
- `references/providers/sensors-data.md` — Sensors Data (神策) adapter.
|
|
194
|
+
- `references/providers/mixpanel.md` — Mixpanel adapter.
|
|
195
|
+
- `references/providers/ga4.md` — Google Analytics 4 (gtag.js / Measurement Protocol) adapter.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# AE Preset Properties & System Fields (authoritative)
|
|
2
|
+
|
|
3
|
+
> **Terminology**: 预置属性 = preset property | 系统字段 = system field | 自动采集 = auto-track
|
|
4
|
+
|
|
5
|
+
Source of truth: bundled AE wiki `wiki/te-docs/raw/preparations-before-data-ingestion/preset-properties-and-system-fields.md`
|
|
6
|
+
(official doc: `https://docs-v2.thinkingdata.cn/?version=v6.0&lan=en-US&code=preset_properties`).
|
|
7
|
+
|
|
8
|
+
> **Scope**: this skill switches the live SDK only; historical data import into AE is offline data-migration work, out of scope. This list is used here for two things: deciding drop-vs-keep on source preset/special properties, and preventing invalid or manual `#` writes.
|
|
9
|
+
|
|
10
|
+
## Hard rules
|
|
11
|
+
|
|
12
|
+
1. **Only the `#` names listed below ingest.** Any property whose name starts with `#` but is NOT in the preset-property table is an illegal field and is rejected at ingestion — it cannot be stored. Never invent a `#` name.
|
|
13
|
+
2. **Look up each source preset/special property here to decide drop-vs-keep.** If an AE preset equivalent exists (Sensors `$os` → `#os`, `$ip` → `#ip`, `$url` → `#url`), **drop the source property and rely on AE auto-collect** — never re-add it as a custom property. If there is **no** equivalent in the list (`$is_first_day`, `mp_country_code`, `$current_url`), do NOT fabricate a `#` name — map it to a normal custom property (snake_case per `mapping-framework.md` §1) or drop it, and **surface the choice to the user for confirmation**.
|
|
14
|
+
3. **Preset properties are SDK-provided.** Except `#ip`, do not set them manually — the AE SDK fills them automatically; manual setting is only done under AE staff guidance (multi-terminal consistency).
|
|
15
|
+
4. **System fields are not event/user properties.** `#distinct_id`, `#account_id`, `#user_id`, `#event_name`, `#time` (and the partition fields) are data-structure fields; they cannot be used as event names or property names. Identity migration goes through `login()` / the visitor-id API (`mapping-framework.md` §4), never through a property.
|
|
16
|
+
|
|
17
|
+
## Preset properties (48)
|
|
18
|
+
|
|
19
|
+
| # name | Description | Type |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `#ip` | Client-side IP (basis for geo parsing) | String |
|
|
22
|
+
| `#country` | Country/region | String |
|
|
23
|
+
| `#country_code` | Country code (ISO 3166-1 alpha-2) | String |
|
|
24
|
+
| `#province` | Province | String |
|
|
25
|
+
| `#city` | City | String |
|
|
26
|
+
| `#os` | OS (Android, iOS, ...) | String |
|
|
27
|
+
| `#os_version` | OS version | String |
|
|
28
|
+
| `#manufacturer` | Device manufacturer | String |
|
|
29
|
+
| `#device_id` | Device ID (iOS IDFV/UUID; Android androidID) | String |
|
|
30
|
+
| `#device_model` | Device model | String |
|
|
31
|
+
| `#device_type` | Device type | String |
|
|
32
|
+
| `#screen_height` | Screen height | Number |
|
|
33
|
+
| `#screen_width` | Screen width | Number |
|
|
34
|
+
| `#app_version` | APP version | String |
|
|
35
|
+
| `#bundle_id` | APP package/process name | String |
|
|
36
|
+
| `#lib` | SDK type | String |
|
|
37
|
+
| `#lib_version` | SDK version | String |
|
|
38
|
+
| `#network_type` | Network type | String |
|
|
39
|
+
| `#carrier` | Operator | String |
|
|
40
|
+
| `#browser` | Browser | String |
|
|
41
|
+
| `#browser_version` | Browser version | String |
|
|
42
|
+
| `#duration` | Event duration (s) | Number |
|
|
43
|
+
| `#url` | Page URL (auto-track) | String |
|
|
44
|
+
| `#url_path` | Page path (`location.pathname`) | String |
|
|
45
|
+
| `#referrer` | Referrer URL | String |
|
|
46
|
+
| `#referrer_host` | Referrer host | String |
|
|
47
|
+
| `#title` | Page title | String |
|
|
48
|
+
| `#screen_name` | Screen name | String |
|
|
49
|
+
| `#element_id` | Element ID (auto-track) | String |
|
|
50
|
+
| `#element_type` | Element type | String |
|
|
51
|
+
| `#element_selector` | Element selector / viewPath | String |
|
|
52
|
+
| `#element_position` | Element position | String |
|
|
53
|
+
| `#element_content` | Element content | String |
|
|
54
|
+
| `#resume_from_background` | Resumed from background (bool) | Number |
|
|
55
|
+
| `#scene` | Scenario value (mini-program launch) | Number |
|
|
56
|
+
| `#mp_platform` | Mini-program platform | String |
|
|
57
|
+
| `#app_crashed_reason` | Crash stack info | String |
|
|
58
|
+
| `#zone_offset` | Timezone offset (hours vs UTC) | Number |
|
|
59
|
+
| `#system_language` | System language (ISO 639-1) | String |
|
|
60
|
+
| `#install_time` | APP install time | Date |
|
|
61
|
+
| `#simulator` | Is simulator (bool) | Number |
|
|
62
|
+
| `#ram` | Memory, e.g. `1.4/2.4` (GB) | String |
|
|
63
|
+
| `#disk` | Storage, e.g. `30/200` (GB) | String |
|
|
64
|
+
| `#fps` | Frames per second | Number |
|
|
65
|
+
| `#background_duration` | Background duration (s) | Number |
|
|
66
|
+
| `#start_reason` | Start reason (non-launcher mode) | String |
|
|
67
|
+
| `#ua` | User-Agent info | String |
|
|
68
|
+
| `#utm` | Ad-source info | String |
|
|
69
|
+
|
|
70
|
+
## System fields
|
|
71
|
+
|
|
72
|
+
Not usable as event/property names; listed for reference when reasoning about identity and partition fields.
|
|
73
|
+
|
|
74
|
+
**Event table**: `$part_event` (partition, from `#event_name`), `$part_date` (partition, from `#event_time`), `#user_id`, `#account_id`, `#distinct_id`, `#event_name`, `#event_time` (= `#time` in the data), `#server_time`.
|
|
75
|
+
|
|
76
|
+
**User table**: `#user_id`, `#account_id`, `#distinct_id`, `#active_time`, `#reg_time`, `#update_time`, `#server_time`.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# IR Schema (scan.json / mapping.json)
|
|
2
|
+
|
|
3
|
+
> **Terminology**: 归一化中间表示 = IR (intermediate representation) | 调用点 = call site | 扫描结果 = scan result | 映射结果 = mapping result
|
|
4
|
+
|
|
5
|
+
Migration artifacts live under `.ae-cli/migration/`. They are JSON, written by the skill at runtime and consumed by the two downstream skills.
|
|
6
|
+
|
|
7
|
+
## scan.json — extracted call sites (Phase 1 output)
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"provider": "firebase",
|
|
12
|
+
"variant": "web-v9",
|
|
13
|
+
"platforms": ["web"],
|
|
14
|
+
"call_sites": [
|
|
15
|
+
{
|
|
16
|
+
"id": "cs-1",
|
|
17
|
+
"file": "src/app.js",
|
|
18
|
+
"line": 42,
|
|
19
|
+
"kind": "event",
|
|
20
|
+
"source_call": "logEvent(analytics, 'user_login', { method: 'phone' })",
|
|
21
|
+
"event_name": "user_login",
|
|
22
|
+
"params": { "method": "phone" },
|
|
23
|
+
"resolved": true
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "cs-2",
|
|
27
|
+
"file": "src/app.js",
|
|
28
|
+
"line": 18,
|
|
29
|
+
"kind": "identity",
|
|
30
|
+
"source_call": "setUserId(analytics, userId)",
|
|
31
|
+
"resolved": true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "cs-3",
|
|
35
|
+
"file": "src/app.js",
|
|
36
|
+
"line": 25,
|
|
37
|
+
"kind": "user_property",
|
|
38
|
+
"source_call": "setUserProperties(analytics, { vip_level: 'gold' })",
|
|
39
|
+
"op": "set",
|
|
40
|
+
"prop": "vip_level",
|
|
41
|
+
"value": "gold"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "cs-4",
|
|
45
|
+
"file": "src/app.js",
|
|
46
|
+
"line": 30,
|
|
47
|
+
"kind": "super_property",
|
|
48
|
+
"source_call": "setDefaultEventParameters(analytics, { app_version: '1.2.3', channel: 'web' })",
|
|
49
|
+
"props": { "app_version": "1.2.3", "channel": "web" }
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- `kind` ∈ `event` | `identity` | `user_property` | `super_property`.
|
|
56
|
+
- `via_wrapper` (optional, string): set on a call site resolved through an analytics wrapper function (see **Wrapper-layer resolution** below) — records the wrapper function's name. `kind` stays one of the three values above; a wrapper-resolved site is a normal call site with different provenance.
|
|
57
|
+
- `identity` is a **client global setter** call site (`setUserId` / `identify` / `login`). Server SDKs pass identity **per event** (Amplitude Node `{ user_id }`, GA4 Measurement Protocol `user_id`, Mixpanel server `distinct_id`): record it as a `user_id` (and/or `device_id`) field on the **`event`** call site — `kind` stays `event`, there is no separate `identity` entry (Phase 2 maps it to the AE per-event `#account_id`, see `mapping-framework.md` §4).
|
|
58
|
+
- `variant` is a **fixed SDK-variant token** (not the fixture/project directory name). Map the platform the adapter's Recognition section identified to one of:
|
|
59
|
+
|
|
60
|
+
| Provider | Variant tokens |
|
|
61
|
+
|---|---|
|
|
62
|
+
| firebase | `web-v8`, `web-v9`, `android`, `ios`, `flutter`, `react-native`, `unity`, `cpp` |
|
|
63
|
+
| amplitude | `legacy-js`, `browser-2.x`, `node`, `python`, `go`, `java`, `android`, `ios`, `react-native`, `flutter`, `unity` |
|
|
64
|
+
| sensors-data | `web`, `java`, `android` |
|
|
65
|
+
| mixpanel | `javascript` (browser JS), `node`, `python`, `go`, `java`, `ruby`, `php`, `android`, `ios` (incl. Swift), `react-native`, `flutter`, `unity` |
|
|
66
|
+
| ga4 | `gtag-web`, `datalayer`, `mp-server` |
|
|
67
|
+
|
|
68
|
+
New providers/platforms add their token to this table alongside their adapter. **Tokens name every documented platform, not only the tested ones** — only a subset has a regression fixture (see `test/ae-migrate-tracking-code/README.md` §Coverage). A token without a fixture is still valid: Phase 1 records it, and the mapping/naming rules apply unchanged.
|
|
69
|
+
|
|
70
|
+
- `resolved` applies to `event` and `identity` entries:
|
|
71
|
+
- `event`: `true` whenever the event **name** is a known static value — a string literal, a constant resolved from the scanned source, or an external-SDK constant identifier (see the `event_name` rules below). `false` **only** when the event name itself is a runtime variable/expression that cannot be resolved to a static name (listed for user confirmation in Phase 2). Runtime **param values** (e.g. `{ amount: order.total }`) do **not** set `resolved: false` — they are recorded in `params` as the variable name and surfaced for *type* confirmation in Phase 2, not name confirmation. A name arriving as a **wrapper function's parameter** is resolved via wrapper-layer tracing (below) — business callers with a static name become `resolved: true` sites carrying `via_wrapper`; `false` is reserved for names that stay unresolved *after* tracing (dynamic names, or a wrapper with no findable callers).
|
|
72
|
+
- `identity`: always `true` — the id is a runtime value, and the mapping target (`login(accountId)`) does not require resolving the id's concrete value.
|
|
73
|
+
- `event_name` records the name **as written in the scanned source**, and only resolves it when the value is visible in that source:
|
|
74
|
+
- a string literal is recorded verbatim (`"user_login"` → `user_login`; `"userLogin"` → `userLogin` — Phase 2 §1 naming conversion does the snake_case/normalization).
|
|
75
|
+
- a constant defined **in the scanned source** (e.g. `EVENT_SIGNUP = 'sign_up'`) is resolved to its value, still with `resolved: true` (the name is static).
|
|
76
|
+
- a constant from an **external SDK** whose value is not visible in the source (e.g. `FirebaseAnalytics.Event.SELECT_CONTENT`) is recorded as the identifier as written (`SELECT_CONTENT`), still with `resolved: true` — it is a static name, not a runtime variable. Do **not** resolve it against SDK documentation; the downstream §1 naming conversion (UPPER_SNAKE → snake_case) yields the correct AE name.
|
|
77
|
+
- **Expression shapes that are not a single static name** record `resolved: false` and are surfaced in Phase 2 for the user to expand:
|
|
78
|
+
- **Ternary / conditional** (`track(cond ? 'sign_up' : 'login', ...)`): the branches are static literals but the runtime value is one of several — it is **several distinct events, not one**. Record `event_name` as the expression text as written; in Phase 2 enumerate each static branch and ask the user which (possibly all) become separate AE events.
|
|
79
|
+
- **Template literal** (`` track(`click_${name}`) ``): the name is unbounded. Record the template as written; in Phase 2 ask the user whether it collapses to a finite set of names or becomes a base event + a `name` property.
|
|
80
|
+
- `user_property` entries carry no `resolved` field. They record `op` (`set` | `setOnce` | `add` | `append` | `unset`, mapping to AE `user_set` / `user_setOnce` / `user_add` / `user_append` / `user_unset`) plus `prop` (the user property name) and `value` (the literal value, or the variable name when not resolvable).
|
|
81
|
+
- `super_property` entries carry no `resolved` field. They record `props` (the full name → value map, like an `event`'s `params`; values may be variable names) — a third-party common-property call sets several properties at once (`register({...})` / `registerSuperProperties({...})` / `setDefaultEventParameters({...})`), so there is no single `prop`/`value` pair. Prop **names** are always static object-literal keys; only the **values** may be runtime variables. `super_property` sites map to AE common event properties (Phase 2 writes them into `draft.json`'s `common_event_properties` pool, Phase 4 emits `setSuperProperties({...})` in place).
|
|
82
|
+
|
|
83
|
+
**Wrapper-layer resolution** — when an SDK call's event name is a **function parameter** (a runtime variable flowing from an enclosing function's argument), Phase 1 treats that function as an analytics wrapper and traces its callers instead of recording `resolved:false` up front. A discovered wrapper `F` (e.g. `trackEvent(name, props)` → `mixpanel.track(name, props)`) is recorded in the top-level optional `wrappers` array, **not** in `call_sites`:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"wrappers": [
|
|
88
|
+
{ "name": "trackEvent", "file": "src/analytics.js", "line": 4, "source_call": "mixpanel.track(name, props)", "delegates_to": "event" }
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- `delegates_to` ∈ `event` | `identity` | `user_property` | `super_property` — the SDK call kind `F` forwards to; it is the `kind` inherited by `F`'s resolved business call sites.
|
|
94
|
+
- The wrapper is the pivot for tracing, not a migration target: its own SDK call is not a `call_sites` entry. Each business caller becomes a normal call site carrying `via_wrapper`. `source_call` on those sites is the **caller's** invocation line (e.g. `trackEvent('sign_up', { method: user.method })`), which appears literally in the caller's file.
|
|
95
|
+
|
|
96
|
+
## mapping.json — source site → AE event (Phase 2 output)
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"provider": "firebase",
|
|
101
|
+
"variant": "web-v9",
|
|
102
|
+
"mode": "switch",
|
|
103
|
+
"entries": [
|
|
104
|
+
{
|
|
105
|
+
"site_id": "cs-1",
|
|
106
|
+
"file": "src/app.js",
|
|
107
|
+
"line": 42,
|
|
108
|
+
"source_call": "logEvent(analytics, 'user_login', { method: 'phone' })",
|
|
109
|
+
"ae_event": "user_login",
|
|
110
|
+
"display_name": "User Login",
|
|
111
|
+
"platform": "client",
|
|
112
|
+
"ae_props": { "method": "string" },
|
|
113
|
+
"action": "replace"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"site_id": "cs-2",
|
|
117
|
+
"file": "src/app.js",
|
|
118
|
+
"line": 18,
|
|
119
|
+
"source_call": "setUserId(analytics, userId)",
|
|
120
|
+
"ae_call": "login(accountId)",
|
|
121
|
+
"account_id_source": "user_account",
|
|
122
|
+
"action": "replace"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"site_id": "cs-3",
|
|
126
|
+
"file": "src/app.js",
|
|
127
|
+
"line": 8,
|
|
128
|
+
"source_call": "getAppInstanceId()",
|
|
129
|
+
"ae_call": "setDistinctId(appInstanceId)",
|
|
130
|
+
"account_id_source": "none",
|
|
131
|
+
"note": "forward compatibility: visitor id set once at init, before any event",
|
|
132
|
+
"action": "replace"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"site_id": "cs-4",
|
|
136
|
+
"file": "src/app.js",
|
|
137
|
+
"line": 25,
|
|
138
|
+
"source_call": "setUserProperties(analytics, { vip_level: 'gold' })",
|
|
139
|
+
"ae_call": "user_set",
|
|
140
|
+
"ae_props": { "vip_level": "string" },
|
|
141
|
+
"action": "replace"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"site_id": "cs-5",
|
|
145
|
+
"file": "src/app.js",
|
|
146
|
+
"line": 30,
|
|
147
|
+
"source_call": "setDefaultEventParameters(analytics, { app_version: '1.2.3', channel: 'web' })",
|
|
148
|
+
"ae_call": "set_super_properties",
|
|
149
|
+
"ae_props": { "app_version": "string", "channel": "string" },
|
|
150
|
+
"action": "replace"
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- `mode` ∈ `switch` | `add` — the run-level default, decided once per run in Phase 2.
|
|
157
|
+
- `action` ∈ `replace` | `add_after` | `add_before` — set **per entry** and authoritative. `mode` is only the default an entry inherits; a `switch` run may still carry `add_after` entries (staged roll-out), and an `add` run may carry `replace` entries. The source SDK dependency is removed only on a full cut-over: `mode` = `switch` **and** every entry `action` = `replace`. A mixed run keeps the dependency — surviving `add_*` sites still call it.
|
|
158
|
+
- Identity entries use `ae_call` (no `ae_event`): `login(accountId)` → `#account_id`; `setDistinctId(visitorId)` / `identify(visitorId)` → `#distinct_id` (forward compatibility, init-time, before any event); `logout()` from source `reset()` / `remove()`. `account_id_source` ∈ `user_account` | `none`.
|
|
159
|
+
- Server event entries (identity rides per event) carry `account_id_source` (`user_account` → AE per-event `#account_id`, e.g. from the scan-side `user_id` field) **instead of** an `ae_call` — `login(accountId)` is client-only.
|
|
160
|
+
- User property entries use `ae_call` (no `ae_event`): `ae_call` = the AE user API (`user_set` / `user_setOnce` / `user_add` / `user_append` / `user_unset`, per the adapter's operation table), and `ae_props` = the property-name → type map, exactly like an event entry (the scan-side `op` / `prop` / `value` are not carried over — `op` becomes `ae_call`, `prop` becomes the `ae_props` key, `value` is dropped from mapping and re-emitted as the literal in the migrated code).
|
|
161
|
+
- Super property entries use `ae_call` (no `ae_event`): `ae_call` = `set_super_properties` (emitted as `setSuperProperties({...})` at Phase 4), and `ae_props` = the property-name → type map. The scan-side `props` map is dropped from mapping and re-emitted as the literal object in the migrated `setSuperProperties` call. These properties land in `draft.json`'s `common_event_properties` pool.
|
|
162
|
+
|
|
163
|
+
## draft.json — AE plan (Phase 2 output, consumed by ae-generate-tracking-plan)
|
|
164
|
+
|
|
165
|
+
Identical schema to `ae-generate-tracking-plan`'s draft: `meta` (sdk_integration_mode, client/server platform+language, user_identity, host/project_id as filled later) + `events[]` (each with `event_name`, `display_name`, `platform`, `prop_names`, `event_tag`, `source: "codebase"`) + `event_properties[]` / `common_event_properties[]` / `user_properties[]` pools. `source` must be one of the AE plan's `Source` enum values — events/properties extracted from existing tracking code use `"codebase"` (there is no `"migration"` source value).
|
|
166
|
+
|
|
167
|
+
**`user_append` / `user_unset` are NOT in the plan's `update_type` enum** (that enum is `user_set` / `user_setOnce` / `user_add` only). A user property mapped to `user_append` / `user_unset` keeps that value in `mapping.json` `ae_call` (Phase 4 emits the SDK call directly) but its `draft.json` `update_type` is written as `user_set` (placeholder) — the plan records that the property exists, not the append/unset semantics.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Mapping Framework (provider-agnostic)
|
|
2
|
+
|
|
3
|
+
> **Terminology**: 映射 = mapping | 事件名 = event name | 属性 = property | 类型推断 = type inference | 去重 = dedup | 公共属性提升 = super-property promotion | 用户身份 = user identity | 蛇形命名 = snake_case
|
|
4
|
+
|
|
5
|
+
This file is the generic algorithm. Provider differences live in `references/providers/<provider>.md`. The algorithm consumes `scan.json` (from Phase 1) and produces `mapping.json` + `.ae-cli/draft.json` (Phase 2).
|
|
6
|
+
|
|
7
|
+
## 1. Event name → snake_case
|
|
8
|
+
|
|
9
|
+
> **Naming policy — decide once per run**: ask whether historical source-platform data has been (or will be) imported into AE **offline** and must join with new SDK data. The offline import is outside this skill (data-migration implementation); this skill only switches the live SDK — it preserves names so new events join the imported data.
|
|
10
|
+
>
|
|
11
|
+
> - **Forward compatibility required** → preserve event / property / user-property names **verbatim** (AE matches names case-sensitively, so renaming splits the event stream). Transform a name only if it violates AE hard constraints (starts with a digit, contains characters outside `[A-Za-z0-9_]`, exceeds the length cap); any such transform must match the naming the offline import used (one shared mapping table — this skill produces it and applies it to the SDK code only).
|
|
12
|
+
> - **Greenfield (no historical data)** → apply steps 1–7 below.
|
|
13
|
+
|
|
14
|
+
**Special characters & reserved prefixes** (apply after the naming policy above):
|
|
15
|
+
|
|
16
|
+
- **`$` prefix** (Sensors Data preset events/properties; Mixpanel special properties): SDK-provided, not custom. Preset properties → AE `#` preset properties; preset events → AE auto-track or drop (adapter's Auto-track decision table). Never rename `$name` into a custom `_name`. **Only map to `#` names in the authoritative list** (`references/ae-preset-properties.md`); a `$` property with no AE preset equivalent becomes a normal custom property (snake_case) or is dropped — never a made-up `#` name — and is surfaced to the user for confirmation.
|
|
17
|
+
- **Other reserved prefixes** — Mixpanel `mp_`; Amplitude `[Amplitude]` (case-insensitive); Firebase/GA4 `_`, `firebase_`, `ga_`, `google_`, `gtag.`: cannot be custom names. Strip the prefix and flag for user confirmation (adapter §2).
|
|
18
|
+
- **Any other special character** in a custom event / property / user-property name (space, `-`, `.`, brackets, etc.) violates the AE charset. Normalize it (replace with `_`, collapse repeats, strip) and **always surface the rename to the user for confirmation** — a wrong normalization silently changes the metric name.
|
|
19
|
+
|
|
20
|
+
1. Apply the provider adapter's reserved-prefix/word rules (e.g. Firebase `firebase_`, `google_`, `ga_`; GA4 `_`, `gtag.`; Mixpanel `mp_`; Amplitude `[Amplitude]` — case-insensitive): strip the prefix and flag the rename for user confirmation. Do this **first**, before any other transform, so a prefix containing special characters (`gtag.`, `[Amplitude]`) is removed intact rather than mangled by step 5.
|
|
21
|
+
2. Convert camelCase / PascalCase boundaries to underscores: `userLogin` → `user_login`, `SELECT_CONTENT` → `select_content`, `addPaymentInfo` → `add_payment_info`.
|
|
22
|
+
3. Lowercase.
|
|
23
|
+
4. Replace spaces and hyphens with underscores.
|
|
24
|
+
5. Strip characters outside `[a-z0-9_]`; collapse repeated underscores.
|
|
25
|
+
6. Ensure the result starts with a letter; if it starts with a digit, prefix `e_`.
|
|
26
|
+
7. AE plan rules still apply: `snake_case`, non-empty `display_name` in the user's language, `event_tag` set per the plan skill conventions.
|
|
27
|
+
|
|
28
|
+
## 2. Property type inference
|
|
29
|
+
|
|
30
|
+
From the literal value at the call site (or the variable's usage when resolvable):
|
|
31
|
+
|
|
32
|
+
| Observed value | AE type |
|
|
33
|
+
|---|---|
|
|
34
|
+
| integer / float | `number` |
|
|
35
|
+
| `true` / `false` | `bool` |
|
|
36
|
+
| string | `string` |
|
|
37
|
+
| Date object (`new Date()`, a `Date` variable used directly) | `datetime` — inferred silently, unambiguous |
|
|
38
|
+
| ISO-8601 string (e.g. `"2024-09-01T12:00:00Z"`, `"2024-09-01"`) | `datetime` — **flag for confirmation** (string shapes are ambiguous: `order_no: "20240901123"`, `version: "2024.1"` look identical) |
|
|
39
|
+
| numeric field whose name suggests time (`*_time`, `*_at`, `*_ts`, `timestamp`, `*_date`) | `datetime` — **flag for confirmation** (name heuristic only; the field may be a duration or count) |
|
|
40
|
+
| array of primitives (strings) | `array_string` |
|
|
41
|
+
| plain object `{...}` | `object` |
|
|
42
|
+
| array of objects `[{...}]` | `array_row` |
|
|
43
|
+
| mixed | default `string`, flag as severe (see §3, rule 1) |
|
|
44
|
+
| unresolved variable | infer from the property **name**: numeric-sounding names (`amount`, `price`, `total`, `cost`, `count`, `quantity`, `duration`, or any `*_count` / `*_num` / `*_sum`) → `number`; otherwise `string`. Flag for confirmation in Phase 2. |
|
|
45
|
+
|
|
46
|
+
`datetime` is the only AE type inferred from a **shape/name heuristic** whose wrong guess silently drops or mangles data at ingestion. Every `datetime` inference except a literal `Date` object must therefore be **flagged for user confirmation in Phase 2**, exactly like `mixed` and `unresolved variable` above. Never silently assign `datetime` to a string or numeric field.
|
|
47
|
+
|
|
48
|
+
Object spread in a property argument (`track('e', { ...baseProps, amount: 9.99 })`): infer the **visible** keys normally; the spread's keys are not visible at the call site. Record the visible keys, and flag the spread for Phase 2 confirmation — resolve `baseProps` to its definition where visible, otherwise ask the user what keys it contributes (and their types).
|
|
49
|
+
|
|
50
|
+
Nested objects: `array_row` children use `parent.child` sub-property naming per the AE plan schema.
|
|
51
|
+
|
|
52
|
+
## 3. Dedup and promotion
|
|
53
|
+
|
|
54
|
+
1. Same property name across events must share one type; conflicting types → flag as severe (AE discards mismatched data), ask the user.
|
|
55
|
+
2. A property appearing on **3 or more events** → promote to a common event property (super property). Rationale matches `ae-generate-tracking-plan`: business-wide global dimensions belong on every event.
|
|
56
|
+
3. AE preset properties (`#` prefix, e.g. `#device_id`, `#os`) are never created or promoted; they are SDK-provided. Only names in the authoritative list (`references/ae-preset-properties.md`) are valid `#` properties — any other `#` name is rejected at ingestion, so never invent one. System fields (`#distinct_id`, `#account_id`, `#user_id`, `#event_name`, `#time`) are not properties at all.
|
|
57
|
+
|
|
58
|
+
## 4. Identity mapping
|
|
59
|
+
|
|
60
|
+
AE uses a three-ID model: `#distinct_id` (visitor ID, anonymous state), `#account_id` (account ID, logged-in state), and `#user_id` (backend-generated; derived from `#account_id` first, else `#distinct_id`). Map the source's two identity layers separately:
|
|
61
|
+
|
|
62
|
+
| Source identity | AE target | How |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| Logged-in user id (`setUserId` / `identify` / `login`) | `#account_id` | client: `login(accountId)`; server: per-event `#account_id` param |
|
|
65
|
+
| Anonymous/device id (auto `distinct_id` / `app_instance_id` / `client_id` / `device_id`) | `#distinct_id` | AE visitor-id API (`setDistinctId` / `identify`, name varies by SDK — read the wiki main doc), **only** when forward compatibility must match the imported `#distinct_id`; otherwise leave SDK-managed |
|
|
66
|
+
| No identity call | `account_id_source = "none"` (guest) | leave visitor id SDK-managed |
|
|
67
|
+
|
|
68
|
+
Rules:
|
|
69
|
+
|
|
70
|
+
- Client SDKs expose a global setter → `login(accountId)` (account_id_source `user_account`). Server SDKs pass identity per event → per-event `#account_id` + account_id_source, **not** `login()`.
|
|
71
|
+
- **Visitor-id timing**: `setDistinctId` / `identify` must run immediately after SDK init and **before any event is uploaded**; re-setting it after upload causes user-matching failures / duplicate users. It is a one-time startup call, unlike `login()`.
|
|
72
|
+
- `reset()` / `remove()` (source) → AE `logout()` (clears account id, returns to visitor). `logout()` only on explicit sign-out / account deletion, never on app close.
|
|
73
|
+
- `alias` (source anonymous→identified merge) → ignore; AE `login()` already merges visitor → account.
|
|
74
|
+
- Group/role identifiers → `needs decision` (AE has no direct group concept).
|
|
75
|
+
- **Forward compatibility**: the offline-imported `#distinct_id` and the SDK-set visitor id must be byte-identical for old and new data to join into one `#user_id`.
|
|
76
|
+
|
|
77
|
+
## 5. User property mapping
|
|
78
|
+
|
|
79
|
+
Use the provider adapter's operation table. Defaults:
|
|
80
|
+
|
|
81
|
+
- overwrite intent → `user_set`
|
|
82
|
+
- first-time-only intent → `user_setOnce`
|
|
83
|
+
- numeric accumulate intent → `user_add`
|
|
84
|
+
- array append → `user_append`
|
|
85
|
+
- remove → `user_unset`
|
|
86
|
+
- Property-name policy follows §1 (preserve verbatim when forward compatibility is required).
|
|
87
|
+
|
|
88
|
+
`user_append` / `user_unset` are **code-level only**: the AE plan's `user_properties[].update_type` enum has only `user_set` / `user_setOnce` / `user_add`, so these two never enter `draft.json`. They stay in `mapping.json` `ae_call` and Phase 4 emits them directly as the AE SDK's `userAppend` / `userUnset` call (read the real API signature from the wiki main doc — never guess). In `draft.json` the property's `update_type` is written as `user_set` (placeholder).
|
|
89
|
+
|
|
90
|
+
## 6. Super property (common event property) mapping
|
|
91
|
+
|
|
92
|
+
Third-party common-property APIs attach properties to **every event** (they are event properties, never user properties): Mixpanel `register` / `registerSuperProperties`, Sensors Data `register` / `registerSuperProperties`, Firebase `setDefaultEventParameters`. Map them to the AE **static** common event property `setSuperProperties({...})`.
|
|
93
|
+
|
|
94
|
+
- `register({k:v})` / `registerSuperProperties({k:v})` / `setDefaultEventParameters({k:v})` → `set_super_properties` (`setSuperProperties({...})` at Phase 4), and the properties land in `draft.json`'s `common_event_properties` pool (name / `display_name` / type / `source: "codebase"`), exactly like event properties.
|
|
95
|
+
- **Overwrite semantics**: AE `setSuperProperties` overwrites the whole common-property set each call, while third-party `register` **accumulates**. If the source calls `register` multiple times at different points, merge them into a single `setSuperProperties` (or flag for user confirmation) rather than emitting several overwriting calls that would drop earlier keys.
|
|
96
|
+
- **No 1:1 equivalent** → `needs decision`:
|
|
97
|
+
- Mixpanel `register_once({k:v})` — AE has no "first-write-wins" common property; `setSuperProperties` overwrites, so either accept the relaxed semantics or mark `needs decision`.
|
|
98
|
+
- Mixpanel `unregister('k')` — AE has no single-key removal; closest is one `setSuperProperties` with the remaining keys, or exclude the key in a dynamic super property; mark `needs decision`.
|
|
99
|
+
- **AE dynamic common properties** (`setDynamicSuperProperties(fn)`, Android `setDynamicSuperPropertiesTracker`) have **no third-party equivalent** — do not map them from a source call. Offer them only as an optional enhancement when the source computes a common-property value at runtime per event (Phase 4, user decision).
|
|
100
|
+
- Property-name policy follows §1 (preserve verbatim when forward compatibility is required); types follow §2.
|
|
101
|
+
- Amplitude and GA4 have **no** common-property API — their `setUserProperties` / `gtag('set', 'user_properties', ...)` are **user** properties (§5), never super properties.
|
|
102
|
+
|
|
103
|
+
## 7. Platform assignment (client / server)
|
|
104
|
+
|
|
105
|
+
- Call site in app/frontend code (client SDK import) → `platform: "client"`.
|
|
106
|
+
- Call site in backend code (server SDK import) → `platform: "server"`.
|
|
107
|
+
- Same event logged from both → `platform: "both"` (timestamps must sync).
|
|
108
|
+
|
|
109
|
+
## 8. Outputs
|
|
110
|
+
|
|
111
|
+
- `mapping.json`: one entry per source call site — `{ site, source_call, ae_event | ae_call, ae_props, mode, action }`. Event entries carry `ae_event` + `ae_props` (property-name → type map); identity, user-property, and super-property entries carry `ae_call` instead of `ae_event`, and user-property / super-property entries still carry `ae_props` (the full schema is in `ir.md` §mapping.json). `mode` (`switch` | `add`) is the run-level default; the per-entry `action` (`replace` | `add_after` | `add_before`) is authoritative, so a staged/mixed run can diverge per entry — the source SDK dependency is removed only when `mode` = `switch` and every entry is `replace`.
|
|
112
|
+
- `.ae-cli/draft.json`: the AE plan schema (`events` / `event_properties` / `common_event_properties` / `user_properties` + `meta`), identical to what `ae-generate-tracking-plan` produces, so its `tracking plan draft` / `validate` / `upload` commands consume it unchanged.
|