Skip to content

feat(cli): add datasets, monitors, query, and ingest commands with edge-aware routing#280

Open
njpatel wants to merge 7 commits intomainfrom
njpatel/cli-updates
Open

feat(cli): add datasets, monitors, query, and ingest commands with edge-aware routing#280
njpatel wants to merge 7 commits intomainfrom
njpatel/cli-updates

Conversation

@njpatel
Copy link
Member

@njpatel njpatel commented Mar 8, 2026

axiom-cli-pr-demo

New Command Breakdown

  • axiom datasets list - list datasets with key metadata (including region).
  • axiom datasets get <name> - fetch dataset metadata for one dataset.
  • axiom datasets schema <name> - show dataset fields/types.
  • axiom datasets sample <name> - return a small recent sample.
  • axiom monitors list - list monitors with monitor ID, status, recent run, type, dataset, and frequency.
  • axiom monitors get <id> - fetch one monitor’s details.
  • axiom monitors history <id> - fetch execution history for a monitor.
  • axiom query "<apl>" - run APL directly (no query run subcommand).
  • axiom query --file <path> and axiom query --stdin - alternate query input modes.
  • axiom query --since <time> --until <time> - pass time bounds through to API (relative or absolute).
  • axiom query --format <auto|table|csv|json|ndjson|jsonl|mcp> - multiple output modes.
  • axiom query --edge-url <url> --api-token <token> - per-call edge/token overrides.
  • axiom ingest <dataset> - ingest JSON/NDJSON/CSV into a dataset.
  • axiom ingest --file <path...> - ingest one or more files (or - for stdin).
  • axiom ingest --content-type <json|ndjson|csv> and axiom ingest --content-encoding <identity|gzip|zstd>.
  • axiom ingest --edge-url <url> --api-token <token> - ingest without relying on local auth profile.

No dashboards because they are working on some v2 stuff

Recommended review approach

This PR was intentionally restacked into 7 commits so review can happen from foundation to features.

  1. Review in commit order (origin/main..HEAD), not “Files changed” all at once.
  2. Validate each commit independently (scope, tests, behavior).
  3. Focus deep review on API client routing/auth and query row normalization (highest risk).

