@wireai/activation 0.13.6-next.0 → 0.14.0

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.
Files changed (42) hide show
  1. package/AGENTS.md +21 -9
  2. package/CHANGELOG.md +258 -3
  3. package/INTEGRATION_PROMPT.md +7 -4
  4. package/README.md +41 -35
  5. package/dist/analytics/index.d.mts +9 -2
  6. package/dist/analytics/index.d.ts +9 -2
  7. package/dist/analytics/index.js +56 -12
  8. package/dist/analytics/index.js.map +1 -1
  9. package/dist/analytics/index.mjs +56 -12
  10. package/dist/analytics/index.mjs.map +1 -1
  11. package/dist/{currentSession-Cs3lweFZ.d.mts → currentSession-CUvTOchb.d.mts} +62 -7
  12. package/dist/{currentSession-DD6dKB0i.d.ts → currentSession-CW_5Mq4O.d.ts} +62 -7
  13. package/dist/index.d.mts +26 -6
  14. package/dist/index.d.ts +26 -6
  15. package/dist/index.js +635 -544
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +635 -544
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/questionnaire/index.js.map +1 -1
  20. package/dist/questionnaire/index.mjs.map +1 -1
  21. package/dist/reviews/index.js.map +1 -1
  22. package/dist/reviews/index.mjs.map +1 -1
  23. package/llms.txt +3 -3
  24. package/package.json +1 -1
  25. package/src/OnboardingFlow.tsx +23 -5
  26. package/src/WireOnboarding.tsx +4 -3
  27. package/src/activation/useWireActivation.ts +14 -1
  28. package/src/activation/wireActivation.ts +68 -2
  29. package/src/analytics/analyticsFacade.ts +24 -0
  30. package/src/analytics/eventQueue.ts +106 -11
  31. package/src/analytics/reportClientEvent.ts +31 -7
  32. package/src/analytics/useAnalytics.ts +17 -0
  33. package/src/context/deviceId.ts +10 -3
  34. package/src/permissions/permissionMemory.ts +12 -1
  35. package/src/session/persistedSession.ts +32 -8
  36. package/src/session-analytics/lifecycle.ts +26 -5
  37. package/src/session-analytics/reportSessionStart.ts +14 -10
  38. package/src/session-analytics/useLifecycleEvents.ts +70 -32
  39. package/src/session-analytics/useSessionStart.ts +57 -15
  40. package/src/types.ts +43 -8
  41. package/src/utils/readPlan.ts +26 -10
  42. package/src/utils/readProgress.ts +5 -0
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * readPlan — lift the backend's onboarding plan off the message thread.
3
3
  *
4
- * WHY IT EXISTS. On the AI path the server appends a SECOND A2A DataPart to the turn it finishes
5
- * on: `{ kind: "onboarding_plan", plan: {...} }`, alongside the component envelope the renderer
6
- * already consumes. The kit carries that payload out through `OnboardingResult.plan` and stops
7
- * there. It does NOT interpret it, does NOT validate its fields, does NOT log it and does NOT
4
+ * WHY IT EXISTS. When it sends a plan, the server appends a SECOND A2A DataPart to the turn it
5
+ * finishes on: `{ kind: "onboarding_plan", plan: {...} }`, alongside the component envelope the
6
+ * renderer already consumes. The kit carries that payload out through `OnboardingResult.plan` and
7
+ * stops there. It does NOT interpret it, does NOT validate its fields, does NOT log it and does NOT
8
8
  * attach it to any event — the plan is user-derived content, and deciding what it MEANS is the
9
9
  * host's job (the kit/host boundary in `ai_rules/context_map.md`: the kit ends at the completion
10
10
  * CTA).
@@ -19,14 +19,24 @@
19
19
  * so a throw here would cost the user the completion of an onboarding they already finished. Every
20
20
  * step below is a runtime-guarded read.
21
21
  *
