Skip to content

feat: track app-store version and folder structure changes field through the CLI#32

Merged
piyushsarin-sib merged 21 commits into
features_set_public_clifrom
add-app-version-config
Jul 23, 2026
Merged

feat: track app-store version and folder structure changes field through the CLI#32
piyushsarin-sib merged 21 commits into
features_set_public_clifrom
add-app-version-config

Conversation

@piyushsarin-sib

@piyushsarin-sib piyushsarin-sib commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

Part A — version tracking end-to-end

  • The app-store API now returns a version field on every app (create/list/get) — this threads it through the CLI end to end.
  • brevo app create shows the server-assigned version in the created-app box and --json output.
  • The base scaffold writes it into app-config.json's version key (on brevo app create, and on brevo app scaffold when it refreshes a drifted config).
  • brevo app list shows a Version: line per app (and includes it in --json).
  • brevo app update shows the current version and backfills it into app-config.json for projects scaffolded before this field existed — the fast path (config already has redirect URLs + version) makes no extra API call; a legacy config missing version triggers exactly one backfill fetch.
  • No CLI-side way to change the version — it's server-assigned, read-only, no new flag.

Design doc: docs/superpowers/specs/2026-07-23-app-version-config-design.md.

Part B — split app creation from feature scaffolding

brevo app create and brevo app scaffold now have distinct, non-overlapping jobs: create sets up the app + basic project structure, and scaffold adds a feature (the OAuth test server being the first/only one) into that project.

  • brevo app create creates the app and writes the basic project structure onlyapp-config.json plus the project meta files (.gitignore, AGENTS.md, CLAUDE.md, README.md). The OAuth server code (src/oauth/*) is no longer part of create.
    • It hard-errors if app-config.json already exists in the working directory (no confirm, no override), and resolves (creates/cds into) its target directory before the create API call.
    • A feature is scaffolded only when the interactive prompt "Do you want to scaffold a feature?" (default yes → "Test OAuth App") is answered yes.
    • Non-interactive runs stay base-only: --json and piped (non-TTY) create write the app + base files but never scaffold a feature — the OAuth code is added afterward with brevo app scaffold. --json reports scaffolded (base file count) + directory, or scaffoldSkipped when the target directory already existed.
  • brevo app scaffold is repurposed to "add a feature to an already-created project":
    • It now requires an app-config.json in the current directory, erroring with guidance to run brevo app create first or cd into a project otherwise (it no longer creates directories).
    • It reads the linked app straight from that config — the --app-id flag and the app picker are gone.
    • Before writing, it diffs the local config against the server; if fields drifted it shows them and, on consent, rewrites the base config to match. Feature files are then merged in — existing (e.g. hand-edited) files are never clobbered.
    • Under --json it never prompts: a config diff comes back as { "cancelled": true, "reason": "...", "diffs": [...] }; with no diff it writes the feature and returns { "scaffolded": <n>, "directory": "..." }.

Supporting changes

  • Templates split into BASE_TEMPLATE_MANIFEST + FEATURE_TEMPLATE_MANIFESTS.oauth, with loadBaseTemplates/loadFeatureTemplates loaders and an exported FeatureType.
  • scaffold.ts's core split into buildTemplateVars + runBaseScaffold + runFeatureScaffold; promptProjectTypepromptFeatureType.
  • Also on this branch: brevo app scaffold --json no longer blocks on interactive prompts (reported as cancelled), and the post-scaffold "Next steps" box's cd hint is computed against the original cwd (see changeset for details).

Follow-ups tracked in TODO.md: brevo app credentials / re-scaffold don't backfill version into app-config.json (only update does); wrap directory-resolution FS calls in friendly CliErrors; the app-limit-reached error case-mismatch.

Test plan

  • yarn test — 676 passed
  • yarn lint
  • yarn build
  • yarn format:check
  • TESTING.md entries covering all parts' verification criteria
  • Manual smoke test not run in this environment (no test Brevo account/API key available) — automated coverage exercises the interactive feature prompt (accept/decline), the base-only --json and piped paths, the directory-exists skip, and scaffold's require-config / diff-refresh / feature-merge paths via mocks.

🤖 Generated with Claude Code

Base automatically changed from enable-public-app to features_set_public_cli July 23, 2026 11:10
piyushsarin-sib and others added 3 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.
@piyushsarin-sib
piyushsarin-sib force-pushed the add-app-version-config branch from e350674 to f5a2eaf Compare July 23, 2026 11:20
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.
@piyushsarin-sib piyushsarin-sib changed the title feat: track app-store version field through the CLI feat: track app-store version and folder structure changes field through the CLI Jul 23, 2026

## Context

BEX-255 ("Brevo CLI app versioning + create and field + creating directory by default") originally asked for a CLI-defaulted `version: "1.0.0"` field plus `description`/`support.*` prompts. Per a Slack decision from Mauricio (2026-07-20, thread linked in the ticket), the `description`/`support.*` fields were dropped from scope entirely — that metadata will live in a future dedicated submission form, not the CLI manifest. The Jira ticket has already been updated to reflect this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Are these files expected to be pushed?

@piyushsarin-sib piyushsarin-sib Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, keeping them now and will remove them before final feature PR main merege remove as we needs them for test scripts update

piyushsarin-sib and others added 13 commits July 23, 2026 18:16
… 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>
…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>
`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>
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 and others added 3 commits July 23, 2026 21:50
SonarCloud S2871: Array.prototype.sort() with no comparator relies on
default string-coercion ordering. Provide an explicit
String.localeCompare comparator on the four redirect/scope diff sorts to
clear the Reliability rating gate on the PR.

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

Append "Implementation notes (as shipped)" sections reconciling the design
specs with the code on this branch:

- app-version-config: confirms shipped as designed, with code anchors.
- create-scaffold-directory-flow: documents the substantial deviations
  (base-vs-feature split, "scaffold a feature?" prompt, promptFeatureType
  rename, non-interactive base-only, richer resolveProjectDirectory, and
  scaffold becoming feature-only with no Case A/C directory setup).
- app-upload-replaces-update: flags it as NOT IMPLEMENTED on this branch
  (proposal only, tracked under BEX-250, still blocked on endpoint shape).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GHSA-g7r4-m6w7-qqqr)

Refresh transitive dev/build dependencies flagged by Dependabot to their
first patched releases, staying within existing package.json ranges:

- js-yaml 3.14.2 -> 3.15.0 and 4.1.1 -> 4.3.0 (CVE-2026-53550)
- @babel/core 7.29.0 -> 7.29.7 (CVE-2026-49356)
- esbuild 0.27.7 -> 0.28.1 via refreshed tsx (GHSA-g7r4-m6w7-qqqr)

All four are development/build-time dependencies, so there is no change to
the published runtime package. Build + full test suite pass on the new lock.

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

Copy link
Copy Markdown

@piyushsarin-sib
piyushsarin-sib merged commit b1c3bee into features_set_public_cli Jul 23, 2026
2 checks passed
@piyushsarin-sib
piyushsarin-sib deleted the add-app-version-config branch July 23, 2026 16:33
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