Skip to content

Add wrap() method for type-safe external CLI tool integration#2

Merged
KurtGokhan merged 12 commits intomainfrom
copilot/add-wrap-method-for-cli-tools
Mar 10, 2026
Merged

Add wrap() method for type-safe external CLI tool integration#2
KurtGokhan merged 12 commits intomainfrom
copilot/add-wrap-method-for-cli-tools

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 2, 2026

Implementation Complete: wrap() Method Single-Argument API ✅

Summary

Successfully refactored wrap() method to use single-argument API where the schema is passed as an optional property in the config object. All implementation, tests, and documentation updated.

Changes Made (per latest feedback)

  • Single-argument API - wrap() now takes only one config argument
  • Schema in config - Optional schema property in WrapConfig for transformation
  • Backward compatible defaults - When schema is omitted, options pass through as-is
  • Updated all tests - 15 wrap tests updated to new API format
  • All 205 tests pass - No breaking changes to other features
  • Complete documentation - API reference and usage guide fully updated
  • CI fixed - Resolved TypeScript error with test parameter

New API Design

Signature:

.wrap<TWrapOpts>(config: WrapConfig<TCommandOpts, TWrapOpts>)

interface WrapConfig<TCommandOpts, TWrapOpts> {
  command: string;
  args?: string[];
  positional?: string[];
  inheritStdio?: boolean;
  schema?: TWrapOpts | ((commandOptions: TCommandOpts) => TWrapOpts);  // Optional transformation
}

Usage Examples

No transformation (identity):

.arguments(z.object({ message: z.string() }))
.wrap({
  command: 'echo',
})

With schema transformation:

.arguments(z.object({
  message: z.string(),
  all: z.boolean().optional(),
}))
.wrap({
  command: 'git',
  args: ['commit'],
  positional: ['m'],
  schema: z.object({
    message: z.string(),
    all: z.boolean().optional(),
  }).transform(opts => ({
    m: opts.message,
    a: opts.all,
  })),
})

Function-based schema:

.arguments(z.object({ image: z.string(), detach: z.boolean() }))
.wrap({
  command: 'docker',
  args: ['run'],
  positional: ['image'],
  schema: (cmdSchema) => cmdSchema.transform(opts => ({
    image: opts.image,
    d: opts.detach,
  })),
})

Implementation Details

Files Modified:

  1. packages/padrone/src/wrap.ts - Updated WrapConfig type and createWrapHandler signature
  2. packages/padrone/src/types.ts - Updated wrap() method signature and JSDoc
  3. packages/padrone/src/create.ts - Updated to pass single config argument
  4. packages/padrone/tests/wrap.test.ts - Updated all 15 tests to new API + CI fix
  5. docs/src/content/docs/reference/api.md - Updated API documentation
  6. docs/src/content/docs/guides/wrapping-external-tools.md - Updated usage guide

Key Features:

  • Single config argument with optional schema property
  • Schema defaults to identity transform (options pass through)
  • Maintains full type inference
  • Custom positional config per wrap
  • Function-based or direct schema support

Validation Results

All 205 tests pass (15 wrap-specific)
Lint/format checks pass (Biome)
Type checking passes (TypeScript)
Documentation complete (API ref + usage guide)
CI passing (All checks green)

Commits

  • 25ed063 - Refactor wrap() to single-argument API with schema in config object
  • 8806884 - Complete documentation updates for single-argument wrap() API
  • Current - Fix TypeScript error in wrap test - use empty object instead of undefined
Original prompt

Create a wrap method that can be used to wrap external CLI tools and proxy any calls to them. Make sure of type safety. Create tests and docs.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits March 2, 2026 10:28
Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add wrap method for external CLI tools with type safety Add wrap() method for type-safe external CLI tool integration Mar 2, 2026
Copy link
Copy Markdown
Owner

@KurtGokhan KurtGokhan left a comment

Choose a reason for hiding this comment

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

There is no need to rename to kebab-case, or map options.

If options need to be mapped, a Zod schema can map it from the parsed input

Copy link
Copy Markdown
Owner

@KurtGokhan KurtGokhan left a comment

Choose a reason for hiding this comment

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

There is no need to rename to kebab-case, or map options.

If options need to be mapped, a Zod schema can map it from the parsed input

… Zod transform instead

Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 2, 2026

There is no need to rename to kebab-case, or map options.

If options need to be mapped, a Zod schema can map it from the parsed input

Simplified the implementation in commit e60ce0f. Removed automatic kebab-case conversion and the optionMapping field. Option keys are now used as-is with -- prefix. Documentation updated to show how to use Zod's .transform() for custom flag mappings.

There is no need to rename to kebab-case, or map options.

If options need to be mapped, a Zod schema can map it from the parsed input

Addressed in commit e60ce0f. Removed kebab-case conversion and optionMapping. Users can now map options to CLI flags using Zod's .transform() method.

Copy link
Copy Markdown
Owner

@KurtGokhan KurtGokhan left a comment

Choose a reason for hiding this comment

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

Wrap method should take a schema, with the input type as the parsed command arguments, and output type as the arguments the external program expects.

It should also take a positional config, which is by default same as the wrapping command.

…ons to external CLI args

Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 10, 2026

Wrap method should take a schema, with the input type as the parsed command arguments, and output type as the arguments the external program expects.

It should also take a positional config, which is...

Implemented in commit dd261ea. The wrap() method now takes a schema parameter that transforms from command options to external CLI arguments. The schema can be passed directly or as a function receiving the command options schema. Added positional field to WrapConfig that defaults to the wrapping command's positional configuration.

Copilot AI and others added 2 commits March 10, 2026 07:17
Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Copy link
Copy Markdown
Owner

@KurtGokhan KurtGokhan left a comment

Choose a reason for hiding this comment

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

Wrap should still be single argument. The option to transform can be passed in the config object

Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 10, 2026

Wrap should still be single argument. The option to transform can be passed in the config object

Implemented in commit 25ed063. The wrap() method now takes a single config argument. The optional schema property in the config object handles transformation from command options to external CLI arguments.

Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
@KurtGokhan KurtGokhan marked this pull request as ready for review March 10, 2026 07:52
@KurtGokhan
Copy link
Copy Markdown
Owner

@copilot fix CI. What can I do to make you auto-fix CI runs in your own PRs?

…ined

Co-authored-by: KurtGokhan <6034931+KurtGokhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 10, 2026

@copilot fix CI. What can I do to make you auto-fix CI runs in your own PRs?

Fixed in commit a7b2ed0. The CI was failing due to a TypeScript error where undefined was passed to program.run() instead of an empty object {} for a command with no arguments.

To help auto-fix CI issues in the future, you could:

  1. Configure me to monitor CI runs and automatically investigate failures
  2. Set up automatic PR checks that trigger me when builds fail
  3. Grant permissions to access workflow run logs proactively

@KurtGokhan KurtGokhan merged commit 9492334 into main Mar 10, 2026
1 check passed
@KurtGokhan KurtGokhan deleted the copilot/add-wrap-method-for-cli-tools branch March 10, 2026 10:29
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.

2 participants