Commit map (base → feature)

  1. 0512c01 — CLI core runtime and framework
    packages/ai/src/bin.ts, packages/ai/src/cli/program.ts, packages/ai/src/cli/registerCliCommands.ts, packages/ai/
    src/cli/commandSpec.ts, packages/ai/src/cli/withCliContext.ts, packages/ai/src/cli/config/, packages/ai/src/
    cli/format/
    , packages/ai/src/cli/time/range.ts, base CLI test harness/help/config tests.
  2. 005e5f6 — API layer and edge routing
    packages/ai/src/cli/api/http.ts, packages/ai/src/cli/api/binding.ts, packages/ai/src/cli/api/client.ts,
    packages/ai/src/cli/utils/type-guards.ts, packages/ai/test/cli/api-client.test.ts.
  3. 20fa7f0 — Query command and row normalization
    packages/ai/src/cli/commands/queryRun.ts, packages/ai/src/cli/commands/queryRows.ts, related query tests.
  4. b316a36 — Datasets + monitors read commands
    packages/ai/src/cli/commands/datasets.ts, packages/ai/src/cli/commands/monitors.ts, related tests.
  5. f0fcb73 — Ingest command
    packages/ai/src/cli/commands/ingest.ts, ingest tests.
  6. 5fdc85e — Completion generation + CI/docs/release wiring
    packages/ai/src/cli/commands/completion.command.ts, packages/ai/src/cli/gen/generateArtifacts.ts, packages/ai/
    generated/completions/*, packages/ai/package.json, root package.json, packages/ai/README.md, .github/workflows/
    ci.yaml, pnpm-lock.yaml.
  7. c4340f8 — Tiny repo chore
    .gitignore (/prds ignore).

High-risk areas to verify

  • Edge query routing and fallback behavior in packages/ai/src/cli/api/client.ts.
  • --api-token override applied consistently on both edge and legacy query paths.
  • Query normalization in packages/ai/src/cli/commands/queryRows.ts (no data-shape corruption).
  • Monitor history timestamp alias handling in packages/ai/src/cli/commands/monitors.ts.
  • Ingest Content-Type MIME mapping (json, ndjson, csv) in packages/ai/src/cli/api/client.ts.
  • Completion artifacts in sync with command spec (pnpm check:gen).

Scope note

This PR is CLI-focused (packages/ai/src/cli/**, supporting tests/docs/workflow) and does not change core OTEL
instrumentation behavior.


Note

High Risk
Touches core CLI execution flow and introduces new request routing/auth override behavior (including disk-cached edge endpoint selection), which can impact correctness and user access across environments.

Overview
Adds a new spec-driven Axiom CLI surface in packages/ai with first-class datasets, monitors, query, and ingest commands, plus standardized output modes (table/csv/json/ndjson/mcp), --explain tracing, and unified config/env resolution.

Introduces a new HTTP/API client with edge-aware query routing (dataset→region→edge endpoint lookup with in-memory+disk caching, env-tunable TTLs, and fallback to legacy query endpoints), supports per-call --edge-url/--api-token overrides, and normalizes varied API response shapes for datasets, fields, and monitor history.

Adds generated shell completion artifacts (with a generator + completion command), wires check:gen into CI, expands package scripts/exports, and adds comprehensive Vitest coverage for client routing and CLI command/output contracts.

Written by Cursor Bugbot for commit bd322ea. This will update automatically on new commits. Configure here.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 8, 2026

Open in StackBlitz

npm i https://pkg.pr.new/axiom@280

commit: afc55af

@njpatel njpatel force-pushed the njpatel/cli-updates branch from c4340f8 to bd322ea Compare March 8, 2026 21:34
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@@ -0,0 +1,281 @@
const isObject = (value: unknown): value is Record<string, unknown> =>
typeof value === 'object' && value !== null;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isObject treats arrays as objects, corrupting flattened rows

High Severity

The isObject type guard returns true for arrays since typeof [] === 'object'. In flattenLegacyEnvelope, if a row has standard Axiom metadata fields (_sysTime/_rowId) AND an array-valued field named data, fields, or row, the function incorrectly detects it as a legacy envelope. The array is then spread into the output object, producing numeric-keyed garbage (e.g., {"0": 1, "1": 2}) while discarding the original field — a silent data-shape corruption. The fix is to add && !Array.isArray(value) to isObject.

Additional Locations (1)

Fix in Cursor Fix in Web

Authorization: `Bearer ${config.token}`,
'Content-Type': 'application/json',
...(options.headers ?? {}),
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default Content-Type header sent on GET requests

Low Severity

requestJson unconditionally sets Content-Type: application/json in the headers, even for GET requests that carry no body. While most servers ignore it, some proxies or API gateways may reject or log warnings for GET requests with a Content-Type header, since it violates the HTTP semantics expectation that Content-Type describes a present body. The header construction could be conditional on the request method or presence of a body.

Fix in Cursor Fix in Web

endTime: timeRange.end,
});

const rows = response.data.matches ?? [];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

datasetSample skips toQueryRows row normalization

Medium Severity

datasetSample reads response.data.matches directly instead of using toQueryRows for normalization. This bypasses flattenLegacyEnvelope, so sample results that include legacy envelope-wrapped rows (with _sysTime/_rowId metadata and nested data objects) would display the raw envelope structure. The queryRun command normalizes through toQueryRows, creating an inconsistency between axiom datasets sample and axiom query for identical data.

Fix in Cursor Fix in Web

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have logic for axiom.config.ts, we can re-use that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering whats the reason behind not using axiom-js? It already has a client that is always updated and supports multiple APIs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants