From 7ddfb1f5cba0ef4b80fd231d99665387ad135e5a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 14 Jul 2026 08:01:29 +0000 Subject: [PATCH] chore(deps): bump @photon-ai/dashboard-api to 1.6.12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Syncs the type contract with dashboard@v1.6.12 (webhook release, sha 9e2913d). The published dashboard-api package moves from 1.2.0 -> 1.6.12; two upstream routes have breaking body/response shape changes that are covered here: - spectrum/profile PATCH no longer accepts avatarUrl in its body. The avatar URL is now applied server-side by spectrum/avatar/commit, so the client no longer needs a follow-up PATCH after upload. Remove the profile-update step (and its --no-update-profile flag + recovery-command helpers) from `spectrum avatar upload`, and drop the --avatar-url option from `spectrum profile update` — that flag now only carries firstName / lastName. Users should use `spectrum avatar upload` for avatar changes. - lines GET now returns { lines, pendingRegistrations } instead of a bare SpectrumLine[] array. Unwrap data?.lines in the list command before casting to the local DTO. UPSTREAM_DIFF.md gets a new "Changed Routes" section noting both signatures. `bun run check` is green (typecheck + 36 tests + build). Co-authored-by: citron --- UPSTREAM_DIFF.md | 11 +++++-- bun.lock | 5 +-- package.json | 2 +- src/commands/spectrum/avatar.ts | 55 -------------------------------- src/commands/spectrum/lines.ts | 2 +- src/commands/spectrum/profile.ts | 9 ++---- 6 files changed, 17 insertions(+), 67 deletions(-) diff --git a/UPSTREAM_DIFF.md b/UPSTREAM_DIFF.md index 7e7d390..c3afe12 100644 --- a/UPSTREAM_DIFF.md +++ b/UPSTREAM_DIFF.md @@ -36,9 +36,16 @@ |-------|--------| | `api.projects.:id.spectrum.avatar-upload-url` | `GET` | +## Changed Routes + +| Route | Method | Change | +|-------|--------|--------| +| `api.projects.:id.spectrum.profile` | `PATCH` | body no longer accepts `avatarUrl` (only `firstName` / `lastName`); avatar URL is set server-side by `spectrum/avatar/commit` | +| `api.projects.:id.lines` | `GET` | response is now `{ lines, pendingRegistrations }` instead of a bare `SpectrumLine[]` array | + ## Summary - **23** added - **1** removed -- **0** changed -- **35** unchanged +- **2** changed +- **33** unchanged diff --git a/bun.lock b/bun.lock index 748dba3..de07488 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.6.12", "@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.6.12", "", { "peerDependencies": { "@elysiajs/eden": "^1.4.9", "elysia": "^1.4.28" } }, "sha512-CxUyvSpJmi5dn3razikiD8xw6l1YN3dflRlBghukV/fYIQaSL25UNJpaBYjdX8Qj0ka4+/RLJoloBdQdUTstmA=="], "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], diff --git a/package.json b/package.json index afb9a76..0ed3d87 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.6.12", "@types/bun": "latest", "@types/node": "^25.6.2", "@types/update-notifier": "^6.0.8", diff --git a/src/commands/spectrum/avatar.ts b/src/commands/spectrum/avatar.ts index bba48aa..a83d097 100644 --- a/src/commands/spectrum/avatar.ts +++ b/src/commands/spectrum/avatar.ts @@ -3,7 +3,6 @@ import { readFile, stat } from "node:fs/promises"; import { extname } from "node:path"; import { getApi } from "~/lib/api.ts"; import { resolveProject } from "~/lib/api-context.ts"; -import { PRODUCTION_URL } from "~/lib/env.ts"; import { SessionExpiredError } from "~/lib/errors.ts"; import { c, die, formatApiError } from "~/lib/output.ts"; @@ -21,7 +20,6 @@ export function registerSpectrumAvatar(spectrum: Command): void { avatar .command("upload ") .description("upload an image as the Spectrum avatar") - .option("--no-update-profile", "only upload, don't update the profile to use the new avatar") .option("-p, --project ", "project id (overrides $PHOTON_PROJECT_ID)") .option("--api-host ", "API host URL (defaults to PHOTON_API_HOST or built-in production)") .option("-t, --token ", "API token (overrides stored creds)") @@ -97,60 +95,7 @@ export function registerSpectrumAvatar(spectrum: Command): void { } const avatarUrl = commitResult.avatarUrl; - // 4) Optionally update the Spectrum profile to point at the new URL. - if (opts.updateProfile !== false) { - const patch = await api.api - .projects({ id: projectId }) - .spectrum.profile.patch({ avatarUrl }); - if (patch.status === 401) throw new SessionExpiredError(resolved.name); - if (patch.error) { - // Upload + commit succeeded; surface the patch failure but don't - // undo. Build the recovery command with the same --project / - // --api-host / --token context the user originally passed, and - // quote the URL so shell-significant chars don't break copy-paste. - const recovery = buildRecoveryCommand({ - projectId, - apiHost: resolved.url, - token: opts.token, - avatarUrl, - }); - die(`Uploaded, but failed to update profile: ${formatApiError(patch.error)}`, { - hint: `Update manually: ${recovery}`, - context: `Avatar URL: ${avatarUrl}`, - }); - } - } - console.log(c.success(`Uploaded avatar from ${file}`)); console.log(c.dim(` URL: ${avatarUrl}`)); }); } - -function buildRecoveryCommand(opts: { - projectId: string; - apiHost: string; - token?: string; - avatarUrl: string; -}): string { - const parts: string[] = ["photon spectrum profile update"]; - parts.push(`--project ${shellQuote(opts.projectId)}`); - // Only include --api-host if it differs from the default production URL, - // so the recovery command stays minimal in the common case. - if (opts.apiHost !== PRODUCTION_URL) { - parts.push(`--api-host ${shellQuote(opts.apiHost)}`); - } - if (opts.token !== undefined) { - parts.push(`--token ${shellQuote(opts.token)}`); - } - parts.push(`--avatar-url ${shellQuote(opts.avatarUrl)}`); - return parts.join(" "); -} - -/** - * Single-quote a value for safe shell copy-paste. Escapes embedded - * single quotes via the standard `'\''` trick. Avoids shell injection - * vectors in URLs that contain `&`, `?`, `;`, `|`, etc. - */ -function shellQuote(value: string): string { - return `'${value.replace(/'/g, `'\\''`)}'`; -} diff --git a/src/commands/spectrum/lines.ts b/src/commands/spectrum/lines.ts index e9231c9..81c4710 100644 --- a/src/commands/spectrum/lines.ts +++ b/src/commands/spectrum/lines.ts @@ -35,7 +35,7 @@ export function registerSpectrumLines(spectrum: Command): void { if (status === 401) throw new SessionExpiredError(resolved.name); if (error) die(`Failed to list lines: ${formatApiError(error)}`); - const list = (data ?? []) as SpectrumLine[]; + const list = (data?.lines ?? []) as SpectrumLine[]; if (opts.json) return printJson(list); if (list.length === 0) { console.log(c.dim("No lines yet.")); diff --git a/src/commands/spectrum/profile.ts b/src/commands/spectrum/profile.ts index 967a713..9d47692 100644 --- a/src/commands/spectrum/profile.ts +++ b/src/commands/spectrum/profile.ts @@ -57,7 +57,6 @@ export function registerSpectrumProfile(spectrum: Command): void { .description("update the Spectrum profile (preserves unset fields)") .option("--first-name ") .option("--last-name ") - .option("--avatar-url ", "avatar image URL (use `spectrum avatar upload` instead)") .option("-p, --project ", "project id (overrides $PHOTON_PROJECT_ID)") .option("--api-host ", "API host URL (defaults to PHOTON_API_HOST or built-in production)") .option("-t, --token ", "API token (overrides stored creds)") @@ -65,11 +64,10 @@ export function registerSpectrumProfile(spectrum: Command): void { .action(async (opts) => { const hasMutation = opts.firstName !== undefined || - opts.lastName !== undefined || - opts.avatarUrl !== undefined; + opts.lastName !== undefined; if (!hasMutation) { die("Nothing to update.", { - hint: "Pass at least one of --first-name / --last-name / --avatar-url.", + hint: "Pass at least one of --first-name / --last-name (avatar: use `spectrum avatar upload`).", }); } @@ -83,10 +81,9 @@ export function registerSpectrumProfile(spectrum: Command): void { requireAuth: true, }); - const body: Record = {}; + const body: { firstName?: string; lastName?: string } = {}; if (opts.firstName !== undefined) body.firstName = opts.firstName; if (opts.lastName !== undefined) body.lastName = opts.lastName; - if (opts.avatarUrl !== undefined) body.avatarUrl = opts.avatarUrl; const { data, error, status } = await api.api .projects({ id: projectId })