fix(output): canonicalize shortcut format and align pretty scan window

Further review fixes:
- Normalize the framework-injected --format to its canonical lowercase and
  write it back to the runtime context and the cobra flag, so shortcuts that
  branch on the exact value (e.g. Format == "pretty") behave correctly for
  mixed-case input like --format Pretty, which previously slipped past those
  checks and produced empty output.
- Size the pretty rendered-text scan window to the content-safety scanner's
  native 128 KiB per-string capacity (was 64 KiB) so the windowing is no more
  restrictive than scanning the raw value; keep the 4 KiB overlap for matches
  crossing a window boundary.
This commit is contained in:
shanglei
2026-07-22 16:31:54 +08:00
parent 0a61b41f92
commit d668d754d5
4 changed files with 56 additions and 14 deletions

View File

@@ -12,10 +12,10 @@ import (
)
const (
// Keep each pretty-output scan window comfortably below the content-safety
// scanner's per-string limit. The overlap covers rule matches that cross a
// window boundary without coupling this package to that private limit.
prettySafetyScanWindowBytes = 64 << 10
// Match the native content-safety scanner's 128 KiB per-string capacity so
// rendered-output scanning does not impose a smaller regex match window.
// The overlap keeps realistic rule matches visible across window boundaries.
prettySafetyScanWindowBytes = 128 << 10
prettySafetyScanOverlapBytes = 4 << 10
)

View File

@@ -45,9 +45,8 @@ func (p *truncatingContractSafetyProvider) Name() string {
}
func (p *truncatingContractSafetyProvider) Scan(_ context.Context, req extcs.ScanRequest) (*extcs.Alert, error) {
// This deliberately differs from the production scanner's private limit; it
// models any provider that bounds work independently for each string.
const perStringCap = 160 << 10
// Model the production scanner's native per-string capacity.
const perStringCap = 128 << 10
var containsMatch func(any) bool
containsMatch = func(data any) bool {
switch value := data.(type) {
@@ -231,13 +230,13 @@ func TestEmitterPrettyBlockScansRenderedTextBeforeWriting(t *testing.T) {
}
}
func TestEmitterPrettyBlockScansLargeRenderedTextPastPerStringCap(t *testing.T) {
func TestEmitterPrettyBlockDetectsLongMatchPastFirstScanWindow(t *testing.T) {
t.Setenv("LARKSUITE_CLI_CONTENT_SAFETY_MODE", "block")
const match = "blocked phrase"
// Place the match beyond the scanner's per-string cap and across a scan
// window boundary. A single-string scan misses it; overlapping windows keep
// the complete match visible to the provider.
rendered := strings.Repeat("a", 188410) + match + "\n"
const nativePerStringCap = 128 << 10
// The match starts after the first native-capacity window and is longer than
// the old 64 KiB window. A native-capacity later window must retain it whole.
match := strings.Repeat("blocked", 10<<10)
rendered := strings.Repeat("a", nativePerStringCap+1) + match + "\n"
provider := &truncatingContractSafetyProvider{
alert: &extcs.Alert{
Provider: "truncating-emitter-contract",

View File

@@ -944,9 +944,18 @@ func runShortcut(cmd *cobra.Command, f *cmdutil.Factory, s *Shortcut, botOnly bo
// own format flag (e.g. base +record-list's markdown|json, mail +watch's
// json|data) owns a different enum, already validated by validateEnumFlags.
if !shortcutDeclaresFormatFlag(s) {
if _, err := output.ParseFormatStrict(rctx.Format); err != nil {
format, err := output.ParseFormatStrict(rctx.Format)
if err != nil {
return err
}
canonicalFormat := format.String()
if rctx.Str("format") != canonicalFormat {
if err := rctx.Cmd.Flags().Set("format", canonicalFormat); err != nil {
return errs.NewInternalError(errs.SubtypeUnknown,
"failed to canonicalize the framework --format value").WithCause(err)
}
}
rctx.Format = canonicalFormat
}
if s.Validate != nil {
if err := s.Validate(rctx.ctx, rctx); err != nil {

View File

@@ -367,6 +367,40 @@ func TestRunShortcut_DryRunMixedCasePrettyUsesPlainTextPreview(t *testing.T) {
}
}
func TestRunShortcut_MixedCaseFrameworkFormatIsCanonicalized(t *testing.T) {
var runtimeFormat string
var flagFormat string
prettyBranchFired := false
s := &Shortcut{
Service: "test",
Command: "test-shortcut",
AuthTypes: []string{"bot"},
Execute: func(_ context.Context, rctx *RuntimeContext) error {
runtimeFormat = rctx.Format
flagFormat = rctx.Str("format")
prettyBranchFired = rctx.Format == "pretty"
return nil
},
}
f := newTestFactory()
cmd := newTestShortcutCmd(s, f)
cmd.Flags().Set("format", "PRETTY")
cmd.Flags().Set("as", "bot")
if err := runShortcut(cmd, f, s, false); err != nil {
t.Fatalf("runShortcut() error = %v", err)
}
if runtimeFormat != "pretty" {
t.Fatalf("RuntimeContext.Format = %q, want pretty", runtimeFormat)
}
if flagFormat != "pretty" {
t.Fatalf("RuntimeContext.Str(\"format\") = %q, want pretty", flagFormat)
}
if !prettyBranchFired {
t.Fatal("downstream RuntimeContext.Format == \"pretty\" branch did not fire")
}
}
func TestRunShortcut_UnknownFormatErrorIncludesPretty(t *testing.T) {
s := &Shortcut{
Service: "test",