Skip to content

feat: sync charts, OAuth device login, agent JSON mode, and public hygiene - #4

Merged
ekim-amplitude merged 1 commit into
mainfrom
sync/20260724
Jul 29, 2026
Merged

feat: sync charts, OAuth device login, agent JSON mode, and public hygiene#4
ekim-amplitude merged 1 commit into
mainfrom
sync/20260724

Conversation

@ekim-amplitude

@ekim-amplitude ekim-amplitude commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Single squashed sync of developer-cli/ from monorepo amplitude/javascript@1b44da248692 (master).

Brings @amplitude/developer-cli up to date with charts, OAuth device-flow login, agent/JSON output mode, public-hygiene fixes, and removal of client-side telemetry for v1.

Source

Field Value
Monorepo amplitude/javascript
Commit 1b44da248692
Branch master
Path server/packages/api-server/developer-cli

What ships

Analytics & API surface (MCP-472)

  • Charts commands: amp charts list, get, query
  • Regenerated OpenAPI bundle + CLI manifest
  • Default device-login scopes include read:analytics

Auth & agent workflow

  • Split device login: amp auth login start / amp auth login poll with pending-login store
  • JSON envelopes on stdout; exit 75 for still-pending polls
  • Optional --profile (defaults to default); --region us|eu for prod targeting
  • --force for cross-region retargets; logout/list/status JSON paths
  • --env / --base-url: hidden from help and usage errors but still functional

Public hygiene & telemetry (MCP-431)

  • No monorepo paths, Hydra client IDs, SecEng ops, or internal product jargon in synced docs/OpenAPI
  • No client-side telemetry in v1: no Amp-Device-Id, no state.json, no opt-out env vars (security team decision)
  • Enforced by monorepo check:developer-cli-external-ready before sync

External-only

  • Add fastest-levenshtein to package.json (monorepo dependency parity)

Verification

pnpm install
HOME=/tmp/amp-cli-verify pnpm test          # 415/415 passed
pnpm test:typescript                        # OK
pnpm build                                  # OK
npm pack --dry-run                          # OK

Synced with pnpm sync:developer-cli-external … --verify after internal merges through #138644.

Release notes (draft)

feat: charts commands, OAuth device-flow login, agent/JSON output mode, read:analytics in default login scopes, and public-hygiene cleanup for npm publish.


Note

High Risk
Large auth and credential-resolution changes (split device flow, region targeting, pending store, profile defaults) are security-sensitive despite broad tests; new chart query paths also hit live analytics APIs.

Overview
Adds saved chart support via regenerated OpenAPI/manifest: amp charts list, get, and query (read:analytics), plus doc/smoke updates for the new surface.

Reworks authentication for agents and scripts: amp auth login start / poll with a pending-login store, JSON {status,message,…} on stdout, exit 75 when still pending, and bounded polling via --timeout. Interactive login/PAT paths now default --profile to default, require --region us|eu for new profiles (docs de-emphasize --env/--base-url), support --force for cross-region retargets, and clear stranded pending logins on logout or completed auth. auth list / status gain JSON output; status uses resolver CliError exit codes consistently.

CLI ergonomics: global flags are split so auth-only flags are rejected on API commands; unknown options get “did you mean” hints (fastest-levenshtein); AGENTS.md documents command-change guardrails. Default device-login scopes add read:analytics; EU PAT links use app.eu.amplitude.com.

Reviewed by Cursor Bugbot for commit 68f4422. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Internal monorepo path in docs
    • Replaced the internal monorepo file path with product-neutral wording about updating the OAuth client allowlist in Amplitude's backend configuration.

Create PR

Or push these changes by commenting:

@cursor push bed6d983ca
Preview (bed6d983ca)
diff --git a/docs/cli.md b/docs/cli.md
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -83,8 +83,8 @@
 Route-level scopes are defined on each OpenAPI operation (`x-required-scopes`).
 
 When adding new CLI scopes, the Hydra device client allowlist must be updated
-out-of-band (client IDs in `server/packages/api-server/src/oauthConfig.ts`)
-before default login can request them.
+out-of-band in Amplitude's backend OAuth client configuration before default
+login can request them.
 
 ## Global flags

You can send follow-ups to the cloud agent here.

Comment thread docs/cli.md Outdated
@ekim-amplitude

Copy link
Copy Markdown
Collaborator Author

@cursor push bed6d98

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Profile creation error omits flags
    • Updated the loginBaseUrl usage error to list --region, --env, and --base-url as valid options for creating a profile.

Create PR

Or push these changes by commenting:

@cursor push 9b65af7650
Preview (9b65af7650)
diff --git a/src/auth-commands.ts b/src/auth-commands.ts
--- a/src/auth-commands.ts
+++ b/src/auth-commands.ts
@@ -122,7 +122,9 @@
   if (args.existing) {
     return args.existing.base_url;
   }
