Skip to content

feat: BEX-250 — replace brevo app update with brevo app upload#33

Merged
piyushsarin-sib merged 30 commits into
features_set_public_clifrom
feat/BEX-250-app-upload
Jul 23, 2026
Merged

feat: BEX-250 — replace brevo app update with brevo app upload#33
piyushsarin-sib merged 30 commits into
features_set_public_clifrom
feat/BEX-250-app-upload

Conversation

@piyushsarin-sib

Copy link
Copy Markdown
Collaborator

Summary

  • Removes brevo app update entirely (no stub, no forwarding shim) and replaces it with brevo app upload — a config-only command with no --app-id, no edit flags (--name/--redirect-uri/--scope/--logo-uri are all gone). To change name, redirect URLs, scopes, or logo, edit app-config.json directly, then run brevo app upload.
  • upload always fetches the current remote app state and renders a local-vs-server diff before pushing anything — even under --yes (skips only the confirm prompt) and --json (diff is returned as structured data instead of skipped). If nothing differs, it exits 0 with "already up to date" and makes no network push.
  • Pushes to the confirmed POST /v3/app-store/apps/{app_id}/upload contract — a wire shape distinct from the rest of the API (app_version top-level, auth.distribution_type/auth.redirect_urls nested) — and writes the server-confirmed state back into app-config.json on success.
  • ui_app is never sent (accepted risk — local config has no field for it; documented in TODO.md).
  • Lifecycle gate (block upload when app state is Submitted/In Review, absorbed from BEX-254) is explicitly deferred — its dependencies (BEX-252 status / BEX-253 withdraw) don't exist in this codebase yet. Tracked in TODO.md.
  • ~11 existing messages that told users to run brevo app update --scope/--redirect-uri as a one-liner fix (scaffold tips, port-conflict hints, legacy-scope migration guidance, the scaffold template's own README) are reworded to point at editing app-config.json + running upload.
  • AGENTS.md/SKILL.md updated per this repo's CLAUDE.md rule for user-visible command changes.
  • Changeset added, major bump (breaking: removes a public command).

Full design rationale and the decisions behind each scoping choice (endpoint/payload confirmation, ui_app handling, lifecycle-gate deferral, dropping edit flags): docs/superpowers/specs/2026-07-23-app-upload-replaces-update-design.md. Implementation plan: docs/superpowers/plans/2026-07-23-app-upload-replaces-update-plan.md.

Base branch note: targets add-app-version-config, not main — this work depends on that branch's version/top-level distribution_type schema, which hasn't merged to main yet.

Test plan

  • yarn test:ci — 40 suites / 637 tests passing
  • yarn lint / yarn format:check / yarn build — clean
  • Config validation: missing file / invalid JSON / missing appId all hard-error before any API call
  • Diff always fetched/shown under --yes and --json, never skipped
  • Up-to-date config → exit 0, no upload call
  • Confirm/decline/non-interactive paths behave correctly
  • Outgoing payload matches the confirmed wire contract exactly (app_version, nested auth.distribution_type/auth.redirect_urls, no ui_app)
  • Legacy 'all'-scope block and redirect URL validation carried over unchanged from update.ts
  • Server rejection propagates as an error (exit 1)
  • Success writes server-confirmed state back into app-config.json
  • brevo app update fully deregistered; grep sweep confirms zero remaining references in src//agent-context/
  • Manual smoke test against a real backend (not run in this pass — recommend before merging, since the endpoint/payload contract, while confirmed via a live example, hasn't been exercised end-to-end by this PR)

🤖 Generated with Claude Code

piyushsarin-sib and others added 24 commits July 23, 2026 16:45
Surfaces the app-store API's `version` field end-to-end: `brevo app create`
and `brevo app list` display it, `brevo app scaffold` writes it into
app-config.json, and `brevo app update` backfills it into projects
scaffolded before this field existed. Version is server-assigned and
read-only from the CLI's perspective — no flag to change it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
brevo app create now always scaffolds afterward instead of asking
"Generate starter code now?" — in both interactive and --json mode.
Interactive mode still prompts for the target directory and how to
handle an existing one; --json scaffolds into the same default
directory non-interactively and skips (never overwrites) if it
already exists, reporting scaffoldSkipped instead of scaffolded.

scaffold.ts's core logic (fetch context aside) is extracted into a
side-effect-free runScaffold() plus a pure computeSlug() helper, both
reused by create.ts's --json path so it never emits a second JSON blob.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…y default

Records the design for end-to-end app version tracking (per the
already-authored app-version-config spec) and default directory creation
on `brevo app create`, so the plan travels with the branch.
Splits directory setup (mkdir + chdir) out of scaffolding into its own
step for `brevo app create`, and adds a project-type prompt plus a
same-app/different-app/no-config directory branch for standalone
`brevo app scaffold`.
…ard and diff-driven re-scaffold

Updates the spec and adds the implementation plan: brevo app create now
hard-errors on an already-linked directory instead of a soft confirm, and
brevo app scaffold's same-app case diffs local config against the server,
only prompting for consent when they actually differ.
… and project-type prompt

Replace the blunt "app-config.json exists -> refuse" guard in `brevo app
scaffold` with a three-case directory flow: no local config (same
directory-selection flow as before, now actually chdir-ing into the
resolved directory), local config for the same app (silent merge-only
proceed when it already matches the server, otherwise show a diff and
ask before doing a full overwrite), and local config for a different
app (must pick a new directory or cancel, never overwrites in place).
Also adds an interactive project-type prompt ahead of scaffolding.
… its own directory before creating the app

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Proposes the BEX-250 user-story rewrite (upload replaces update entirely,
directory-only resolution with no --app-id flag, unconditional pre-upload
diff, ui_app passthrough-only) and BEX-254's disposition as superseded.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…te/scaffold directory flow

Documents the decoupled create/scaffold directory flow (hard-error guard on an
already-linked cwd, directory-first create, diff-driven scaffold for the same
app) with a TESTING.md checklist and appends to the branch's pending
add-app-version-config changeset. Also logs two follow-ups flagged during
review: extracting the duplicated chooseAgain retry loop, and wrapping
directory-resolution fs calls in try/catch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ont where files land

resolveProjectDirectory/resolveScaffoldTarget already chdir into the target
directory while resolving it, so the Next steps box's `cd <dir>` step was
always a no-op `cd .` by the time it printed. Removed it, and added an
upfront notice before scaffolding writes anything, so the user knows where
the project is landing instead of finding out only after the fact.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The API returns a lowercase code but client.ts only matches the uppercase
literal, so the friendly error message never fires when a user hits the
10-app limit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Resolves the open blockers: confirmed POST /v3/app-store/apps/{id}/upload
payload shape, ui_app is never sent (accepted risk), the Submitted/In-Review
lifecycle gate is deferred (BEX-252/253 don't exist yet), and upload drops
all of update's edit flags in favor of a full-config push only.
…t internal chdir

process.chdir() inside resolveProjectDirectory/resolveCreateDirectory only moves the
CLI's own Node process, never the shell the user typed the command into — so despite
the "...and moving into it..." message, the user's terminal never actually lands in
the scaffolded directory. Restore the `cd <dir>` step in the Next steps box, computed
relative to the cwd captured before any directory resolution/chdir runs, and omit it
when scaffolding writes into the directory the command was already run from.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…t/BEX-250-app-upload

# Conflicts:
#	TESTING.md
#	TODO.md
`brevo app create` now writes only the basic project structure
(app-config.json + .gitignore/AGENTS.md/CLAUDE.md/README.md); the OAuth
test-server code becomes a scaffoldable *feature*. Interactive create
asks whether to add a feature (default yes -> "Test OAuth App"); --json
auto-scaffolds the oauth feature.

`brevo app scaffold` is repurposed to add a feature to an
already-created project: it now requires an app-config.json in cwd
(erroring with guidance otherwise), reads the linked app from it (the
--app-id flag and app picker are gone), diffs the local config against
the server, and on consent refreshes the base config before writing the
feature files (merged in -- existing files are never clobbered).

Template manifest split into BASE_TEMPLATE_MANIFEST and
FEATURE_TEMPLATE_MANIFESTS; runScaffold split into runBaseScaffold /
runFeatureScaffold. AGENTS.md and SKILL.md updated to match.

Co-authored-by: Claude <noreply@anthropic.com>
…ia scaffold

Non-interactive `brevo app create` (--json or piped/non-TTY) no longer
auto-scaffolds the oauth feature — it writes the basic project structure
only. The OAuth test server is now created solely by answering the
interactive feature prompt yes, or by running `brevo app scaffold`
afterward. Updates tests, agent docs, changeset, and TESTING.md to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t/BEX-250-app-upload

# Conflicts:
#	TESTING.md
#	agent-context/AGENTS.md
#	agent-context/SKILL.md
#	src/lang/en.ts

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

Please cross check the committed markdown files.

piyushsarin-sib and others added 3 commits July 23, 2026 21:32
In interactive `brevo app create`, the "App created" box and the list of
base files now print immediately after the app is created and the base
structure is written — before the "Do you want to scaffold a feature?"
prompt runs. Previously the box printed after the prompt. Adds a
`reportBaseScaffoldSuccess` reporter for the base files and an ordering
test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@piyushsarin-sib

piyushsarin-sib commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Please cross check the committed markdown files.
Hi @shubham773 !
Intentionally committing the markdown files for now. I'll remove them from the feature set after updating the smoke test script before merging the main

Base automatically changed from add-app-version-config to features_set_public_cli July 23, 2026 16:33
piyushsarin-sib and others added 3 commits July 23, 2026 22:16
Resolve conflicts from the app update→upload replacement:
- Keep update.ts / update.test.ts deleted (replaced by upload.ts)
- scaffold.ts: take base's locale-compare diff sorts
- en.ts / en.test.ts / agent docs: point at editing app-config.json + upload
- Drop stale duplicate `version` paragraph and update refs from SKILL.md
- Docs/trackers: keep BEX-250 upload entries; version-config design docs
  kept as historical snapshots (still reference update.ts)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The "Implementation notes (as shipped)" section still described the version
write-back against the removed `brevo app update` command. Point it at
`brevo app upload` (BEX-250) and describe where the logic actually lives
today: version is sent on the wire as `app_version` and the server-confirmed
value is written back into app-config.json. The design body above is left as
the historical record and the notes section is marked authoritative.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`brevo app scaffold` now asks before reusing existing feature files: when any
feature file is present, interactive runs prompt Overwrite / Merge / Cancel
(default Merge — keep existing, add missing). A new `--overwrite` flag forces a
full overwrite and skips the prompt, working both interactively and under
`--json`. Non-interactive `--json` runs stay non-destructive (merge) unless
`--overwrite` is passed. Replaces the previous silent-skip behavior.

Wires the choice through `resolveFeatureConflict`, adds the `--overwrite` flag
in definitions, new en.ts strings, tests, a TESTING.md entry, and keeps
AGENTS.md/SKILL.md in sync.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@piyushsarin-sib
piyushsarin-sib merged commit 0d2a6e3 into features_set_public_cli Jul 23, 2026
@piyushsarin-sib
piyushsarin-sib deleted the feat/BEX-250-app-upload branch July 23, 2026 17:08
@sonarqubecloud

Copy link
Copy Markdown

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