@owlmetry/cli 0.1.8 → 0.1.10

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
@@ -6360,7 +6360,8 @@ var METRIC_PHASES = ["start", "complete", "fail", "cancel", "record"];
6360
6360
  init_cjs_shims();
6361
6361
 
6362
6362
  // src/commands/apps.ts
6363
- var appsCommand = new Command("apps").description("List apps").enablePositionalOptions().option("--project-id <id>", "Filter by project ID").action(async (opts, cmd) => {
6363
+ var appsCommand = new Command("apps").description("Manage apps");
6364
+ appsCommand.command("list").description("List apps").option("--project-id <id>", "Filter by project ID").action(async (opts, cmd) => {
6364
6365
  const { client, globals } = createClient(cmd);
6365
6366
  let apps = await client.listApps();
6366
6367
  if (opts.projectId) {
@@ -6782,7 +6783,8 @@ function formatQueryResult(result) {
6782
6783
  }
6783
6784
  return lines.join("\n");
6784
6785
  }
6785
- var metricsCommand = new Command("metrics").description("List metric definitions").enablePositionalOptions().requiredOption("--project-id <id>", "Project ID").action(async (opts, cmd) => {
6786
+ var metricsCommand = new Command("metrics").description("Manage metric definitions");
6787
+ metricsCommand.command("list").description("List metric definitions").requiredOption("--project-id <id>", "Project ID").action(async (opts, cmd) => {
6786
6788
  const { client, globals } = createClient(cmd);
6787
6789
  const metrics = await client.listMetrics(opts.projectId);
6788
6790
  output(globals.format, metrics, () => formatMetricsTable(metrics));
@@ -6953,7 +6955,8 @@ function formatQueryResult2(result) {
6953
6955
  }
6954
6956
  return lines.join("\n");
6955
6957
  }
6956
- var funnelsCommand = new Command("funnels").description("List funnel definitions").enablePositionalOptions().requiredOption("--project-id <id>", "Project ID").action(async (opts, cmd) => {
6958
+ var funnelsCommand = new Command("funnels").description("Manage funnel definitions");
6959
+ funnelsCommand.command("list").description("List funnel definitions").requiredOption("--project-id <id>", "Project ID").action(async (opts, cmd) => {
6957
6960
  const { client, globals } = createClient(cmd);
6958
6961
  const result = await client.listFunnels(opts.projectId);
6959
6962
  output(globals.format, result.funnels, () => formatFunnelsTable(result.funnels));
@@ -7195,7 +7198,7 @@ var switchCommand = new Command("switch").description("Switch active team profil
7195
7198
  });
7196
7199
 
7197
7200
  // src/index.ts
7198
- var program2 = new Command().name("owlmetry").version("0.1.8").description("OwlMetry CLI \u2014 query metrics and manage your apps from the terminal").addOption(
7201
+ var program2 = new Command().name("owlmetry").version("0.1.10").description("OwlMetry CLI \u2014 query metrics and manage your apps from the terminal").addOption(
7199
7202
  new Option("--format <format>", "Output format").choices(["table", "json", "log"]).default("table")
7200
7203
  ).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");
7201
7204
  program2.addCommand(authCommand);
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: owlmetry-cli
3
- version: 0.1.8
3
+ version: 0.1.10
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
@@ -116,6 +116,59 @@ OwlMetry organises resources in a `Team → Project → Apps` hierarchy:
116
116
 
117
117
  Projects group apps cross-platform: an iOS app and its backend API can share the same project, enabling unified funnel and metric analysis across both.
118
118
 
119
+ ## Command Quick Reference
120
+
121
+ Copy-paste ready. All commands support `--format json` for machine-readable output. Global flags: `--endpoint <url>`, `--api-key <key>`, `--team <name-or-id>`.
122
+
123
+ ```
124
+ # Auth
125
+ owlmetry auth send-code --email <email>
126
+ owlmetry auth verify --email <email> --code <code> --format json
127
+ owlmetry whoami --format json
128
+ owlmetry switch [<name-or-slug>]
129
+ owlmetry setup --endpoint <url> --api-key <key> [--ingest-endpoint <url>]
130
+
131
+ # Projects
132
+ owlmetry projects --format json
133
+ owlmetry projects view <id> --format json
134
+ owlmetry projects create --name <name> --slug <slug> [--team-id <id>] --format json
135
+ owlmetry projects update <id> --name <name> --format json
136
+
137
+ # Apps
138
+ owlmetry apps list [--project-id <id>] --format json
139
+ owlmetry apps view <id> --format json
140
+ owlmetry apps create --project-id <id> --name <name> --platform <platform> [--bundle-id <id>] --format json
141
+ owlmetry apps update <id> --name <name> --format json
142
+
143
+ # Metrics
144
+ owlmetry metrics list --project-id <id> --format json
145
+ owlmetry metrics view <slug> --project-id <id> --format json
146
+ owlmetry metrics create --project-id <id> --name <name> --slug <slug> [--lifecycle] [--description <desc>] --format json
147
+ owlmetry metrics update <slug> --project-id <id> [--name <name>] [--status active|paused] --format json
148
+ owlmetry metrics delete <slug> --project-id <id>
149
+ owlmetry metrics events <slug> --project-id <id> [--phase <phase>] [--user-id <id>] [--since <time>] [--until <time>] --format json
150
+ owlmetry metrics query <slug> --project-id <id> [--since <date>] [--until <date>] [--app-id <id>] [--user-id <id>] [--group-by <field>] --format json
151
+
152
+ # Funnels
153
+ owlmetry funnels list --project-id <id> --format json
154
+ owlmetry funnels view <slug> --project-id <id> --format json
155
+ owlmetry funnels create --project-id <id> --name <name> --slug <slug> --steps-file <path> [--description <desc>] --format json
156
+ owlmetry funnels update <slug> --project-id <id> --steps-file <path> --format json
157
+ owlmetry funnels delete <slug> --project-id <id>
158
+ owlmetry funnels query <slug> --project-id <id> [--since <date>] [--until <date>] [--open] [--group-by <field>] --format json
159
+
160
+ # Events
161
+ owlmetry events [--project-id <id>] [--app-id <id>] [--level <level>] [--user-id <id>] [--session-id <id>] [--since <time>] [--limit <n>] --format json
162
+ owlmetry events view <id> --format json
163
+ owlmetry investigate <eventId> [--window <minutes>] --format json
164
+
165
+ # Users
166
+ owlmetry users <app-id> [--anonymous] [--real] [--search <query>] [--limit <n>] --format json
167
+
168
+ # Audit Logs
169
+ owlmetry audit-log list --team-id <id> [--resource-type <type>] [--actor-id <id>] [--action <action>] [--since <time>] --format json
170
+ ```
171
+
119
172
  ## Resource Management
120
173
 
121
174
  ### Projects
@@ -134,8 +187,8 @@ owlmetry projects update <id> --name <new-name> --format json
134
187
  An app represents a single deployable target. The `client_key` returned on creation is what SDKs use for event ingestion. The `bundle_id` is **immutable after creation** — to change it, delete and recreate the app. Backend apps have no bundle_id.
135
188
 
136
189
  ```bash
137
- owlmetry apps --format json # List all
138
- owlmetry apps --project-id <id> --format json # List by project
190
+ owlmetry apps list --format json # List all
191
+ owlmetry apps list --project-id <id> --format json # List by project
139
192
  owlmetry apps view <id> --format json # View details
140
193
  owlmetry apps create --project-id <id> --name <name> --platform <platform> [--bundle-id <id>] --format json
141
194
  owlmetry apps update <id> --name <new-name> --format json
@@ -155,7 +208,7 @@ Metrics are project-scoped definitions that tell OwlMetry what structured data t
155
208
  The metric definition must exist on the server **before** the SDK emits events for that slug, otherwise the server will reject the events.
156
209
 
157
210
  ```bash
158
- owlmetry metrics --project-id <id> --format json # List all
211
+ owlmetry metrics list --project-id <id> --format json # List all
159
212
  owlmetry metrics view <slug> --project-id <id> --format json # View details
160
213
  owlmetry metrics create --project-id <id> --name <name> --slug <slug> [--lifecycle] [--description <desc>] --format json
161
214
  owlmetry metrics update <slug> --project-id <id> [--name <name>] [--status active|paused] --format json
@@ -177,7 +230,7 @@ Funnels support two analysis modes:
177
230
  Maximum 20 steps per funnel.
178
231
 
179
232
  ```bash
180
- owlmetry funnels --project-id <id> --format json # List all
233
+ owlmetry funnels list --project-id <id> --format json # List all
181
234
  owlmetry funnels view <slug> --project-id <id> --format json # View details
182
235
  owlmetry funnels delete <slug> --project-id <id>
183
236
  ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: owlmetry-node
3
- version: 0.1.8
3
+ version: 0.1.10
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
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: owlmetry-swift
3
- version: 0.1.8
3
+ version: 0.1.10
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
@@ -311,7 +311,45 @@ op.fail(error: "timeout", attributes: ["retry_count": "3"])
311
311
  op.cancel(attributes: ["reason": "user_cancelled"])
312
312
  ```
313
313
 
314
- `duration_ms` and `tracking_id` (UUID) are auto-added. Create the metric definition first:
314
+ `duration_ms` and `tracking_id` (UUID) are auto-added.
315
+
316
+ **Rules for lifecycle operations:**
317
+
318
+ - **Every `startOperation()` must end** with exactly one `.complete()`, `.fail()`, or `.cancel()`. An operation that starts but never ends creates orphaned metric data with no duration.
319
+ - **`.complete()`** — the operation succeeded and produced its intended result.
320
+ - **`.fail(error:)`** — the operation attempted work but encountered an error.
321
+ - **`.cancel()`** — the operation was intentionally stopped before completion (user cancelled, view disappeared, became irrelevant).
322
+ - **Don't start for no-ops** — if the operation is skipped entirely (cache hit, dedup, precondition not met), don't call `startOperation()` at all. Only start when actual work begins.
323
+ - **Don't track duration manually** — `duration_ms` is auto-calculated from start to complete/fail/cancel. Never pass a manual duration attribute.
324
+ - **Long-lived operations** — if the operation outlives the scope where it was started (e.g., recording that spans a view lifecycle), store the `OwlOperation` handle as a property. Cancel it on cleanup (`.onDisappear`, `deinit`) if it hasn't ended yet:
325
+
326
+ ```swift
327
+ // Store handle for operations that span a lifecycle
328
+ @State private var recordingOp: OwlOperation?
329
+
330
+ func startRecording() {
331
+ recordingOp = Owl.startOperation("video-recording")
332
+ // ... begin recording
333
+ }
334
+
335
+ func stopRecording(url: URL) {
336
+ recordingOp?.complete(attributes: ["format": "mp4"])
337
+ recordingOp = nil
338
+ }
339
+
340
+ func onError(_ error: Error) {
341
+ recordingOp?.fail(error: error.localizedDescription)
342
+ recordingOp = nil
343
+ }
344
+
345
+ // Safety net: cancel if view disappears mid-operation
346
+ .onDisappear {
347
+ recordingOp?.cancel()
348
+ recordingOp = nil
349
+ }
350
+ ```
351
+
352
+ Create the metric definition first:
315
353
  ```bash
316
354
  owlmetry metrics create --project-id <id> --name "Photo Upload" --slug photo-upload --lifecycle --format json
317
355
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmetry/cli",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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",