feat(profile): add project profile sync commands#72
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds Spectrum profile synchronization, line profile and avatar commands, shared presigned-upload handling, updated line response compatibility, and contract coverage for the new flows. ChangesSpectrum management commands
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CLI as Spectrum CLI
participant DashboardAPI as Dashboard API
participant Storage as Presigned storage
CLI->>DashboardAPI: Request avatar upload URL
DashboardAPI-->>CLI: Return upload URL
CLI->>Storage: PUT avatar payload
Storage-->>CLI: Return upload status
CLI->>DashboardAPI: Commit avatar upload
DashboardAPI-->>CLI: Return avatar result
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@package.json`:
- Line 52: Update the `@photon-ai/dashboard-api` dependency in package.json from
unavailable version 1.7.0 to a currently published registry release, ensuring
installs and typechecks resolve successfully.
In `@src/commands/spectrum/profile.ts`:
- Around line 279-295: Update finishProfileSync to accept context identifying
whether it was called by sync or sync-status, and use that context to avoid
suggesting sync-status when already running that command. Adjust every
finishProfileSync call site accordingly while preserving the existing failure
messages and aggregate output.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3d848948-d0a1-483a-b71d-202da48927c5
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock,!bun.lock
📒 Files selected for processing (5)
package.jsonsrc/commands/spectrum/lines.tssrc/commands/spectrum/profile.tstests/contract/spectrum-profile-sync.contract.test.tstests/helpers/mock-server.ts
| function finishProfileSync( | ||
| result: ProfileSyncAggregate, | ||
| json: boolean | ||
| ): void { | ||
| printProfileSyncAggregate(result, json); | ||
|
|
||
| if (result.status === "partial_failed") { | ||
| die("Spectrum profile sync completed with failed lines.", { | ||
| hint: "Run `photon spectrum profile sync-status` to inspect the current aggregate.", | ||
| }); | ||
| } | ||
| if (result.status === "failed") { | ||
| die("Spectrum profile sync failed.", { | ||
| hint: "Run `photon spectrum profile sync-status` to inspect the current aggregate.", | ||
| }); | ||
| } | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
finishProfileSync hint is misleading when called from sync-status.
The hint "Run photon spectrum profile sync-status to inspect the current aggregate" is shown for partial_failed/failed in both sync and sync-status commands. When the user just ran sync-status, telling them to run it again is unhelpful and confusing.
💡 Proposed fix: add a context parameter to differentiate the calling command
function finishProfileSync(
result: ProfileSyncAggregate,
- json: boolean
+ json: boolean,
+ command: "sync" | "sync-status" = "sync"
): void {
printProfileSyncAggregate(result, json);
if (result.status === "partial_failed") {
die("Spectrum profile sync completed with failed lines.", {
- hint: "Run `photon spectrum profile sync-status` to inspect the current aggregate.",
+ hint: command === "sync"
+ ? "Run `photon spectrum profile sync-status` to inspect the current aggregate."
+ : "Re-run `photon spectrum profile sync` to retry failed lines.",
});
}
if (result.status === "failed") {
die("Spectrum profile sync failed.", {
- hint: "Run `photon spectrum profile sync-status` to inspect the current aggregate.",
+ hint: command === "sync"
+ ? "Run `photon spectrum profile sync-status` to inspect the current aggregate."
+ : "Re-run `photon spectrum profile sync` to retry.",
});
}
}Then update the call sites:
- finishProfileSync(result, opts.json ?? false);
+ finishProfileSync(result, opts.json ?? false, "sync");- finishProfileSync(result, opts.json ?? false);
+ finishProfileSync(result, opts.json ?? false, "sync-status");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/commands/spectrum/profile.ts` around lines 279 - 295, Update
finishProfileSync to accept context identifying whether it was called by sync or
sync-status, and use that context to avoid suggesting sync-status when already
running that command. Adjust every finishProfileSync call site accordingly while
preserving the existing failure messages and aggregate output.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/presigned-upload.ts`:
- Around line 1-31: When updating readLocalUploadFile to use Bun.file, preserve
the existing MIME behavior by using MIME_TYPES based on the file extension and
falling back to application/octet-stream for unknown extensions; do not use
bunFile.type directly when it reports Bun’s default text/plain;charset=utf-8.
- Around line 33-48: Add a 60-second timeout to the fetch request in
putPresignedUpload by passing AbortSignal.timeout(60_000) as its signal option,
ensuring both upload command call sites inherit the timeout without changing
existing response handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c047914c-686b-4c2e-b252-dc636bc10ae4
📒 Files selected for processing (6)
src/commands/spectrum/avatar.tssrc/commands/spectrum/line-profile.tssrc/commands/spectrum/lines.tssrc/lib/presigned-upload.tstests/contract/spectrum-line-profile.contract.test.tstests/helpers/mock-server.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/helpers/mock-server.ts
| export async function putPresignedUpload( | ||
| file: string, | ||
| uploadUrl: string, | ||
| upload: LocalUploadFile | ||
| ): Promise<void> { | ||
| console.log(c.dim(`Uploading ${file} (${(upload.size / 1024).toFixed(1)} KB)…`)); | ||
|
|
||
| const response = await fetch(uploadUrl, { | ||
| method: "PUT", | ||
| body: upload.body, | ||
| headers: { "Content-Type": upload.contentType }, | ||
| }); | ||
| if (!response.ok) { | ||
| die(`Upload failed: ${response.status} ${response.statusText}`); | ||
| } | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Add a timeout to the presigned PUT request.
fetch here has no signal/timeout, so a slow or unreachable storage endpoint can stall the CLI. This shared implementation is used by both upload commands, so adding signal: AbortSignal.timeout(60_000) here covers both call sites.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/lib/presigned-upload.ts` around lines 33 - 48, Add a 60-second timeout to
the fetch request in putPresignedUpload by passing AbortSignal.timeout(60_000)
as its signal option, ensuring both upload command call sites inherit the
timeout without changing existing response handling.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 4 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ac39b17. Configure here.
1d1a4f7
into
photon-hq:main