22
- * The static (non-AI) flow carries no plan at all. That path is unchanged and fully supported.
22
+ * WHICH RUNS CARRY A PLAN IS THE BACKEND'S CONFIGURATION, NOT THE KIT'S. This reader matches the
23
+ * `kind` MARKER below and never the flow that produced the turn, so it needs no knowledge of how
24
+ * the tenant is configured. A run that carries no plan yields `undefined`: unchanged, and fully
25
+ * supported.
23
26
  */
24
27
  import type { Message } from "wireai-rn";
25
28
 
26
29
  /**
27
- * The read-back member the SDK surfaces for every A2A DataPart past the first, in wire order and
28
- * uninterpreted. Declared HERE, structurally, because the installed `wireai-rn` peer (0.2.4) does
29
- * not declare it on `Message` yet.
30
+ * The read-back member the SDK surfaces for every A2A DataPart past the first, uninterpreted.
31
+ *
32
+ * NOT in wire order, and nothing here may assume it is. The SDK FLATTENS a task's parts across
33
+ * agent messages LATEST-FIRST (and then artifacts latest-first) before dropping the first one, so
34
+ * this array is a cross-message collection, not one turn's parts in the order they arrived. On a
35
+ * task carrying history, a previous turn's component envelope lands here beside this turn's plan.
36
+ * `readPlan` is safe from that because it matches the `kind` MARKER below, never a position.
37
+ *
38
+ * Declared HERE, structurally, because the installed `wireai-rn` peer (0.2.4) does not declare it
39
+ * on `Message` yet.
30
40
  *
31
41
  * TODO(re-pin): delete this local type and read the member straight off `Message` once a
32
42
  * `wireai-rn` that declares it is published and the peer range is re-pinned. Until then the two
@@ -58,8 +68,14 @@ const planFromPart = (part: unknown): unknown => {
58
68
  *
59
69
  * ORDERING, stated so it is not undefined behavior: the thread is scanned NEWEST TURN FIRST, so a
60
70
  * thread carrying two plans resolves to the LAST one — the same turn `handleFinish` completes on.
61
- * Within a single turn, wire order decides: the first well-formed plan part wins. A malformed part
62
- * is skipped rather than treated as a terminator, so a broken payload can never shadow a good one.
71
+ *
72
+ * Inside one message's `dataParts` the first WELL-FORMED plan part wins, and that is a scan order,
73
+ * NOT a wire-order guarantee. Wire order does not hold even within a single turn: `dataParts` is
74
+ * the SDK's flattened, cross-agent-message collection (latest-first, see `WithDataParts` above), so
75
+ * on a task carrying history a previous turn's parts sit in the same array. This is exactly why the
76
+ * match is on the `onboarding_plan` MARKER and never on a position. A part that is not a
77
+ * well-formed plan is skipped rather than treated as a terminator, so neither a stale envelope nor
78
+ * a broken payload can shadow a good plan.
63
79
  */
64
80
  export const readPlan = (messages: readonly Message[]): unknown => {
65
81
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -18,6 +18,8 @@ type PartialProgress = {
18
18
  /** The stable per-slot identity, when the backend sends one. See `OnboardingProgress.slot_id`. */
19
19
  slot_id?: string;
20
20
  skippable?: boolean;
21
+ /** The experiment arm assigned to this session, when the tenant runs one. See `OnboardingProgress.variant`. */
22
+ variant?: string;
21
23
  };
22
24
 
23
25
  export const readProgress = (response?: WireAIResponse): PartialProgress => {
@@ -33,5 +35,8 @@ export const readProgress = (response?: WireAIResponse): PartialProgress => {
33
35
  // Whitelisted the same way as every other field: an old backend simply omits it.
34
36
  slot_id: typeof p.slot_id === "string" ? p.slot_id : undefined,
35
37
  skippable: typeof p.skippable === "boolean" ? p.skippable : undefined,
38
+ // Whitelisted like the rest: a non-string (or absent) arm key reads as "no experiment", never
39
+ // as an error. The kit does not interpret the value — see `OnboardingProgress.variant`.
40
+ variant: typeof p.variant === "string" ? p.variant : undefined,
36
41
  };
37
42
  };