@hogsend/cli 0.14.0 → 0.16.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hogsend/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"tsup": "^8.5.1",
|
|
35
35
|
"tsx": "^4.22.4",
|
|
36
36
|
"vitest": "^4.1.7",
|
|
37
|
-
"@hogsend/studio": "^0.
|
|
37
|
+
"@hogsend/studio": "^0.16.0",
|
|
38
38
|
"@repo/typescript-config": "0.0.0"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"@clack/prompts": "^1.5.0",
|
|
45
45
|
"better-auth": "^1.6.11",
|
|
46
46
|
"picocolors": "^1.1.1",
|
|
47
|
-
"@hogsend/db": "^0.
|
|
48
|
-
"@hogsend/engine": "^0.
|
|
47
|
+
"@hogsend/db": "^0.16.0",
|
|
48
|
+
"@hogsend/engine": "^0.16.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"prebuild": "node scripts/bundle-studio.mjs",
|
|
@@ -184,3 +184,12 @@ Semantics at click time:
|
|
|
184
184
|
- The answering journey reads the payload from
|
|
185
185
|
`ctx.waitForEvent(...) → { timedOut, properties }` — see the
|
|
186
186
|
hogsend-authoring-journeys skill.
|
|
187
|
+
- **No landing page?** `href={HOSTED_ANSWER_HREF}` (from `@hogsend/email`)
|
|
188
|
+
resolves to the engine-hosted answer page: a thanks page with an optional
|
|
189
|
+
free-text box whose submission ingests `<event>.comment` (one comment per
|
|
190
|
+
send + event). Possession of the link is the auth, like unsubscribe.
|
|
191
|
+
- **Cross-device stitch (opt-in):** `TRACKING_IDENTITY_TOKEN=true` appends an
|
|
192
|
+
encrypted one-hour `hs_t` token to tracked redirects; the landing site
|
|
193
|
+
exchanges it at `POST /v1/t/identify` for the distinct id and calls
|
|
194
|
+
`posthog.identify`. Never put a raw email in a URL — the token exists so
|
|
195
|
+
you don't have to.
|
|
@@ -37,10 +37,12 @@ Not every surface accepts all four types — match the type to the field:
|
|
|
37
37
|
|
|
38
38
|
- **`trigger.where`** (journey) → `PropertyCondition[]` ONLY. Property
|
|
39
39
|
conditions, AND-ed together, evaluated against the triggering event's
|
|
40
|
-
properties. No event/engagement/composite legs here.
|
|
40
|
+
properties. No event/engagement/composite legs here. Authoring sugar: a
|
|
41
|
+
builder function — `where: (b) => b.prop("score").lte(6)` (or an array of
|
|
42
|
+
terminals) — resolves ONCE at `defineJourney` time to the identical POJOs.
|
|
41
43
|
- **`exitOn[].where`** (journey) → `PropertyCondition[]` ONLY. Same shape;
|
|
42
44
|
AND-ed against the incoming event's properties. Omit `where` to exit on the
|
|
43
|
-
event name alone.
|
|
45
|
+
event name alone. Accepts the same builder-function sugar.
|
|
44
46
|
- **`criteria`** (bucket) → a single `ConditionEval` tree — ALL FOUR types,
|
|
45
47
|
composed with `composite` / `b.all()` / `b.any()`. This is the only surface
|
|
46
48
|
that runs against the database (event counts, engagement, windows).
|
|
@@ -57,7 +59,8 @@ Not every surface accepts all four types — match the type to the field:
|
|
|
57
59
|
|
|
58
60
|
## Golden rules
|
|
59
61
|
|
|
60
|
-
1. `trigger.where` and `exitOn[].where` take `PropertyCondition[]`
|
|
62
|
+
1. `trigger.where` and `exitOn[].where` take `PropertyCondition[]` (write them
|
|
63
|
+
with the `(b) => b.prop(...)` builder for short) — if
|
|
61
64
|
you need an event count or a time window, that logic belongs in the
|
|
62
65
|
journey's `run` body (`ctx.history.hasEvent`) or in a bucket's `criteria`,
|
|
63
66
|
not in `where`.
|
|
@@ -14,6 +14,23 @@ properties. Only `property` conditions are valid here — there is no `within`,
|
|
|
14
14
|
no event count, no composite. (Need a count or a window? Put that logic in the
|
|
15
15
|
`run` body via `ctx.history.hasEvent`, or model it as a bucket.)
|
|
16
16
|
|
|
17
|
+
Author it either way — the builder form resolves once at `defineJourney` time
|
|
18
|
+
to the identical data (same machinery as bucket criteria):
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
// Builder form (recommended)
|
|
22
|
+
trigger: {
|
|
23
|
+
event: Events.NPS_DETRACTOR,
|
|
24
|
+
where: (b) => b.prop("score").lte(3),
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
// Multiple conditions: return an array (AND-ed)
|
|
28
|
+
trigger: {
|
|
29
|
+
event: Events.CHECKOUT_ABANDONED,
|
|
30
|
+
where: (b) => [b.prop("plan").eq("pro"), b.prop("cartValue").gte(100)],
|
|
31
|
+
},
|
|
32
|
+
```
|
|
33
|
+
|
|
17
34
|
```ts
|
|
18
35
|
import { days, hours } from "@hogsend/core";
|
|
19
36
|
import { defineJourney, sendEmail } from "@hogsend/engine";
|
|
@@ -56,7 +73,8 @@ export const proCheckoutAbandoned = defineJourney({
|
|
|
56
73
|
|
|
57
74
|
`exitOn` is an array of `{ event, where? }`. The engine matches the incoming
|
|
58
75
|
event name; if `where` is present it must pass (`PropertyCondition[]`, AND-ed)
|
|
59
|
-
for the exit to fire. Omit `where` to exit on the event name alone.
|
|
76
|
+
for the exit to fire. Omit `where` to exit on the event name alone. The
|
|
77
|
+
builder form works here too: `where: (b) => b.prop("plan").eq("pro")`.
|
|
60
78
|
|
|
61
79
|
```ts
|
|
62
80
|
meta: {
|