Summary
photon spectrum profile syncto align the saved Project Profile across active dedicated iMessage Lines through the Dashboard BFFphoton spectrum lines profile update <line-id>photon spectrum lines avatar upload <line-id> <file>using the signed upload → PUT → commit flow--avatar-url,--no-update-profile, and post-commit Profile PATCH paths@photon-ai/dashboard-api@1.7.0Semantics
profile syncperforms one POST and returns{ projectId, syncedLineCount }; it does not poll or expose a status commandsyncedLineCountis the number of active dedicated iMessage Lines aligned after the request, including Lines that already matchedavatarUrlProfile PATCH is sentCommands
All commands support the existing Project/API host/token resolution. Sync and name update also support
--jsonwhere applicable.Dependency / rollout
@photon-ai/dashboard-api@1.7.0is not published yet, so fresh frozen installs and CLI CI remain blocked until that package is published; after publication, rerun this PR's checksValidation
Scope
syncId, worker status, revision state, or Line-level worker errorsNote
Medium Risk
Behavior changes on existing avatar/profile commands and a large dashboard-api bump; risk is moderated by contract tests and client-side SVG blocking before API calls.
Overview
Extends Spectrum CLI for project–line profile management against a newer
@photon-ai/dashboard-api(1.2.0 → 1.6.12).photon spectrum profile synctriggers a single POST to align the saved project profile across dedicated iMessage lines and reportstargetedLineCount(no polling).photon spectrum lines profile updateandphoton spectrum lines avatar uploadadd per-line name edits and the same presigned upload → PUT → commit flow used for project avatars.Avatar handling is centralized in
~/lib/presigned-upload.ts(local file read, MIME mapping, SVG rejection by extension or content). Projectspectrum avatar uploaduses that helper and stops auto-patching the profile after commit (--no-update-profile, recovery hints, and--avatar-urlonprofile updateare removed).spectrum lines listreadsdata.linesand showsdisplayPhoneNumberwhenphoneNumberis absent.Contract tests and mock routes cover sync, line profile PATCH, line avatar faults, and SVG rejection.
Reviewed by Cursor Bugbot for commit 63f3885. Bugbot is set up for automated code reviews on this repo. Configure here.