Skip to content

feat: sync developer-cli from amplitude/javascript@42230fcc19fb#4

Open
ekim-amplitude wants to merge 4 commits into
mainfrom
sync/20260724
Open

feat: sync developer-cli from amplitude/javascript@42230fcc19fb#4
ekim-amplitude wants to merge 4 commits into
mainfrom
sync/20260724

Conversation

@ekim-amplitude

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

Copy link
Copy Markdown
Collaborator

Summary

External vendoring sync for @amplitude/developer-cli, mirroring server/packages/api-server/developer-cli/ from monorepo amplitude/javascript@42230fcc19fb (master, post–#138033 merge).

This PR catches up the standalone repo with charts + OAuth device flow + agent output mode (MCP-472) and applies MCP-431 portability fixes for synced docs (no monorepo paths in Hydra scope guidance).

Source

Field Value
Monorepo amplitude/javascript
Commit 42230fcc19fb
Branch master
Path server/packages/api-server/developer-cli
Internal PR javascript#138033 (MCP-431)
Linear MCP-431

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 (removed LOGIN_SCOPE_EXCLUSIONS)

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
  • Auth-only globals rejected on API commands; unknown flags get “did you mean” hints
  • --env / --base-url: hidden from help but still functional (smoke scripts, local dev) — create-profile errors only mention --region

Portability (MCP-431 / #138033)

  • docs/cli.md: Hydra scope guidance uses public client IDs (amplitude-developer-api-device-staging, amplitude-developer-api-v0) — no monorepo file paths

External-only fixes

  • Add missing fastest-levenshtein dependency (required by monorepo; sync enforces parity)

Commits on this branch

  1. dddcf17 — bulk sync from 73e884bc2a6 (MCP-472 baseline)
  2. a82de60 — interim docs fix (superseded by monorepo wording in fbc1d35)
  3. fbc1d35 — sync from 42230fcc19fb (MCP-431 docs portability)
  4. Latest — revert visible --env/--base-url in loginBaseUrl usage errors

Verification

Synced with bash scripts/sync-developer-cli-external.sh … --verify from internal api-server after pulling master.

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

Use isolated HOME if local ~/.amplitude/amp/credentials.json would interfere with auth tests.

Release notes (draft)

feat: charts commands, OAuth device-flow login, agent/JSON output mode, and read:analytics in default login scopes. External docs use portable Hydra client IDs (MCP-431).


Note

High Risk
Large auth and credential-store changes (device flow, pending state, profile defaults, scope expansion) plus new analytics API commands affect how every user and agent authenticates and calls prod APIs.

Overview
Vendoring sync that expands amp with an Analytics/charts surface and a reworked auth story aimed at agents and simpler defaults.

Charts: OpenAPI adds list/get/query chart endpoints (read:analytics); the generated manifest exposes amp charts list, get, and query, with catalog/help/smoke docs updated accordingly. Default OAuth login scopes now include read:analytics.

Auth & profiles: Docs and flows shift from naming every profile/--env to --region us|eu and an implicit default profile (--profile optional). amp auth login start / poll implement a two-phase device flow with a pending-login store, JSON envelopes on stdout, exit 75 while authorization is still pending, and --timeout / --force for retargeting. Interactive login, pat, list, status, and logout gain JSON paths, region labels, pending-login cleanup, and stricter CliError / usage handling. Auth-only globals are rejected on API commands; unknown flags get “did you mean” hints via fastest-levenshtein.

Docs & guardrails: README/cli docs de-emphasize --base-url/--env for end users; AGENTS.md documents the command-change checklist and device-flow stdout exception. EU app links use app.eu.amplitude.com; Hydra scope guidance uses portable client IDs.

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

Mirror monorepo developer-cli through MCP-472 (read:analytics default
login scopes), charts commands, OAuth device flow, and agent output mode.

- Add fastest-levenshtein to package.json (dependency drift fix)
- Verified: pnpm test (423), test:typescript, build, npm pack

Co-authored-by: Cursor <cursoragent@cursor.com>

@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

Replace reference to server/packages/api-server/src/oauthConfig.ts with
product-neutral wording about backend OAuth client configuration.

Applied via @cursor push command

@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
Includes MCP-431 external sync guards and portability fixes (#138033):
- docs/cli.md: portable Hydra client IDs (no monorepo paths)
- auth-commands.ts: loginBaseUrl error mentions --region, --env, --base-url
- auth-login.test.ts: updated assertion

Supersedes partial docs fix in a82de60 with canonical monorepo wording.

Monorepo: 42230fcc19fb7e1d983c0b2d5ce51a70426af534
Verified: pnpm test (423), typecheck, build, pack
Co-authored-by: Cursor <cursoragent@cursor.com>
@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
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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Internal OAuth ops leaked in docs

Medium Severity

New docs tell public readers to register scopes on internal Hydra OAuth client IDs (amplitude-developer-api-device-staging, amplitude-developer-api-v0) and to coordinate with SecEng. That leaks internal infrastructure names and org process into the published package docs, which violates the public-hygiene review rule.

Fix in Cursor Fix in Web

Triggered by project rule: Bugbot review guide — @amplitude/developer-cli

Reviewed by Cursor Bugbot for commit fbc1d35. Configure here.

type: object
description: |
v1 query parameters. Filter and group-by overrides are intentionally omitted
until Tier 2 allowlist validation is defined.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Internal product jargon in OpenAPI

Medium Severity

New charts OpenAPI copy references internal systems and planning terms (Nova/Dash, internal Dash types, asql/eventsLog, DAC-filtered, Tier 2 allowlist). Those details are not meaningful to external API consumers and leak internal product context from the published bundled spec.

Additional Locations (2)
Fix in Cursor Fix in Web

Triggered by project rule: Bugbot review guide — @amplitude/developer-cli

Reviewed by Cursor Bugbot for commit fbc1d35. Configure here.

--env and --base-url are hidden but functional (omitted from help); only
--region should appear in user-facing create-profile errors.

Reverts the MCP-431 error-message expansion while keeping portable docs.

Co-authored-by: Cursor <cursoragent@cursor.com>

@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).

Fix All in Cursor

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.

Reviewed by Cursor Bugbot for commit 26e1ff0. Configure here.

},
"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",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

OpenAPI leaks internal product names

Low Severity

New Chart schema copy references internal Nova/Dash product names and internal Dash type identifiers. That leaks internal tooling context in a public OpenAPI bundle, which the public-hygiene rule asks reviewers to flag.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: Bugbot review guide — @amplitude/developer-cli

Reviewed by Cursor Bugbot for commit 26e1ff0. Configure here.

@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.

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.

3 participants