Token efficient deploy and retrieves via --quiet and --no-progress flags#1585
Open
jprichter wants to merge 1 commit into
Open
Token efficient deploy and retrieves via --quiet and --no-progress flags#1585jprichter wants to merge 1 commit into
jprichter wants to merge 1 commit into
Conversation
|
Thanks for the contribution! Before we can merge this, we need @jprichter to sign the Salesforce Inc. Contributor License Agreement. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
sf project deploy startis verbose even with--concise. Output comes in two phases:MultiStageOutputstreaming block (stages + per-stage counters + footer). In a TTY this redraws in place, but when a harness captures piped stdout, each redraw can land as a fresh line which is a large, repetitive token sink.DeployResultFormatterreport (the "Deployed Source" table listing every component, plus failures/deletes/test results).--conciseonly narrows phase 2 (drops the success table; keeps failures), and has no effect on phase 1 — which is most of the residual verbosity. There was no single switch to get genuinely minimal output, and nothing surfaced the--json --conciserecipe.Output matrix
--concise--no-progress--quiet--quiet⊇--no-progresson the streaming axis (both turn streaming off) but differs on the report axis. So--quietis implemented as "imply--no-progressbehavior + collapse the report," reusing one shared suppression primitive rather than two parallel code paths.Measured impact
Against a live scratch org (
sample-project-multiple-packages), a representative deploy:--no-progress--quiet~99.5% reduction at
--quiet. Example--quietsuccess line:Deployed 2/2 components to test-…@example.com (Deploy ID …).What
Adds opt-in "minimal output" modes to the deploy/retrieve commands so that AI coding harnesses and other token or log-conscious consumers don't pay an out-sized cost every time an agent deploys or retrieves metadata. Three coordinated pieces:
--quiet— a true minimal-output verbosity that both suppresses the live streaming progress and collapses the final result report to a single summary line.--no-progressflag +SF_DEPLOY_PROGRESSenv var — suppress only the live streamingMultiStageOutput, leaving the full final report intact. This is the reusable primitive that--quietbuilds on (flag overrides env var; both default to showing progress).--json --conciserecipe, and clarification of what--conciseactually does.All behavior is opt-in. No command's default output changes.
Commands affected
--quiet/--no-progressadded to:project deploy startproject deploy validateproject deploy quick(no live progress stream;--quietmainly trims the final report —--no-progressis accepted for parity, documented as such)project deploy resumeproject retrieve startDeliberately excluded:
deploy preview/retrieve preview— their entire output is the component list, so a "quiet preview" would print almost nothing.How
shouldShowDeployProgress({ jsonEnabled, quiet, noProgress })insrc/utils/deployStages.tscentralizes the precedence:--json→ off;--quiet/--no-progress→ off; otherwiseSF_DEPLOY_PROGRESS(showDeployProgress()); otherwise default on. Every deploy command wires itsDeployStagesthrough this one helper.DeployResultFormatter.determineVerbosity()resolvesverbose > quiet > concise > normal;--quietcollapses the report to the one-line summary.resolveResumeVerbose()ensures a current explicit verbosity flag (--quiet/--concise) overrides a cachedverbose: truefrom the original deploy.MultiStageOutputand no concise/verbose ladder, so it gets--quiet(one-line "Retrieved N files from …" summary on success) +--no-progressonly — the smallest change that solves the token problem. (See "Pre-existing asymmetry" below.)Reviewer call-out: the
jsonEnabledreuse indeployStages.tsThe
MultiStageOutputis suppressed viajsonEnabled: jsonEnabled || !showProgress. This is intentional and commented.MultiStageOutput'sjsonEnabledoption is effectively a non-interactive-mode toggle; when true it skips painting the live stage UI. It does not change serialization. OR-ing in!showProgressreuses that existing "don't render to the terminal" behavior for a non-JSON reason (--quiet/--no-progress). The only mismatch is nominal (the option is named for its most common trigger). A follow-up is noted to add a dedicatedsuppressOutput/enabledoption upstream in@oclif/multi-stage-outputand retire the overload.Pre-existing asymmetry
Deploy has a
verbose | concise | normalladder and retrieve does not. This change narrows the gap that matters for token cost (deploy and retrieve now share--quiet+--no-progress). The remaining gap (no--concise/--verboseon retrieve) is left in place.Testing
test/commands/deploy/quick.test.ts— quiet suppresses command-owned success logs, failure detail still surfaces under--quiet.test/commands/deploy/resume.test.ts—resolveResumeVerboseprecedence, incl. a current--conciseoverriding cached verbose.test/utils/deployStages.test.ts—shouldShowDeployProgressprecedence matrix.test/utils/output.test.ts(ANSI-aware assertions) andtest/commands/retrieve/start.test.ts.test/nuts/deploy/quiet.nut.ts— 9 cases run green against a live Dev Hub(
TESTKIT_AUTH_URL/ AUTO strategy): baseline,--no-progress,SF_DEPLOY_PROGRESS=false,--quiet,--quiet --json(files: []), flag exclusivity (oclif exit 2),validate --quiet("Validated" wording),resume --quiet,retrieve --quiet, and the preview guard.command-snapshot.jsonregenerated showing all five in-scope commands carryquiet+no-progress, bothpreviewcommands excluded.--json --conciserecipe). README.mdis intentionally excluded as it's regenerated and committed by the release bot (svc-cli-bot,chore(release)`), which will pick up the new flag help from the message files at the next release. (Regenerating it locally produced unrelated tooling-version churn so it was reverted.)Potential Follow-ups
suppressOutput/enabledoption to@oclif/multi-stage-outputand retire thejsonEnabled || !showProgressoverload here.project deploy reportcould similarly gain from--quiet.Backwards compatibility
No default output changes; every new behavior is opt-in via flag or env var.
--quietis mutually exclusive with--verbose/--concise(oclif exits 2 on conflict). The--jsonpayload shape is unchanged.