@syntrologie/adapt-content 2.8.0-canary.581 → 2.8.0-canary.583

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/dist/schema.js CHANGED
@@ -10,6 +10,202 @@ function n(n2) {
10
10
  // ../../sdk-contracts/dist/canvas-context.js
11
11
  var canvasRuntimeContext = n("syntrologie:canvas-runtime");
12
12
 
13
+ // ../../sdk-contracts/dist/telemetry-events.js
14
+ var entry = (e2) => e2;
15
+ var TELEMETRY_EVENTS = {
16
+ // --- intervention metrics (April 2026) — wire names unchanged, all plan-scope
17
+ syntro_config_served: entry({
18
+ subject: "config",
19
+ verb: "served",
20
+ scope: "plan",
21
+ props: ["tiles", "actions"]
22
+ }),
23
+ syntro_intervention_seen: entry({
24
+ subject: "intervention",
25
+ verb: "seen",
26
+ scope: "plan",
27
+ props: ["intervention_id", "intervention_kind"]
28
+ }),
29
+ syntro_intervention_triggered: entry({
30
+ subject: "intervention",
31
+ verb: "triggered",
32
+ scope: "plan",
33
+ props: ["intervention_id", "intervention_kind"]
34
+ }),
35
+ syntro_intervention_interacted: entry({
36
+ subject: "intervention",
37
+ verb: "interacted",
38
+ scope: "plan",
39
+ props: ["intervention_id", "intervention_kind", "interaction_type"]
40
+ }),
41
+ // --- concierge (FEAT-1789150184) ---------------------------------------
42
+ syntro_concierge_opened: entry({
43
+ subject: "concierge",
44
+ verb: "opened",
45
+ scope: "open",
46
+ props: ["trigger", "page_path"]
47
+ // trigger: ConciergeOpenTrigger
48
+ }),
49
+ syntro_concierge_closed: entry({
50
+ subject: "concierge",
51
+ verb: "closed",
52
+ scope: "open",
53
+ props: ["duration_ms", "reason", "messages_sent", "tiles_dismissed", "pages_viewed"]
54
+ // reason: ConciergeCloseReason
55
+ }),
56
+ /**
57
+ * The shopper asked to leave the canvas by a link. Emitted on intent, before
58
+ * the host answers, so refused or denied opens are counted too (parity with
59
+ * syntro_concierge_closed reason navigation).
60
+ *
61
+ * On a merchant's own page a link tap closes the canvas, and
62
+ * `syntro_concierge_closed { reason: 'navigation' }` is the row that
63
+ * records it. Inside a chat app's card the frame is sandboxed: the canvas
64
+ * cannot navigate, does not close, and asks the host to open the link
65
+ * instead, so that close row never fires. This is its counterpart, and it
66
+ * carries the same `reason` so one query covers both surfaces.
67
+ */
68
+ syntro_link_opened: entry({
69
+ subject: "link",
70
+ verb: "opened",
71
+ scope: "open",
72
+ props: ["kind", "reason"]
73
+ // kind: LinkOpenKind, reason: ConciergeCloseReason
74
+ }),
75
+ syntro_deck_paged: entry({
76
+ subject: "deck",
77
+ verb: "paged",
78
+ scope: "open",
79
+ props: ["from_index", "to_index", "method"]
80
+ // method: DeckPageMethod
81
+ }),
82
+ syntro_tile_dismissed: entry({
83
+ subject: "tile",
84
+ verb: "dismissed",
85
+ scope: "open",
86
+ props: ["tile_id", "tile_kind", "visible_ms"]
87
+ }),
88
+ // A tile's own data load finished: the network wait between the concierge
89
+ // mounting a tile and the shopper seeing its content (BUG-1784767817 was a
90
+ // 30 s reviews hang here). `outcome` is 'ok' | 'error'; `requested` is how
91
+ // many items the tile asked for, `received` how many came back.
92
+ syntro_tile_data_received: entry({
93
+ subject: "tile_data",
94
+ verb: "received",
95
+ scope: "open",
96
+ props: ["tile_id", "tile_kind", "total_ms", "outcome", "requested", "received"]
97
+ }),
98
+ // The three chat atoms are OPEN-scope: they carry `surface` / `open_id` and
99
+ // only make sense inside a concierge open. An INLINE chat bar (no concierge)
100
+ // still dispatches them on every turn, and the core drops each one and
101
+ // increments the `telemetry_dropped` health counter. That is EXPECTED on an
102
+ // inline-chat host page, not a bug — `telemetry_dropped` there mixes "real
103
+ // defect" with "inline chat has no open scope", so do not alert on it alone.
104
+ syntro_chat_message_sent: entry({
105
+ subject: "chat_message",
106
+ verb: "sent",
107
+ scope: "open",
108
+ props: ["turn", "chars", "via"]
109
+ // via: ChatSendVia
110
+ }),
111
+ syntro_chat_reply_received: entry({
112
+ subject: "chat_reply",
113
+ verb: "received",
114
+ scope: "open",
115
+ // mount_tools: the mount_* tool name of every mount this reply fired, in order (two product cards appear twice).
116
+ props: ["turn", "ttft_ms", "total_ms", "mounts", "cards", "mount_tools"]
117
+ }),
118
+ syntro_chat_interrupted: entry({
119
+ subject: "chat",
120
+ verb: "interrupted",
121
+ scope: "open",
122
+ props: ["turn", "after_ms"]
123
+ }),
124
+ syntro_chat_maximize_toggled: entry({
125
+ subject: "chat_maximize",
126
+ verb: "toggled",
127
+ scope: "open",
128
+ props: ["maximized"]
129
+ }),
130
+ syntro_chat_takeover_triggered: entry({
131
+ subject: "chat_takeover",
132
+ verb: "triggered",
133
+ scope: "open",
134
+ props: ["turn"]
135
+ }),
136
+ // --- search takeover (2026-09-17) ---------------------------------------
137
+ // All plan-scope: the search interceptor fires before any concierge open
138
+ // exists. No prop here ever carries query text (SEE the contract test's
139
+ // no-text-prop rule) — classification/signal_hits are the interceptor's
140
+ // own derived signals, never the string itself.
141
+ syntro_search_sent: entry({
142
+ subject: "search",
143
+ verb: "sent",
144
+ scope: "plan",
145
+ props: ["classification", "word_count", "signal_hits", "entry_point", "platform"]
146
+ // classification: SearchClassification, entry_point: SearchEntryPoint
147
+ }),
148
+ // `ms_to_skeleton` is intentionally the only timing prop: it is always
149
+ // knowable the instant the surface mounts. `ms_to_first_content` is NOT
150
+ // declared here (revision 1 defect) because a surface that never painted
151
+ // content still fires this event, and a required prop it cannot supply
152
+ // would make TelemetryCore.emit drop exactly the row worth measuring.
153
+ syntro_search_surface_seen: entry({
154
+ subject: "search_surface",
155
+ verb: "seen",
156
+ scope: "plan",
157
+ props: ["variant", "classification", "result_count", "ms_to_skeleton"]
158
+ // variant: SearchVariant, classification: SearchClassification
159
+ }),
160
+ syntro_search_result_tapped: entry({
161
+ subject: "search_result",
162
+ verb: "tapped",
163
+ scope: "plan",
164
+ props: ["variant", "region_id", "module", "position"]
165
+ // variant: SearchVariant
166
+ }),
167
+ syntro_search_followup_sent: entry({
168
+ subject: "search_followup",
169
+ verb: "sent",
170
+ scope: "plan",
171
+ props: ["delta_kind", "variant"]
172
+ // delta_kind: SearchDeltaKind, variant: SearchVariant
173
+ }),
174
+ // Declares `ms_since_boot` (not a "since surface mounted" timing prop) so a
175
+ // not-ready fallback the takeover never rendered is still measurable —
176
+ // revision 1 emitted nothing on this path.
177
+ syntro_search_native_served: entry({
178
+ subject: "search_native",
179
+ verb: "served",
180
+ scope: "plan",
181
+ props: ["reason", "platform", "ms_since_boot"]
182
+ // reason: SearchFallbackReason
183
+ }),
184
+ syntro_search_takeover_dismissed: entry({
185
+ subject: "search_takeover",
186
+ verb: "dismissed",
187
+ scope: "plan",
188
+ props: ["variant", "reason"]
189
+ // variant: SearchVariant, reason: SearchDismissReason
190
+ }),
191
+ // --- chat-app card lifecycle (2026-09-24) --------------------------------
192
+ // One row per stage a card reached, from `reportCardStage` in
193
+ // card-lifecycle.ts. Plan scope: most stages happen before a config is
194
+ // served and none happen inside a concierge open. `stage` is a
195
+ // CardLifecycleStage; `since_shell_ms` is the card shell's own clock, so a
196
+ // card's rows order themselves from the first byte of the page. The same
197
+ // stages reach the connector through the shell's beacon, which is the only
198
+ // record of a card whose SDK never booted.
199
+ syntro_card_lifecycle_seen: entry({
200
+ subject: "card_lifecycle",
201
+ verb: "seen",
202
+ scope: "plan",
203
+ props: ["stage", "since_shell_ms"]
204
+ // stage: CardLifecycleStage
205
+ })
206
+ };
207
+ var TELEMETRY_EVENT_NAMES = Object.keys(TELEMETRY_EVENTS);
208
+
13
209
  // ../../sdk-contracts/dist/detector-events.js
14
210
  var DETECTOR_EVENT_NAMES = [
15
211
  "ui.hover",
@@ -4350,187 +4546,6 @@ var NotifyZ = external_exports.object({
4350
4546
  icon: external_exports.string().optional().describe("Notification icon (emoji or URL)")
4351
4547
  }).describe("Optional toast notification shown when this action triggers.").nullable().optional();
4352
4548
 
4353
- // ../../sdk-contracts/dist/telemetry-events.js
4354
- var entry = (e2) => e2;
4355
- var TELEMETRY_EVENTS = {
4356
- // --- intervention metrics (April 2026) — wire names unchanged, all plan-scope
4357
- syntro_config_served: entry({
4358
- subject: "config",
4359
- verb: "served",
4360
- scope: "plan",
4361
- props: ["tiles", "actions"]
4362
- }),
4363
- syntro_intervention_seen: entry({
4364
- subject: "intervention",
4365
- verb: "seen",
4366
- scope: "plan",
4367
- props: ["intervention_id", "intervention_kind"]
4368
- }),
4369
- syntro_intervention_triggered: entry({
4370
- subject: "intervention",
4371
- verb: "triggered",
4372
- scope: "plan",
4373
- props: ["intervention_id", "intervention_kind"]
4374
- }),
4375
- syntro_intervention_interacted: entry({
4376
- subject: "intervention",
4377
- verb: "interacted",
4378
- scope: "plan",
4379
- props: ["intervention_id", "intervention_kind", "interaction_type"]
4380
- }),
4381
- // --- concierge (FEAT-1789150184) ---------------------------------------
4382
- syntro_concierge_opened: entry({
4383
- subject: "concierge",
4384
- verb: "opened",
4385
- scope: "open",
4386
- props: ["trigger", "page_path"]
4387
- // trigger: ConciergeOpenTrigger
4388
- }),
4389
- syntro_concierge_closed: entry({
4390
- subject: "concierge",
4391
- verb: "closed",
4392
- scope: "open",
4393
- props: ["duration_ms", "reason", "messages_sent", "tiles_dismissed", "pages_viewed"]
4394
- // reason: ConciergeCloseReason
4395
- }),
4396
- /**
4397
- * The shopper asked to leave the canvas by a link. Emitted on intent, before
4398
- * the host answers, so refused or denied opens are counted too (parity with
4399
- * syntro_concierge_closed reason navigation).
4400
- *
4401
- * On a merchant's own page a link tap closes the canvas, and
4402
- * `syntro_concierge_closed { reason: 'navigation' }` is the row that
4403
- * records it. Inside a chat app's card the frame is sandboxed: the canvas
4404
- * cannot navigate, does not close, and asks the host to open the link
4405
- * instead, so that close row never fires. This is its counterpart, and it
4406
- * carries the same `reason` so one query covers both surfaces.
4407
- */
4408
- syntro_link_opened: entry({
4409
- subject: "link",
4410
- verb: "opened",
4411
- scope: "open",
4412
- props: ["kind", "reason"]
4413
- // kind: LinkOpenKind, reason: ConciergeCloseReason
4414
- }),
4415
- syntro_deck_paged: entry({
4416
- subject: "deck",
4417
- verb: "paged",
4418
- scope: "open",
4419
- props: ["from_index", "to_index", "method"]
4420
- // method: DeckPageMethod
4421
- }),
4422
- syntro_tile_dismissed: entry({
4423
- subject: "tile",
4424
- verb: "dismissed",
4425
- scope: "open",
4426
- props: ["tile_id", "tile_kind", "visible_ms"]
4427
- }),
4428
- // A tile's own data load finished: the network wait between the concierge
4429
- // mounting a tile and the shopper seeing its content (BUG-1784767817 was a
4430
- // 30 s reviews hang here). `outcome` is 'ok' | 'error'; `requested` is how
4431
- // many items the tile asked for, `received` how many came back.
4432
- syntro_tile_data_received: entry({
4433
- subject: "tile_data",
4434
- verb: "received",
4435
- scope: "open",
4436
- props: ["tile_id", "tile_kind", "total_ms", "outcome", "requested", "received"]
4437
- }),
4438
- // The three chat atoms are OPEN-scope: they carry `surface` / `open_id` and
4439
- // only make sense inside a concierge open. An INLINE chat bar (no concierge)
4440
- // still dispatches them on every turn, and the core drops each one and
4441
- // increments the `telemetry_dropped` health counter. That is EXPECTED on an
4442
- // inline-chat host page, not a bug — `telemetry_dropped` there mixes "real
4443
- // defect" with "inline chat has no open scope", so do not alert on it alone.
4444
- syntro_chat_message_sent: entry({
4445
- subject: "chat_message",
4446
- verb: "sent",
4447
- scope: "open",
4448
- props: ["turn", "chars", "via"]
4449
- // via: ChatSendVia
4450
- }),
4451
- syntro_chat_reply_received: entry({
4452
- subject: "chat_reply",
4453
- verb: "received",
4454
- scope: "open",
4455
- // mount_tools: the mount_* tool name of every mount this reply fired, in order (two product cards appear twice).
4456
- props: ["turn", "ttft_ms", "total_ms", "mounts", "cards", "mount_tools"]
4457
- }),
4458
- syntro_chat_interrupted: entry({
4459
- subject: "chat",
4460
- verb: "interrupted",
4461
- scope: "open",
4462
- props: ["turn", "after_ms"]
4463
- }),
4464
- syntro_chat_maximize_toggled: entry({
4465
- subject: "chat_maximize",
4466
- verb: "toggled",
4467
- scope: "open",
4468
- props: ["maximized"]
4469
- }),
4470
- syntro_chat_takeover_triggered: entry({
4471
- subject: "chat_takeover",
4472
- verb: "triggered",
4473
- scope: "open",
4474
- props: ["turn"]
4475
- }),
4476
- // --- search takeover (2026-09-17) ---------------------------------------
4477
- // All plan-scope: the search interceptor fires before any concierge open
4478
- // exists. No prop here ever carries query text (SEE the contract test's
4479
- // no-text-prop rule) — classification/signal_hits are the interceptor's
4480
- // own derived signals, never the string itself.
4481
- syntro_search_sent: entry({
4482
- subject: "search",
4483
- verb: "sent",
4484
- scope: "plan",
4485
- props: ["classification", "word_count", "signal_hits", "entry_point", "platform"]
4486
- // classification: SearchClassification, entry_point: SearchEntryPoint
4487
- }),
4488
- // `ms_to_skeleton` is intentionally the only timing prop: it is always
4489
- // knowable the instant the surface mounts. `ms_to_first_content` is NOT
4490
- // declared here (revision 1 defect) because a surface that never painted
4491
- // content still fires this event, and a required prop it cannot supply
4492
- // would make TelemetryCore.emit drop exactly the row worth measuring.
4493
- syntro_search_surface_seen: entry({
4494
- subject: "search_surface",
4495
- verb: "seen",
4496
- scope: "plan",
4497
- props: ["variant", "classification", "result_count", "ms_to_skeleton"]
4498
- // variant: SearchVariant, classification: SearchClassification
4499
- }),
4500
- syntro_search_result_tapped: entry({
4501
- subject: "search_result",
4502
- verb: "tapped",
4503
- scope: "plan",
4504
- props: ["variant", "region_id", "module", "position"]
4505
- // variant: SearchVariant
4506
- }),
4507
- syntro_search_followup_sent: entry({
4508
- subject: "search_followup",
4509
- verb: "sent",
4510
- scope: "plan",
4511
- props: ["delta_kind", "variant"]
4512
- // delta_kind: SearchDeltaKind, variant: SearchVariant
4513
- }),
4514
- // Declares `ms_since_boot` (not a "since surface mounted" timing prop) so a
4515
- // not-ready fallback the takeover never rendered is still measurable —
4516
- // revision 1 emitted nothing on this path.
4517
- syntro_search_native_served: entry({
4518
- subject: "search_native",
4519
- verb: "served",
4520
- scope: "plan",
4521
- props: ["reason", "platform", "ms_since_boot"]
4522
- // reason: SearchFallbackReason
4523
- }),
4524
- syntro_search_takeover_dismissed: entry({
4525
- subject: "search_takeover",
4526
- verb: "dismissed",
4527
- scope: "plan",
4528
- props: ["variant", "reason"]
4529
- // variant: SearchVariant, reason: SearchDismissReason
4530
- })
4531
- };
4532
- var TELEMETRY_EVENT_NAMES = Object.keys(TELEMETRY_EVENTS);
4533
-
4534
4549
  // src/schema.ts
4535
4550
  var configSchema = external_exports.object({
4536
4551
  /** Text replacements */