-  throw usageError('Creating a profile requires --region <us|eu>.');
+  throw usageError(
+    'Creating a profile requires --region <us|eu>, --env, or --base-url <url>.',
+  );
 }
 
 /**

You can send follow-ups to the cloud agent here.

Comment thread src/auth-commands.ts
@ekim-amplitude ekim-amplitude changed the title Sync from amplitude/javascript@73e884bc2a6 Sync from amplitude/javascript@42230fcc19fb Jul 24, 2026
@ekim-amplitude ekim-amplitude changed the title Sync from amplitude/javascript@42230fcc19fb feat: sync developer-cli from amplitude/javascript@42230fcc19fb Jul 24, 2026
Comment thread docs/cli.md Outdated
Comment thread openapi/bundled/openapi.bundled.yaml Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: OpenAPI leaks internal product names
    • Removed Nova/Dash product names and internal type identifiers from the Chart definition and ChartType descriptions in both bundled OpenAPI files, replacing them with public-facing copy that still documents the unknown mapping behavior.

Create PR

Or push these changes by commenting:

@cursor push da593148ef
Preview (da593148ef)
diff --git a/openapi/bundled/openapi.bundled.json b/openapi/bundled/openapi.bundled.json
--- a/openapi/bundled/openapi.bundled.json
+++ b/openapi/bundled/openapi.bundled.json
@@ -2370,13 +2370,13 @@
           "definition": {
             "type": "object",
             "additionalProperties": true,
-            "description": "Read-only chart definition. Returned only when `include_definition=true`\non GET chart. Shape is unstable and may change with Nova/Dash versions;\nnot intended for authoring.\n"
+            "description": "Read-only chart definition. Returned only when `include_definition=true`\non GET chart. Shape is unstable and may change over time; not intended\nfor authoring.\n"
           }
         }
       },
       "ChartType": {
         "type": "string",
-        "description": "Public chart type discriminator (snake_case). Maps from internal Dash types\n(e.g. `eventsSegmentation` → `event_segmentation`). All values may appear on\nlist/get; query returns `422` (`unsupported_chart_type`) for types outside\nthe v1 supported matrix.\n\nInternal-only or deprecated Dash types (e.g. `asql`, `eventsLog`) are not\nexposed on the public wire; those charts surface as `unknown`.\n\nNew chart types may be added over time. An internal type the adapter cannot\nmap is surfaced as `unknown` rather than failing the response, so the wire\nvalue is always one of the members below. Clients should treat `unknown` as\n\"a chart type this API version does not model yet\".\n",
+        "description": "Public chart type discriminator (snake_case). All values may appear on\nlist/get; query returns `422` (`unsupported_chart_type`) for types outside\nthe v1 supported matrix.\n\nUnsupported chart types surface as `unknown` on the public wire.\n\nNew chart types may be added over time. A chart type this API version does not\nrecognize is surfaced as `unknown` rather than failing the response, so the wire\nvalue is always one of the members below. Clients should treat `unknown` as\n\"a chart type this API version does not model yet\".\n",
         "enum": [
           "event_segmentation",
           "sessions",

diff --git a/openapi/bundled/openapi.bundled.yaml b/openapi/bundled/openapi.bundled.yaml
--- a/openapi/bundled/openapi.bundled.yaml
+++ b/openapi/bundled/openapi.bundled.yaml
@@ -1833,23 +1833,21 @@
           additionalProperties: true
           description: |
             Read-only chart definition. Returned only when `include_definition=true`
-            on GET chart. Shape is unstable and may change with Nova/Dash versions;
-            not intended for authoring.
+            on GET chart. Shape is unstable and may change over time; not intended
+            for authoring.
     ChartType:
       type: string
       description: |
-        Public chart type discriminator (snake_case). Maps from internal Dash types
-        (e.g. `eventsSegmentation` → `event_segmentation`). All values may appear on
+        Public chart type discriminator (snake_case). All values may appear on
         list/get; query returns `422` (`unsupported_chart_type`) for types outside
         the v1 supported matrix.
 
-        Internal-only or deprecated Dash types (e.g. `asql`, `eventsLog`) are not
-        exposed on the public wire; those charts surface as `unknown`.
+        Unsupported chart types surface as `unknown` on the public wire.
 
-        New chart types may be added over time. An internal type the adapter cannot
-        map is surfaced as `unknown` rather than failing the response, so the wire
-        value is always one of the members below. Clients should treat `unknown` as
-        "a chart type this API version does not model yet".
+        New chart types may be added over time. A chart type this API version does
+        not recognize is surfaced as `unknown` rather than failing the response, so
+        the wire value is always one of the members below. Clients should treat
+        `unknown` as "a chart type this API version does not model yet".
       enum:
         - event_segmentation
         - sessions

You can send follow-ups to the cloud agent here.

Comment thread openapi/bundled/openapi.bundled.json Outdated
@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Internal OAuth ops leaked in docs
    • Removed the Hydra OAuth client ID and SecEng coordination paragraph from docs/cli.md since it was internal contributor guidance not actionable for public package users.
  • ✅ Fixed: Internal product jargon in OpenAPI
    • Rewrote charts-related descriptions in the bundled OpenAPI spec to use public-facing language, removing references to Nova/Dash, DAC-filtered, asql/eventsLog, and Tier 2 allowlist.

Create PR

Or push these changes by commenting:

@cursor push d4aa2c8719
Preview (d4aa2c8719)
diff --git a/docs/cli.md b/docs/cli.md
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -82,12 +82,6 @@
 
 Route-level scopes are defined on each OpenAPI operation (`x-required-scopes`).
 
-When adding new CLI scopes, register them on the Hydra device-flow OAuth client
-for each target environment (for example `amplitude-developer-api-device-staging`
-on staging, `amplitude-developer-api-v0` on prod). This is an out-of-band Hydra
-admin change — coordinate with SecEng before shipping CLI changes that request
-new scopes by default.
-
 ## Global flags
 
 | Flag / env                              | Purpose                                    |

diff --git a/openapi/bundled/openapi.bundled.json b/openapi/bundled/openapi.bundled.json
--- a/openapi/bundled/openapi.bundled.json
+++ b/openapi/bundled/openapi.bundled.json
@@ -1414,7 +1414,7 @@
         "tags": ["Analytics"],
         "operationId": "queryChart",
         "summary": "Query chart",
-        "description": "Computes and returns normalized results for a saved chart. v1 supports\n`event_segmentation`, `sessions`, `funnels`, and `retention` chart types;\nother chart types return `422` with `error_code: unsupported_chart_type`.\nResults are DAC-filtered for the authenticated caller.\n\nThis POST computes a result and does not mutate state. It is therefore a\nread operation and does not require an `Idempotency-Key`.\n\nOmitting `time_range` uses the chart's saved range; if the chart has no\nsaved range, the server defaults to the last 30 days.\n\nQuery is synchronous with bounded defaults. Expensive queries may return\n`504` when exceeding the server timeout; async query jobs are planned for\na follow-up slice. Retryable responses (`429`, `502`, `504`) populate\n`retry_after_seconds` in the problem body when a delay is advised.\n",
+        "description": "Computes and returns normalized results for a saved chart. v1 supports\n`event_segmentation`, `sessions`, `funnels`, and `retention` chart types;\nother chart types return `422` with `error_code: unsupported_chart_type`.\nResults respect the authenticated caller's chart access permissions.\n\nThis POST computes a result and does not mutate state. It is therefore a\nread operation and does not require an `Idempotency-Key`.\n\nOmitting `time_range` uses the chart's saved range; if the chart has no\nsaved range, the server defaults to the last 30 days.\n\nQuery is synchronous with bounded defaults. Expensive queries may return\n`504` when exceeding the server timeout; async query jobs are planned for\na follow-up slice. Retryable responses (`429`, `502`, `504`) populate\n`retry_after_seconds` in the problem body when a delay is advised.\n",
         "x-required-scopes": ["read:analytics"],
         "requestBody": {
           "required": false,
@@ -2370,13 +2370,13 @@
           "definition": {
             "type": "object",
             "additionalProperties": true,
-            "description": "Read-only chart definition. Returned only when `include_definition=true`\non GET chart. Shape is unstable and may change with Nova/Dash versions;\nnot intended for authoring.\n"
+            "description": "Read-only chart definition. Returned only when `include_definition=true`\non GET chart. Shape is unstable and may change between API versions;\nnot intended for authoring.\n"
           }
         }
       },
       "ChartType": {
         "type": "string",
-        "description": "Public chart type discriminator (snake_case). Maps from internal Dash types\n(e.g. `eventsSegmentation` → `event_segmentation`). All values may appear on\nlist/get; query returns `422` (`unsupported_chart_type`) for types outside\nthe v1 supported matrix.\n\nInternal-only or deprecated Dash types (e.g. `asql`, `eventsLog`) are not\nexposed on the public wire; those charts surface as `unknown`.\n\nNew chart types may be added over time. An internal type the adapter cannot\nmap is surfaced as `unknown` rather than failing the response, so the wire\nvalue is always one of the members below. Clients should treat `unknown` as\n\"a chart type this API version does not model yet\".\n",
+        "description": "Public chart type discriminator (snake_case). All values may appear on\nlist/get; query returns `422` (`unsupported_chart_type`) for types outside\nthe v1 supported matrix.\n\nCharts whose type is not modeled in this API version surface as `unknown`\nrather than failing the response.\n\nNew chart types may be added over time. Clients should treat `unknown` as\n\"a chart type this API version does not model yet\".\n",
         "enum": [
           "event_segmentation",
           "sessions",
@@ -2396,7 +2396,7 @@
       },
       "ChartQueryRequest": {
         "type": "object",
-        "description": "v1 query parameters. Filter and group-by overrides are intentionally omitted\nuntil Tier 2 allowlist validation is defined.\n",
+        "description": "v1 query parameters. Filter and group-by overrides are intentionally omitted\nuntil override validation is supported in a future version.\n",
         "properties": {
           "time_range": {
             "$ref": "#/components/schemas/TimeRange"

diff --git a/openapi/bundled/openapi.bundled.yaml b/openapi/bundled/openapi.bundled.yaml
--- a/openapi/bundled/openapi.bundled.yaml
+++ b/openapi/bundled/openapi.bundled.yaml
@@ -1028,7 +1028,7 @@
         Computes and returns normalized results for a saved chart. v1 supports
         `event_segmentation`, `sessions`, `funnels`, and `retention` chart types;
         other chart types return `422` with `error_code: unsupported_chart_type`.
-        Results are DAC-filtered for the authenticated caller.
+        Results respect the authenticated caller's chart access permissions.
 
         This POST computes a result and does not mutate state. It is therefore a
         read operation and does not require an `Idempotency-Key`.
@@ -1833,22 +1833,19 @@
           additionalProperties: true
           description: |
             Read-only chart definition. Returned only when `include_definition=true`
-            on GET chart. Shape is unstable and may change with Nova/Dash versions;
+            on GET chart. Shape is unstable and may change between API versions;
             not intended for authoring.
     ChartType:
       type: string
       description: |
-        Public chart type discriminator (snake_case). Maps from internal Dash types
-        (e.g. `eventsSegmentation` → `event_segmentation`). All values may appear on
+        Public chart type discriminator (snake_case). All values may appear on
         list/get; query returns `422` (`unsupported_chart_type`) for types outside
         the v1 supported matrix.
 
-        Internal-only or deprecated Dash types (e.g. `asql`, `eventsLog`) are not
-        exposed on the public wire; those charts surface as `unknown`.
+        Charts whose type is not modeled in this API version surface as `unknown`
+        rather than failing the response.
 
-        New chart types may be added over time. An internal type the adapter cannot
-        map is surfaced as `unknown` rather than failing the response, so the wire
-        value is always one of the members below. Clients should treat `unknown` as
+        New chart types may be added over time. Clients should treat `unknown` as
         "a chart type this API version does not model yet".
       enum:
         - event_segmentation
@@ -1869,7 +1866,7 @@
       type: object
       description: |
         v1 query parameters. Filter and group-by overrides are intentionally omitted
-        until Tier 2 allowlist validation is defined.
+        until override validation is supported in a future version.
       properties:
         time_range:
           $ref: '#/components/schemas/TimeRange'

You can send follow-ups to the cloud agent here.

@ekim-amplitude ekim-amplitude changed the title feat: sync developer-cli from amplitude/javascript@42230fcc19fb feat: sync developer-cli from amplitude/javascript@083b16f59710 Jul 27, 2026
Mirror monorepo developer-cli/ at 1b44da24869290a2a4f10ca3d4fbdc3228ada2e7.

Includes:
- MCP-472 charts commands and read:analytics in default OAuth scopes
- BA-426/BA-444 agent device login (start/poll) and JSON output mode
- MCP-431 external sync guards, public hygiene, no client-side telemetry (v1)
- fastest-levenshtein dependency for CLI error hints

Monorepo: 1b44da24869290a2a4f10ca3d4fbdc3228ada2e7
Checks: pnpm check:developer-cli-external-ready, sync --verify (415 tests)
Co-authored-by: Cursor <cursoragent@cursor.com>
@ekim-amplitude ekim-amplitude changed the title feat: sync developer-cli from amplitude/javascript@083b16f59710 feat: sync developer-cli from amplitude/javascript@1b44da248692 Jul 29, 2026
@ekim-amplitude ekim-amplitude changed the title feat: sync developer-cli from amplitude/javascript@1b44da248692 feat: sync charts, OAuth device login, agent JSON mode, and public hygiene Jul 29, 2026
@bird-m

bird-m commented Jul 29, 2026

Copy link
Copy Markdown

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 68f4422. Configure here.

@ekim-amplitude
ekim-amplitude merged commit ce7ed11 into main Jul 29, 2026
3 checks passed
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