From df7875b2387d5c119c3f46733f028561cde3eef1 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 23 Jun 2026 00:18:33 +0000 Subject: [PATCH] feat: sync CLI with dashboard@v1.3.0 Bump @photon-ai/dashboard-api 1.2.0 -> 1.3.0 and reconcile the two type errors introduced by the upstream type-contract simplification: - src/commands/projects.ts: list response now opaque, cast to Project[] - src/commands/spectrum/users.ts: users page now opaque, cast to SpectrumUsersPage (and drop local SpectrumUser duplicate) Add Project, SpectrumUser, and SpectrumUsersPage DTOs in src/lib/types.ts (per AGENTS.md: new DTOs live in types.ts, cast at the API boundary). Refresh UPSTREAM_DIFF.md for the 1.2.0 -> 1.3.0 delta. No new runtime dependencies, no snapshot changes. Co-authored-by: citron --- UPSTREAM_DIFF.md | 52 ++++++++++++++-------------------- bun.lock | 5 ++-- package.json | 2 +- src/commands/projects.ts | 3 +- src/commands/spectrum/users.ts | 12 ++------ src/lib/types.ts | 35 ++++++++++++++++++++++- 6 files changed, 64 insertions(+), 45 deletions(-) diff --git a/UPSTREAM_DIFF.md b/UPSTREAM_DIFF.md index 7e7d390..57c78c6 100644 --- a/UPSTREAM_DIFF.md +++ b/UPSTREAM_DIFF.md @@ -1,44 +1,34 @@ # Upstream API Diff -> Old routes: 36 ยท New routes: 58 +> `@photon-ai/dashboard-api` `1.2.0` โ†’ `1.3.0` (dashboard `v1.3.0`) ## Added Routes | Route | Method | |-------|--------| -| `api.profile.spectrum-updates` | `PATCH` | -| `api.projects.:id.members` | `GET` | -| `api.projects.:id.members` | `POST` | -| `api.projects.:id.members.:memberUserId` | `DELETE` | -| `api.projects.:id.slack` | `DELETE` | -| `api.projects.:id.slack` | `GET` | -| `api.projects.:id.slack` | `PUT` | -| `api.projects.:id.slack.installations` | `GET` | -| `api.projects.:id.slack.installations.:teamId` | `DELETE` | -| `api.projects.:id.spectrum.avatar` | `DELETE` | -| `api.projects.:id.spectrum.avatar.commit` | `POST` | -| `api.projects.:id.spectrum.avatar.upload` | `POST` | -| `api.projects.:id.voice.imessage-enabled` | `PATCH` | -| `api.projects.:id.voice.settings` | `GET` | -| `api.projects.:id.voice.sip-inbound` | `DELETE` | -| `api.projects.:id.voice.sip-inbound` | `PATCH` | -| `api.projects.:id.webhooks` | `GET` | -| `api.projects.:id.webhooks` | `POST` | -| `api.projects.:id.webhooks.:webhookId` | `DELETE` | -| `api.projects.:id.whatsapp.templates` | `GET` | -| `api.projects.:id.whatsapp.templates` | `POST` | -| `api.projects.:id.whatsapp.templates.:templateId` | `DELETE` | -| `api.projects.:id.whatsapp.templates.:templateId` | `PATCH` | +| `api.profile.promotional-status` | `GET` | +| `api.profile.promotional-emails` | `PATCH` | ## Removed Routes -| Route | Method | -|-------|--------| -| `api.projects.:id.spectrum.avatar-upload-url` | `GET` | +_(none)_ + +## Schema Changes + +The 1.3.0 type-contract drop dropped every named response interface +(`SpectrumUser`, `WhatsAppTemplate`, etc.) and degraded most route response +bodies to opaque records (`{ [x: string]: any; ... }`). Two CLI list commands +relied on the previously inferred Eden treaty types and now need explicit +casts at the API boundary: + +- `src/commands/projects.ts` โ€” `GET /api/projects` (list) +- `src/commands/spectrum/users.ts` โ€” `GET /api/projects/:id/spectrum/users` + +DTOs added in `src/lib/types.ts`: `Project`, `SpectrumUser`, `SpectrumUsersPage`. ## Summary -- **23** added -- **1** removed -- **0** changed -- **35** unchanged +- **2** added +- **0** removed +- **0** otherwise changed +- All other routes unchanged at the route level; response typing degraded across the board (see Schema Changes) diff --git a/bun.lock b/bun.lock index 748dba3..7e7bbea 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "dashboard-cli", @@ -15,7 +16,7 @@ "update-notifier": "^7.3.1", }, "devDependencies": { - "@photon-ai/dashboard-api": "1.2.0", + "@photon-ai/dashboard-api": "1.3.0", "@types/bun": "latest", "@types/node": "^25.6.2", "@types/update-notifier": "^6.0.8", @@ -49,7 +50,7 @@ "@noble/hashes": ["@noble/hashes@2.2.0", "", {}, "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg=="], - "@photon-ai/dashboard-api": ["@photon-ai/dashboard-api@1.2.0", "", { "peerDependencies": { "@elysiajs/eden": "^1.4.9", "elysia": "^1.4.28" } }, "sha512-ZQ4OVaGQMFVMa2/bL2OfRxMaQDABwi+tHUFQHmQOH39N7pCXC6vQ8m32+Its2FxQ5VwU+dyvqmyv0ccxCmK8hw=="], + "@photon-ai/dashboard-api": ["@photon-ai/dashboard-api@1.3.0", "", { "peerDependencies": { "@elysiajs/eden": "^1.4.9", "elysia": "^1.4.28" } }, "sha512-qGC/0lzxk6c6akoaVwvFpJZpc6WPdsq7oft2OJV2AsWbEWYTwVOAC4oWwxZ3919VX/ZcvKf8HZkSNLaIgkFvmA=="], "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], diff --git a/package.json b/package.json index 6da0c0c..c51d3e0 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "prepublishOnly": "bun run typecheck && bun run build" }, "devDependencies": { - "@photon-ai/dashboard-api": "1.2.0", + "@photon-ai/dashboard-api": "1.3.0", "@types/bun": "latest", "@types/node": "^25.6.2", "@types/update-notifier": "^6.0.8", diff --git a/src/commands/projects.ts b/src/commands/projects.ts index a75c993..4ab3da8 100644 --- a/src/commands/projects.ts +++ b/src/commands/projects.ts @@ -20,6 +20,7 @@ import { SessionExpiredError } from "~/lib/errors.ts"; import { confirmDestructive } from "~/lib/interactive.ts"; import { c, die, formatApiError, printJson, printTable } from "~/lib/output.ts"; import { isInteractive } from "~/lib/tty.ts"; +import type { Project } from "~/lib/types.ts"; /** Platforms accepted by `projects create` (mirrors the API's create body). */ const PLATFORMS = ["imessage", "whatsapp_business", "voice"] as const; @@ -64,7 +65,7 @@ function registerListCommand(projects: Command): void { die(`Failed to list projects: ${formatApiError(error)}`); } - const list = data ?? []; + const list = (data as Project[] | null | undefined) ?? []; if (opts.json) { printJson(list); return; diff --git a/src/commands/spectrum/users.ts b/src/commands/spectrum/users.ts index 8fc8ad1..d89b25a 100644 --- a/src/commands/spectrum/users.ts +++ b/src/commands/spectrum/users.ts @@ -6,6 +6,7 @@ import { SessionExpiredError } from "~/lib/errors.ts"; import { confirmDestructive } from "~/lib/interactive.ts"; import { c, die, formatApiError, printJson, printTable } from "~/lib/output.ts"; import { isInteractive } from "~/lib/tty.ts"; +import type { SpectrumUser, SpectrumUsersPage } from "~/lib/types.ts"; export function registerSpectrumUsers(spectrum: Command): void { const users = spectrum @@ -37,7 +38,8 @@ export function registerSpectrumUsers(spectrum: Command): void { if (status === 401) throw new SessionExpiredError(resolved.name); if (error) die(`Failed to list users: ${formatApiError(error)}`); - const list = data?.users ?? []; + const page = data as SpectrumUsersPage | null | undefined; + const list = page?.users ?? []; if (opts.json) return printJson(list); if (list.length === 0) { console.log(c.dim("No Spectrum users yet.")); @@ -142,14 +144,6 @@ export function registerSpectrumUsers(spectrum: Command): void { }); } -interface SpectrumUser { - id: string; - firstName?: string | null; - lastName?: string | null; - email?: string | null; - phoneNumber?: string | null; -} - interface FilledAdd { firstName: string; lastName: string; diff --git a/src/lib/types.ts b/src/lib/types.ts index 179f417..f33baa1 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -9,4 +9,37 @@ * in command logic. */ -export {}; +/** + * Subset of fields the CLI reads from a project. Mirrors what the dashboard + * returns from `GET /api/projects` (list) and `GET /api/projects/:id` (show). + * Kept as one shared shape so list/show/delete don't drift apart. + */ +export interface Project { + id: string; + name: string; + status: string; + location: string; + platforms: string[]; + template: boolean; + observability: boolean; + slackChannelId: string | null; + slackTeamId: string | null; + isOwner?: boolean; + createdAt: string | Date; + updatedAt: string | Date; +} + +/** A Spectrum user as returned by `GET /api/projects/:id/spectrum/users`. */ +export interface SpectrumUser { + id: string; + firstName?: string | null; + lastName?: string | null; + email?: string | null; + phoneNumber?: string | null; +} + +/** Response envelope for the Spectrum users list route. */ +export interface SpectrumUsersPage { + total: number; + users: SpectrumUser[]; +}