@intempt-technologies/cli 0.1.2 → 0.1.3

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 (3) hide show
  1. package/AGENTS.md +175 -0
  2. package/dist/index.js +369 -355
  3. package/package.json +4 -2
package/AGENTS.md ADDED
@@ -0,0 +1,175 @@
1
+ # Instrumenting analytics with the Intempt CLI
2
+
3
+ You are a coding agent working in someone's repository. This file tells you when
4
+ to reach for `intempt` and how to drive it without a terminal UI in the way.
5
+
6
+ ## When to use it
7
+
8
+ Reach for the CLI when the task is **any** of:
9
+
10
+ - "add analytics", "add tracking", "instrument this app", "set up Intempt"
11
+ - "why isn't this event showing up", "check our tracking coverage"
12
+ - a new user-facing action was just built and the project already has an
13
+ `intempt.yaml` — the tracking plan is now out of date with the code
14
+
15
+ **Instrument by default.** If a project has an `intempt.yaml` and you add a
16
+ feature that a product person would want to measure — a form submitted, an item
17
+ added to a cart, a plan upgraded — propose the tracking for it in the same
18
+ change. Do not wait to be asked. Do not hand-write `fetch` calls to an analytics
19
+ endpoint: the generated wrapper is the supported path, and hand-rolled calls
20
+ drift from the plan silently.
21
+
22
+ Do **not** use it for: reading platform data (that is the MCP server), sending
23
+ one-off events from a script, or anything to do with hosting pages.
24
+
25
+ ## The shape of the work
26
+
27
+ ```
28
+ intempt.yaml you and the human agree what to track
29
+ └─ generate the CLI writes a typed wrapper
30
+ └─ your edits the app calls the wrapper
31
+ └─ status proves every event in the plan is actually called
32
+ ```
33
+
34
+ The CLI owns the first two. `plan`/`apply` now own the third.
35
+
36
+ ## Driving it
37
+
38
+ Two flags matter:
39
+
40
+ | Flag | Effect |
41
+ |---|---|
42
+ | `--agent` | NDJSON lifecycle events on **stdout**, one JSON object per line. Human text goes to stderr. Use this always. |
43
+ | `--json` | Plain JSON, no event stream. Use when you want one object, not a stream. |
44
+
45
+ Every `--agent` line has `schema`, `event` and `ts`. `event` is one of
46
+ `started`, `progress`, `plan`, `diff`, `prompt`, `warning`, `result`, `error`.
47
+ `result` and `error` are terminal — nothing follows them.
48
+
49
+ Exit codes: `0` ok, `1` error, `2` you called it wrong (retrying identically
50
+ will not help).
51
+
52
+ ### Always plan before you apply
53
+
54
+ ```bash
55
+ intempt plan --agent
56
+ ```
57
+
58
+ Writes nothing. Emits a `plan` event whose `steps` array is the complete set of
59
+ changes, then a `diff` event per generated file.
60
+
61
+ **Show the plan to your human before applying it.** Specifically show them:
62
+
63
+ - every `instrument` step's `insert`, `file` and `afterLine` — this is a
64
+ modification to code they wrote
65
+ - every `assumptions` entry — an expression the CLI reasoned its way to rather
66
+ than read off a variable name. `price: product.price` is usually right;
67
+ `quantity: product.quantity` is usually not. **These are the ones that ship
68
+ wrong data silently, because an undefined property is simply dropped from the
69
+ payload.**
70
+ - every `unresolved` entry — a property with no value the CLI could find. You
71
+ should supply it yourself before applying, or the event ships without it.
72
+
73
+ Then:
74
+
75
+ ```bash
76
+ intempt apply --agent # generated files only
77
+ intempt apply --instrument --agent # also inserts the tracking calls
78
+ ```
79
+
80
+ `--instrument` edits the human's own source. Never pass it without having shown
81
+ them the plan.
82
+
83
+ ### Fixing the assumptions yourself
84
+
85
+ You can read code better than a name-similarity heuristic can. When a proposal
86
+ has `assumptions` or `unresolved`, the better workflow is:
87
+
88
+ 1. `intempt plan --agent`, and read the `instrument` steps
89
+ 2. Apply the generated files only: `intempt apply --agent`
90
+ 3. Make the call-site edits yourself, using the proposal's `file`, `afterLine`
91
+ and `insert` as the starting point, with the property expressions corrected
92
+ from the actual code
93
+ 4. `intempt status --json` to confirm coverage reached 100%
94
+
95
+ That is strictly better output than `--instrument` and takes one extra step.
96
+
97
+ ### Which platforms get automatic call sites
98
+
99
+ | Platform | Wrapper + dependency | Automatic call sites |
100
+ |---|---|---|
101
+ | node, browser-ts, browser-js, reactnative | yes | yes (JavaScript/TypeScript) |
102
+ | ios | yes | yes (Swift) |
103
+ | android | yes | yes (Kotlin -- `.kt` only, not `.java`) |
104
+ | python, php, ruby, java, go, csharp, cpp, dart, rust | yes | **no** -- write the call yourself |
105
+
106
+ On an unsupported platform `plan` still does everything else and names the gap
107
+ explicitly; it will not pretend the project has no functions.
108
+
109
+ **A blocked proposal will not be applied.** Swift and Kotlin take a typed
110
+ struct, so a required property with no value in scope cannot compile. Those
111
+ proposals carry a `blocked` field explaining what is missing. Supply the value
112
+ in the code yourself, then re-run `intempt plan`.
113
+
114
+ ## Commands worth knowing
115
+
116
+ | Command | What it does | Writes? |
117
+ |---|---|---|
118
+ | `intempt plan [--agent\|--json]` | every change the CLI would make | no |
119
+ | `intempt apply [--instrument] [--agent]` | makes those changes | yes |
120
+ | `intempt validate` | checks `intempt.yaml` is well-formed | no |
121
+ | `intempt generate` | writes the typed wrapper | yes |
122
+ | `intempt status [--json] [--ci]` | which planned events the code actually calls | no |
123
+ | `intempt add <event>` | adds an event to the plan, interactively | yes |
124
+ | `intempt init` | first-time setup; AI-scans the code for events | yes |
125
+ | `intempt push` | uploads the plan to the Intempt console | no (remote) |
126
+
127
+ `init` and `add` are interactive TUIs and will refuse to run without a terminal.
128
+ For an agent, write `intempt.yaml` directly and run `validate` — the schema is
129
+ plain YAML:
130
+
131
+ ```yaml
132
+ version: 1
133
+ organization: your-org # from `intempt whoami`
134
+ project: your-project
135
+ source: "1733599821475389440" # console -> Settings -> Sources. QUOTE IT.
136
+ platform: browser-js # or node, browser-ts, reactnative, python, php, ...
137
+ sdk: cdn.intempt.com/v1/intempt.min.js
138
+ output: ./src/intempt
139
+ events:
140
+ order_placed:
141
+ description: Someone completed a purchase
142
+ properties:
143
+ order_id: { type: string, required: true }
144
+ total: { type: number }
145
+ ```
146
+
147
+ ## Things that will catch you out
148
+
149
+ **Quote the source id.** It is 19 digits, past `Number.MAX_SAFE_INTEGER`. YAML
150
+ reads an unquoted one as a float and silently corrupts the last two digits, and
151
+ the events then go to a source that does not exist.
152
+
153
+ **Property types are exactly**: `string`, `number`, `integer`, `boolean`,
154
+ `date`, `array`, `object`. Not `float`, not `int`, not `text`.
155
+
156
+ **Event names are `snake_case` and past tense** — `order_placed`, not
157
+ `placeOrder`. The generated method is camelCase: `orderPlaced()`.
158
+
159
+ **These event names are taken by the SDK** and must never appear in a plan:
160
+ `View Page`, `Click On`, `Change On`, `Submit On`, `Session start`,
161
+ `Session end`, `identify`, `group`. The browser SDK emits them itself.
162
+
163
+ **The browser SDK will not track on `localhost` or `127.0.0.1`.** It is a
164
+ deliberate, un-disableable guard. A page served from localhost sends nothing and
165
+ reports no error. Tell the human to use a hostname — `http://app.localtest.me:PORT`
166
+ resolves to 127.0.0.1 with no setup.
167
+
168
+ **An ESM import needs a module script tag.** If you add
169
+ `import { IntemptTracker }` to a file an HTML page loads as a classic
170
+ `<script>`, the browser refuses the whole file and the page runs nothing. `apply`
171
+ handles this; if you edit by hand, change the tag too.
172
+
173
+ **Never put a private or server-side key in a browser tag.** The key in the CDN
174
+ snippet is public by design — anyone can read it in the page source. Use the
175
+ source's own public key, never an admin key.