Skip to content

feat(build): per-run size-budget override (#260)#263

Merged
YosefHayim merged 2 commits into
mainfrom
feat/260-size-budget-override
Jun 28, 2026
Merged

feat(build): per-run size-budget override (#260)#263
YosefHayim merged 2 commits into
mainfrom
feat/260-size-budget-override

Conversation

@YosefHayim

@YosefHayim YosefHayim commented Jun 28, 2026

Copy link
Copy Markdown
Owner

User description

Summary

Lets a single build override the soft size budget without editing launch.config.ts. Previously the budget was locked to the chosen profile's sizeBudgetMB (or the 200 MB fallback), so a one-off threshold meant editing config and re-running.

What changed

  • src/core/pipeline.ts — added an optional sizeBudgetMB?: number to BuildRunOptions and a single shared resolver resolveSizeBudgetMB(options, profile) (+ a DEFAULT_SIZE_BUDGET_MB constant). Precedence: options.sizeBudgetMB ?? profile.sizeBudgetMB ?? 200. Both enforcement sites (runIosBuild, runAndroidBuild) now call it instead of duplicating the ?? 200 chain.
  • src/core/easPipeline.ts — the EAS handoff's confirmUpload uses the same resolver, so the override applies on every build path (local iOS, local Android, EAS), not just two of three.
  • src/cli/commands/build.ts — added --size-budget <MB> (alias --budget), parsed and validated > 0 at the CLI boundary via parseSizeBudget (rejects ≤ 0 and non-numeric with a clear message), threaded into runBuild as sizeBudgetMB.
  • src/cli/commands/wizard.ts — after selectProfile() in both the iOS and Android journeys, a new selectSizeBudget step offers "Use profile budget (<n> MB)" (default) vs "Enter a custom budget…" (numeric, validated > 0), reusing the same Clack select/text primitives. The chosen value flows into the same confirmUpload budgetMB.
  • Remembered-flow replay is unaffected: a one-off custom budget is per-run only and is not written into rememberLastFlow, so a "Repeat last build?" replay keeps the profile budget (as the issue allows).

Acceptance criteria

  • Wizard offers "use profile budget" (default) or "enter custom" after the profile.
  • A custom value overrides the budget for that build only; launch.config.ts is not written.
  • The override drives the confirmUpload over-budget warning/gate.
  • --size-budget <MB> (alias --budget) provides the same override non-interactively; in CI/--yes the prompt is skipped.
  • Invalid input (≤ 0, non-numeric) is rejected with a clear message.
  • Remembered-flow replay is unaffected.

Tests

  • resolveSizeBudgetMB precedence (override > profile > default) — src/core/pipeline.test.ts.
  • parseSizeBudget validation + --size-budget/--budget flag registration — src/cli/commands/build.test.ts (new).
  • validateCustomBudget rejection wording and profileBudgetMB default fallback — src/cli/commands/wizard.test.ts.

Full suite: 1917 passing. typecheck, lint (biome), and build are green.

Note: docs:check flags only schema/launch.config.schema.json as stale locally — that is a pre-existing prettier-version skew in this checkout (main's committed schema is already biome-formatted and is not touched by this feature), so the schema is intentionally left at main's committed version to keep lint green. CI's pinned prettier resolves it.

Closes #260

🤖 Generated with Claude Code


Summary by cubic

Adds a per-run soft size budget override for builds, so you can bypass the profile budget without editing launch.config.ts. Works across local iOS, local Android, and EAS builds.

  • New Features

    • CLI: --size-budget <MB> (alias --budget) to set a positive MB budget for this run only; validated at the flag boundary.
    • Wizard (iOS/Android): new step after selecting a profile to keep the profile budget or enter a custom budget; affects the pre-upload warning; not stored or replayed.
    • Precedence: override > profile sizeBudgetMB > default 200 MB.
  • Refactors

    • Added DEFAULT_SIZE_BUDGET_MB and a shared resolveSizeBudgetMB(options, profile) used by all confirmUpload sites (iOS, Android, EAS).
    • Tests added for precedence and validation; docs updated with the new flags; README badges now show 1899 tests.

Written for commit b5966f8. Summary will update on new commits.

Review in cubic


CodeAnt-AI Description

Let each build use a custom size budget without changing config

What Changed

  • You can now override the soft size budget for a single build from the command line or the wizard
  • The wizard now offers a choice between using the profile’s budget and entering a custom budget for that run
  • The budget used during upload now follows the same order everywhere: per-run override, then profile budget, then the 200 MB default
  • Command, docs, and test references were updated to show the new size budget option and current test count

Impact

✅ One-off build budget overrides
✅ Fewer config edits before uploads
✅ Clearer size-limit choices in the build flow

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • Added a per-build size budget override for builds, including a new command option and a matching wizard prompt.
    • The build flow now supports entering a custom budget or using the selected profile’s default.
  • Bug Fixes

    • Build uploads now consistently use the correct size budget precedence: custom override, profile value, then default.
  • Documentation

    • Updated README badges and command docs to reflect the latest test count.
    • Added documentation for the new build budget option.
  • Tests

    • Added and updated tests for build budget parsing and selection behavior.

Let a single build override the soft size budget without editing
launch.config.ts. A new optional `BuildRunOptions.sizeBudgetMB` is
resolved at the upload gate by `resolveSizeBudgetMB(options, profile)`
— one shared helper for all three `confirmUpload` sites (local iOS,
local Android, EAS handoff) with the precedence:
override > profile.sizeBudgetMB > DEFAULT_SIZE_BUDGET_MB (200).

- `launch build`: add `--size-budget <MB>` (alias `--budget`), parsed
  and validated > 0 at the CLI boundary (rejects ≤ 0 / non-numeric).
- wizard: after picking a profile in both the iOS and Android journeys,
  offer "Use profile budget (<n> MB)" (default) or "Enter a custom
  budget…" (numeric, validated > 0), threaded into the same gate.
- Remembered-flow replay is unaffected: a one-off custom budget is
  per-run only and is not carried into `rememberLastFlow`.

Tests cover the resolve order, CLI/wizard validation, and the
profile-default fallback. Docs regenerated for the new flags.

Closes #260

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@YosefHayim YosefHayim added the enhancement New feature or request label Jun 28, 2026
@codeant-ai

codeant-ai Bot commented Jun 28, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@codeant-ai

codeant-ai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@changeset-bot

changeset-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b5966f8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a per-run size budget override: BuildRunOptions gains an optional sizeBudgetMB field, a shared resolveSizeBudgetMB resolver (run → profile → 200 MB default) replaces inline fallbacks in pipeline.ts and easPipeline.ts, the build command gains --size-budget/--budget flags with a parseSizeBudget validator, and the interactive wizard gains a post-profile budget selection step. All README badges and docs update from 1885 to 1899 passing tests.

Changes

Per-run size budget override

Layer / File(s) Summary
BuildRunOptions field and resolveSizeBudgetMB resolver
src/core/pipeline.ts, src/core/easPipeline.ts, src/core/pipeline.test.ts
BuildRunOptions gains optional sizeBudgetMB. DEFAULT_SIZE_BUDGET_MB=200 and resolveSizeBudgetMB are exported, implementing run-override → profile → default precedence. confirmUpload calls in iOS and Android paths switch to the resolver. easPipeline.ts adopts the same resolver. Tests assert all three precedence cases.
--size-budget flag on build command
src/cli/commands/build.ts, src/cli/commands/build.test.ts
BuildCommandOptions gains sizeBudget and budget fields. Exported parseSizeBudget validates the CLI string (rejects ≤0 and non-numeric). registerBuildCommand registers --size-budget <MB> and --budget <MB> alias, parses them, and passes sizeBudgetMB to runBuild. Tests cover parse edge cases and option registration.
Wizard budget selection step
src/cli/commands/wizard.ts, src/cli/commands/wizard.test.ts
Exports profileBudgetMB and validateCustomBudget. New selectSizeBudget prompts the user to keep the profile budget or enter a custom MB value. buildOptions threads optional sizeBudgetMB. Both iOS and Android journeys insert the budget step after profile selection. Tests cover fallback rules and validation.
Docs and badge updates
docs/commands.md, llms.txt, README*.md
docs/commands.md documents --size-budget and --budget flags. All README variants and llms.txt update the tests-passing badge from 1885 to 1899.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 A budget once fixed to the profile alone,
now floats on the wind of a flag or a tone.
--size-budget speaks, the wizard asks too,
"Keep the profile's MB, or pick something new?"
The resolver decides — run, profile, default in line.
Fourteen READMEs agree: 1899 tests shine! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly names the main change: a per-run size-budget override for builds.
Linked Issues check ✅ Passed The wizard, CLI, and pipeline implement the per-run budget override and validation requested in #260.
Out of Scope Changes check ✅ Passed The docs and README updates track the new budget option and test-count changes, so no unrelated changes are evident.
Docstring Coverage ✅ Passed Docstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/260-size-budget-override

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Jun 28, 2026
Comment thread src/core/pipeline.ts
Comment on lines +102 to +107
/**
* Per-run soft size-budget override in MB (`--size-budget`, or the wizard's custom-budget prompt). When
* set it wins over the profile's `sizeBudgetMB` for this build only — `launch.config.ts` is untouched.
* See {@link resolveSizeBudgetMB}.
*/
sizeBudgetMB?: number;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Move this newly added run-option shape change into the appropriate src/core/types/*.ts module and consume it from pipeline.ts via import instead of extending the interface inline in the feature file. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

The PR adds a new run-option field directly inside src/core/pipeline.ts, but the rule requires shape/interface changes to live in the matching src/core/types/*.ts module instead of a feature file. This is a real violation because BuildRunOptions is being extended inline here.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/core/pipeline.ts
**Line:** 102:107
**Comment:**
	*Custom Rule: Move this newly added run-option shape change into the appropriate `src/core/types/*.ts` module and consume it from `pipeline.ts` via import instead of extending the interface inline in the feature file.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai

codeant-ai Bot commented Jun 28, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@coderabbitai coderabbitai Bot 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.

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/cli/commands/build.ts`:
- Around line 104-117: The parseSizeBudget boundary in build.ts is too
permissive because Number.parseFloat accepts partial strings like “250mb” and
non-finite inputs like “Infinity”. Update parseSizeBudget to validate the full
input string as a numeric, finite MB value greater than 0, and keep the existing
error path for invalid values so the value passed into runBuild remains strictly
numeric.

In `@src/cli/commands/wizard.ts`:
- Around line 167-209: The wizard budget path is accepting non-strict numeric
input because validateCustomBudget and selectSizeBudget rely on
parseFloat/Number parsing, which lets values like “250mb” and “Infinity”
through. Tighten the validation in validateCustomBudget so it only accepts a
plain positive finite MB number, then make selectSizeBudget return that
validated numeric value without re-parsing loosely; use the existing
validateCustomBudget, selectSizeBudget, and profileBudgetMB symbols to update
the prompt flow consistently.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 45e81ecc-cb97-4940-b214-38a8d576d7d6

📥 Commits

Reviewing files that changed from the base of the PR and between 3111564 and b5966f8.

📒 Files selected for processing (18)
  • README.de.md
  • README.es.md
  • README.fr.md
  • README.ja.md
  • README.ko.md
  • README.md
  • README.pt-BR.md
  • README.ru.md
  • README.zh-CN.md
  • docs/commands.md
  • llms.txt
  • src/cli/commands/build.test.ts
  • src/cli/commands/build.ts
  • src/cli/commands/wizard.test.ts
  • src/cli/commands/wizard.ts
  • src/core/easPipeline.ts
  • src/core/pipeline.test.ts
  • src/core/pipeline.ts

Comment thread src/cli/commands/build.ts
Comment on lines +104 to +117
/**
* Parse `--size-budget`/`--budget` into a positive MB number, rejecting `≤ 0` and non-numeric input at the
* CLI boundary. Returns undefined when omitted, so the pipeline falls back to the profile's `sizeBudgetMB`
* then the default — see {@link resolveSizeBudgetMB}. Exported so the same rejection is unit-tested directly.
*/
export function parseSizeBudget(sizeBudget: string | undefined): number | undefined {
if (sizeBudget === undefined) return undefined;
const value = Number.parseFloat(sizeBudget);
if (Number.isNaN(value) || value <= 0) {
throw new Error(`Invalid --size-budget "${sizeBudget}". Pass a size in MB greater than 0.`);
}
return value;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Reject partial numeric strings and non-finite values.

Number.parseFloat accepts inputs like "250mb" as 250 and "Infinity" as a valid budget, so this CLI boundary currently lets malformed values through instead of rejecting them. That breaks the PR's “numeric and greater than zero” contract before Line 179 threads the value into runBuild.

Suggested fix
 export function parseSizeBudget(sizeBudget: string | undefined): number | undefined {
   if (sizeBudget === undefined) return undefined;
-  const value = Number.parseFloat(sizeBudget);
-  if (Number.isNaN(value) || value <= 0) {
+  const value = Number(sizeBudget.trim());
+  if (!Number.isFinite(value) || value <= 0) {
     throw new Error(`Invalid --size-budget "${sizeBudget}". Pass a size in MB greater than 0.`);
   }
   return value;
 }

Also applies to: 179-179

🤖 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/cli/commands/build.ts` around lines 104 - 117, The parseSizeBudget
boundary in build.ts is too permissive because Number.parseFloat accepts partial
strings like “250mb” and non-finite inputs like “Infinity”. Update
parseSizeBudget to validate the full input string as a numeric, finite MB value
greater than 0, and keep the existing error path for invalid values so the value
passed into runBuild remains strictly numeric.

Comment on lines +167 to +209
/**
* Validate a typed custom-budget string for the wizard prompt, returning a Clack error message when it's
* rejected (empty, non-numeric, or `≤ 0`) or undefined when it's a positive MB number. Pure → the
* rejection wording is unit-testable without driving a prompt.
*/
export function validateCustomBudget(input: string): string | undefined {
const value = Number.parseFloat(input);
if (Number.isNaN(value)) return 'Enter a number of megabytes.';
if (value <= 0) return 'Enter a budget greater than 0 MB.';
return undefined;
}

/**
* Step (both, after the profile): let the user keep the profile's size budget (default — just press
* Enter) or type a per-run override that wins at the upload gate for this build only. Returns the custom
* MB number, or undefined to leave the profile's budget in force. Reuses the same Clack `select`/`text`
* primitives the rest of the wizard uses, so it degrades and cancels identically.
*/
async function selectSizeBudget(
config: LaunchConfig,
profileName: string,
): Promise<number | undefined> {
const budget = profileBudgetMB(config, profileName);
const choice = resolvePrompt(
await select<'profile' | 'custom'>({
message: 'Size budget for this build?',
options: [
{ value: 'profile', label: `Use profile budget (${budget} MB)`, hint: 'no change' },
{ value: 'custom', label: 'Enter a custom budget…', hint: 'this build only' },
],
initialValue: 'profile',
}),
);
if (choice === 'profile') return undefined;
const entered = resolvePrompt(
await text({
message: 'Custom size budget (MB)',
placeholder: String(budget),
validate: (value) => validateCustomBudget(value ?? ''),
}),
);
return Number.parseFloat(entered);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tighten the wizard's numeric validation.

This prompt path has the same permissive parsing bug as the CLI: "250mb" and "Infinity" both pass validation and then become real overrides at Line 208. The wizard is supposed to reject anything that is not a positive numeric MB value.

Suggested fix
 export function validateCustomBudget(input: string): string | undefined {
-  const value = Number.parseFloat(input);
-  if (Number.isNaN(value)) return 'Enter a number of megabytes.';
+  const value = Number(input.trim());
+  if (!Number.isFinite(value)) return 'Enter a number of megabytes.';
   if (value <= 0) return 'Enter a budget greater than 0 MB.';
   return undefined;
 }
@@
-  return Number.parseFloat(entered);
+  return Number(entered.trim());
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Validate a typed custom-budget string for the wizard prompt, returning a Clack error message when it's
* rejected (empty, non-numeric, or `≤ 0`) or undefined when it's a positive MB number. Pure → the
* rejection wording is unit-testable without driving a prompt.
*/
export function validateCustomBudget(input: string): string | undefined {
const value = Number.parseFloat(input);
if (Number.isNaN(value)) return 'Enter a number of megabytes.';
if (value <= 0) return 'Enter a budget greater than 0 MB.';
return undefined;
}
/**
* Step (both, after the profile): let the user keep the profile's size budget (default — just press
* Enter) or type a per-run override that wins at the upload gate for this build only. Returns the custom
* MB number, or undefined to leave the profile's budget in force. Reuses the same Clack `select`/`text`
* primitives the rest of the wizard uses, so it degrades and cancels identically.
*/
async function selectSizeBudget(
config: LaunchConfig,
profileName: string,
): Promise<number | undefined> {
const budget = profileBudgetMB(config, profileName);
const choice = resolvePrompt(
await select<'profile' | 'custom'>({
message: 'Size budget for this build?',
options: [
{ value: 'profile', label: `Use profile budget (${budget} MB)`, hint: 'no change' },
{ value: 'custom', label: 'Enter a custom budget…', hint: 'this build only' },
],
initialValue: 'profile',
}),
);
if (choice === 'profile') return undefined;
const entered = resolvePrompt(
await text({
message: 'Custom size budget (MB)',
placeholder: String(budget),
validate: (value) => validateCustomBudget(value ?? ''),
}),
);
return Number.parseFloat(entered);
}
/**
* Validate a typed custom-budget string for the wizard prompt, returning a Clack error message when it's
* rejected (empty, non-numeric, or `≤ 0`) or undefined when it's a positive MB number. Pure → the
* rejection wording is unit-testable without driving a prompt.
*/
export function validateCustomBudget(input: string): string | undefined {
const value = Number(input.trim());
if (!Number.isFinite(value)) return 'Enter a number of megabytes.';
if (value <= 0) return 'Enter a budget greater than 0 MB.';
return undefined;
}
/**
* Step (both, after the profile): let the user keep the profile's size budget (default — just press
* Enter) or type a per-run override that wins at the upload gate for this build only. Returns the custom
* MB number, or undefined to leave the profile's budget in force. Reuses the same Clack `select`/`text`
* primitives the rest of the wizard uses, so it degrades and cancels identically.
*/
async function selectSizeBudget(
config: LaunchConfig,
profileName: string,
): Promise<number | undefined> {
const budget = profileBudgetMB(config, profileName);
const choice = resolvePrompt(
await select<'profile' | 'custom'>({
message: 'Size budget for this build?',
options: [
{ value: 'profile', label: `Use profile budget (${budget} MB)`, hint: 'no change' },
{ value: 'custom', label: 'Enter a custom budget…', hint: 'this build only' },
],
initialValue: 'profile',
}),
);
if (choice === 'profile') return undefined;
const entered = resolvePrompt(
await text({
message: 'Custom size budget (MB)',
placeholder: String(budget),
validate: (value) => validateCustomBudget(value ?? ''),
}),
);
return Number(entered.trim());
}
🤖 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/cli/commands/wizard.ts` around lines 167 - 209, The wizard budget path is
accepting non-strict numeric input because validateCustomBudget and
selectSizeBudget rely on parseFloat/Number parsing, which lets values like
“250mb” and “Infinity” through. Tighten the validation in validateCustomBudget
so it only accepts a plain positive finite MB number, then make selectSizeBudget
return that validated numeric value without re-parsing loosely; use the existing
validateCustomBudget, selectSizeBudget, and profileBudgetMB symbols to update
the prompt flow consistently.

@YosefHayim YosefHayim merged commit a6d6cab into main Jun 28, 2026
8 checks passed
@YosefHayim YosefHayim deleted the feat/260-size-budget-override branch June 28, 2026 15:12
YosefHayim added a commit that referenced this pull request Jun 28, 2026
…ing safe slice (#267)

Rollup since v0.30.0:
- feat(build): per-run `--size-budget`/`--budget` override + wizard step (#260, #263)
- fix(apple): multi-target iOS signing safe slice — pbxproj target discovery,
  stale-profile capability-diff regenerate, `creds setup --app`, build preflight
  (#261 safe slice, #264; archive-vector flip tracked in #262)
- chore: finish the eslint+prettier → biome migration; repair the red CI gate (#265)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build wizard: let me override the size budget per-run (keep config or enter manually) after picking a profile

1 participant