Skip to content

feat: support array body fields as repeatable CLI flags #1

@toyayuto

Description

@toyayuto

Body

Problem

When an OpenAPI request body has an array-typed property, specli does not generate a CLI flag for it. The property is silently skipped in body-flags.ts:

// src/cli/runtime/body-flags.ts — collectFlags()
} else if (
  t === "string" ||
  t === "number" ||
  t === "integer" ||
  t === "boolean"
) {
  // Leaf property - generate a flag
  out.push({ ... });
}
// Skip arrays and other complex types for now

This means any endpoint whose only body field is an array becomes effectively unusable from the CLI (no flags are generated, so the user has no way to provide the required data other than --data).

Real-world example

The Langfuse CLI (which uses specli) has this endpoint:

PATCH /api/public/v2/prompts/{name}/versions/{version}

Request body schema:

schema:
  type: object
  properties:
    newLabels:
      type: array
      items:
        type: string
  required:
    - newLabels

The CLI command prompt-versions update is generated with the correct positional args (<name> and <version>), and the help text says "Update labels for a specific prompt version" — but there is no --new-labels flag, so the user cannot actually update labels without falling back to --data '{"newLabels": ["production"]}'.

Proposed solution

specli already supports repeatable flags for query/header array parameters in generated.ts:

if (isArray) {
  cmd.option(key, desc, (value, prev) => {
    const next = [...(prev ?? [])];
    const items = coerceArrayInput(value, itemType);
    for (const item of items) next.push(item);
    return next;
  });
}

The same pattern could be applied to body field flags:

  1. In body-flags.ts, handle type: "array" when items.type is a scalar (string, number, integer, boolean)
  2. Add an isArray field to BodyFlagDef
  3. In generated.ts, use the repeatable flag pattern for array body flags
  4. In parseDotNotationFlags, collect array values into an actual array in the output object

This would allow:

# All equivalent:
mycli prompt-versions update my-prompt 4 --new-labels production --new-labels staging
mycli prompt-versions update my-prompt 4 --new-labels production,staging

Environment

  • specli: 0.0.39
  • Node.js: 22.x
  • OS: macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions