@hogsend/cli 0.18.0 → 0.19.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.19.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.19.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.19.0",
|
|
48
|
+
"@hogsend/engine": "^0.19.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"prebuild": "node scripts/bundle-studio.mjs",
|
|
@@ -149,7 +149,10 @@ orchestration:
|
|
|
149
149
|
- **`getPostHog()`** — `import { getPostHog } from "@hogsend/engine"` for the raw
|
|
150
150
|
PostHog service (a fire-and-forget escape hatch). For fanning lifecycle data out
|
|
151
151
|
to product/data tools, prefer an outbound DESTINATION (see above) — it delivers
|
|
152
|
-
durably and is vendor-neutral.
|
|
152
|
+
durably and is vendor-neutral. Note: capture and `$set` person WRITES use the
|
|
153
|
+
`phc_` project key; person READS (`getPersonProperties`) additionally need
|
|
154
|
+
`POSTHOG_PERSONAL_API_KEY` (the project key is write-only by PostHog's design)
|
|
155
|
+
and soft-fail to `{}` without it.
|
|
153
156
|
- **SMS / push / Slack** — plain functions you import, never on `ctx`.
|
|
154
157
|
- There is **no `ctx.db`, no `ctx.sendEmail`, no `ctx.hatchet`** surfaced to
|
|
155
158
|
consumer journeys. If you reach for one of those, you are modelling it wrong —
|
|
@@ -73,10 +73,19 @@ dashboard at `http://localhost:8888`, login `admin@example.com` / `Admin123!!`.)
|
|
|
73
73
|
All commented-out in `.env.example` — add only what you use:
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
|
-
# PostHog
|
|
76
|
+
# PostHog event capture + person property WRITES (no-op if unset).
|
|
77
77
|
POSTHOG_API_KEY=phc_...
|
|
78
78
|
POSTHOG_HOST=https://us.i.posthog.com
|
|
79
79
|
|
|
80
|
+
# PostHog person property READS (timezone resolution, property conditions).
|
|
81
|
+
# The phc_ key is write-only by PostHog's design — reads need a PERSONAL API
|
|
82
|
+
# key scoped person:read. Without it reads soft-fail to contact properties.
|
|
83
|
+
POSTHOG_PERSONAL_API_KEY=...
|
|
84
|
+
# Project id for the private API — discovered automatically when unset.
|
|
85
|
+
# POSTHOG_PROJECT_ID=12345
|
|
86
|
+
# Private API host — derived (eu.i.posthog.com → eu.posthog.com) when unset.
|
|
87
|
+
# POSTHOG_PRIVATE_HOST=https://us.posthog.com
|
|
88
|
+
|
|
80
89
|
# Verify incoming PostHog webhooks (POST /v1/webhooks/posthog).
|
|
81
90
|
POSTHOG_WEBHOOK_SECRET=...
|
|
82
91
|
|
|
@@ -92,6 +101,12 @@ Notes:
|
|
|
92
101
|
|
|
93
102
|
- **PostHog is fully optional.** Without `POSTHOG_API_KEY`, person-property
|
|
94
103
|
fetches and event captures are no-ops — journeys still run.
|
|
104
|
+
- **Two PostHog credentials, by PostHog's design.** The `phc_` project key is
|
|
105
|
+
public (it ships in browser bundles) so PostHog makes it WRITE-only: capture
|
|
106
|
+
and `$set` person writes work, reads never will. Person READS (per-user
|
|
107
|
+
timezone resolution) need `POSTHOG_PERSONAL_API_KEY` — a personal API key
|
|
108
|
+
scoped `person:read`, created in PostHog → Settings → Personal API keys.
|
|
109
|
+
`hogsend doctor` warns when capture is configured without it.
|
|
95
110
|
- **Webhook secrets are per-source.** Only set the secret for a webhook source
|
|
96
111
|
you've actually registered (see the consumer's `src/webhook-sources`).
|
|
97
112
|
- **`ADMIN_API_KEY` gates `/v1/admin/*`.** Set it in prod if you want to drive
|
package/src/commands/doctor.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseArgs } from "node:util";
|
|
2
|
+
import { loadDotEnv } from "../lib/config.js";
|
|
2
3
|
import { isHttpError } from "../lib/http.js";
|
|
3
4
|
import { color } from "../lib/output.js";
|
|
4
5
|
import { skillsStaleness } from "../lib/skills.js";
|
|
@@ -22,6 +23,34 @@ function skillsNudge(ctx: CommandContext): void {
|
|
|
22
23
|
);
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Best-effort nudge: PostHog capture configured (`POSTHOG_API_KEY` in the
|
|
28
|
+
* cwd's `.env` or process env) without `POSTHOG_PERSONAL_API_KEY` means
|
|
29
|
+
* person READS are silently disabled — the phc_ project key is write-only by
|
|
30
|
+
* PostHog's design, so timezone resolution falls back to contact properties.
|
|
31
|
+
* Warn-not-fail: capture and person writes still work.
|
|
32
|
+
*/
|
|
33
|
+
function analyticsNudge(ctx: CommandContext): void {
|
|
34
|
+
if (ctx.json) return;
|
|
35
|
+
const dotenv = loadDotEnv(process.cwd());
|
|
36
|
+
const captureKey = process.env.POSTHOG_API_KEY ?? dotenv.POSTHOG_API_KEY;
|
|
37
|
+
const personalKey =
|
|
38
|
+
process.env.POSTHOG_PERSONAL_API_KEY ?? dotenv.POSTHOG_PERSONAL_API_KEY;
|
|
39
|
+
if (!captureKey || personalKey) return;
|
|
40
|
+
ctx.out.note(
|
|
41
|
+
[
|
|
42
|
+
"POSTHOG_API_KEY is set without POSTHOG_PERSONAL_API_KEY — person",
|
|
43
|
+
"property READS are disabled (the phc_ project key is write-only by",
|
|
44
|
+
"PostHog's design), so per-user timezone resolution falls back to",
|
|
45
|
+
"contact properties. Capture and person WRITES are unaffected.",
|
|
46
|
+
"",
|
|
47
|
+
`Fix: create a personal API key scoped ${color.cyan("person:read")} and set ${color.cyan("POSTHOG_PERSONAL_API_KEY")}.`,
|
|
48
|
+
`Docs: ${color.cyan("https://hogsend.com/docs/guides/analytics-access")}`,
|
|
49
|
+
].join("\n"),
|
|
50
|
+
"PostHog person reads disabled",
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
25
54
|
const usage = `hogsend doctor [--url <baseUrl>] [--admin-key <key>] [--json]
|
|
26
55
|
|
|
27
56
|
Probe a running Hogsend instance via GET /v1/health and report its health:
|
|
@@ -221,6 +250,7 @@ async function run(ctx: CommandContext): Promise<void> {
|
|
|
221
250
|
ctx.out.note(lines.join("\n"), "Doctor");
|
|
222
251
|
|
|
223
252
|
skillsNudge(ctx);
|
|
253
|
+
analyticsNudge(ctx);
|
|
224
254
|
|
|
225
255
|
if (ok) {
|
|
226
256
|
ctx.out.outro(color.green("doctor: ok"));
|