Skip to content

feat: add support for multiPositional#199

Open
kricsleo wants to merge 9 commits intounjs:mainfrom
kricsleo:feat/multi-positional
Open

feat: add support for multiPositional#199
kricsleo wants to merge 9 commits intounjs:mainfrom
kricsleo:feat/multi-positional

Conversation

@kricsleo
Copy link
Copy Markdown
Member

@kricsleo kricsleo commented Apr 9, 2025

resolves #115
resolves #80

This PR adds support for multiPositional.

Summary by CodeRabbit

  • New Features
    • Added a multi-positional argument type to capture multiple values in one command, with defaults and required/optional validation.
  • Documentation
    • Usage output and argument listing updated to show multi-positional placeholders and descriptive default hints.
  • Tests
    • Added tests covering parsing, defaults, optional/required behavior, and error handling for the new argument type.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@ea428c7). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #199   +/-   ##
=======================================
  Coverage        ?   97.62%           
=======================================
  Files           ?        8           
  Lines           ?      379           
  Branches        ?      135           
=======================================
  Hits            ?      370           
  Misses          ?        8           
  Partials        ?        1           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kricsleo kricsleo marked this pull request as ready for review April 10, 2025 08:19
@kricsleo kricsleo changed the title WIP: add support for multiPositional feat: add support for multiPositional Apr 10, 2025
@valadaptive
Copy link
Copy Markdown

/cc @pi0: this has been sitting since April, and I wanted to make sure it was on your radar. I'm working on a CLI app that could make use of this feature and found my way to this PR.

Preserve multiPositional feature while adopting main's changes:
- Remove number type (dropped in main)
- Use colors.cyan instead of backtick formatting for multiPositional
- Adopt satisfies ParseOptions pattern
- Update inline snapshots

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 15, 2026

📝 Walkthrough

Walkthrough

Adds a new multiPositional argument type across the CLI: types, parser, usage rendering, tests, and an example command now accept and handle multiple positional values (e.g., likes collects multiple values).

Changes

Cohort / File(s) Summary
Type System
src/types.ts
Introduce multiPositional in ArgType; add MultiPositionalArgDef; allow _ArgDef VT to be string[]; add ParsedMultiPositionalArg and extend ParsedArg/ParsedArgs paths to support string[] results.
Parser Implementation
src/args.ts
Expand ParseOptions.default to permit string[]; add parsing branch for multiPositional to consume remaining positional args, apply defaults, or error if required and missing.
Usage Rendering
src/usage.ts
Add multiPositional rendering: uppercase name, required detection, default hint handling, and usage placeholder <...NAME> or optional [...] formatting; update ARGUMENTS listing.
Tests
test/args.test.ts, test/usage.test.ts
Add tests for multiPositional parsing (defaults, optional, required-missing error) and usage output with the new multi positional placeholder and ARGUMENTS entry.
Example / Playground
playground/hello.ts
Add exported likes argument of type multiPositional with description and default; command output now includes "You like ..." when likes contains items.
Manifest / Package
package.json
Minor manifest updates referenced by other changes (lines changed).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • pi0

Poem

