@owlmetry/cli 0.1.2 → 0.1.6
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/index.cjs
CHANGED
|
@@ -6262,10 +6262,19 @@ projectsCommand.command("view <id>").description("View project details").action(
|
|
|
6262
6262
|
const project = await client.getProject(id);
|
|
6263
6263
|
output(globals.format, project, () => formatProjectDetail(project));
|
|
6264
6264
|
});
|
|
6265
|
-
projectsCommand.command("create").description("Create a new project").
|
|
6265
|
+
projectsCommand.command("create").description("Create a new project").option("--team-id <id>", "Team ID (defaults to active team)").requiredOption("--name <name>", "Project name").requiredOption("--slug <slug>", "Project slug").action(async (opts, cmd) => {
|
|
6266
6266
|
const { client, globals } = createClient(cmd);
|
|
6267
|
+
let teamId = opts.teamId;
|
|
6268
|
+
if (!teamId) {
|
|
6269
|
+
const config = loadConfig();
|
|
6270
|
+
if (!config) {
|
|
6271
|
+
throw new Error("No team ID specified and no config found. Use --team-id or run `owlmetry auth verify` first.");
|
|
6272
|
+
}
|
|
6273
|
+
const resolved = getActiveProfile(config, globals.team);
|
|
6274
|
+
teamId = resolved.teamId;
|
|
6275
|
+
}
|
|
6267
6276
|
const project = await client.createProject({
|
|
6268
|
-
team_id:
|
|
6277
|
+
team_id: teamId,
|
|
6269
6278
|
name: opts.name,
|
|
6270
6279
|
slug: opts.slug
|
|
6271
6280
|
});
|
|
@@ -7174,7 +7183,7 @@ var switchCommand = new Command("switch").description("Switch active team profil
|
|
|
7174
7183
|
});
|
|
7175
7184
|
|
|
7176
7185
|
// src/index.ts
|
|
7177
|
-
var program2 = new Command().name("owlmetry").version("0.1.
|
|
7186
|
+
var program2 = new Command().name("owlmetry").version("0.1.6").description("OwlMetry CLI \u2014 query metrics and manage your apps from the terminal").addOption(
|
|
7178
7187
|
new Option("--format <format>", "Output format").choices(["table", "json", "log"]).default("table")
|
|
7179
7188
|
).option("--endpoint <url>", "OwlMetry API server URL").option("--api-key <key>", "API key").option("--ingest-endpoint <url>", "OwlMetry ingest endpoint URL (for SDKs; defaults to API endpoint for self-hosted)").option("--team <name-or-id>", "Use a specific team profile for this command");
|
|
7180
7189
|
program2.addCommand(authCommand);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owlmetry-cli
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.6
|
|
4
4
|
description: >-
|
|
5
5
|
Install the OwlMetry CLI, sign up, and manage projects, apps, metrics,
|
|
6
6
|
funnels, and events. Use when adding OwlMetry to a project, querying
|
|
@@ -121,7 +121,7 @@ Projects group apps by product and scope metrics and funnels. Create one project
|
|
|
121
121
|
```bash
|
|
122
122
|
owlmetry projects --format json # List all
|
|
123
123
|
owlmetry projects view <id> --format json # View details + apps
|
|
124
|
-
owlmetry projects create --
|
|
124
|
+
owlmetry projects create --name <name> --slug <slug> [--team-id <id>] --format json
|
|
125
125
|
owlmetry projects update <id> --name <new-name> --format json
|
|
126
126
|
```
|
|
127
127
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owlmetry-node
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.6
|
|
4
4
|
description: >-
|
|
5
5
|
Integrate the OwlMetry Node.js SDK into a backend service for server-side
|
|
6
6
|
analytics, event tracking, metrics, funnels, and A/B experiments. Use when
|
|
@@ -37,6 +37,8 @@ Zero runtime dependencies. Node.js 20+. ESM only.
|
|
|
37
37
|
|
|
38
38
|
## Configure
|
|
39
39
|
|
|
40
|
+
Place `Owl.configure()` in the **main entry point** of your service — the root `index.ts`, `server.ts`, or `app.ts` file where your server starts. It must run once at process startup, before any other `Owl` calls. Do **not** put it in a helper/utility file — it should be alongside your other top-level initialization (e.g., `express()`, `Fastify()`, Firebase `setGlobalOptions`).
|
|
41
|
+
|
|
40
42
|
```typescript
|
|
41
43
|
import { Owl } from '@owlmetry/node';
|
|
42
44
|
|
|
@@ -57,15 +59,25 @@ Owl.configure({
|
|
|
57
59
|
- Generates a fresh `sessionId` (UUID) on each `configure()` call
|
|
58
60
|
- Registers a `beforeExit` handler to auto-flush on graceful shutdown
|
|
59
61
|
|
|
62
|
+
**Serverless (Firebase Cloud Functions, AWS Lambda, Vercel):** After adding `Owl.configure()`, also wrap your exported handler functions with `Owl.wrapHandler()` to guarantee events are flushed before the runtime freezes. This is essential boilerplate for serverless — without it, buffered events are lost:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// Before:
|
|
66
|
+
export const myFunction = onCall(async (request) => { ... });
|
|
67
|
+
|
|
68
|
+
// After:
|
|
69
|
+
export const myFunction = onCall(Owl.wrapHandler(async (request) => { ... }));
|
|
70
|
+
```
|
|
71
|
+
|
|
60
72
|
## Next Steps — Codebase Instrumentation
|
|
61
73
|
|
|
62
|
-
Once `Owl.configure()` is in place and the project builds, **stop and ask the user** which area they'd like to instrument first. Present these three options:
|
|
74
|
+
Once `Owl.configure()` is in place and the project builds successfully, **you MUST stop here and ask the user** which area they'd like to instrument first — even if the user's original prompt asked you to "instrument the app." Do not proceed with any code changes until the user chooses. Present these three options:
|
|
63
75
|
|
|
64
76
|
1. **Event & error logging** — Audit the codebase for request handlers, error paths, background jobs, and key operations. Add `Owl.info()`, `Owl.warn()`, `Owl.error()` calls at meaningful points throughout the service. This is SDK-only — no CLI setup required beyond what's already done.
|
|
65
77
|
2. **Structured metrics** — Identify operations worth measuring (API response times, database queries, external service calls, etc.). Add `Owl.startOperation()` / `Owl.recordMetric()` to track durations and success rates. **Requires CLI first:** each metric slug must be defined on the server via `owlmetry metrics create` (use the `/owlmetry-cli` skill) before the SDK can emit events for it.
|
|
66
78
|
3. **Funnel tracking** — Identify server-side user journeys (sign-up flow, payment processing, onboarding steps). Add `Owl.track()` calls at each step to measure drop-off. **Requires CLI first:** the funnel definition (with steps and event filters) must be created via `owlmetry funnels create` (use the `/owlmetry-cli` skill) before tracking makes sense.
|
|
67
79
|
|
|
68
|
-
|
|
80
|
+
After the user chooses, do a thorough audit of the entire codebase to find all relevant locations, then present a summary of proposed changes before making any edits.
|
|
69
81
|
|
|
70
82
|
## Buffering and Delivery
|
|
71
83
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owlmetry-swift
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.6
|
|
4
4
|
description: >-
|
|
5
5
|
Integrate the OwlMetry Swift SDK into an iOS or macOS app for analytics,
|
|
6
6
|
event tracking, metrics, funnels, and A/B experiments. Use when
|
|
@@ -68,7 +68,7 @@ Once the user confirms the package is added, retry the build to verify, then pro
|
|
|
68
68
|
|
|
69
69
|
## Configure
|
|
70
70
|
|
|
71
|
-
Configuration must happen once,
|
|
71
|
+
Configuration must happen once, as early as possible — in the `@main` App `init()` or AppDelegate `didFinishLaunching`. **Do not defer it** to a later point (e.g., after async setup or user consent). The SDK measures app launch time (`_launch_ms`) from process start to the `configure()` call, so placing it early gives an accurate cold-start metric. It also ensures no events are dropped before configuration. Each `configure()` call generates a fresh `session_id` (UUID) that groups all subsequent events together.
|
|
72
72
|
|
|
73
73
|
```swift
|
|
74
74
|
import OwlMetry
|
|
@@ -94,18 +94,92 @@ struct MyApp: App {
|
|
|
94
94
|
- `apiKey: String` — client key, must start with `owl_client_` (required)
|
|
95
95
|
- `flushOnBackground: Bool` — auto-flush when app backgrounds (default: `true`)
|
|
96
96
|
- `compressionEnabled: Bool` — gzip request bodies (default: `true`)
|
|
97
|
+
- `networkTrackingEnabled: Bool` — auto-track URLSession HTTP requests (default: `true`)
|
|
97
98
|
|
|
98
99
|
Auto-detects: bundle ID, debug mode (`#if DEBUG`). Auto-generates: session ID (fresh each launch).
|
|
99
100
|
|
|
101
|
+
## User Identity (set up during initial configuration)
|
|
102
|
+
|
|
103
|
+
After adding `Owl.configure()`, find where the app handles authentication and add `Owl.setUser()` / `Owl.clearUser()`. This is part of the basic setup — do it now, before moving on to instrumentation.
|
|
104
|
+
|
|
105
|
+
Look for the auth state change handler (e.g., Firebase Auth listener, login/logout methods) and add:
|
|
106
|
+
|
|
107
|
+
```swift
|
|
108
|
+
// After successful login — claims all previous anonymous events for this user
|
|
109
|
+
Owl.setUser(userId)
|
|
110
|
+
|
|
111
|
+
// On logout — reverts to anonymous tracking
|
|
112
|
+
Owl.clearUser()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Where to find it:** Search for login/logout methods, auth state listeners, or session management code. Look for patterns like setting a user ID on other services (crash reporting, analytics), storing auth tokens, or clearing user state. Place `Owl.setUser()` right after the user ID becomes available. Place `Owl.clearUser()` in the sign-out/logout handler.
|
|
116
|
+
|
|
117
|
+
The SDK automatically flushes buffered events before claiming identity, so anonymous events from before login are retroactively linked to the user.
|
|
118
|
+
|
|
100
119
|
## Next Steps — Codebase Instrumentation
|
|
101
120
|
|
|
102
|
-
Once `Owl.configure()` is in place and the project builds, **stop and ask the user** which area they'd like to instrument first. Present these
|
|
121
|
+
Once `Owl.configure()` is in place and the project builds successfully, **you MUST stop here and ask the user** which area they'd like to instrument first — even if the user's original prompt asked you to "instrument the app." Do not proceed with any code changes until the user chooses. Present these options:
|
|
122
|
+
|
|
123
|
+
1. **Screen tracking** — Add `.owlScreen("ScreenName")` to every distinct screen in the app. This is the quickest win — automatic screen view and time-on-screen tracking with a single modifier per screen. No CLI setup needed.
|
|
124
|
+
2. **Event & error logging** — Audit the codebase for user actions, error handling, and key flows. Add `Owl.info()`, `Owl.warn()`, `Owl.error()` calls at meaningful points. This is SDK-only — no CLI setup required beyond what's already done.
|
|
125
|
+
3. **Structured metrics** — Identify operations worth measuring (data loading, image processing, etc.). Add `Owl.startOperation()` / `Owl.recordMetric()` to track durations and success rates. **Requires CLI first:** each metric slug must be defined on the server via `owlmetry metrics create` (use the `/owlmetry-cli` skill) before the SDK can emit events for it.
|
|
126
|
+
4. **Funnel tracking** — Identify user journeys (onboarding, checkout, key conversions). Add `Owl.track()` calls at each step to measure drop-off. **Requires CLI first:** the funnel definition (with steps and event filters) must be created via `owlmetry funnels create` (use the `/owlmetry-cli` skill) before tracking makes sense.
|
|
127
|
+
|
|
128
|
+
After the user chooses, do a thorough audit of the entire codebase to find all relevant locations, then present a summary of proposed changes before making any edits.
|
|
129
|
+
|
|
130
|
+
## Screen Tracking (`.owlScreen()`)
|
|
131
|
+
|
|
132
|
+
The SDK provides a SwiftUI view modifier that automatically tracks screen appearances and time-on-screen with zero manual event calls.
|
|
133
|
+
|
|
134
|
+
```swift
|
|
135
|
+
struct HomeView: View {
|
|
136
|
+
var body: some View {
|
|
137
|
+
VStack { ... }
|
|
138
|
+
.owlScreen("Home")
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
struct SettingsView: View {
|
|
143
|
+
var body: some View {
|
|
144
|
+
Form { ... }
|
|
145
|
+
.owlScreen("Settings")
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**What it does automatically:**
|
|
151
|
+
- On appear: emits `sdk:screen_appeared` (info level) with `screenName` set — included in production data
|
|
152
|
+
- On disappear: emits `sdk:screen_disappeared` (debug level) with `screenName` set and `_duration_ms` attribute — only visible in dev data mode
|
|
153
|
+
|
|
154
|
+
**Where to place it:** Attach `.owlScreen("ScreenName")` to the outermost view of each screen — typically on the `NavigationStack`, `Form`, `ScrollView`, or root `VStack`. Use it on every distinct screen in the app. Choose names that are short, readable, and consistent (e.g., `"Home"`, `"Settings"`, `"Profile"`, `"Checkout"`).
|
|
155
|
+
|
|
156
|
+
**Prefer `.owlScreen()` over manual `Owl.info()` for screen views** — it handles both appear and disappear with duration tracking. Use manual `Owl.info()` with `screenName:` only for events within a screen (button taps, state changes), not for screen appearances themselves.
|
|
103
157
|
|
|
104
|
-
|
|
105
|
-
2. **Structured metrics** — Identify operations worth measuring (network requests, data loading, image processing, etc.). Add `Owl.startOperation()` / `Owl.recordMetric()` to track durations and success rates. **Requires CLI first:** each metric slug must be defined on the server via `owlmetry metrics create` (use the `/owlmetry-cli` skill) before the SDK can emit events for it.
|
|
106
|
-
3. **Funnel tracking** — Identify user journeys (onboarding, checkout, key conversions). Add `Owl.track()` calls at each step to measure drop-off. **Requires CLI first:** the funnel definition (with steps and event filters) must be created via `owlmetry funnels create` (use the `/owlmetry-cli` skill) before tracking makes sense.
|
|
158
|
+
## Network Request Tracking
|
|
107
159
|
|
|
108
|
-
|
|
160
|
+
The SDK automatically tracks all URLSession HTTP requests made via completion handler APIs. This is **enabled by default** — no code needed beyond `Owl.configure()`. To disable:
|
|
161
|
+
|
|
162
|
+
```swift
|
|
163
|
+
try Owl.configure(
|
|
164
|
+
endpoint: "https://ingest.owlmetry.com",
|
|
165
|
+
apiKey: "owl_client_...",
|
|
166
|
+
networkTrackingEnabled: false
|
|
167
|
+
)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**What it captures automatically:**
|
|
171
|
+
- `_http_method` — GET, POST, etc.
|
|
172
|
+
- `_http_url` — sanitized URL (scheme + host + path only, query params stripped for privacy)
|
|
173
|
+
- `_http_status` — response status code
|
|
174
|
+
- `_http_duration_ms` — request duration in milliseconds
|
|
175
|
+
- `_http_response_size` — response body size in bytes
|
|
176
|
+
- `_http_error` — error description (failures only)
|
|
177
|
+
|
|
178
|
+
**Log levels:** `.info` for 2xx/3xx responses, `.warn` for 4xx/5xx, `.error` for network failures (no response).
|
|
179
|
+
|
|
180
|
+
**Safety:** The SDK's own requests to the OwlMetry ingest endpoint are automatically filtered out. Query parameters are stripped from URLs to prevent accidental logging of tokens or user IDs.
|
|
181
|
+
|
|
182
|
+
**Coverage:** Tracks requests made with `URLSession.dataTask(with:completionHandler:)` (both URL and URLRequest overloads). Delegate-based and async/await requests are not tracked in this version.
|
|
109
183
|
|
|
110
184
|
## Log Events
|
|
111
185
|
|
|
@@ -251,8 +325,8 @@ Owl.clearExperiments()
|
|
|
251
325
|
When instrumenting a new app, follow this priority:
|
|
252
326
|
|
|
253
327
|
**Always instrument (events — no CLI setup needed):**
|
|
328
|
+
- Screen views (`.owlScreen("ScreenName")` on every distinct screen)
|
|
254
329
|
- App launch / cold start (`info` in `init()` or `didFinishLaunching`)
|
|
255
|
-
- Key screen views (`info` with `screenName` in `onAppear`)
|
|
256
330
|
- Authentication events (login, logout, signup)
|
|
257
331
|
- Errors and failures (`error` in `catch` blocks, error handlers)
|
|
258
332
|
- Core business actions (purchase, share, create, delete)
|
|
@@ -266,7 +340,7 @@ When instrumenting a new app, follow this priority:
|
|
|
266
340
|
- A/B experiments when testing alternative UI or flows
|
|
267
341
|
|
|
268
342
|
**Where to place calls:**
|
|
269
|
-
- Screen views: `.
|
|
343
|
+
- Screen views: `.owlScreen("Name")` on the outermost view of each screen (SwiftUI), `viewDidAppear` in UIKit
|
|
270
344
|
- User actions: button action handlers, gesture callbacks
|
|
271
345
|
- Errors: `catch` blocks, `Result.failure` handlers
|
|
272
346
|
- Metrics: wrap the async operation between `startOperation()` and `complete()`/`fail()`
|
|
@@ -296,3 +370,10 @@ Every event automatically includes:
|
|
|
296
370
|
- `_connection` — network type (wifi, cellular, ethernet, offline) via `NWPathMonitor`
|
|
297
371
|
- `experiments` — current A/B experiment assignments
|
|
298
372
|
- `environment` — specific runtime (ios, ipados, macos)
|
|
373
|
+
|
|
374
|
+
**Auto-emitted lifecycle events** (no manual calls needed):
|
|
375
|
+
- `sdk:session_started` — on `configure()`, includes `_launch_ms` (time from process start to configure)
|
|
376
|
+
- `sdk:app_foregrounded` — when app enters foreground
|
|
377
|
+
- `sdk:app_backgrounded` — when app enters background
|
|
378
|
+
- `sdk:screen_appeared` (info) / `sdk:screen_disappeared` (debug) — when using `.owlScreen()` modifier (disappear includes `_duration_ms`)
|
|
379
|
+
- `sdk:network_request` (info/warn/error) — URLSession HTTP requests with method, URL, status, duration (enabled by default, disable with `networkTrackingEnabled: false`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmetry/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "OwlMetry CLI — manage projects, apps, metrics, funnels, and events from the terminal. Includes AI skill files for agent-assisted development.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|