"I'm a rabbit with a pocket full of keys,
I gather words like carrots in the breeze.
Now many names hop into one little jar,
<...NAMES> dance — near and far! 🥕🐇"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main feature being added: support for the multiPositional argument type.
Linked Issues check ✅ Passed The PR implements the core requirements from both issues: adds multiPositional type support to capture multiple positional arguments [#115, #80], enabling CLIs to accept multiple filenames as positional args.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing multiPositional support across type definitions, argument parsing, usage rendering, and tests with no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

Tip

CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.

Add a .trivyignore file to your project to customize which findings Trivy reports.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/usage.test.ts (1)

28-32: Redundant name property.

The name: "pos" property appears to be unused here. The argument name is derived from the object key (multiPositional), as evidenced by the snapshot showing MULTIPOSITIONAL in the output. This pattern exists in other args in this test (lines 25, 35, 41), so it's not introduced by this PR, but you could clean it up for consistency.

🧹 Optional cleanup
        multiPositional: {
          type: "multiPositional",
-          name: "pos",
          description: "Multi positional",
        },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/usage.test.ts` around lines 28 - 32, Remove the redundant name property
from the multiPositional arg object in the test (the object keyed as
multiPositional in test/usage.test.ts); the arg name is derived from the key, so
delete the line containing name: "pos" from the multiPositional object
(mirroring the pattern used for the other args in this test such as the nearby
entries) to keep the test consistent and avoid unused properties.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/usage.test.ts`:
- Around line 28-32: Remove the redundant name property from the multiPositional
arg object in the test (the object keyed as multiPositional in
test/usage.test.ts); the arg name is derived from the key, so delete the line
containing name: "pos" from the multiPositional object (mirroring the pattern
used for the other args in this test such as the nearby entries) to keep the
test consistent and avoid unused properties.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2f33afb4-ebb3-4aed-b6d2-b2e8bc6ec111

📥 Commits

Reviewing files that changed from the base of the PR and between cc75125 and 7262ac8.

📒 Files selected for processing (6)
  • playground/hello.ts
  • src/args.ts
  • src/types.ts
  • src/usage.ts
  • test/args.test.ts
  • test/usage.test.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/usage.ts (2)

43-47: Consider aligning column structure and description hints with positional args.

Two inconsistencies with the positional branch (line 52):

  1. Column count: multiPositional pushes 3 columns [name, description, valueHint], while positional pushes 2 columns. This may cause formatting inconsistencies in formatLineColumns when both types appear together in posLines.

  2. Description format: positional uses renderDescription(arg, isRequired) which includes (Required) and (Default: ...) hints in the description column. multiPositional only uses arg.description || "", omitting these hints.

♻️ Proposed fix for consistency
      const name = arg.name.toUpperCase();
      const isRequired = arg.required !== false && arg.default === undefined;
-      // (isRequired ? " (required)" : " (optional)"
-      const defaultHint = arg.default ? `=[${arg.default}]` : "";
      posLines.push([
-        colors.cyan(name + defaultHint),
-        arg.description || "",
-        arg.valueHint ? `<${arg.valueHint}>` : "",
+        colors.cyan(name + renderValueHint(arg)),
+        renderDescription(arg, isRequired),
       ]);
      usageLine.push(isRequired ? `<...${name}>` : `[...${name}]`);

This also requires updating renderValueHint to handle multiPositional:

-  if (!arg.type || arg.type === "positional" || arg.type === "boolean") {
+  if (!arg.type || arg.type === "positional" || arg.type === "multiPositional" || arg.type === "boolean") {
     return valueHint;
   }

Note: renderDescription will display array defaults as (Default: a,b) via implicit toString. If a different format is preferred for arrays, consider extending renderDescription to handle array defaults explicitly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/usage.ts` around lines 43 - 47, posLines assembly for multiPositional is
inconsistent with positional: multiPositional pushes three columns [name,
description, valueHint] while positional pushes two, and multiPositional omits
required/default hints that renderDescription provides; fix by making
multiPositional push the same column structure as positional (use
colors.cyan(name + defaultHint) and renderDescription(arg, isRequired) for the
description column) and move any value-hint rendering into renderValueHint so
both branches call renderValueHint(arg) for the third column (which may return
"" when not applicable); update renderValueHint to return an appropriate string
for multiPositional entries (e.g., format <value> or empty) and ensure
formatLineColumns is fed uniform column counts.

41-41: Remove orphaned comment.

This appears to be leftover debug or development code. The comment is incomplete and serves no purpose.

🧹 Proposed fix
      const isRequired = arg.required !== false && arg.default === undefined;
-      // (isRequired ? " (required)" : " (optional)"
      const defaultHint = arg.default ? `=[${arg.default}]` : "";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/usage.ts` at line 41, Remove the orphaned commented fragment "//
(isRequired ? \" (required)\" : \" (optional)\"" from the codebase; this
incomplete comment serves no purpose and should be deleted so the surrounding
function (the usage/help text builder) no longer contains the stray leftover
debug text.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/usage.ts`:
- Around line 43-47: posLines assembly for multiPositional is inconsistent with
positional: multiPositional pushes three columns [name, description, valueHint]
while positional pushes two, and multiPositional omits required/default hints
that renderDescription provides; fix by making multiPositional push the same
column structure as positional (use colors.cyan(name + defaultHint) and
renderDescription(arg, isRequired) for the description column) and move any
value-hint rendering into renderValueHint so both branches call
renderValueHint(arg) for the third column (which may return "" when not
applicable); update renderValueHint to return an appropriate string for
multiPositional entries (e.g., format <value> or empty) and ensure
formatLineColumns is fed uniform column counts.
- Line 41: Remove the orphaned commented fragment "// (isRequired ? \"
(required)\" : \" (optional)\"" from the codebase; this incomplete comment
serves no purpose and should be deleted so the surrounding function (the
usage/help text builder) no longer contains the stray leftover debug text.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fdd11df2-6d80-48ab-aa01-238f1293fea6

📥 Commits

Reviewing files that changed from the base of the PR and between 7262ac8 and 10b839a.

📒 Files selected for processing (2)
  • src/usage.ts
  • test/usage.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/usage.test.ts

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.

Support multiple (wildcard) positional args Support multiple optional positional args

3 participants